Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 731
  • Last Modified:

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

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
joelsilva
Asked:
joelsilva
  • 15
  • 10
  • 4
  • +1
1 Solution
 
HypoviaxCommented:
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
 
HypoviaxCommented:
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
 
SJohnsonCommented:
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
SJohnsonCommented:
Mmm.. YOu may want to do this too:

procedure TForm1.FormClose(Sender: Tobject; var Action: TCloseAction);
begin
  Application.OnDeactivate := nil;
end;
0
 
Amir AzhdariCommented:
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
 
joelsilvaAuthor Commented:
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
 
HypoviaxCommented:
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
 
HypoviaxCommented:
Actually, let me just fix up those conditions, it doesnt quite work yet.
0
 
HypoviaxCommented:
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
 
Amir AzhdariCommented:
>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
 
joelsilvaAuthor Commented:
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
 
joelsilvaAuthor Commented:
I mean, both CODES worked, but i dont know who must i qualify because you both are correct.
0
 
HypoviaxCommented:
In that case you split the points. Which ever one you used accept first, then select assist for the other.

Regards,

Hypoviax
0
 
HypoviaxCommented:
You could just accept mine but that wouldn't be fair ;)

Regards

Hypoviax
0
 
joelsilvaAuthor Commented:
Good Idea, but i didnt find the SPLIT POINT button.
0
 
HypoviaxCommented:
It should be near the comment box where you type comments - next to the accept button
0
 
joelsilvaAuthor Commented:
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
 
HypoviaxCommented:
Thankyou very much, i am glad i could help.

Hypoviax
0
 
joelsilvaAuthor Commented:
I thank you man... I will add you and AMIR in my FRIENDS LIST... Best regards!!!
0
 
HypoviaxCommented:
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
 
joelsilvaAuthor Commented:
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
 
HypoviaxCommented:
A nice site. Although i cannot read it, it looks very professional. Is this your site?

Regards,

Hypoviax
0
 
joelsilvaAuthor Commented:
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
 
HypoviaxCommented:
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
 
joelsilvaAuthor Commented:
Oh... Cool site too. It´s getting very good.
Who are you? Nam Hoang or Michael Langley?
0
 
HypoviaxCommented:
Michael - but don't post it here or around too much. We've only started so the site needs a lot of work.
0
 
HypoviaxCommented:
by "post it" i mean our names.

Best regards,

Hypoviax
0
 
Amir AzhdariCommented:
joelsilva :)
I am glad i could help , and thanks to Adding me in your friends list
0
 
joelsilvaAuthor Commented:
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
 
Amir AzhdariCommented:
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
 
HypoviaxCommented:
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

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

  • 15
  • 10
  • 4
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now