Page 1 of 3

Hook and steal mouse clicks?

Posted: Sat Mar 15, 2008 9:48 pm
by kenmo
Got a Windows event hooking question here... What I'm trying to do is globally intercept middle-mouse button clicks while either control key is down (yes I know this seems like a very specific strange method...). It's simple enough to catch CONTROL+MBUTTON events using, say, getasynckeystate_(). The only issue bugging me though is that I want to block the mouse click event from going to the active window. For example, you're browsing the web and you want to bring up my ctrl+mclick window, but middle clicking in the browser activates the auto-scroll feature... which is not desired... so I want to steal the event.

Is there a way to do this? Thanks for any help.

Posted: Sat Mar 15, 2008 11:01 pm
by netmaestro
You can use a mouse hook, and if you return non-zero from the hook procedure it will not pass on the press event to any windows. This is the only way I know of to prevent the active window from processing the event.

Posted: Sun Mar 16, 2008 1:19 am
by Fluid Byte
Where should the hook be installed? Just your PB application or globally?

Posted: Sun Mar 16, 2008 2:18 pm
by SFSxOI
I think it will need to be global. I tried something similar (not exactly like this but kinda) back in PB 4.02 and the only way I could get it to work was globally.

Posted: Sun Mar 16, 2008 3:46 pm
by Fluid Byte
Then you could do it like this:

Code: Select all

Procedure MouseHook(nCode,wParam,lParam)
	If wParam = #WM_MBUTTONDOWN And GetAsyncKeyState_(#VK_CONTROL) & 32768 	
		ProcedureReturn 1
	EndIf

   ProcedureReturn CallNextHookEx_(0,nCode,wParam,lParam)
EndProcedure

OpenWindow(0,0,0,240,140,"MouseBlock",#WS_CAPTION | #WS_SYSMENU | 1)

StickyWindow(0,1)

hhkLLMouse = SetWindowsHookEx_(#WH_MOUSE_LL,@MouseHook(),GetModuleHandle_(0),0)

While WaitWindowEvent() ! 16 : Wend

UnhookWindowsHookEx_(hhkLLMouse)

Posted: Sun Mar 16, 2008 5:06 pm
by netmaestro
The hook procedure has to be compiled to a dll in order to work globally. Otherwise it only works on your own window when it's active.

Posted: Sun Mar 16, 2008 5:29 pm
by Fluid Byte
netmaestro wrote:The hook procedure has to be compiled to a dll in order to work globally.
No, it's hasn't. I tested it with Firefox and it work's like a charm.

Posted: Sun Mar 16, 2008 5:35 pm
by DarkDragon
netmaestro wrote:The hook procedure has to be compiled to a dll in order to work globally. Otherwise it only works on your own window when it's active.
WH_MOUSE_LL = Low-level (Influences the whole Windows System)
WH_MOUSE = High level (Influences only GetMessage or PeekMessage)

See MSDN... http://msdn2.microsoft.com/en-us/library/ms644959.aspx

If you wanted to make an API Hook you should compile it to a DLL for global hooks. But you don't even have to then.

Posted: Sun Mar 16, 2008 5:38 pm
by netmaestro
From the article you quote:
MSDN wrote:A global hook procedure can be called in the context of any application in the same desktop as the calling thread, so the procedure must be in a separate DLL module.
There is no ambiguity or gray area here. You must compile to a dll or it won't be effective for all running applications. Windows has to have a dll to inject into the other processes.

Posted: Sun Mar 16, 2008 5:52 pm
by DarkDragon
netmaestro wrote:From the article you quote:
MSDN wrote:A global hook procedure can be called in the context of any application in the same desktop as the calling thread, so the procedure must be in a separate DLL module.
There is no ambiguity or gray area here. You must compile to a dll or it won't be effective for all running applications. Windows has to have a dll to inject into the other processes.
But you know what low level means?
The LowLevelMouseProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system call this function every time a new mouse input event is about to be posted into a thread input queue. The mouse input can come from the local mouse driver or from calls to the mouse_event function. If the input comes from a call to mouse_event, the input was "injected". However, the WH_MOUSE_LL hook is not injected into another process. Instead, the context switches back to the process that installed the hook and it is called in its original context. Then the context switches back to the application that generated the event.
From this article (Which is a subarticle from the article I gave you):
http://msdn2.microsoft.com/en-us/librar ... S.85).aspx

[EDIT]
In the next posting of netmaestro he indirectly says I'm right. :lol: It's ok, netmaestro, we know I'm right and we also know you're too self-confident to tell us the truth. :lol:

Err.. even Microsoft makes faults in their documentation.

Posted: Sun Mar 16, 2008 6:00 pm
by netmaestro
But you know what low level means?
Yes. When you were in diapers I knew. And I know what "must be in a separate DLL module" means. I see no point in commenting further on this.

Posted: Mon Mar 17, 2008 12:03 am
by DoubleDutch
It really depends on the core of the OS...

It works globally without being in a DLL if the windows is < NT. If NT based (XP, 2k, Vista, etc ) then it needs to be in a DLL.

Posted: Mon Mar 17, 2008 12:37 am
by Sparkie
WH_KEYBOARD_LL = no DLL required for global use
WH_MOUSE_LL = no DLL required for global use

all other WH_* = DLL required for global use

Posted: Mon Mar 17, 2008 12:41 am
by DoubleDutch
ic, that may be useful.... ;)

Posted: Mon Mar 17, 2008 12:51 am
by Sparkie
I have seen some reports that say using either of the 2 _LL hooks can slow your system down in some cases. I have never used either of them so I can't say first hand if that is true or not.