_WinAPI_SetWindowSubclass und additional/reference data

  • Grüßt euch erstmal,
    ich möchte mit _WinAPI_SetWindowSubclass ( $hWnd, $pSubclassProc, $ID [, $pData = 0] ) ein structure übergeben. Komischerweise kann ich den Inhalt nur korrekt auslesen, wenn

    Zitat

    $iMsg = 135 And $iwParam = 0 And $ilParam = 0


    ist. Wenn ich das COnsoleWrite außerhalb der Abfrage setze, liest er komische ASCII Zeichen oder so aus. Außerdem stürzt er ab, sobald ich mit dem Cursor ins ComboBox Feld komme. Hat jemand eine Idee, wieso ich nur mit diesen bestimmten Bedingungen das structure korrekt auslesen kann?

    [autoit]

    #include <WinAPIShellEx.au3>
    #include <GUIConstantsEx.au3>
    #include <GuiComboBox.au3>

    [/autoit][autoit][/autoit][autoit]

    OnAutoItExitRegister('OnAutoItExit')

    [/autoit][autoit][/autoit][autoit]

    ; Create GUI
    Local $hForm = GUICreate('Test ' & StringReplace(@ScriptName, '.au3', '()'))
    Local $hCombo = _GUICtrlComboBox_Create($hForm, "", 2, 2, 396, 296)

    [/autoit][autoit][/autoit][autoit]

    ; Register DLL callback that will be used as window subclass procedure
    Local $hDll = DllCallbackRegister('_SubclassProc', 'lresult', 'hwnd;uint;wparam;lparam;uint_ptr;dword_ptr')
    Local $pDll = DllCallbackGetPtr($hDll)
    Local $hDll2 = DllCallbackRegister('_SubclassProc2', 'lresult', 'hwnd;uint;wparam;lparam;uint_ptr;dword_ptr')
    Local $pDll2 = DllCallbackGetPtr($hDll2)

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    ; Install window subclass callback
    _WinAPI_SetWindowSubclass($hForm, $pDll, 1000, 0)

    [/autoit][autoit][/autoit][autoit]

    GUISetState(@SW_SHOW)

    [/autoit][autoit][/autoit][autoit]

    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    [/autoit][autoit][/autoit][autoit]

    Func _SubclassProc($hWnd, $iMsg, $iwParam, $ilParam, $ID, $pData)
    #forceref $ID, $pData

    [/autoit][autoit][/autoit][autoit]

    Local $Array[3] = ["test", "hallo", "gih"]
    Local $struct = _WinAPI_ArrayToStruct($Array)
    _WinAPI_SetWindowSubclass($hCombo, $pDll2, 1001, DllStructGetPtr($struct))

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $iwParam, $ilParam)
    EndFunc ;==>_SubclassProc

    [/autoit][autoit][/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func _SubclassProc2($hWnd, $iMsg, $iwParam, $ilParam, $ID, $pData)
    #forceref $ID, $pData

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    If $iMsg = 135 And $iwParam = 0 And $ilParam = 0 Then
    Local $struct1 = DllStructCreate("wchar[5];wchar[6];wchar[4];wchar[1]", Ptr($pData))
    ConsoleWrite("$iMsg: " & $iMsg & " $iwParam: " & $iwParam & " $ilParam: " & $ilParam & " data1: " & DllStructGetData($struct1, 1) & " data2: " & DllStructGetData($struct1, 2) & " data3: " & DllStructGetData($struct1, 3) & @CRLF)
    EndIf
    Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $iwParam, $ilParam)
    EndFunc ;==>_SubclassProc

    [/autoit][autoit][/autoit][autoit]

    Func OnAutoItExit()
    _WinAPI_RemoveWindowSubclass($hForm, $pDll, 1000)
    _WinAPI_RemoveWindowSubclass($hCombo, $pDll2, 1001)
    DllCallbackFree($hDll)
    DllCallbackFree($hDll2)
    EndFunc ;==>OnAutoItExit

    [/autoit]

    Edit: Klappt auch mit

    Zitat

    $iMsg: 132 $iwParam: 0 $ilParam: 21627917 data1: test data2: hallo data3: gih


    Irgendwas stimmt da nicht...

  • ok besseres Beispiel:

    [autoit]

    #include <GuiComboBox.au3>
    #include <GuiListView.au3>
    #include <GuiEdit.au3>
    #include <WindowsConstants.au3>
    #include <WinAPI.au3>
    #include <WinAPIShellEx.au3>

    [/autoit][autoit][/autoit][autoit]

    $hHandle = DllCallbackGetPtr(DllCallbackRegister('MY_SUBCLASSPROC', 'LRESULT', 'HWND;UINT;WPARAM;LPARAM;UINT_PTR;DWORD_PTR'))
    $hHandle2 = DllCallbackGetPtr(DllCallbackRegister('MY_SUBCLASSPROC2', 'LRESULT', 'HWND;UINT;WPARAM;LPARAM;UINT_PTR;DWORD_PTR'))

    [/autoit][autoit][/autoit][autoit]

    GUI()
    Func GUI()
    Global $gui = GUICreate('Subclass Test - Phoenix XL', 450, 500)
    Global $hListView = _GUICtrlListView_Create($gui, "", 2, 2, 394, 268)
    Global $hEdit = _GUICtrlEdit_Create($hListView, 'Hello world!', 10, 45, 250, 25, BitOR($WS_TABSTOP, $WS_CHILD, $WS_VISIBLE, $ES_LEFT, $ES_AUTOHSCROLL, $ES_NOHIDESEL), $WS_EX_CLIENTEDGE)
    Global $hCombo = _GUICtrlComboBox_Create($hListView, "test", 10, 10, 50, 25)
    _GUICtrlComboBox_AddDir($hCombo, "", $DDL_DRIVES, False)

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    ;~ $struct = Test() ; Wenn ich den unteren Befehlsblock in dieser Funktion ausführen lasse, dann lässt sich der Inhalt des structures nicht mehr auslesen, aber warum?

    [/autoit][autoit][/autoit][autoit][/autoit][autoit][/autoit][autoit]

    ; so funktioniert es
    Local $struct = DllStructCreate("wchar[5];wchar[5];wchar[5];wchar[5]")
    DllStructSetData($struct, 1, "test")
    DllStructSetData($struct, 2, "sack")
    DllStructSetData($struct, 3, "nege")
    DllStructSetData($struct, 4, "puff")
    _Winapi_SetWindowSubclass($hEdit, $hHandle, 0, DllStructGetPtr($struct))

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    GUISetState()

    [/autoit][autoit][/autoit][autoit]

    While (True)
    Switch (GUIGetMsg())
    Case -3 ;GUI_EVENT_CLOSE
    ExitLoop
    EndSwitch
    WEnd

    [/autoit][autoit][/autoit][autoit]

    _WinAPI_RemoveWindowSubclass($hEdit, $hHandle, 0)
    _WinAPI_RemoveWindowSubclass($hCombo, $hHandle2, 1)

    [/autoit][autoit][/autoit][autoit]

    Exit

    [/autoit][autoit][/autoit][autoit]

    EndFunc

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func Test()
    Local $struct = DllStructCreate("wchar[5];wchar[5];wchar[5];wchar[5]")
    DllStructSetData($struct, 1, "test")
    DllStructSetData($struct, 2, "sack")
    DllStructSetData($struct, 3, "nege")
    DllStructSetData($struct, 4, "puff")
    _Winapi_SetWindowSubclass($hEdit, $hHandle, 0, DllStructGetPtr($struct))
    EndFunc

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func MY_SUBCLASSPROC($hWnd, $uMsg, $wParam, $lParam, $uIdSubclass, $dwRefData)
    If $uMsg = $WM_LBUTTONDOWN Then
    ConsoleWrite(VarGetType($dwRefData) & " data: " & $dwRefData & @CRLF)

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    ConsoleWrite("pointer:" & Ptr($dwRefData) & @CRLF)

    [/autoit][autoit][/autoit][autoit]

    Local $struct1 = DllStructCreate("wchar[5];wchar[5];wchar[5];wchar[5]", Ptr($dwRefData))
    ConsoleWrite("data1: " & DllStructGetData($struct1, 1) & @CRLF)
    ConsoleWrite("data2: " & DllStructGetData($struct1, 2) & @CRLF)
    ConsoleWrite("data3: " & DllStructGetData($struct1, 3) & @CRLF)
    ConsoleWrite("data4: " & DllStructGetData($struct1, 4) & @CRLF)

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    _Winapi_SetWindowSubclass($hCombo, $hHandle2, 1, DllStructGetPtr($struct1))
    Return 0
    EndIf
    Return _Winapi_DefSubclassProc($hWnd, $uMsg, $wParam, $lParam)
    EndFunc

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func MY_SUBCLASSPROC2($hWnd, $uMsg, $wParam, $lParam, $uIdSubclass, $dwRefData)

    [/autoit][autoit][/autoit][autoit]

    If $uMsg = $WM_LBUTTONDOWN Then

    [/autoit][autoit][/autoit][autoit]

    Local $struct1 = DllStructCreate("wchar[5];wchar[5];wchar[5];wchar[5]", Ptr($dwRefData))
    ConsoleWrite("data1: " & DllStructGetData($struct1, 1) & @CRLF)
    ConsoleWrite("data2: " & DllStructGetData($struct1, 2) & @CRLF)
    ConsoleWrite("data3: " & DllStructGetData($struct1, 3) & @CRLF)
    ConsoleWrite("data4: " & DllStructGetData($struct1, 4) & @CRLF)

    [/autoit][autoit][/autoit][autoit]

    EndIf
    Return _Winapi_DefSubclassProc($hWnd, $uMsg, $wParam, $lParam)
    EndFunc

    [/autoit][autoit][/autoit][autoit][/autoit]

    Wenn ich Zeile 25 bis 30 auskommentiere und stattdessen in der Funktion Test() ausführe, kann ich den Inhalt in den subclasses nicht mehr auslesen, wenn ich den Befehlsblock innerhabl der Funktion GUI() lasse, klappt es. Hat jemand eine Idee warum das so ist?