Sign in to follow this  
Followers 0
rdwray

Hooking Windows Messages

13 posts in this topic

I don't know if this has been asked before or not, but I can't find an answer. "GUIRegisterMsg" is designed to call a function if a message arrives. AutoIt is seeing all messages, is there a way to hook all messages as C++ does with "WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)" with "message"? Thanks...


“No other God have I but Thee; born in a manger, died on a tree.” Martin Luther

Share this post


Link to post
Share on other sites



If GUIGetMsg()/GUIRegisterMsg() isn't enough you can change wndproc with _WinAPI_SetWindowLong to a function of your own. There should be examples on the forum, do a search.

Share this post


Link to post
Share on other sites

If GUIGetMsg()/GUIRegisterMsg() isn't enough you can change wndproc with _WinAPI_SetWindowLong to a function of your own. There should be examples on the forum, do a search.

Unless I am wrong, the above only trap single messages. I am interested in trapping all WM_xxx with a single function like this:
Func WM_Message()
    Switch $message
        Case WM_ANYMESSAGE  ; All WM_constants in WindowsConstants.au3
            do something
        EndSwitch
EndFunc

“No other God have I but Thee; born in a manger, died on a tree.” Martin Luther

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Yes.... _WinAPI_SetWindowLong allows you to change the windowproc... IE all messages. That is what AdmiralAlkex was on about.

Remember to get the normal proc and call it yourself in your function, or else the window won't do much :P

Edit: GRRRR... :x can't delete the double post

Edited by Mat

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Without WM_MOUSEMOVE I get WM_LBUTTONDOWN - why? Thanks...

#Include <Constants.au3>
#Include <GUIConstants.au3>
#Include <WinAPI.au3>
#Include <WindowsConstants.au3>

$hForm = GUICreate('', 400, 400)
$hHook = DllCallbackRegister('_WinProc', 'ptr', 'hwnd;uint;long;ptr')
$pHook = DllCallbackGetPtr($hHook)
$hProc = _WinAPI_SetWindowLong($hForm, $GWL_WNDPROC, $pHook)
GUISetState()

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

_WinAPI_SetWindowLong($hForm, $GWL_WNDPROC, $hProc)
DllCallBackFree($hProc)

Func _WinProc($hWnd, $iMsg, $wParam, $lParam)

    Local $Res = _WinAPI_CallWindowProc($hProc, $hWnd, $iMsg, $wParam, $lParam)
    Local $hDC, $hSv, $oldMsg

    Select
        Case $iMsg = $WM_LBUTTONDOWN
            ToolTip($WM_LBUTTONDOWN)
        Case $iMsg = $WM_MOUSEMOVE
            ToolTip($WM_MOUSEMOVE)
    EndSelect
    Return $Res
EndFunc   ;==>_WinProc
Got the code from here and modified it:

Edited by rdwray

“No other God have I but Thee; born in a manger, died on a tree.” Martin Luther

Share this post


Link to post
Share on other sites

It's still there, the tooltip just replaces it before you see it :x Try this for proof:

#Include <Constants.au3>
#Include <GUIConstants.au3>
#Include <WinAPI.au3>
#Include <WindowsConstants.au3>

$hForm = GUICreate('', 400, 400)
$hHook = DllCallbackRegister('_WinProc', 'ptr', 'hwnd;uint;long;ptr')
$pHook = DllCallbackGetPtr($hHook)
$hProc = _WinAPI_SetWindowLong($hForm, $GWL_WNDPROC, $pHook)
GUISetState()

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

_WinAPI_SetWindowLong($hForm, $GWL_WNDPROC, $hProc)
DllCallBackFree($hProc)

Func _WinProc($hWnd, $iMsg, $wParam, $lParam)

    Local $Res = _WinAPI_CallWindowProc($hProc, $hWnd, $iMsg, $wParam, $lParam)
    Local $hDC, $hSv, $oldMsg

    Select
        Case $iMsg = $WM_LBUTTONDOWN
            ConsoleWrite($WM_LBUTTONDOWN & @LF)
        Case $iMsg = $WM_MOUSEMOVE
            ToolTip($WM_MOUSEMOVE)
    EndSelect
    Return $Res
EndFunc   ;==>_WinProc

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

It's still there, the tooltip just replaces it before you see it Try this for proof:

Ok, it writes to the output window, but if I try a MsgBox it only activates "sometimes" and will eventually lock up the program if I press the LButton enough.

Edit:

I have not ran into this problem before and I think it is by MS design. Is the WM_MOUSEMOVE function designed to be used in response to other functions? After looking through the SDK, I cannot find any examples were the WM_MOUSEMOVE is not activated in response to some other action.

Edited by rdwray

“No other God have I but Thee; born in a manger, died on a tree.” Martin Luther

Share this post


Link to post
Share on other sites

The reason it locks up is becouse it queues all the messages, and the window doesn't respond while the msgbox is open.

The reason for the sometimes is that a click to activate the window is NOT sent to the windowproc as being a button press. After the msgbox, you'll need to click it again and then you will start to get the messages again. Alternatively use WinActivate after the msgbox.

The correct way to stop it locking up is to use a dummy... I'm sure there are examples of that lying around somewhere. Basically, you send a message to the dummy to trigger the code to happen on an event, and then return from the loop and it makes the return from the proc not have to wait for msgbox to close.

I hope I got all that right, I'm finding it hard to think at the moment :x

Share this post


Link to post
Share on other sites

I am starting to think that the best way to keep my sanity is to use GUIRegisterMsg with commands that don't require user interaction. :x


“No other God have I but Thee; born in a manger, died on a tree.” Martin Luther

Share this post


Link to post
Share on other sites

What is it you are trying to do exactly? Maybe there is a better way. The only time I'd use the above method is when hooking external windows.

Share this post


Link to post
Share on other sites

What is it you are trying to do exactly? Maybe there is a better way. The only time I'd use the above method is when hooking external windows.

I was trying to avoid writing a list of GUIRegisterMsg calls and creating several functions. I guess I could point all GUIRegisterMsg to a single function and then sort it out; or maybe create a #include wrapper.

“No other God have I but Thee; born in a manger, died on a tree.” Martin Luther

Share this post


Link to post
Share on other sites

I was trying to avoid writing a list of GUIRegisterMsg calls and creating several functions. I guess I could point all GUIRegisterMsg to a single function and then sort it out; or maybe create a #include wrapper.

In the end, it's either a big switch statement or a big bunch of functions... Your choice. I personally always go for functions as you can do it with just internal functions rather than getting stuck in with the winapi, and you just return 'GUI_RUNDEFMSG' to use the default proc.

Share this post


Link to post
Share on other sites

In the end, it's either a big switch statement or a big bunch of functions... Your choice. I personally always go for functions as you can do it with just internal functions rather than getting stuck in with the winapi, and you just return 'GUI_RUNDEFMSG' to use the default proc.

Thanks Matt...

“No other God have I but Thee; born in a manger, died on a tree.” Martin Luther

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0