Solved

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

Posted on 2004-09-28
31
708 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
 
LVL 1

Expert Comment

by:SJohnson
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
Actually, let me just fix up those conditions, it doesnt quite work yet.
0
 
LVL 5

Accepted Solution

by:
Hypoviax earned 25 total points
Comment Utility
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
Comment Utility
>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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
You could just accept mine but that wouldn't be fair ;)

Regards

Hypoviax
0
 

Author Comment

by:joelsilva
Comment Utility
Good Idea, but i didnt find the SPLIT POINT button.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 5

Expert Comment

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

Author Comment

by:joelsilva
Comment Utility
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
Comment Utility
Thankyou very much, i am glad i could help.

Hypoviax
0
 

Author Comment

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

Expert Comment

by:Hypoviax
Comment Utility
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
Comment Utility
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
Comment Utility
A nice site. Although i cannot read it, it looks very professional. Is this your site?

Regards,

Hypoviax
0
 

Author Comment

by:joelsilva
Comment Utility
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
Comment Utility
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
Comment Utility
Oh... Cool site too. It´s getting very good.
Who are you? Nam Hoang or Michael Langley?
0
 
LVL 5

Expert Comment

by:Hypoviax
Comment Utility
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
Comment Utility
by "post it" i mean our names.

Best regards,

Hypoviax
0
 
LVL 6

Expert Comment

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

Author Comment

by:joelsilva
Comment Utility
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
Comment Utility
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
Comment Utility
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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

728 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now