MOUSECLICK outside the client area of my control - how ??

I am writing delphi components. For some of them i would need the mouse click event in every mouse position - even when the mouse cursor is NOT over the client area of the control.

The events from TControl

(like  procedure WMLButtonDown(var Message: TWMLButtonDown); message
WM_LBUTTONDOWN;    procedure Click; override; ...)

are only triggered when the mouse is over the control. I am sure there is a possibility.
Once again my problem: Imagine a Combobox. The Combobox is closing the drop down list automatically when the user clicks the mouse SOMEWHERE on the screen. I have some components that look like combos (and should behave like them) but they are not derived from TCombobox. They for example open a TForm for the drop down list.

So - how can i close this TForm on any (somewhere on the screen) mouseclick ???

Thank you very much for your help

Bernhard Angerer
Technical University Vienna

Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

You may want to have a look at the mouse 'capture' method (or was it a property? cannot remember).

I've made use of it (a long ago:); it may do the job, but it's a bit tricky to make it work properly.

Rgds, julio
There are something like 1001 different solutions to this problem.
Could you possibly be more specific?

/// John

Depending on the level of control you need for the mouse you have a couple of options.  The Mouse Capture method mentioned is of course an option but is rather unstable when used on NT, I'm not entirely certain why either. The Next option is much more difficult but is also much more complete and is probably the more appropriate.  The trick is to use a Global Hook, see the article on "Hooks in Win32" on the MSDN site a or if you have access to MSDN or Technet CD's there.  Hooks are best implemented as DLL's and since you are designing as components, I would suggest that you use LoadLibrary instead of static linking the DLL so that you may choose to leave the DLL unloaded when in csDesign reducing the risk of bring down the IDE and the CompLib inadvertantly.  If this is the route you choose to go, let me suggest that you also invest in the Delphi 3 upgrade as it's Interface implementation and improved header files will ease the conversion of the C code the MS samples are done in.  If I can find the code I will follow this up with the Code I wrote to do X-Mouse Focus follows mouse on NT before they added ActiveWindowTracking to the shell, (or more specifically, documented it :-))Andy
Build an E-Commerce Site with Angular 5

Learn how to build an E-Commerce site with Angular 5, a JavaScript framework used by developers to build web, desktop, and mobile applications.

Hi there angerer,

I believe what you want is to process the 'WM_NCLButtonDown'  or  LButtonUp or R button up/down  etc etc....

These messages (WM_NC...) are sent in response to a mouse button in the NON-Client area.  You can do the standard window processing for them.

I'm sure this is what you want.  If not, I'll be more specific.

angererAuthor Commented:
Edited text of question
angererAuthor Commented:
Dear icampbel !

I think you understood me right. I tried it - but it did not work. (?)
I  think that this msg goes to the form in which my control is liying in. But i want my control to react on this.

Once again my problem: Imagine a Combobox. The Combobox is closing the drop down list automatically when the user clicks the mouse SOMEWHERE on the screen. I have some components that look like combos (and should behave like them) but they are not derived from TCombobox. They for example open a TForm for the drop down list.

So - how can i close this TForm on any (somewhere on the screen) mouseclick ???

Thank you very much (for your effort)

DI Bernhard Angerer

OK, I think I understand.  You want to detect a click 'Anywhere' on the screen.  You might have to subclass the WndProc routine of your application to catch the clicks.  Im sure you are familliar with this process.  You replace the Application's WndProc with one of your own. (GetWindowLong/SetWindowLong etc).  If the message is not interresting to you, you call the original routine.  In most cases, you call the original routine anyhow.  I can clarify further if you need more help.

Ian C.

I just read your earlier comment again.  What you can do is use my original solution, but have the form pass the click on the the control that it contains.  In fact, if you process the HitTest message (NCHITTEST I think), you can make the control believe that the mouse was clicked inside its own area.  I believe that you only want to inform the control of the click though, not of the exact click location.  OK?

Ian C.

angererAuthor Commented:
Dear icampbel !

I am sorry but i could not reach a solution with your information.

In the mean time i found a component that is managing exactly my problem. If you are interested you can find it on the delphi super page under the section freeware (file:

Thank you very much

DI Bernhard Angerer

PS: Your secound answer is - i think - a possibility but the component should manage this problem by itself.
Use MouseCapture to grab control over the mouse while you're displaying the combo box etc. This will deliver clicks to you if they hit anywhere on your application ( or anywhere on the screen if you are using Windows 3.1 ). Don't forget to release capture when the window has been removed.

You'll probably also need to watch for the exit event for the control, so you can spot if the user clicks on another application.

I wouldn't advise messing around with hooking into the record/playback events that windows offers. They really aren't designed for this at all. It isn't 'correct' windows programming for this problem.

In addition, you really don't want to be stealing the mouse do you, from everything else that is running. That's the whole point of windows - that you can ( attempt! ) to do more than one thing at once.

I'm sure we can come up with a complete solution if you actually post ( or e-mail ) some real code to us / me.



I've been doing a similar thing recently only with a popup menu based on a TListbox.

If I've read your question correctly the same principles should apply. What you need to do is trap the CM_CANCELMODE message in your component. This is generated when the user clicks anywhere else - including on the desktop or another application - provided your dropdown has the focus at the time.

In the handler make sure you ensure that you only process messages that don't originate from you own component! Your handler will look something like this:

procedure TNewComp.CMCANCELMODE(var Message: TCMCancelMode);
  if Message.Sender <> Self then
    // Code to close or hide the dropdown window

You may find that you will also need to trap the WM_KILLFOCUS message in order to get the desired effect. If you do this and you are actually destroying the dropdown window - make sure you don't free it twice - ie from the Cancelmode message and from the killfocus message.

Hope this sets you on the right track, need any more info please drop me a line at


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
angererAuthor Commented:
thank you very much - this is excactaly the solution i was lookong for
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.