How to properly override mouse events in other apps (Windows)? - winapi

I'm trying to implement system-wide drag operation with middle mouse button. It should override middle mouse drag behavior in other programs. Currently, I am handling global mouse events with system-wide hooks.
Problem is - many programs still receive and handle same events like I did not intercept them.
Here's what I tried:
not call the next hook for mouse down event: I never receive mouse up, so I don't know where and when to stop dragging
not call the next hook for mouse move: cursor slows down tremendously
not call the next hook for mouse up: most windows in the system stop reacting to mouse events completely after my drag is finished
always call the next hook in the chain: if the control under mouse has scroll in it, most of the time it will be scrolling while my drag is in progress. Also UWP apps continue receiving mouse events during my drag, so if a link in MS Edge happens to be under cursor when it started, and mouse does not leave Edge boundary, Edge receives click event, and new tab is opened
What I need is: when user holds middle mouse and starts dragging, my drag handler should be called, and no other handlers, like file drag, scroll, etc should happen.

I ended up with somewhat hacky solution:
do not call the next hook for mouse down for middle button
record where it was pressed
when handling mouse up, if user did not drag - replay the whole mouse up + mouse down using SendInput from a separate thread (to avoid deadlock due to reentrancy)

Related

FireMonkey - how to capture TScrollBar mouse events?

I'm trying to capture mouse events on a TScrollBar. In design time, I created a handler for each mouse event, on the Events tab of the Object Inspector. At runtime, the TScrollBar does not fire the mouse events, therefore the handlers are not executed. For instance, when the mouse pointer enters the TScrollBar, the OnMouseEvent never triggers the associated ScrollBarMouseEnter. I'm working with FireMonkey, Berlin 10.1 Update 2, Win32 platform. Any help would be appreciated.

Programmatic start NSSlider dragging

I would like to start a slider action programmatically. So pressing on some text in a NSTextView that displays a slider also automatically starts the mousedown event on the slider so you can drag immediately instead of pressing twice. What approach should i take on this? Should i listen for global mouse events and then manually update the slider position, or can i somehow imitate the systems mouseDown / mouseMoved calls on the NSSlider?

gwt mouse over events not fired when mouse button is down

When you push down the left mouse button mouse down event fires. If you then move the mouse over a label (while holding the mouse button down) mouse over event does not fire.
Is there any way to enable this events or fire them manualy or simulate them?
What you are actually doing is two separate events, one is a mouse down event as you have described and the other is a mouse drag.
If you want to simulate them, that you might have to consider using a mouse click to track the user's (x,y) location. Subsequently, if you want to "simulate" it you could do some computation and decide for yourself if it is indeed a mouse click or mouse drag event that has occurred.
Hope it helps :) Cheers!

Windows: Mouse Down on Window Decoration

In almost any Windows application, I notice that holding the mouse button down in a non-client area causes the painting to stop. Why is this required?
For example, I have a Managed Direct 3D application which displays a spinning cube. If I place the pointer over the title bar and hold the mouse button down, the cube ceases to spin even though I have not coded any such condition into my loop.
Why is painting halted? What are the benefits? Most importantly, how can I work around this?
When you click on the title bar, there's a brief pause while the window manager tries to determine whether or not you're clicking or beginning a drag (moving the window). If you're still holding down the button, then it's a drag: the window manager sets up its own message loop and pumps messages until you release the mouse. Your window should still be able to process messages, because they'll still be dispatched, but if your animation depends on a custom message loop then you'll be stuck 'till the modal drag loop ends.
Work around it by triggering your animation in response to messages: a timer seems like a good choice to me.

How to tell if a a mouse button has been released outside the window?

Usually, when a user holds the mouse pressed over a button, moves the mouse away from the window, and then releases it, the button can tell that the mouse has been released even though the release has actually occured outside the window.
When I inspect mouse clicks in my window, how can I imitate the same behavior?
When a mouse button being pushed down over the window I get the WM_XBUTTONDOWN message, but Windows don't treat it as if anything is logically being "clicked", so after the mouse leaves the window, no further messages will arrive at the window, which results in a "lost" WM_XBUTTONUP message.
When you receive the button down, you capture the mouse. That means that all the mouse events until releasing the capture will be reported to the window that captured the mouse.
See the documentation here. You also have a link to an example from that page.
Use the DragDetect() function.
https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-dragdetect?redirectedfrom=MSDN

Resources