WM_PAINT Hook - Bin ich richtig?

  • Sonstige

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von Facebamm.

    WM_PAINT Hook - Bin ich richtig?

    Hallo zusammen :D,

    Bin bin gerade bei via VBA (logisch in diesem Abteil) in ein Fenster zu hooken zu dort meine visuellen Dinge zu Zeichen.
    Btw. es ist kein richtiges Vba, in der Software ist das so ein Misch masch.
    e.g wenn ich beim Import nicht byval (was eig. default ist) angebe, funktioniert dieser nicht oder Unsigned-Typen gibt es auch nicht. Bit-Shiften erst recht nicht.

    Back to Top:

    Das Zeichen funktioniert so weit. Hab es einmal kurz gesehen und dann hat mir WM_PAINT wieder alles überzeichnet.
    Nun will ich via Hook nach WM_PAINT zeichnen und da kommt der Knackpunkt, die Software stürzt jedes mal ab, wenn ich beginne zu hooken

    Meine Imports sehen wie folgt zu Hook aus.

    Visual Basic-Quellcode

    1. 'https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setwindowshookexa
    2. Public Declare Function SetWindowsHookEx Lib "User32.dll" Alias "SetWindowsHookExA" (ByVal idHook As HookType, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
    3. 'https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setwindowshookexa
    4. Public Declare Function CallNextHookEx Lib "User32.dll" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    5. 'https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-unhookwindowshookex
    6. Public Declare Function UnhookWindowsHookEx Lib "User32.dll" (ByVal hHook As Long) As Boolean
    7. Public Enum HookType
    8. WH_JOURNALRECORD = 0
    9. WH_JOURNALPLAYBACK = 1
    10. WH_KEYBOARD = 2
    11. WH_GETMESSAGE = 3
    12. WH_CALLWNDPROC = 4
    13. WH_CBT = 5
    14. WH_SYSMSGFILTER = 6
    15. WH_MOUSE = 7
    16. WH_HARDWARE = 8
    17. WH_DEBUG = 9
    18. WH_SHELL = 10
    19. WH_FOREGROUNDIDLE = 11
    20. WH_CALLWNDPROCRET = 12
    21. WH_KEYBOARD_LL = 13
    22. WH_MOUSE_LL = 14
    23. End Enum


    Der aufruf zum Hook

    Visual Basic-Quellcode

    1. Public Sub InitHook(ByVal windowName As String)
    2. Dim hwnd As Long: hwnd = 0
    3. cThread = GetCurrentThreadId
    4. If FindFirstWindowByTitle(hwnd, windowName, hcwnd) Then 'hcwnd as long (global)
    5. hookID = SetWindowsHookEx(WH_CALLWNDPROC, AddressOf PaintCallback, 0, cThread)
    6. End If
    7. End Sub


    und die CallBack

    Visual Basic-Quellcode

    1. Private Function PaintCallback(ByVal Code As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    2. If Code = WindowsMessages.WM_PAINT Then
    3. ...
    4. End If
    5. PaintCallback = CallNextPaintHook(Null, wParam, lParam)
    6. End Function



    Stürzt das programm deswegen ab, weil ich GetCurrentThreadId aufrufe, aber mein Fenster in dem ich zeichnen will ein Kind-Fenster ist?
    Muss ich GetModuleHandleA aufrufen um es zu zuordnen können?
    Hab ich beim Import fehler gemacht?

    petaod schrieb:

    In VBA ist der Standardübergabemechanismus ByRef.


    öhm... Okay warum muss ich dann explicit byref angeben wenn ich ein Type XXX element habe - O.o das verwirrt mich jetzt

    Visual Basic-Quellcode

    1. Type a
    2. end Type
    3. public sub(byref bla as a)
    4. end sub
    Ist das Fenster in dem du Zeichnen willst ein Fenster von deinem eigenen Prozess oder ein externes? Bei einem externen Fenster muss deine Funktion im Shared Memory liegen, damit ein externen Fenster überhaupt dahin springen kann. Ein externes Programm kann nicht einfach eine Funktion in deinem Speicher aufrufen, wenn diese nicht im Shared Memory liegt. Oder du brauchst ein Global Hook, was in C# und damit denke ich auch mal in VB.Net nicht möglich ist, aber vielleicht geht das ja bei VBA.

    ​"Global hooks are not supported in the .NET Framework. Except for the WH_KEYBOARD_LL low-level hook and the WH_MOUSE_LL low-level hook, you cannot implement global hooks in the Microsoft .NET Framework."
    Quelle.

    Facebamm schrieb:

    warum muss ich dann explicit byref angeben wenn ich ein Type XXX element habe
    Gute Frage.
    In Office-VBA musst du es nicht explizit angeben.

    Welche Anwendung dient als Host für dein VBA?
    Das mag dann vielleicht ein anderer Dialekt sein, der seine eigenen Regeln verwendet.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    Bluespide schrieb:

    Global Hook, was in C# und damit denke ich auch mal in VB.Net nicht möglich ist, aber vielleicht geht das ja bei VBA.


    Mach kein sch*** ... Bilder sagen mehr als 1000 Worte ...
    Blau markiert die Stelle des Ziels :D ... An dieses Fenster will ich ran :D



    petaod schrieb:

    Welche Anwendung dient als Host für dein VBA?

    IFIX ... Deswegen meinte ich ja, es ist irgendwie kein richtiges VBA ...

    Ich hab kein BitShiften, Modulo, Log, Ln, etc. mega komisch die IDE


    Mein nächster ansatz wäre gewesen das ich das WM_PAINT aus der Event-Queue nehmen und erst wieder eintrage, wenn ich was zeichnen will ...
    ChangeWindowMessageFilter

    Oder ich nehm das Programm, verschieb es in einen von mir erstellten Thread und log darüber ob mein WM_PAINT kommt und zeichne dann

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Facebamm“ ()