Subclassing und AutoIts interne Nachrichtenverarbeitung

  • Hi,

    ich bin im Rahmen eines größeren Projektes mit AutoIt auf ein kleines Problem gestoßen. Konkret betrifft das das Thema Subclassing, also Veränderung der internen Nachrichtenverarbeitung eines Fensters (und damit Controls). Dazu gibt es grundsätzlich mehrere Möglichkeiten. Man kann einmal die Subclassing-API verwenden, man kann aber auch simpel über SetWindowLong die WndProc verändern (siehe Code). Ich präferiere eigentlich die zweitere Möglichkeit, weil die Subclassing-API bei mir immer mal wieder Probleme verursacht hat.

    Nun stehe ich jedoch vor dem Problem, dass beim Ersetzen der WndProc scheinbar AutoIts internes Nachrichtenhandling nicht mehr greift. Das heißt, ich kriege weder im OnEvent-Modus noch über GUIGetMsg() irgendwelche Aktionen mit dem Control mit. Auch ein Minimalbeispiel zeigt, dass das Problem nur beim Ersetzen der WndProc auftritt, nicht beim Nutzen der Subclassing-API. In den jeweiligen WndProcs/SubclassingProcs kommt jedoch die entsprechende Klick-Nachricht korrekt an. Übersehe ich etwas, oder geht hier AutoIt-Intern was gewaltig schief?

  • Ich präferiere eigentlich die zweitere Möglichkeit, weil die Subclassing-API bei mir immer mal wieder Probleme verursacht hat.

    Das Thema hatten wir doch vor kurzem... Oscar hatte da auch ein Problem damit... im blauen Forum gibt es dazu auch einen Thread.

    Ich arbeite derzeit auch an einem großen Projekt, bei dem ich mehrere Listviews (farbig) und Header (mehrzeilig) mit Subclassing bearbeite und hatte auch arge Probleme damit (Script stürzt ab oder friert ein).

    Der Grund war bei mir folgende Zeilen:

    Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $iWParam, $iLParam)

    Return _WinAPI_CallWindowProc($pOldWndProc, $hWnd, $iMsg, $iWParam, $iLParam)

    Die habe ich durch diese ersetzt und mein Problem war damit gelöst:

    Return DllCall("comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $iWParam, "lparam", $iLParam)[0]

    Return DllCall("user32.dll", "lresult", "CallWindowProc", "ptr", $pOldWndProc, "hwnd", $hWnd, "uint", $iMsg, "wparam", $iWParam, "lparam", $iLParam)[0]

    Nun stehe ich jedoch vor dem Problem, dass beim Ersetzen der WndProc scheinbar AutoIts internes Nachrichtenhandling nicht mehr greift.

    Ja, bin sehr erstaunt, dass es mit WndProc nicht (mehr) geht...

    Einmal editiert, zuletzt von Bitnugger (18. November 2018 um 13:29)

  • Ja, bin sehr erstaunt, dass es mit WndProc nicht (mehr) geht...

    So, ich hab's gelöst. Des Rätsels Lösung liegt im GWL_USERDATA-Feld. AutoIt scheint dort Informationen zu speichern. Um den Zugriff auf globale Variablen zu vermeiden, hatte ich in meinem Minimalbeispiel die Adresse der alten WNDPROC in diesem Feld abgelegt. Ohne funktioniert's.