GUIRegisterMsg($WM_DRAWITEM, ...) Problem mit Map

  • Ich habe die Problematik mal auf ein mimimales Skript runtergebrochen.
    Im Original lese ich Daten aus einer INI in eine Map, habe ich hier nachgestellt.
    Diese Daten sollen abhängig von dem Wert in 'access' (0/1) in rot oder Schwarz in der Combobox gelistet werden. Das funktioniert auch grundlegend.
    Versuche ich jedoch innerhalb der WM_DRAWITEM-Funktion aus der Map den Wert für 'access' abzufragen, um entsprechend einzufärben, bekomme ich einen Fehler:

    Code
    ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:
    If $mUnit[GUICtrlRead($cCombo)]['access'] = 0 Then $clrForeground = 0x0000FF
    If $mUnit[GUICtrlRead($cCombo)]^ ERROR

    Wie aber im Skript sichtbar ist, lasse ich zur Kontrolle die gesamte Map vorab in die Konsole ausgeben - problemlos.
    Eigentlich könnte ich statt GUICtrlRead($cCombo) auf das funktionsintern gelesene $sText zugreifen. Hatte das aber mal testweise geändert, um es als Fehlerquelle auszuschließen.

    Vielleicht hat ja schonmal jemand das Problem gehabt.

    In Zeilen #90 / #91 mal die Kommentierung tauschen, um den Effekt zu sehen.

  • Scheint eventuell ein Bug zu sein, denn die globale Variable $mUnit ist nicht vollständig in der Funktion _WM_DRAWITEM sichtbar, selbst wann man aus der _WM_DRAWITEM Funktion eine andere Function aufruft.

    Kanashius die Farbe wird dann für alle gesetzt und nicht nach "Access".

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Ja, weil in seinem Beispiel die ComboBox (für alle Einträge) ausgelesen wird.

    Zitat

    Eigentlich könnte ich statt GUICtrlRead($cCombo) auf das funktionsintern gelesene $sText zugreifen. Hatte das aber mal testweise geändert, um es als Fehlerquelle auszuschließen.

    Wenn man das also mit $sText ersetzt sieht es so aus:

    AutoIt
    If MapExists($mUnit, $sText) And $mUnit[$sText]['access'] = 0 Then $clrForeground = 0x0000FF

    Und das funktioniert bei mir einwandfrei. Es sind Einträge in der Liste Rot und wenn man die auswählt ist auch die Farbe in dem ComboFeld richtig.

    Wenn ich mir $sText ausgeben lasse ist es halt manchmal ein leerer String und in so einem Fall existiert $mUnit[$sText] nunmal nicht und wenn man dann damit auf etwas zugreifen will schlägt das mit der Fehlermeldung fehl.
    Ich hab mir mit _ToStringC($mUnit) (_toString für alle (AutoIt-) Objekte (und mehr) sowie eine Methode zum Errorhandling) das ganze auch ausgeben lassen und die Map war immer komplett definiert.

    Win10, AutoIt 3.3.16.1

  • Wenn ich mir $sText ausgeben lasse ist es halt manchmal ein leerer String

    Ja, ich war der (irrigen) Meinung, wenn ich die Listbox befüllt habe, ist doch da auf jeden Fall Inhalt. Der Inhalt, der in der Callbackfunktion relevant ist, entsteht ja erst beim Zeichnen desselben. Somit ist beim ersten Zeichnen der Wert von _GUICtrlComboBox_GetLBText noch leer und führt zum Crash.

    Ich habe die Callbackfunktion jetzt dahingehend angepasst, dass sie bei leerem Text wieder verlassen wird.

  • Moin, die Ursache der Abbrüche ist wahrscheinlich:

    DRAWITEMSTRUCT

    Zitat

    itemID

    Type: UINT

    The menu item identifier for a menu item or the index of the item in a list box or combo box. For an empty list box or combo box, this member can be -1. This allows the application to draw only the focus rectangle at the coordinates specified by the rcItem member even though there are no items in the control. This indicates to the user whether the list box or combo box has the focus. How the bits are set in the itemAction member determines whether the rectangle is to be drawn as though the list box or combo box has the focus.

    Weil das Strukturfeld auch im Skript als UInt definiert ist, kommt als Wert 4294967295 an. Für diesen 'Index' kann man die _WM_DRAWITEM Funktion sofort verlassen.