Solved

How can i check if the user gave a LEFT MOUSE CLICK out the application?

Posted on 2004-09-28
31
711 Views
Last Modified: 2012-05-05
Hi folks,

I have a Delphi application. After open the application i´d like that, if the user LEFT MOUSE BUTTON CLICK in any place that not in my APPLICATION (in other words, if he click out the application), I see a message.

Thanks very much.
0
Comment
Question by:joelsilva
  • 15
  • 10
  • 4
  • +1
31 Comments
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12176342
We meet again!

Try this in a timer at about 10ms

if ((GetAsyncKeyState(VK_LBUTTON) and 1) = 1) then
  begin
    memo1.lines.add('Left button has been clicked at: ' + inttostr(mouse.cursorpos.x)+',' + inttostr(mouse.cursorpos.y) )
  end;

It will add to a memo control whenever a left mouse button has been clicked. it will also tell you the coordinates of where it was clicked. If you want to have it so that it wont record when inside your app then on every other controls onclick event assign a global boolean variable to true then do something like:

If insideappclicked<>true then
begin
if ((GetAsyncKeyState(VK_LBUTTON) and 1) = 1) then
  begin
    memo1.lines.add('Left button has been clicked at: ' + inttostr(mouse.cursorpos.x)+',' + inttostr(mouse.cursorpos.y) )
  end;
end;

Note: to declare a global variable at it to the public or private sections up the top of the code

Regards,

Hypoviax
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12176515
By the way, the above code will work for any key. You would just have to replace the section where VK_LBUTTON is

Regards,

Hypoviax
0
 
LVL 1

Expert Comment

by:SJohnson
ID: 12177153
How about this:

procedure TForm1.AppDeactivate(Sender: TObject);
begin
  if ((GetAsyncKeyState(VK_LBUTTON) and 1) = 1) then
    ShowMessage('Form deactivated with left mouse button');
end;

then, in the FormCreate do this:

procedure TMainForm.FormCreate(Sender: TObject);
begin
  Application.OnDeactivate := AppDeactivate;
end;

I couldn't get the GetAsyncKeyState to differentiate between my left and right buttons, but that maybe just my mouse.

Stu
0
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

 
LVL 1

Expert Comment

by:SJohnson
ID: 12177160
Mmm.. YOu may want to do this too:

procedure TForm1.FormClose(Sender: Tobject; var Action: TCloseAction);
begin
  Application.OnDeactivate := nil;
end;
0
 
LVL 6

Expert Comment

by:Amir Azhdari
ID: 12184217
joelsilva ,
the easiest way to get all the systems mouse button Downs and Ups and ... is with the Journal hook.  This code uses a Form with 2 buttons on it, one button starts the journal hook and the other button stops it. There is One List box which will show all the mouse ups and downs and their screen coordinates.
There is also one TApplicationEvents to get the OnMessage event, so you can restart the hook if there's a WM_CANCELJOURNAL message.


unit MouseButton;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls, AppEvnts;

type
 TForm1 = class(TForm)
   Button_StartJour: TButton;
   Button_StopJour: TButton;
   ListBox1: TListBox;
   ApplicationEvents1: TApplicationEvents;
   procedure Button_StartJourClick(Sender: TObject);
   procedure Button_StopJourClick(Sender: TObject);
   procedure ApplicationEvents1Message(var Msg: tagMSG;
     var Handled: Boolean);
   procedure FormClose(Sender: TObject; var Action: TCloseAction);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
 JHook: THandle;
 Track: Boolean;

implementation

{$R *.DFM}

function JournalProc(Code, wParam: Integer; var EventStrut: TEVENTMSG): Integer; stdcall;
var
Char1: PChar;
begin
{this is the JournalRecordProc}
Result := CallNextHookEx(JHook, Code, wParam, Longint(@EventStrut));
{the CallNextHookEX is not really needed for journal hook since it it not
really in a hook chain, but it's standard for a Hook}
if Code < 0 then Exit;

{you should cancel operation if you get HC_SYSMODALON}
if Code = HC_SYSMODALON then Exit;
if Code = HC_ACTION then
 begin
{the EventStrut record has the Information about the mouse or keyboard
event. You said you just wanted the mouse button events so I get the
mouse down and mouse up event messages}
   if EventStrut.message = WM_LBUTTONUP then
   Form1.ListBox1.Items.Add('Left Mouse UP at X pos '+IntToStr(EventStrut.paramL)
                            +' and Y pos '+IntToStr(EventStrut.paramH));
   if EventStrut.message = WM_LBUTTONDOWN then
   Form1.ListBox1.Items.Add('Left Mouse Down at X pos '+IntToStr(EventStrut.paramL)
                            +' and Y pos '+IntToStr(EventStrut.paramH));
   if EventStrut.message = WM_RBUTTONDOWN then
   Form1.ListBox1.Items.Add('Right Mouse Down at X pos '+IntToStr(EventStrut.paramL)
                            +' and Y pos '+IntToStr(EventStrut.paramH));
   if (EventStrut.message = WM_RBUTTONUP) then
   Form1.ListBox1.Items.Add('Right Mouse Up at X pos '+IntToStr(EventStrut.paramL)
                            +' and Y pos '+IntToStr(EventStrut.paramH));
 end;
end;

procedure TForm1.Button_StartJourClick(Sender: TObject);
begin
if Track then
 begin
 ShowMessage('Mouse is already being Journaled, can not restart');
 Exit;
 end;

JHook := SetWindowsHookEx(WH_JOURNALRECORD , @JournalProc, 0, 0);
{SetWindowsHookEx starts the Hook}
if JHook > 0 then
 begin
 Track := True;
 end else
 ShowMessage('No Journal Hook availible');
end;

procedure TForm1.Button_StopJourClick(Sender: TObject);
begin
Track := False;
UnhookWindowsHookEx(JHook);
JHook := 0;
end;

procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
 var Handled: Boolean);
begin
{the journal hook is automaticly camceled if the Task manager
(Ctrl-Alt-Del) or the Ctrl-Esc keys are pressed, you restart it
when the WM_CANCELJOURNAL is sent to the parent window, Application}
Handled := False;
if (Msg.message = WM_CANCELJOURNAL) and Track then
 JHook := SetWindowsHookEx(WH_JOURNALRECORD , @JournalProc, 0, 0);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
{make sure you UN hook it if the app closes}
UnhookWindowsHookEx(JHook);
end;

end.



- - - - - - - - - - - - - - - - -  - - - - - - - - - - - -

Hope you can use it, ask questions if you need more.
0
 

Author Comment

by:joelsilva
ID: 12185249
Thank you very much: HYPOVIAX, SJohnson and Amir.
Thank you for your attention too.

Comments:

HYPOVIAX:
=======
I´ve tried your suggestion. That was great but it just works inside my application. So, if i click OUTSIDE the application, it didn´t work (and this is the point: i´d like to SHOW a message when the user click on any place OUTSIDE my application).


Amir:
=======
I´ve tried your suggestion but when i click on 'Button_StartJour' button, i got the following message: "No journal HOOK available". What´s happening? Could i implement this withou using buttons?


SJohnson:
=======
I don´t know why but nothing happens when i left button click OUTSIDE the application (even INSIDE nothing happens).





0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12185571
Fixed it. Now all you have to do is have this inside a timer there is no other code you need to add!:

if ((GetAsyncKeyState(VK_LBUTTON) and 1) = 1) then
  begin
  if (mouse.CursorPos.x<form1.Left) or (mouse.CursorPos.x>form1.left+form1.Width) or (mouse.CursorPos.y<form1.Top) or (mouse.CursorPos.y>form1.Top+form1.Height) then
 memo1.lines.add('Left button has been clicked at: ' + inttostr(mouse.cursorpos.x)+',' + inttostr(mouse.cursorpos.y) );
  end;

Best Regards,

Hypoviax
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12185576
Actually, let me just fix up those conditions, it doesnt quite work yet.
0
 
LVL 5

Accepted Solution

by:
Hypoviax earned 25 total points
ID: 12185594
Ok this should work. I justed needed to put brackets around some things:

if ((GetAsyncKeyState(VK_LBUTTON) and 1) = 1) then
  begin
  if (mouse.CursorPos.x<form1.Left) or (mouse.CursorPos.x>(form1.left+form1.Width)) or (mouse.CursorPos.y<form1.Top) or (mouse.CursorPos.y>(form1.Top+form1.Height)) then
    memo1.lines.add('Left button has been clicked at: ' + inttostr(mouse.cursorpos.x)+',' + inttostr(mouse.cursorpos.y) );
    insideappclicked:=false;
  end;
0
 
LVL 6

Expert Comment

by:Amir Azhdari
ID: 12193769
>I´ve tried your suggestion but when i click on 'Button_StartJour' button, i got the following message: "No journal HOOK available". What´s happening?

- Fixed the problem

>Could i implement this withou using buttons?
- yes , just place the button's click code to oncreate event of the form

Regards
Amir


unit MouseButton;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls, AppEvnts;

type
 TForm1 = class(TForm)
    Button_StartJour: TButton;
    Button_StopJour: TButton;
    ListBox1: TListBox;
    ApplicationEvents1: TApplicationEvents;
   procedure Button_StartJourClick(Sender: TObject);
   procedure Button_StopJourClick(Sender: TObject);
   procedure ApplicationEvents1Message(var Msg: tagMSG;
     var Handled: Boolean);
   procedure FormClose(Sender: TObject; var Action: TCloseAction);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
 JHook: THandle;
 Track: Boolean;

implementation

{$R *.DFM}

function JournalProc(Code, wParam: Integer; var EventStrut: TEVENTMSG): Integer; stdcall;
var
Char1: PChar;
begin
{this is the JournalRecordProc}
Result := CallNextHookEx(JHook, Code, wParam, Longint(@EventStrut));
{the CallNextHookEX is not really needed for journal hook since it it not
really in a hook chain, but it's standard for a Hook}
if Code < 0 then Exit;

{you should cancel operation if you get HC_SYSMODALON}
if Code = HC_SYSMODALON then Exit;
if Code = HC_ACTION then
 begin
{the EventStrut record has the Information about the mouse or keyboard
event. You said you just wanted the mouse button events so I get the
mouse down and mouse up event messages}
   if EventStrut.message = WM_LBUTTONUP then
   Form1.ListBox1.Items.Add('Left Mouse UP at X pos '+IntToStr(EventStrut.paramL)
                            +' and Y pos '+IntToStr(EventStrut.paramH));
   if EventStrut.message = WM_LBUTTONDOWN then
   Form1.ListBox1.Items.Add('Left Mouse Down at X pos '+IntToStr(EventStrut.paramL)
                            +' and Y pos '+IntToStr(EventStrut.paramH));
   if EventStrut.message = WM_RBUTTONDOWN then
   Form1.ListBox1.Items.Add('Right Mouse Down at X pos '+IntToStr(EventStrut.paramL)
                            +' and Y pos '+IntToStr(EventStrut.paramH));
   if (EventStrut.message = WM_RBUTTONUP) then
   Form1.ListBox1.Items.Add('Right Mouse Up at X pos '+IntToStr(EventStrut.paramL)
                            +' and Y pos '+IntToStr(EventStrut.paramH));
   if (Eventstrut.message= WM_KEYDOWN ) then
   Form1.ListBox1.Items.Add('Keyboard pressed '+IntToStr(EventStrut.paramL)
                            +' and Y pos '+IntToStr(EventStrut.paramH)+' NEW SET '+inttostr(eventstrut.time));



 end;
end;

procedure TForm1.Button_StartJourClick(Sender: TObject);
begin
if Track then
 begin
 ShowMessage('Mouse is already being Journaled, can not restart');
 Exit;
 end;
                                                                 // or 0
JHook := SetWindowsHookEx(WH_JOURNALRECORD , @JournalProc,hinstance, 0);
{SetWindowsHookEx starts the Hook}
if JHook > 0 then
 begin
 Track := True;
 end else
 ShowMessage('No Journal Hook availible');
end;

procedure TForm1.Button_StopJourClick(Sender: TObject);
begin
Track := False;
UnhookWindowsHookEx(JHook);
JHook := 0;
end;

procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
 var Handled: Boolean);
begin
{the journal hook is automaticly camceled if the Task manager
(Ctrl-Alt-Del) or the Ctrl-Esc keys are pressed, you restart it
when the WM_CANCELJOURNAL is sent to the parent window, Application}
Handled := False;
if (Msg.message = WM_CANCELJOURNAL) and Track then
 JHook := SetWindowsHookEx(WH_JOURNALRECORD , @JournalProc, 0, 0);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
{make sure you UN hook it if the app closes}
UnhookWindowsHookEx(JHook);
end;

end.

0
 

Author Comment

by:joelsilva
ID: 12196743
Hi guys, both guys worked fine and i deeply thank you. I just don´t know who must i qualify... In this cases, what is the most correct? : )
0
 

Author Comment

by:joelsilva
ID: 12196747
I mean, both CODES worked, but i dont know who must i qualify because you both are correct.
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12197093
In that case you split the points. Which ever one you used accept first, then select assist for the other.

Regards,

Hypoviax
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12197108
You could just accept mine but that wouldn't be fair ;)

Regards

Hypoviax
0
 

Author Comment

by:joelsilva
ID: 12197165
Good Idea, but i didnt find the SPLIT POINT button.
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12197190
It should be near the comment box where you type comments - next to the accept button
0
 

Author Comment

by:joelsilva
ID: 12204706
There is not any button to SPLIT BUTTON. I looked forward in many places and didnt find it. I am sorry Mir AMIR, but as HYPOVIAX answer first, i think that at least it is fear that the points go to him.

I deeply thank you for your great code too, man!

0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12204794
Thankyou very much, i am glad i could help.

Hypoviax
0
 

Author Comment

by:joelsilva
ID: 12204821
I thank you man... I will add you and AMIR in my FRIENDS LIST... Best regards!!!
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12204883
Cool, what's your friends list because you mentioned something about it to me in another one of you questions if you recall:

http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_21136356.html

Regards,

Hypoviax
0
 

Author Comment

by:joelsilva
ID: 12205169
Yes, i´ve added you...

Check: http://www.capablanca.com.br  --> go to menu, SITES ÚTEIS --> DELPHI FRIENDS

I am brazilian and the language is portuguese.
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12205836
A nice site. Although i cannot read it, it looks very professional. Is this your site?

Regards,

Hypoviax
0
 

Author Comment

by:joelsilva
ID: 12205967
Thank you... Yes... It is my personal DELPHI site. There i put some articles, tutorials and other resources developed from mine.

Do you have a site?
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12206012
I do but it is not nearly as professional as yours and i only began writing it with my friend a few weeks ago. Currently it has broken links and all but if you wish to see it:

nds1.dyndns.org

(I believe in hardcoding so pardon the spelling mistakes etc)

Regards,

Hypoviax
0
 

Author Comment

by:joelsilva
ID: 12206060
Oh... Cool site too. It´s getting very good.
Who are you? Nam Hoang or Michael Langley?
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12206073
Michael - but don't post it here or around too much. We've only started so the site needs a lot of work.
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12206075
by "post it" i mean our names.

Best regards,

Hypoviax
0
 
LVL 6

Expert Comment

by:Amir Azhdari
ID: 12206445
joelsilva :)
I am glad i could help , and thanks to Adding me in your friends list
0
 

Author Comment

by:joelsilva
ID: 12206988
HYPOVIAX
=======

Ok HYPOVIAX... I dont will not post your name but could i add your SITE address in my website?
If you need something related to WEBDESIGN (mainly related to images, some artwork), just tell me what you need and i think i can help you.


AMIRAZHDARI
=========

Thanks again by providing help, friend... I will try to find the SPLIT BUTTON so in future cases like this (2 guys answer correct), i will be more fair.
By the way, do you have a website?


Sucess for you both!!!

0
 
LVL 6

Expert Comment

by:Amir Azhdari
ID: 12208585
I don't have web site at the moment,
but most of the times i use some trial ASP support web hostings (ex. http://europe.webmatrixhosting.net )
and use Dreamweaver MX to create the pages

wish you best
Amir
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12209390
You most certainly can add my URL to your website. I thankyou for your kind offer and may take it up in a couple of months since right now i am very close to doing exams. I sent you an e-mail (from your site) which i assumed was you and added you to my contact list on MSN. You (i think it was anyway) added me to your contact list.

Best Regards,

Hypoviax
0

Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

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

Suggested Solutions

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In a recent question (https://www.experts-exchange.com/questions/28997919/Pagination-in-Adobe-Acrobat.html) here at Experts Exchange, a member asked how to add page numbers to a PDF file using Adobe Acrobat XI Pro. This short video Micro Tutorial sh…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

803 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