• Re: using WH_CALLWNDPROCRET correctly

    From JJ@21:1/5 to Nonso Nosiri on Mon Dec 13 12:12:20 2021
    On Sun, 12 Dec 2021 20:31:45 -0800 (PST), Nonso Nosiri wrote:
    Hi,
    I am using a hook with the WH_CALLWNDPROCRET flag to intercept a hwnd's procedure messages and intercept WM_INPUT and WM_PAINT, but I am having problems with it.

    I cast the LPARAM to a CWPRETSTRUCT pointer according to msdn: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nc-winuser-hookproc
    But unfortunately, the "message" member in the struct is not used the same way as in a normal procedure callback function: https://docs.microsoft.com/en-us/windows/win32/winmsg/using-window-procedures
    It's either that or it is garbage data.

    Am I using it wrong? would you mind creating a small code example that could help me? Or pointing out my errors, I would really appreciate it.

    This is the code I'm using: https://pastebin.com/DNZhUP4m

    Thanks in advance,
    Chinomso Nosiri.

    What do you meant by "the same way"?
    What exactly are you expecting, and what exactly are you getting?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Nonso Nosiri@21:1/5 to All on Sun Dec 12 20:31:45 2021
    Hi,
    I am using a hook with the WH_CALLWNDPROCRET flag to intercept a hwnd's procedure messages and intercept WM_INPUT and WM_PAINT, but I am having problems with it.

    I cast the LPARAM to a CWPRETSTRUCT pointer according to msdn: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nc-winuser-hookproc
    But unfortunately, the "message" member in the struct is not used the same way as in a normal procedure callback function: https://docs.microsoft.com/en-us/windows/win32/winmsg/using-window-procedures
    It's either that or it is garbage data.

    Am I using it wrong? would you mind creating a small code example that could help me? Or pointing out my errors, I would really appreciate it.

    This is the code I'm using: https://pastebin.com/DNZhUP4m

    Thanks in advance,
    Chinomso Nosiri.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Mon Dec 13 18:43:22 2021
    Chinomso,

    I argree with JJ. Without knowing what you are getting and what you are expecting instead it's rather hard (understatement) to know what, if
    anything, is going wrong.


    To test I just added that SetWindowsHookEx call to a basic dialog and in the callback I "dumped" the arguments to the callback as well the pointed-to structure, and got a rather recognisable list, including the WM_PAINT
    message.

    Alas, my language of choice is Assembly, so there is a good chance its
    rather meaningless to you. Than again ...

    Please do notice that I've got some arguments to the involved functions set
    to Zero. Just might make the difference.

    ;-- Initialisation :

    call GetCurrentThreadId
    call SetWindowsHookExA,WH_CALLWNDPROCRET,offset HookProcCB,0,eax

    ;-- callback function:

    HookProcCB proc
    arg @@wMsg:DWORD,@@wParam:DWORD,@@lParam:DWORD
    uses ebx,esi,edi
    local @@sBuffer[MAX_PATH]:BYTE

    Debug_HexLongNR,[@@wMsg]
    Debug_HexLongNR,[@@wParam]
    Debug_HexLongNR,[@@lParam]
    Debug_Chr,'- '

    mov ebx,[@@lParam]
    Debug_HexLongNR,[ebx].CWPRET_lResult
    Debug_HexLongNR,[ebx].CWPRET_lParam
    Debug_HexLongNR,[ebx].CWPRET_wParam
    Debug_HexLongNR,[ebx].CWPRET_lMessage
    Debug_HexLongNR,[ebx].CWPRET_hWnd
    Debug_wMsg,[ebx].CWPRET_lMessage

    call CallNextHookEx,0,[@@wMsg],[@@wParam],[@@lParam]
    ret
    HookProcCB endp

    ;-- Result :
    00000000 00000000 0012FDD4 - 00000000 00000000 00000003 00000127 009F0276 WM_CHANGEUISTATE
    00000000 00000000 0012FE94 - 00000000 00000000 00000001 00000018 009F0276 WM_SHOWWINDOW
    00000000 00000000 0012FE7C - 00000000 0012FED4 00000000 00000046 009F0276 WM_WINDOWPOSCHANGING
    00000000 00000000 0012FE94 - 00000000 00000468 00000001 0000001C 009F0276 WM_ACTIVATEAPP
    ....
    00000000 00000000 0012FE94 - 00000000 003B012C 00000000 00000005 009F0276 WM_SIZE
    00000000 00000000 0012FE94 - 00000000 001701C6 00000000 00000003 009F0276 WM_MOVE
    00000000 00000000 0012FE88 - 00000000 00000000 00000000 0000000F 009F0276 WM_PAINT
    00000000 00000000 0012FDBC - 00000000 00000000 00000001 00000085 00060280 WM_NCPAINT
    ...
    00000000 00000000 0012F8C8 - 00000000 002F0268 020003E9 00000111 009F0276 WM_COMMAND
    00000000 00000000 0012FA78 - 00000001 00000000 009F0276 00000008 002F0268 WM_KILLFOCUS
    00000000 00000000 0012FA78 - 00000000 00000000 002F0268 00000007 009F0276 WM_SETFOCUS
    00000000 00000000 0012FA48 - 00000000 0012FAA0 00000000 00000046 009F0276 WM_WINDOWPOSCHANGING
    00000000 00000000 0012FA48 - 00000000 0012FAA0 00000000 00000047 009F0276 WM_WINDOWPOSCHANGED
    00000000 00000000 0012FBE8 - 00000000 00000000 00000000 00000010 009F0276 WM_CLOSE
    00000000 00000000 0012FCC4 - 00000000 000902EC 0000F060 00000112 009F0276 WM_SYSCOMMAND

    Hope that helps.

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Nonso Nosiri@21:1/5 to All on Mon Dec 13 11:37:49 2021
    Hi, sorry for the late response.

    In my hook procedure I am expecting the LPARAM to point to a valid CWPRETSTRUCT with window procedure message like WM_PAINT which has a value of 15, it is called repeatedly, no? However, I am getting 32 and 132 and I do not know what cases these are.
    they do not match any of the window proc messages. And the docs contain vague info about that the struct will actually hold: https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-cwpretstruct neither does it describe the procedure
    helpfully: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nc-winuser-hookproc

    Fortunately, for my use case, I was able to resolve the problem last night via subclassing the window procedure function: https://docs.microsoft.com/en-us/windows/win32/winmsg/about-window-procedures#window-procedure-subclassing

    But for the unforeseeable future, I still want to know what was wrong here.

    Thanks in advance,
    Chinomso Nosiri.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Nonso Nosiri@21:1/5 to All on Mon Dec 13 11:39:54 2021
    Just a small edit...

    by "window procedure message like" I mean the message member in the struct "UINT message;"

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Mon Dec 13 22:12:43 2021
    Chinomso,

    with window procedure message like WM_PAINT which has a value of 15, it
    is called
    repeatedly, no?

    That fully depends on what you do with the window you created. My full
    list (from creation of the dialog upto closing it) only shows it twice.

    Though you can "force" the message, simply by (partially) covering-and-uncovering your window.

    However, I am getting 32 and 132 and I do not know what cases these are.
    they do not match any of the window proc messages.

    Than I've got a nice list for you. Not all of them, but quite a bunch :

    https://wiki.winehq.org/List_Of_Windows_Messages

    And the docs contain vague info about that the struct will actually hold:

    What does "actually hold" mean ? Are you referring to the variables themselves ? If so, what what in the (I assume) description is not clear
    to you ? Or perhaps to the variable types ? You're a bit vague about it yourself ...

    But for the unforeseeable future, I still want to know what was wrong
    here.

    Without the "garbage data" you got we can only guess.

    I was able to resolve the problem last night via subclassing the window procedure function

    As mentioned, I had no problem getting the hook to run and produce the data
    I posted using a simple dialog.

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul N@21:1/5 to R.Wieser on Wed Dec 15 09:46:14 2021
    On Monday, December 13, 2021 at 9:13:24 PM UTC, R.Wieser wrote:
    Chinomso,
    with window procedure message like WM_PAINT which has a value of 15, it
    is called
    repeatedly, no?
    That fully depends on what you do with the window you created. My full
    list (from creation of the dialog upto closing it) only shows it twice.

    Though you can "force" the message, simply by (partially) covering-and-uncovering your window.

    I think the recommended way to get a WM_PAINT message is by using InvalidateRect, though there are no doubt other ways.

    But covering and uncovering the window may not now work. In early versions of Windows, Windows itself did not store what any particular window looked like, so if a window was uncovered a WM_PAINT was needed to tell the window to draw (part or all of)
    itself on the screen. Since Vista there is apparently a thing called Desktop Window Manager, all the windows are actually stored and the DWM puts them all together appropriately. See https://en.wikipedia.org/wiki/Desktop_Window_Manager .

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Wed Dec 15 19:18:30 2021
    Paul,

    I think the recommended way to get a WM_PAINT message is by using InvalidateRect,
    though there are no doubt other ways.

    :-) My idea was to provide a quick "does this button work?!" test. After
    that ? Who knows.

    Since Vista there is apparently a thing called Desktop Window Manager, all the
    windows are actually stored and the DWM puts them all together
    appropriately.
    See https://en.wikipedia.org/wiki/Desktop_Window_Manager .

    I was not aware of that change. Thanks for the heads-up.

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)