Articles   Members Online: 3
-Article/Tip Search
-News Group Search over 21 Million news group articles.
-Delphi/Pascal
-CBuilder/C++
-C#Builder/C#
-JBuilder/Java
-Kylix
Member Area
-Home
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Login/Logout
-Become a Member
-Why sign up!
-Newsletter
-Chat Online!
-Indexes NEW!!
Employment
-Build your resume
-Find a job
-Post a job
-Resume Search
Contacts
-Contacts
-Feedbacks
-Link to us
-Privacy/Disclaimer
Embarcadero
Visit Embarcadero
Embarcadero Community
JEDI
Links
How to trap mouse clicks on the Desktop when using a system wide mouse hook Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
03-Oct-02
Category
System
Language
Delphi 2.x
Views
135
User Rating
No Votes
# Votes
0
Replies
0
Publisher:
DSP, Administrator
Reference URL:
DKB
			 Author: Jonas Bilinkevicius

Does anyone know how to tell (in Delphi code) if I have clicked on the Desktop (not 
an icon). I have written a system wide mouse hook program but the window handle and 
the icon handle are the same. How can I tell the difference?

Answer:

I did this by creating a DLL (you can only hook into the desktop via a DLL). The 
DLL then posts messages to the main application. You need to load the DLL, call 
Initialize supplying the applications handle (note: StdCall). You then need to 
assign a custom message handler (application.OnMessage) to listen for the messages 
posted from the DLL.

Here is the application message handler:

1   const
2     WM_DESKTOPMOUSEMESSAGE = WM_USER + 1;
3   
4   procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);
5   begin
6     case Msg of
7       WM_DESKTOPMOUSEMESSAGE:
8         case Msg.WParam of
9           WM_LBUTTONUP: ShowMessage('You clicked on the desktop');
10        end;
11    end;
12  
13  procedure TForm1.OnCreate(Sender: TObject);
14  begin
15    Application.OnMessage := AppMessage;
16  end;



Here is the hook code:


Important note about DLL memory management: ShareMem must be the first unit in your 
library's USES clause AND your project's (select Project-View Source) USES clause 
if your DLL exports any procedures or functions that pass strings as parameters or 
function results. This applies to all strings passed to and from your DLL - even 
those that are nested in records and classes. ShareMem is the interface unit to the 
BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To 
avoid using BORLNDMM.DLL, pass string information using PChar or ShortString 
parameters.

17  library test;
18  
19  uses
20    SysUtils, Messages, Windows;
21  
22  {$R *.RES}
23  
24  const
25    WM_DESKTOPMOUSEMESSAGE = WM_USER + 1;
26  
27  var
28    HookHandle: HHook;
29    DesktopHandle: HWnd;
30    AppHandle: HWnd;
31  
32  procedure log(logstr: string);
33  var
34    F1: Textfile;
35  begin
36    AssignFile(F1, 'c:\temp.log');
37    if FileExists('c:\temp.log') then
38      Append(F1)
39    else
40      Rewrite(F1);
41    writeln(F1, logstr);
42    CloseFile(F1);
43  end;
44  
45  function MouseHook(code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT stdcall;
46  var
47    WinDir: array[0..MAX_PATH] of Char;
48    f: file of HWnd;
49  begin
50    {This only happens once, we use the file just to get the variable across to the 
51  systems memory}
52    if AppHandle = 0 then
53    begin
54      GetWindowsDirectory(Windir, MAX_PATH);
55      AssignFile(f, WinDir + '\ah.dat');
56      Reset(f);
57      read(f, AppHandle);
58      CloseFile(f);
59    end;
60    PostMessage(AppHandle, WM_DESKTOPMOUSEMESSAGE, wParam, lParam);
61    Result := CallNextHookEx(HookHandle, Code, WParam, LParam);
62  end;
63  
64  procedure Initialize(ApplicationHandle: HWnd); stdcall;
65  var
66    res, pid: DWORD;
67    f: file of HWnd;
68    WinDir: array[0..MAX_PATH] of Char;
69  begin
70    {Write the application handle to a file so that it can be read first time round 
71  	by the hook (the hook has its own memory space)}
72    Fillchar(windir, sizeOf(WinDir), 0);
73    GetWindowsDirectory(Windir, MAX_PATH);
74    AssignFile(f, WinDir + '\ah.dat');
75    Rewrite(f);
76    write(f, ApplicationHandle);
77    CloseFile(f);
78    DesktopHandle := FindWindow(nil, 'Program Manager');
79    if DesktopHandle = 0 then
80      HookHandle := 0
81    else
82    begin
83      AppHandle := ApplicationHandle;
84      res := GetWindowThreadProcessID(DesktopHandle, @pid);
85      HookHandle := SetWindowsHookEx(WH_MOUSE, @MouseHook, hInstance, res);
86    end;
87  end;
88  
89  procedure DeInitialize; stdcall;
90  begin
91    if HookHandle <> 0 then
92      UnHookWindowsHookEx(HookHandle);
93  end;
94  
95  exports
96    Initialize,
97    DeInitialize;
98  
99  begin
100 end.


			
Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10

 

Advertisement
Share this page
Advertisement
Download from Google

Copyright © Mendozi Enterprises LLC