Fremde GUIs und Controls?

  • Hi,

    gibt es die Möglichkeit mit serienmäßigen Autoit-Funktionen fremde Controls anzusprechen, also auszulesen und/oder zu editieren? Wenn nein,gibt es überhaupt eine Möglichkeit?

    Konkret:
    Ich habe ein Programm als Child engebettet in der GUI meines Skriptes. Nun möchte ich die Scrollbar dieses Fensters ansprechen. Das WinHandle habe ich ja, bringt mir das etwas? Habe mit Au3Info probiert direkt an das Handle der Scrollbar zu kommen. Leider ist diese garnicht erst auswählbar.Funzt das nicht mit controls?

    Habe schon einiges gelesen,jedoch noch nix konkretes gefunden. Versuche es jetzt mit WinAPIEx UDF,lieber wäre mir natürlich eine eigene Funktion, dann müsste ich mich auch nicht erst durch die DOC lesen.

    Hier mal mal mein bisheriger Code:

    [autoit]

    Global $hGUI = GUICreate("BLA", 800, 600, -1, -1, BitOR($WS_MAXIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_SYSMENU, $WS_CLIPCHILDREN))
    Global $PID = Run("C:\EBOOKS\SumatraPDF.exe ", "", @SW_HIDE)
    Global $hWnd = 0
    Global $stPID = DllStructCreate("int")
    Global $nExStyle
    WinSetState("BLA", "", @SW_MAXIMIZE);

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

    Global $WinList
    Do
    $WinList = WinList()
    For $i = 1 To $WinList[0][0]
    If $WinList[$i][0] <> "" Then
    DllCall("user32.dll", "int", "GetWindowThreadProcessId", "hwnd", $WinList[$i][1], "ptr", DllStructGetPtr($stPID))
    If DllStructGetData($stPID, 1) = $PID Then
    $hWnd = $WinList[$i][1]
    ExitLoop
    EndIf
    EndIf
    Next
    Sleep(100)
    Until $hWnd <> 0
    $stPID = 0

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

    If $hWnd <> 0 Then
    $nExStyle = DllCall("user32.dll", "int", "GetWindowLong", "hwnd", $hWnd, "int", -20)
    $nExStyle = $nExStyle[0]
    DllCall("user32.dll", "int", "SetWindowLong", "hwnd", $hWnd, "int", -20, "int", BitOR($nExStyle, $WS_EX_MDICHILD))
    DllCall("user32.dll", "int", "SetParent", "hwnd", $hWnd, "hwnd", $hGUI)
    WinMove($hWnd, "", 200, -48, 825, 757) ;HIER auf 200,-48,600,650 stellen damit nicht mehr sichtbar
    WinSetState($hWnd, "", @SW_SHOW)

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

    EndIf
    GUISetState()

    [/autoit]
  • Habe eben bemerkt dass dei Windows Nachricht SBM_GETPOS Genau das liefert was ich suche. Kann ich das irgendwie ausnutzen und die Nachricht per autoit verschicken?

  • habe ich eben versucht. Laut msdn brauche ich nicht einmal lparam und wparam behandeln. Ich fürchte jedoch dafür brauche ich das Handle zu dem Control,also zur Scrollbar, und an das komme ich nicht ran. Habs auch mit den microsoft winspy tools probiert, die scrollbar ist aber nicht auswählbar

  • danke für die antwort.Habe ich eben ausprobiert und mit winspector festgestellt dass einfach nur WM_VSCROLL verschickt wird. Kann ich da irgendwie an den Momentan wert rankommen? In der MSDN habe ich gefunden:
    wParam
    The HIWORD specifies the current position of the scroll box if the LOWORD is SB_THUMBPOSITION or SB_THUMBTRACK; otherwise, this word is not used.....


    Quelle:http://msdn.microsoft.com/en-us/library/…v=vs.85%29.aspx

    Jedoch habe ich keine ahnung wie ich die Msg korrekt verschicke,da mir die beschreibung der anderen Parameter absolut nix sagt. Hat da jemand erfahrung`?

  • hi autobert,

    es geht um das Programm Sumatra_PDF. Ich möchte persönliche Markierungen und Kommentare zu meinen ebooks hinzufügen. Dazu möchte ich jedoch nicht die pdf manipulieren sondern eine eigene "Layout"-Datei anlegen in der dann Art, Position, Größe ,Inhalt, etc.... der Markierung gespeichert werden. Dazu brauche ich so etwas wie Koordinaten. Einfach die Mauskoord.nehmen geht nicht, weil damit das scrollen und zoomen nicht berücksichtigt wird. Gibts es vielleicht einen einfacheren Weg?

    edit:Ich scheiter schon daran die Nachrichten des eingebetteten child-fensters auszulesen.
    Habs probiert mit

    [autoit]

    guiswitch(hwndSumatra)
    GuiRegisterMsg(WM_RBUTTONDOWN,"WM_RBUTTONDOWN") ;Nur als test
    guiswitch(hwndParent)

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

    func WM_RBUTTONDOWN
    ConsoleWrite("RBUTTONDOWN")
    endfunc

    [/autoit]

    Die Konsole meldet sich aber immer nur, wenn ich im Hauptfenster rechtsklicke. Da nützt auch GuiSwitch nix.
    Gibt es vllt. sowas wie GuiRegisterMsgForHwnd(....) ? Das müsste doch mit autoit machbar sein


    EDIT:Habe mich nun etwa mehr eingelesen und weiss nun dass es etwas mit Hooks zu tun hat. Zum glück gibts da die WinapiEx.udf

    3 Mal editiert, zuletzt von taugenix (5. August 2012 um 19:17)

  • Sooo... bin jetzt einigermaßen dahintergestiegen wie hooks funktionieren. Hier ein kleines BSP für interessierte:

    [autoit]

    #include <WinAPI.au3>

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

    Dim Const $WM_RBUTTONDOWN = 0x0204

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

    Dim Const $tagMSLLHOOKSTRUCT = $tagPOINT&';dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo'

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

    HotKeySet('{ESC}', '_EXIT')
    Run("notepad.exe")
    WinWait("[CLASS:Notepad]")
    WinActivate("[CLASS:Notepad]")

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

    $hFunc = DllCallbackRegister("Mouse_LL", "long", "int;wparam;lparam")
    $pFunc = DllCallbackGetPtr($hFunc)
    $hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, $pFunc, _WinAPI_GetModuleHandle(0))

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

    While 1
    sleep(100)
    WEnd

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

    Func _EXIT()
    Exit
    EndFunc

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

    Func OnAutoItExit()
    _WinAPI_UnhookWindowsHookEx($hHook)
    DllCallbackFree($hFunc)
    EndFunc

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

    Func Mouse_LL($iCode, $iwParam, $ilParam)
    Local $tMSLLHOOKSTRUCT = DllStructCreate($tagMSLLHOOKSTRUCT, $ilParam)

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

    If $iCode < 0 Then
    Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
    EndIf

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

    If $iwParam = $WM_RBUTTONDOWN Then
    local $state
    $state= WinGetState("[CLASS:Notepad]")
    if $State=15 Then
    ConsoleWrite('WM_RBUTTONDOWN'); & @TAB)
    endif

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

    EndIf

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

    Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
    EndFunc ;==>_KeyProc

    [/autoit]

    Aber vielleicht kann mir doch jemand zumindest eine frage beantworten: Testes mal das Bsp. Wenn man im Editor rechtsklickt erscheint ja normalerweise das kleine Menü (Kopieren,Einfügen,Ausschneiden, etc...)
    Wie kann ich dieses Control ansprechen? Ich möchte es z.B. schließen mit WinKill(...)

    Mit Winspector habe ich zumindest den Klassennamen des Fensters bestimmen können.Er ist #32768
    Teste ich aber mit WinGetHandle("[CLASS:32768]) oder auch WinGetHandle("[CLASS:#32768]) erhalte ich als rückgabewert einen leeren string (= " " ), d.h. das fenster wurde garnicht erst gefunden????

    Was mache ich falsch?