Link to home
Start Free TrialLog in
Avatar of quantum2
quantum2

asked on

Global Mouse Double Button Click Detection

I am looking for a System Hook that will allow me to detect when both the left and right mouse buttons have been clicked. I will then need to be able to use that event to fire procedures after detection. Does anyone have something like this...?

Thanks

Q2
Avatar of Lee_Nover
Lee_Nover

if you already have a system mouse hook then you simply check the pressed buttons
from your hook dll send the info on the buttons to your app with PostMessage
then in the app handle the message like:


type
  TBtnSet = set of TMouseButton;

var BtnSet: TBtnSet;

procedure TForm1.WMMyMessage(var Msg: TMessage);
var bothdown: boolean;
begin
  // lParam is the down/up flag, wParam is the button
  case Msg.lParam of
    0: Exclude(BtnSet, TMouseButton(Msg.wParam));
    1: Include(BtnSet, TMouseButton(Msg.wParam));
  end;
  bothdown:=(mbLeft in BtnSet) and (mbRight in BtnSet);
end;

the hook procedure looking smth like :

function hpWSH(nCode: integer; wParam: WPARAM; lParam: LPARAM): LRESULT;stdcall;
begin
     try
        // maybe do some other stuff
        PostMessage(MainWindow, WM_lnHOOK, wParam, lParam);
     finally
        Result:=CallNextHookEx(HookID, nCode, wParam, lParam);
     end;
end;
I have a tip how to hook all next mouse events .I don't remember the link and is to long to put here . If interested can send it through mail .

 Message.wParam of
     WM_LBUTTONDBLCLK    
     WM_LBUTTONDOWN      
     WM_LBUTTONUP        
     WM_MBUTTONDBLCLK    
     WM_MBUTTONDOWN      
     WM_MBUTTONUP        
     WM_MOUSEMOVE        
     WM_NCHITTEST        
     WM_NCLBUTTONDBLCLK  
     WM_NCLBUTTONDOWN    
     WM_NCLBUTTONUP      
     WM_NCMBUTTONDBLCLK  
     WM_NCMBUTTONDOWN    
     WM_NCMBUTTONUP      
     WM_NCMOUSEMOVE      
     WM_NCRBUTTONDBLCLK  
     WM_NCRBUTTONDOWN    
     WM_NCRBUTTONUP      
     WM_RBUTTONDBLCLK    
     WM_RBUTTONDOWN      
     WM_RBUTTONUP        
Avatar of quantum2

ASKER

I am guessing that this link is a DLL that does this type of hook. I wish i could read the comments. I am also guessing that this App shows how to use the DLL. I will check it out in more detail tonight.

Q2
ASKER CERTIFIED SOLUTION
Avatar of ginsonic
ginsonic
Flag of Romania image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hey thanks...
I rally appreciate it. Good site.

Q2
Well...
I cant get it to work in Win2000. This hook needs to function in both Win95,98,me,NT,2000 and Yes you gussed it... XP.

Does anyone have any ideas. If someone can provide me with working code (DLL + source or a link to it) and a sample of handling the message for the Left+right mouse button click I will give out 300 pts.

I am in a pinch and dont have time to fiddle with this, so a no brainer solution would be apprecaited.

Q2
I know that. I use it in old Win98 and got problem just in XP .

For this reason,in present I use another project for hooking the mouse. But tested just under XP .
Forgot . Give me your address to send you the project.
The dll segment . Mark where to work for your wishes .

library HookDLL;

uses WinTypes,WinProcs,Messages;

var
  HookCount: integer;
  HookHandle: HHook;

{$IFDEF WIN32}
function MouseHookCallBack(Code: integer; Msg: WPARAM; MouseHook: LPARAM): LRESULT; stdcall;
{$ELSE}
function MouseHookCallBack(Code: integer; Msg: word; MouseHook: longint): longint; export;
{$ENDIF}
begin
  if Code >= 0 then begin

    { HERE YOUR JOB <--------------------------------}

    if Msg = WM_LBUTTONDOWN then
        begin
 {******************Your Job ******************}
        end;

{<-----------------------------------------}

  Result := CallNextHookEx(HookHandle, Code, Msg, MouseHook);
  end else
    Result := CallNextHookEx(HookHandle, Code, Msg, MouseHook);
end;

function InstallHook(SystemHook: boolean; TaskHandle: THandle) : boolean; export;
 function GetModuleHandleFromInstance: THandle;
  var
    s: array[0..512] of char;
  begin
    GetModuleFileName(hInstance, s, sizeof(s)-1);
    Result := GetModuleHandle(s);
  end;
begin
  Result := TRUE;
  if HookCount = 0 then begin
    if SystemHook then
      HookHandle := SetWindowsHookEx(WH_MOUSE, MouseHookCallBack, HInstance, 0)
    else
      HookHandle := SetWindowsHookEx(WH_MOUSE, MouseHookCallBack,
                                     GetModuleHandleFromInstance, TaskHandle);
    if HookHandle <> 0 then
      inc(HookCount)
    else
      Result := FALSE;
  end else
    inc(HookCount);
end;

function RemoveHook: boolean; export;
begin
 Result := FALSE;
  if HookCount < 1 then exit;
  Result := TRUE;
  dec(HookCount);
  if HookCount = 0 then
    Result := UnhookWindowsHookEx(HookHandle);
end;

function IsHookSet: boolean; export;
begin
  Result := (HookCount > 0) and (HookHandle <> 0);
end;

exports
  InstallHook,
  RemoveHook,
  IsHookSet,
  MouseHookCallBack;

begin
  HookCount := 0;
  HookHandle := 0;
end.
Demo application . Button1 install the hook, Button2 ... uninstall .

unit Main;

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,Forms, Dialogs, StdCtrls;

type
  THookForm = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  public
  end;

var
  HookForm: THookForm;

const
  HOOK_DLL = 'HOOKDLL.DLL';

implementation

{$R *.DFM}

function InstallHook(SystemHook: boolean; TaskHandle: THandle): boolean; external HOOK_DLL;
function RemoveHook: boolean;  external HOOK_DLL;
function IsHookSet: boolean;   external HOOK_DLL;

function InstallSystemHook: boolean;
begin
  InstallHook(TRUE, 0);
end;

procedure THookForm.FormDestroy(Sender: TObject);
begin
  while IsHookSet do
    RemoveHook;
end;

procedure THookForm.Button1Click(Sender: TObject);
begin
  if not InstallSystemHook then
 ShowMessage('SetWindowsHookEx() failed.');
 button1.enabled := false;
 button2.enabled := true;
end;

procedure THookForm.Button2Click(Sender: TObject);
begin
  if IsHookSet then
    RemoveHook;
     button1.enabled := true;
 button2.enabled := false;
end;

procedure THookForm.FormCreate(Sender: TObject);
begin
 button1.enabled := true;
 button2.enabled := false;
end;

end.
I see now that wish to hook the right button, too. So


  if Msg = WM_LBUTTONDOWN then
       begin
{******************Your Job ******************}
       end;


  if Msg = WM_RBUTTONDOWN then
       begin
{******************Your Job ******************}
       end;


How I say already. Tested in XP, but don't see any reason to fail in the others Win versions .

Hope that this code to solve your problem ... and mine :)
The promise points will keep me in KPro zone for next two months.
I will have to try this out in a few. I am looking for the hook to catch each mouse button being pressed at the same time simultaneously.

I will see if this does the trick.

Q2
If this one doesnt get both mouse button clicks at once and you want to email the projects, send them to:

iiamsolutions@hotmail.com
interesting ... I don't get notifications for your comments !? I visit now this topic just to let a comment . Hmm , I will contact the Community Support  to inform about this posible bug ( no comment notification after accepted answer ).

I send you the project file . All what you have to do is to put your condition ( use Message.wParam from my comment 05/22/2002 11:33PM ) in MouseHookCallBack.
quantum2, you can download it:
http://www.ginsonic.ro/MouseHook.zip
Now the hook capture the moment when right and left mouse buttons are pressed in same time .
Comments ?
Ginsonic,
Hey thanks for the files. I need to add a simple message pass to let me know when the DLL detects the click. My event code to process once this double click is triggered would be in the application that sets the hook.

This is looking good though.

Q2
Ginsonic,
Hey thanks for the files. I need to add a simple message pass to let me know when the DLL detects the click. My event code to process once this double click is triggered would be in the application that sets the hook.

This is looking good though.

Q2
Ginsonic,
Hey thanks for the files. I need to add a simple message pass to let me know when the DLL detects the click. My event code to process once this double click is triggered would be in the application that sets the hook.

This is looking good though.

Q2
ginsonic,
I have sent you a couple of emails. The basic hook works well. I have asked a couple of more questions. Either way, I am going to post at least one new question that is an award for points. Just post an answer to it and I will give you the points.

Q2