Хук для нажатия кнопки мыши.
Не могу разобраться, как сделать вот так:
Отслеживается нажатие левой кнопки мыши, при нажатии (LMouseDown) должен выполняться код, как только кнопка отжата (LMouseUp), код должен прекратить свое выполнение на той строке, на которой была отжата кнопка и при следующем нажатии начать свое выполнение заново.
Код:
library LowLevelMouseHook;
uses
Windows,
Messages;
const
WH_MOUSE_LL = 14;
MMFName: PChar = 'MMF';
type
PGlobalDLLData = ^TGlobalDLLData;
TGlobalDLLData = packed record
WndHook: HWND;
Wnd: HWND;
end;
type
TMouseHookFilters = record
BlockMouseMove: boolean;
BlockLeftButton: boolean;
BlockRightButton: boolean;
BlockMiddleButton: boolean;
BlockWheel: boolean;
end;
var
GlobalData: PGlobalDLLData;
MMFHandle: THandle;
Filters: TMouseHookFilters;
MWM_LBUTTONDOWN: Cardinal;
MWM_LBUTTONUP: Cardinal;
MWM_MBUTTONDOWN: Cardinal;
MWM_MBUTTONUP: Cardinal;
MWM_RBUTTONDOWN: Cardinal;
MWM_RBUTTONUP: Cardinal;
MWM_MOUSEWHEEL: Cardinal;
MWM_MOUSEMOVE: Cardinal;
function LowLevelMouseProc(Code: Integer; wParam: DWORD; lParam: DWORD): Longint; stdcall;
begin
if (Code = HC_ACTION) then
begin
if (wParam = WM_LBUTTONDOWN) then
begin
SendMessage(GlobalData.Wnd, MWM_LBUTTONDOWN, 0, 0);
if Filters.BlockLeftButton = True then
Result := - 1
else
Result := CallNextHookEx(GlobalData^.WndHook, Code, wParam, lParam);
end else
if (wParam = WM_LBUTTONUP) then
begin
SendMessage(GlobalData.Wnd, MWM_LBUTTONUP, 0, 0);
if Filters.BlockLeftButton = True then
Result := - 1
else
Result := CallNextHookEx(GlobalData^.WndHook, Code, wParam, lParam);
end else
if (wParam = WM_MBUTTONDOWN) then
begin
SendMessage(GlobalData.Wnd, MWM_MBUTTONDOWN, 0, 0);
if Filters.BlockMiddleButton = True then
Result := - 1
else
Result := CallNextHookEx(GlobalData^.WndHook, Code, wParam, lParam);
end else
if (wParam = WM_MBUTTONUP) then
begin
SendMessage(GlobalData.Wnd, MWM_MBUTTONUP, 0, 0);
if Filters.BlockMiddleButton = True then
Result := - 1
else
Result := CallNextHookEx(GlobalData^.WndHook, Code, wParam, lParam);
end else
if (wParam = WM_RBUTTONDOWN) then
begin
SendMessage(GlobalData.Wnd, MWM_RBUTTONDOWN, 0, 0);
if Filters.BlockRightButton = True then
Result := - 1
else
Result := CallNextHookEx(GlobalData^.WndHook, Code, wParam, lParam);
end else
if (wParam = WM_RBUTTONUP) then
begin
SendMessage(GlobalData.Wnd, MWM_RBUTTONUP, 0, 0);
if Filters.BlockRightButton = True then
Result := - 1
else
Result := CallNextHookEx(GlobalData^.WndHook, Code, wParam, lParam);
end else
if (wParam = WM_MOUSEWHEEL) then
begin
SendMessage(GlobalData.Wnd, MWM_MOUSEWHEEL, 0, 0);
if Filters.BlockWheel = True then
Result := - 1
else
Result := CallNextHookEx(GlobalData^.WndHook, Code, wParam, lParam);
end else
if (wParam = WM_MOUSEMOVE) then
begin
SendMessage(GlobalData.Wnd, MWM_MOUSEMOVE, 0, 0);
if Filters.BlockMouseMove = True then
Result := - 1
else
Result := CallNextHookEx(GlobalData^.WndHook, Code, wParam, lParam);
end
else
Result := CallNextHookEx(GlobalData^.WndHook, Code, wParam, lParam);
end;
end;
function StartMouseHook(State: Boolean; Wnd: HWND): Boolean; export; stdcall;
begin
Result := False;
if State = True then
begin
GlobalData^.WndHook := SetWindowsHookEx(WH_MOUSE_LL, @LowLevelMouseProc, hInstance, 0);
GlobalData^.Wnd := Wnd;
if GlobalData^.WndHook <> 0 then
Result := True;
end
else
begin
UnhookWindowsHookEx(GlobalData^.WndHook);
Result := False;
end;
end;
function StopMouseHook(): Boolean; export; stdcall;
begin
UnhookWindowsHookEx(GlobalData^.WndHook);
if GlobalData^.WndHook = 0 then
Result := False
else
Result := True;
end;
function UpdateMouseHook(HookFilters: TMouseHookFilters): Boolean; export; stdcall;
begin
Filters := HookFilters;
end;
procedure OpenGlobalData();
begin
MWM_LBUTTONDOWN := RegisterWindowMessage('MWM_LBUTTONDOWN');
MWM_LBUTTONUP := RegisterWindowMessage('MWM_LBUTTONUP');
MWM_MBUTTONDOWN := RegisterWindowMessage('MWM_MBUTTONDOWN');
MWM_MBUTTONUP := RegisterWindowMessage('MWM_MBUTTONUP');
MWM_RBUTTONDOWN := RegisterWindowMessage('MWM_RBUTTONDOWN');
MWM_RBUTTONUP := RegisterWindowMessage('MWM_RBUTTONUP');
MWM_MOUSEWHEEL := RegisterWindowMessage('MWM_MOUSEWHEEL');
MWM_MOUSEMOVE := RegisterWindowMessage('MWM_MOUSEMOVE');
MMFHandle := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(TGlobalDLLData), MMFName);
GlobalData := MapViewOfFile(MMFHandle, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TGlobalDLLData));
if GlobalData = nil then
CloseHandle(MMFHandle);
end;
procedure CloseGlobalData();
begin
UnmapViewOfFile(GlobalData);
CloseHandle(MMFHandle);
end;
procedure DLLEntryPoint(Reason: DWORD);
begin
case Reason of
DLL_PROCESS_ATTACH: OpenGlobalData;
DLL_PROCESS_DETACH: CloseGlobalData;
end;
end;
exports StartMouseHook, StopMouseHook, UpdateMouseHook;
begin
DLLEntryPoint(DLL_PROCESS_ATTACH);
end.
Код:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, sGroupBox, sComboBox, sSkinManager, sButton, ExtCtrls,
acImage, ComCtrls, sLabel;
type
TForm1 = class(TForm)
sSkinManager1: TsSkinManager;
sComboBox1: TsComboBox;
sRadioGroup1: TsRadioGroup;
sImage1: TsImage;
sButton1: TsButton;
sLabel1: TsLabel;
sButton2: TsButton;
Timer1: TTimer;
sGroupBox1: TsGroupBox;
procedure sRadioGroup1Click(Sender: TObject);
procedure FormCanResize(Sender: TObject; var NewWidth,
NewHeight: Integer; var Resize: Boolean);
procedure FormDestroy(Sender: TObject);
procedure sButton1Click(Sender: TObject);
procedure sButton2Click(Sender: TObject);
protected
procedure WndProc(var Msg: TMessage); override;
private
{ Private declarations }
public
{ Public declarations }
end;
type
TMouseHookFilters = record
BlockMouseMove: boolean;
BlockLeftButton: boolean;
BlockRightButton: boolean;
BlockMiddleButton: boolean;
BlockWheel: boolean;
end;
var
Form1: TForm1;
HookEnable: Boolean = False;
HookFilters: TMouseHookFilters;
MWM_LBUTTONDOWN: Cardinal;
MWM_LBUTTONUP: Cardinal;
MWM_MBUTTONDOWN: Cardinal;
MWM_MBUTTONUP: Cardinal;
MWM_RBUTTONDOWN: Cardinal;
MWM_RBUTTONUP: Cardinal;
MWM_MOUSEWHEEL: Cardinal;
MWM_MOUSEMOVE: Cardinal;
p: TPoint;
Key: Word;
function StartMouseHook(State: Boolean; Wnd: HWND): Boolean; stdcall; external 'LowLevelMouseHook.dll';
function StopMouseHook(): Boolean; stdcall; external 'LowLevelMouseHook.dll';
function UpdateMouseHook(HookFilters: TMouseHookFilters): Boolean; stdcall; external 'LowLevelMouseHook.dll';
implementation
{$R *.dfm}
procedure TForm1.FormCanResize(Sender: TObject; var NewWidth,
NewHeight: Integer; var Resize: Boolean);
begin
Resize := False;
end;
procedure TForm1.WndProc(var Msg: TMessage);
begin
inherited;
if (Msg.Msg = MWM_LBUTTONDOWN) then
begin
if (sRadioGroup1.ItemIndex=0) and (sComboBox1.ItemIndex=4) then
begin
GetCursorPos(p);
SetCursorPos(p.X-4, p.Y+3);
Sleep(85);
Application.ProcessMessages;
GetCursorPos(p);
SetCursorPos(p.X-5, p.Y+2);
Sleep(85);
Application.ProcessMessages;
GetCursorPos(p);
SetCursorPos(p.X+6, p.Y+1);
Sleep(85);
Application.ProcessMessages;
end;
end;
if (Msg.Msg = MWM_LBUTTONUP) then
begin
end;
if (Msg.Msg = MWM_MBUTTONDOWN) then
begin
...
end;
if (Msg.Msg = MWM_MBUTTONUP) then
begin
...
end;
if (Msg.Msg = MWM_RBUTTONDOWN) then
begin
...
end;
if (Msg.Msg = MWM_RBUTTONUP) then
begin
...
end;
end;
procedure TForm1.sRadioGroup1Click(Sender: TObject);
begin
Timer1.Enabled:=False;
case sRadioGroup1.ItemIndex of
0: begin
sComboBox1.Clear;
sComboBox1.Items.Add('0');
sComboBox1.Items.Add('1');
sComboBox1.Items.Add('2');
sComboBox1.Items.Add('3');
sComboBox1.Items.Add('4');
sComboBox1.Items.Add('5');
sComboBox1.Items.Add('6');
sComboBox1.Items.Add('7');
end;
...
end;
end;
procedure TForm1.sButton1Click(Sender: TObject);
begin
if StartMouseHook(True, Handle) = True then
begin
HookEnable := True;
sButton1.Enabled := False;
sButton2.Enabled := True;
end else
end;
procedure TForm1.sButton2Click(Sender: TObject);
begin
if StopMouseHook = True then
begin
HookEnable := False;
sButton2.Enabled := False;
sButton1.Enabled := True;
end else
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
if HookEnable <> False then
StopMouseHook;
end;
initialization
MWM_LBUTTONDOWN := RegisterWindowMessage('MWM_LBUTTONDOWN');
MWM_LBUTTONUP := RegisterWindowMessage('MWM_LBUTTONUP');
MWM_MBUTTONDOWN := RegisterWindowMessage('MWM_MBUTTONDOWN');
MWM_MBUTTONUP := RegisterWindowMessage('MWM_MBUTTONUP');
MWM_RBUTTONDOWN := RegisterWindowMessage('MWM_RBUTTONDOWN');
MWM_RBUTTONUP := RegisterWindowMessage('MWM_RBUTTONUP');
MWM_MOUSEWHEEL := RegisterWindowMessage('MWM_MOUSEWHEEL');
MWM_MOUSEMOVE := RegisterWindowMessage('MWM_MOUSEMOVE');
end.
Последний раз редактировалось vers0, 02.08.2015 в 10:46.
|