How to capture mouse clicks outside the form (e.g. using Code Insight in Delphi)

I like the idea of ​​a Delphi Code Insight window (a custom list on a form without borders basically) where you can click outside the form and it will automatically close it.

My first thought was to call SetCapture / ReleaseCapture in FormCreate and FormDestroy respectively. I set the title of the form in X / Y to FormMouseMove, but it does not update the coordinates outside the form.

If I call SetCapture / ReleaseCapture from MouseDown and MouseUp, it will update the coordinates as expected, which proves that the concept really works.

I have tried other things, for example. send WM_USER to the OnShow event and call SetCapture from there, but it still does not update the coordinates. Then I tried the TApplicationEvents (OnMessage) component, but that does not work either.

I already read several articles, but could not find what I was looking for. Some articles are called SetCapture from MouseMove, but this does not work when the mouse cursor starts outside the form. Hmm ...

The next step is to use WindowsHook, but where I left off. I know how to implement it, but it seems to me that I am missing something really obvious here. There should be an easier way to do this.

Any ideas? :)

Cheers, Jarno

+4
source share
3 answers

What you need to make easier is by adding TApplicationEvents to your form and use the OnDeactivate event. This fires whenever the application loses focus.

+1
source

Maybe WM_NCHITTEST can help you somehow. As the saying goes, if the mouse is captured, this message is sent to the window that captured the mouse. Therefore, I would grab the mouse for the form, and then wait until the result of this message is HTNOWHERE, which should mean "from the window." But as far as I remember, this never worked for me perfectly, so I finally used (as you mentioned) a mouse hook.
But in my case, I had many components in this popup form, and you need to consider messaging for them.
The implementation I used (with minor changes) and which works here .

0
source

I had a similar problem (I needed to inject scrolling windows if the mouse hovered over a special area and I could not use SetCapture) and bypassed it using the timer method + GetCursorPos. Just execute ScreenToClient and check if the mouse is in the window.

0
source

Source: https://habr.com/ru/post/1333271/


All Articles