OnMessage v. a custom WndProc

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

OnMessage v. a custom WndProc

20 Apr 2017, 01:13

Does OnMessage receive messages, e.g. from AutoHotkey GUI controls, that an ordinary WndProc wouldn't?

I provide 2 scripts, the first, the OnMessage script receives WM_LBUTTONDOWN from a GUI and 0x5555 messages, the second, the WndProc script only receives the 0x5555 messages.

Code: Select all

;OnMessage

;based on an example at:
;https://autohotkey.com/docs/commands/OnMessage.htm
Gui, Add, Text,, Click anywhere in this window.
Gui, Show
OnMessage(0x201, "WM_LBUTTONDOWN")
OnMessage(0x5555, "MsgMonitor")
return

WM_LBUTTONDOWN(wParam, lParam)
{
	ToolTip, % A_Now " " A_MSec
}
MsgMonitor(wParam, lParam, msg)
{
	ToolTip, % A_Now " " A_MSec
}

GuiClose:
ExitApp

Code: Select all

;OnMessage replaced with a custom WndProc

pWndProc := RegisterCallback("MyWndProc", "")
;GWL_WNDPROC := -4
vSfx := (A_PtrSize=8) ? "Ptr" : ""
pWndProcOld := DllCall("SetWindowLong" vSfx, Ptr,A_ScriptHwnd, Int,-4, Ptr,pWndProc, Ptr)

Gui, Add, Text,, Click anywhere in this window.
Gui, Show
return

MyWndProc(hWnd, uMsg, wParam, lParam)
{
	global pWndProcOld
	if (uMsg = 0x201) ;WM_LBUTTONDOWN
		ToolTip, % A_Now " " A_MSec
	if (uMsg = 0x5555)
		ToolTip, % A_Now " " A_MSec
	return DllCall("CallWindowProc", Ptr,pWndProcOld, Ptr,hWnd, UInt,uMsg, UPtr,wParam, Ptr,lParam)
}

GuiClose:
ExitApp

w::
DetectHiddenWindows, On
PostMessage, 0x5555,,,, % "ahk_id " A_ScriptHwnd
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
Drugwash
Posts: 850
Joined: 29 May 2014, 21:07
Location: Ploieşti, Romania
Contact:

Re: OnMessage v. a custom WndProc

20 Apr 2017, 07:59

Using A_ScriptHwnd is not gonna cut it. Here's how it does work:

Code: Select all

;OnMessage replaced with a custom WndProc

Gui, +LastFound
hGui := WinExist()
pWndProc := RegisterCallback("MyWndProc", "")
;GWL_WNDPROC := -4
vSfx := (A_PtrSize=8) ? "Ptr" : ""
pWndProcOld := DllCall("SetWindowLong" vSfx, Ptr,hGui, Int,-4, Ptr,pWndProc, Ptr)

Gui, Add, Text,, Click anywhere in this window.
Gui, Show
return

MyWndProc(hWnd, uMsg, wParam, lParam)
{
	global pWndProcOld
	if (uMsg = 0x201) ;WM_LBUTTONDOWN
		ToolTip, % A_Now " " A_MSec
	if (uMsg = 0x5555)
		ToolTip, % A_Now " " A_MSec
	return DllCall("CallWindowProc", Ptr,pWndProcOld, Ptr,hWnd, UInt,uMsg, UPtr,wParam, Ptr,lParam)
}

GuiClose:
ExitApp

w::
DetectHiddenWindows, On
PostMessage, 0x5555,,,, % "ahk_id " A_ScriptHwnd
return
Part of my AHK work can be found here.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: OnMessage v. a custom WndProc

20 Apr 2017, 08:46

Many thanks Drugwash, in your new version of the script, the WndProc now receives the WM_LBUTTONDOWN message from the GUI but fails to receive the 0x5555 message directed at A_ScriptHwnd.

It seems that OnMessage acts like a WndProc, and receives messages sent to the main window (A_ScriptHwnd)/its controls and windows/controls created via the Gui command, and possibly some other windows.

Maybe this is *obvious* but I read the documentation on OnMessage and didn't notice such a simple description of what it does.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
Drugwash
Posts: 850
Joined: 29 May 2014, 21:07
Location: Ploieşti, Romania
Contact:

Re: OnMessage v. a custom WndProc

20 Apr 2017, 09:07

You should probably direct the custom message to the same hGui as well. That's a hidden, empty GUI as long as there's no GUI element added by the script and most likely everything directed to the script is processed internally. It's been a long time since I skimmed through AHK 1.0 sources and even so I have no real knowledge of the C/C++ language, so can't help with an explanation as to why things go the way they go.

Try this:

Code: Select all

;OnMessage replaced with a custom WndProc

Gui, +LastFound
hGui := WinExist()
pWndProc := RegisterCallback("MyWndProc", "")
;GWL_WNDPROC := -4
vSfx := (A_PtrSize=8) ? "Ptr" : ""
pWndProcOld := DllCall("SetWindowLong" vSfx, Ptr,hGui, Int,-4, Ptr,pWndProc, Ptr)

Gui, Add, Text,, Click anywhere in this window.
Gui, Show
return

MyWndProc(hWnd, uMsg, wParam, lParam)
{
	global pWndProcOld
	if (uMsg = 0x201) ;WM_LBUTTONDOWN
		ToolTip, % A_Now " " A_MSec " msg 0x201"
	if (uMsg = 0x5555)
		ToolTip, % A_Now " " A_MSec " msg 0x5555"
	return DllCall("CallWindowProc", Ptr,pWndProcOld, Ptr,hWnd, UInt,uMsg, UPtr,wParam, Ptr,lParam)
}

GuiClose:
ExitApp

w::
DetectHiddenWindows, On
PostMessage, 0x5555,,,, % "ahk_id " hGui
return
Last edited by Drugwash on 20 Apr 2017, 09:10, edited 1 time in total.
Part of my AHK work can be found here.
just me
Posts: 9451
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: OnMessage v. a custom WndProc

20 Apr 2017, 09:09

The script's hidden main window belongs to the class AutoHotkey and has it's own window procedure.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: OnMessage v. a custom WndProc

20 Apr 2017, 09:33

Just to be clear to anyone reading, the script's 'main window', A_ScriptHwnd, is the one you see when you do 'right-click tray icon, Open', ListLines/ListVars/ListHotkeys/KeyHistory etc.

Code: Select all

q:: ;show the script's main window
DetectHiddenWindows, On
WinShow, % "ahk_id " A_ScriptHwnd
WinActivate, % "ahk_id " A_ScriptHwnd
return
Out of interest, showing the main window, if it hasn't been shown before, shows an empty Edit control. Also, 'right-click tray icon, Open' appears to be equivalent to ListLines, if the window hasn't been shown yet (via ListLines/ListVars/ListHotkeys/KeyHistory or Open), otherwise it appears to work like WinShow.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: OnMessage v. a custom WndProc

20 Apr 2017, 22:46

AutoHotkey calls message monitors registered by OnMessage only for messages that the program can detect. Obviously.

More specifically, that includes messages sent to the script's main window or any AutoHotkeyGUI, since those use a custom window proc. It does not include messages *sent* to any other window.

Messages which are *posted* to any window created in AutoHotkey's main thread are also monitored. Posted messages pass through the message loop (they are returned by GetMessage()), whereas sent messages are dispatched by the inner workings of the message functions.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Lamron750, nacken012, septrinus and 235 guests