Link to home
Start Free TrialLog in
Avatar of ShawnCurry
ShawnCurry

asked on

Controls do not recieve middle mouse button events occurring outside the client area.

I have a TImage-derived component to which I'm attempting to add middle-click panning functionality.  It seems that middle mouse events do not get delivered to my component when the mouse cursor is outside of it's client area, like left and right mouse events do.

I've tried intercepting the WM_NCMBUTTONUP message using a message handler, and even overriding the WndProc function, and I still never see this message come through.

The component also does not seem to receive Mouse Move messages when the cursor is outside the client area and the middle button is down.  It does receive the non-client Mouse Moves when the left or right button is down.

I can provide a small demo project if what I'm asking isn't clear enough.
Avatar of jimyX
jimyX

Could you provide a demo or show some code please?
Avatar of ShawnCurry

ASKER

I've attached a demo that I've created exploring 2 alternate methods for receiving the missing events.  All the results are essentially the same.

To Test:
Place the mouse cursor inside the client area of the component.
Click and release each mouse button individually.
 - Should receive MouseUp notification
For each mouse button, place cursor in client area, click and drag outside client area, release.
 - Should receive MouseUp notification
 * Only receive MouseUp notification for left mouse button.

MiddleMouse.zip
That seems not catching. I can think of work around solution:
I used a Panel but you can apply this to the descendant components as well.
MiddleMouseUpdated.zip
Here is a complete demo for the three Mouse Buttons:
MiddleMouseUpdated-2.zip
Just noticed that will not work outside the client area.
Then you can try the global mouse hook which catches all the mouse events:
http://delphigeek.blogspot.com/2007/02/global-mouse-hook-in-delphi.html

Why would you expect the component to receive messages that do not belong to it. If you click on the form, thats a mouse click on the form and not on your component.

Same as when you have a button on the form, you don't expect the button to get a mousedown event when you click on the form, imagine what kind of problems we would run into.
The Mouse Hook method does look promising; but I wish I didn't have to put it into a DLL.  Do you have any idea how to figure out what thread I need to attach it to in order to allow it to live in my application?

I am not interested in listening for every single mouse event that occurs.  I'm really only interested in a very narrow set of them that I think I should be receiving now in order to make dragging behavior consistent for all mouse buttons.

Normally, a component wouldn't receive Mouse Move events when the cursor is outside it's client area.  However, they do if the left mouse button is down.  For example, try highlighting some text on this page, and drag the mouse cursor outside of the browser window.  The text selection still responds - or at least that seems normal for Windows applications.  Likewise, I still get the Mouse Up event (for the left button) so long as a Mouse Down event occurred inside the client area.

So, I'm only interested in certain events, and only under certain conditions:

Precondition: Mouse Down inside client area.
Deliver the missing non-client move events.
Deliver the missing non-client mouse up event if it occurs.
ASKER CERTIFIED SOLUTION
Avatar of developmentguru
developmentguru
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Perfect.  Exactly what I was looking for.  Short and sweet.