Jump to content
Sign in to follow this  
rdwray

Hooking Windows Messages

Recommended Posts

rdwray

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
AdmiralAlkex

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
rdwray

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
Mat

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
rdwray

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
Mat

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
rdwray

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
Mat

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
rdwray

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
Mat

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
rdwray

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
Mat

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
rdwray

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  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.