Solved

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

Posted on 1997-06-10
12
1,049 Views
Last Modified: 2010-05-18
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
angerer@eftuv1.tuwien.ac.at

 
0
Comment
Question by:angerer
12 Comments
 
LVL 5

Expert Comment

by:julio011597
ID: 1336929
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
0
 
LVL 4

Expert Comment

by:erajoj
ID: 1336930
There are something like 1001 different solutions to this problem.
Could you possibly be more specific?

/// John

0
 

Expert Comment

by:kangadru
ID: 1336931
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 www.microsoft.com/msdn 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
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 2

Expert Comment

by:icampbe1
ID: 1336932
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.

0
 
LVL 1

Author Comment

by:angerer
ID: 1336933
Edited text of question
0
 
LVL 1

Author Comment

by:angerer
ID: 1336934
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
angerer@eftuv1.tuwien.ac.at

0
 
LVL 2

Expert Comment

by:icampbe1
ID: 1336935
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.


0
 
LVL 2

Expert Comment

by:icampbe1
ID: 1336936
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.

0
 
LVL 1

Author Comment

by:angerer
ID: 1336937
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: selcombo.zip).

Thank you very much

DI Bernhard Angerer
angerer@eftuv1.tuwien.ac.at

PS: Your secound answer is - i think - a possibility but the component should manage this problem by itself.
0
 
LVL 12

Expert Comment

by:andrewjb
ID: 1336938
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.


AJB


0
 

Accepted Solution

by:
iainmagee earned 100 total points
ID: 1336939
Hi,

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);
begin
  if Message.Sender <> Self then
    // Code to close or hide the dropdown window
end;

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 iainmagee@enterprise.net

Iain.
0
 
LVL 1

Author Comment

by:angerer
ID: 1336940
thank you very much - this is excactaly the solution i was lookong for
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Using idhttp to login to instagram 2 106
Adoquery sql  left join does not work 25 98
Delphi and Access based Enumeration 9 70
Tidtcpserver listening on multiports? 1 35
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…

839 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question