Page 1 of 1
How to test for hotkey of Alt+LMB?
Posted: Sun Feb 09, 2020 4:29 am
by BarryG
I was wondering if there's a way to detect a "hotkey" combo of the Alt key and left mouse button down, no matter which app has the focus at the time? I know #WM_HOTKEY is for keys and not mouse, and below is a start, but it only works if the left mouse button is held down BEFORE you press the Alt key. It doesn't work if Alt is held down FIRST. From what I can see, the #WM_HOTKEY message isn't received until after the key is released? That's what I need to overcome: when it's down, as opposed to up.
Note: I ideally want this to work with all keys, not just Alt. Reason is that the user specifies which hotkey combo to use with my app, which is triggered by #WM_HOTKEY in my callback. So I can't do a poll of all key states or use GetAsyncKeyState_() for their specified keys. I just need a way, either before or after #WM_HOTKEY is received, to detect the left mouse button state at that moment. Thanks!
Code: Select all
Procedure WinCallback(hWnd,uMsg,WParam,LParam)
Result=#PB_ProcessPureBasicEvents
If uMsg=#WM_HOTKEY
If GetAsyncKeyState_(#VK_LBUTTON) & $8000
Debug "Alt+LMB down"
EndIf
EndIf
ProcedureReturn Result
EndProcedure
OpenWindow(0,300,300,320,160,"Alt+LMB",#PB_Window_SystemMenu)
RegisterHotKey_(WindowID(0),0,#MOD_ALT,0)
SetWindowCallback(@WinCallback())
Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow
Re: How to test for hotkey of Alt+LMB?
Posted: Sun Feb 09, 2020 8:02 am
by RASHAD
Hi
Code: Select all
Global Keyhook
Procedure HookProc(nCode,wParam,lParam)
Select nCode
Case #HC_ACTION
If GetAsyncKeyState_(#VK_MENU) = -$8000 And GetAsyncKeyState_(#VK_LBUTTON) = -$8000
If GetActiveGadget() = 1
Debug "Editor"
Else
Debug "String"
EndIf
EndIf
UnhookWindowsHookEx_(Keyhook)
EndSelect
ProcedureReturn CallNextHookEx_(0,nCode,wParam,lParam)
EndProcedure
If OpenWindow(0, 0, 0, 600, 300, "WebGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered|#PB_Window_SizeGadget)
EditorGadget(1, 0, 0, 600, 150)
StringGadget(2, 10, 270, 300, 20 ,"")
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Quit = 1
Case #PB_Event_Gadget
Select EventGadget()
Case 1
Keyhook = SetWindowsHookEx_(#WH_KEYBOARD,@HookProc(),0, GetCurrentThreadId_())
Case 2
Keyhook = SetWindowsHookEx_(#WH_KEYBOARD,@HookProc(),0, GetCurrentThreadId_())
EndSelect
EndSelect
Until Quit = 1
EndIf
UnhookWindowsHookEx_(Keyhook)
Re: How to test for hotkey of Alt+LMB?
Posted: Sun Feb 09, 2020 9:48 am
by BarryG
Hi Rashad, thanks, but it doesn't work when third-party apps have the focus (as mentioned). It also seems weirdly hit-and-miss: sometimes I get a debug output once or twice, and other times I get lots of debug outputs in a row. Strange.
Also is the issue of #VK_MENU being hard-coded. In my app, the key can be any hotkey mod combo, so #VK_MENU|#VK_CONTROL, or #VK_MENU|#VK_CONTROL|#VK_SHIFT, etc. I can't code for all these possibilities, so it's best just to check for #WM_HOTKEY in a callback and try to go from there. Unfortunately it seems there's no way to know when a hotkey has been pushed down; Windows only reports when it's been released. I'll keep researching, and I do appreciate your willingness to help. You're a good guy.
Re: How to test for hotkey of Alt+LMB?
Posted: Sun Feb 09, 2020 12:30 pm
by chi
BarryG wrote:but it doesn't work when third-party apps have the focus
You need a global hook if you want to catch all apps...
mhook_appCode: Select all
#MHOOK_DLL = 0
OpenWindow(0, 0, 0, 320, 200, "MHook Example", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
If OpenLibrary(#MHOOK_DLL, "mhook.dll")
MHOOK_DLL = SetWindowsHookEx_(#WH_MOUSE, GetFunction(#MHOOK_DLL, "MHook"), LibraryID(#MHOOK_DLL), #Null)
MHOOK_Message = RegisterWindowMessage_("MHOOK")
ChangeWindowMessageFilter_(MHOOK_Message, #MSGFLT_ADD)
Else
MessageRequester("", "mhook.dll not found...")
End
EndIf
Repeat
event = WaitWindowEvent()
Select event
Case MHOOK_Message
Debug "hWnd: " + Hex(EventwParam())
Debug "rMsg: " + EventlParam()
Debug "-------------"
EndSelect
Until event = #PB_Event_CloseWindow
If MHOOK_DLL
UnhookWindowsHookEx_(MHOOK_DLL)
EndIf
If IsLibrary(#MHOOK_DLL)
CloseLibrary(#MHOOK_DLL)
EndIf
mhook_dll
Code: Select all
ProcedureDLL AttachProcess(Instance)
DisableThreadLibraryCalls_(Instance)
Global MHOOK_Window = FindWindow_(0, "MHook Example")
Global MHOOK_Message = RegisterWindowMessage_("MHOOK")
EndProcedure
ProcedureDLL MHook(nCode, wParam, *lParam.MOUSEHOOKSTRUCT)
If nCode < #HC_ACTION : ProcedureReturn CallNextHookEx_(@MHook(), nCode, wParam, *lParam) : EndIf
Select wParam
Case #WM_LBUTTONDOWN, #WM_NCLBUTTONDOWN
If GetAsyncKeyState_(#VK_MENU) & $8000
PostMessage_(MHOOK_Window, MHOOK_Message, GetAncestor_(*lParam\hwnd, #GA_ROOT), Random(999))
EndIf
EndSelect
ProcedureReturn CallNextHookEx_(@MHook(), nCode, wParam, *lParam)
EndProcedure
[/size]
BarryG wrote:Also is the issue of #VK_MENU being hard-coded...
You'll figure it out

Re: How to test for hotkey of Alt+LMB?
Posted: Sun Feb 09, 2020 1:15 pm
by BarryG
Thanks for the code, chi. A shame I have to use an external DLL, but it may be the only way.
Re: How to test for hotkey of Alt+LMB?
Posted: Sun Feb 09, 2020 2:59 pm
by chi
BarryG wrote:Thanks for the code, chi.
You're welcome
BarryG wrote:A shame I have to use an external DLL, but it may be the only way.
Yeah, it's the only way... Since the dll gets injected into every process, make sure to exclude processes you don't want to trigger (e.g. Taskbar, StartButton, ...)