Ighn
|
Helix pomatia
|
|
|
|
Рег.: 15.06.2005
|
Сообщений: 383
|
Из: Москва
|
Рейтинг: -10
|
|
Выводить координаты мыши через мех-м Хука (Delphi)
30.10.2007 01:29
|
|
|
Недавно задавал вопрос насчет глобального хука. Вроде разобрался, только что-то торможу и не могу понять как выводить координаты мыши вызывающему окну.
Еханый бабай! Не посмотрел, что структура tagMSG имеет поле pt: TPoint - Позиция указателя мыши (в экранных координатах). Проблема решена. Ладно, может кому пригодится код, который я выложил.  Ксати, а как выводить позицию X,Y в координатах вызываемого приложения?
Вот код dll-библиотеки:
code:
library Hkdll;
uses
Windows,Messages,
//this
UExchng;
//получить хендл вызываемого окна(контрола)
procedure GetHandleCausedWnd; stdcall;
var
t:TPoint;
buf: array [0..255] of char;
begin
GetCursorPos(t);//получить значения экранных координат
//значения экранных координат - в общие переменные
CommonArea^.X_:=t.X;
CommonArea^.Y_:=t.Y;
CommonArea^.CausedFmHandle:=WindowFromPoint(t);//получить хендл контрола по экранным координатам
GetClassName(CommonArea^.CausedFmHandle,buf,255);//получить название класса контрола по хендлу
end;
//функция - ловушка клавиатуры
function HookKeybrd(c0de: integer; wParam: WPARAM; lParam : LPARAM): Integer; stdcall;
begin
if c0de >= 0 then
begin//Если c0de не меньше 0, все в порядке, продолжаем
//Работа с клавиатурой
PostMessage(CommonArea^.CausingFmHandle, UExchng.WMKeybrdHook, wParam, lParam);//сообщение окну-обработчику от клавиатуры
//
end else
//Если c0de меньше 0
begin
//Вызываем следующую ловушку в цепочке ловушек Windows и выходим из процедуры
result := CallNextHookEx(CommonArea^.KeyBrdHookHandle, c0de, wParam, lParam);
exit;
end;//if
//Вызываем следующую ловушку в цепочке ловушек Windows
result := CallNextHookEx(CommonArea^.KeyBrdHookHandle, c0de, wParam, lParam);
End;
//функция - ловушка мыши
function HookMouse(c0de: integer; wParam: WPARAM; lParam : LPARAM): Integer; stdcall;
begin
if c0de >= 0 then
begin//Если c0de не меньше 0, все в порядке, продолжаем
//Работа с мышью
PostMessage(CommonArea^.CausingFmHandle, UExchng.WMMouseHook, wParam, lParam);//сообщение окну-обработчику от мыши
GetHandleCausedWnd;//
//
end else
//Если c0de меньше 0
begin
//Вызываем следующую ловушку в цепочке ловушек Windows и выходим из процедуры
result := CallNextHookEx(CommonArea^.MouseHookHandle, c0de, wParam, lParam);
exit;
end;//if
//Вызываем следующую ловушку в цепочке ловушек Windows
result := CallNextHookEx(CommonArea^.MouseHookHandle, c0de, wParam, lParam);
End;
//Установка/удаление ловушки
function SetKeybrdHook(Active: bool): bool; stdcall; export;
begin
Result:=False;
If Active then
begin
CommonArea^.KeyBrdHookHandle:= SetWindowsHookEx(WH_KEYBOARD, @HookKeybrd, hInstance, 0);//ловушку - на клавиатуру
Result:=(CommonArea^.KeyBrdHookHandle <> 0);
end else
begin
If CommonArea^.KeyBrdHookHandle <> 0 then
begin
Result:=UnhookWindowsHookEx(CommonArea^.KeyBrdHookHandle);
If Result then CommonArea^.KeyBrdHookHandle:=0;
end;//If CommonArea^.KeyBrdHookHandle
end;//else If Active
end;
//Установка/удаление ловушки
function SetMouseHook(Active: bool): bool; stdcall; export;
begin
Result:=False;
If Active then
begin
CommonArea^.MouseHookHandle:= SetWindowsHookEx(WH_MOUSE, @HookMouse, hInstance, 0);//ловушку - на мышь
Result:=(CommonArea^.MouseHookHandle <> 0);
end else
begin
If CommonArea^.MouseHookHandle <> 0 then
begin
Result:=UnhookWindowsHookEx(CommonArea^.MouseHookHandle);
If Result then CommonArea^.MouseHookHandle:=0;
end;//If CommonArea^.MouseHookHandle
end;//else If Active
end;
//Экспорт процедуры установки/удаления hook'a
exports
SetKeybrdHook name 'SetKeybrdHook',
SetMouseHook name 'SetMouseHook';
end.
Вот код вспомогательного юнита для обмена данными. Не добавляется в проект, а просто создается в виде *.pas файла, который кидается в папку с программой:
code:
//модуль для обмена данными между dllками и вызывающим приложением
//обмен производится с помощью механизма "отображения файлов на память"
//
unit UExchng;
interface
uses Windows;
type
PKeybrdHookInfo = ^TKeybrdHookInfo;
TKeybrdHookInfo = packed record
CausingFmHandle: THandle;//хендл вызывающего приложения
CausedFmHandle: THandle;//хендл вызываемого окна
KeyBrdHookHandle: THandle;//хендл ловушки клавиатуры
MouseHookHandle: THandle;//хендл ловушки мыши
//значения абс.координат мыши вызываемого окна
X_: Longint;
Y_: Longint;
end;
var
WMKeybrdHook: integer = 0;
WMMouseHook: integer = 0;
CommonArea: PKeybrdHookInfo = nil;
implementation
var
Mapping: THandle = 0;
const
//GUID по умолч-ю для сообщения для вызывающего окна.
UniqueKeybrdHookId = '{802BA1C4-4083-495B-B22F-99D05500D156}';//
UniqueMouseHookId = '{B7772338-EC41-4086-9F27-C14AE8D9F196}';//
initialization
//создаем объект отображ-я файла на память. В случае успеха возващается идентификатор объекта
//MAXDWORD - создаваемый объект файлового отображения свяжем со страничным своп-файлом.
Mapping := CreateFileMapping(MAXDWORD, nil, PAGE_READWRITE, 0, SizeOf(CommonArea), 'HookKeybrdAndMouse');
//представляем объект отображ-я в окне просмотра, получаем указатель
CommonArea:= MapViewOfFile(Mapping,FILE_MAP_ALL_ACCESS,0,0,0);
//проверяем уникальность id; при необх-ти создаем новый id
WMKeybrdHook:= RegisterWindowMessage(UniqueKeybrdHookId);//для сообщений клавиатуры
WMMouseHook:= RegisterWindowMessage(UniqueMouseHookId);//для сообщений мыши
finalization
If Assigned(CommonArea) then
UnMapViewOfFile(CommonArea);//освобождаем отображение файла
If Mapping<>0 then
CloseHandle(Mapping);//освобождаем дескриптор файла
end.
Редактировал Ighn (30.10.2007 01:56)
|
Incertus animus dimidium sapientiae est - Сомнение - половина мудрости |
|
Ighn
|
Helix pomatia
|
|
|
|
Рег.: 15.06.2005
|
Сообщений: 383
|
Из: Москва
|
Рейтинг: -10
|
|
Re: Выводить координаты мыши через мех-м Хука (Delphi)
[re: Ighn]
30.10.2007 01:34
|
|
|
Вот код вызывающего приложения:
code:
unit UtstHook2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,
//this
UExchng, UFunc;
type
TForm1 = class(TForm)
BtnClose: TButton;
CheckBox1: TCheckBox;
Memo1: TMemo;
Edit1: TEdit;
BtnClear: TButton;
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
Edit3: TEdit;
Edit4: TEdit;
Label3: TLabel;
Label4: TLabel;
Edit5: TEdit;
Edit6: TEdit;
procedure CheckBox1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure BtnCloseClick(Sender: TObject);
procedure BtnClearClick(Sender: TObject);
private
{ Private declarations }
procedure AppOnMessage(var Msg: TMsg; var Handled: Boolean);
public
{ Public declarations }
end;
var
Form1: TForm1;
function SetKeybrdHook(Active: bool): bool; stdcall; external 'Hkdll.dll';
function SetMouseHook(Active: bool): bool; stdcall; external 'Hkdll.dll';
implementation
{$R *.dfm}
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
SetKeybrdHook(CheckBox1.Checked);//установить или снять ловушку
SetMouseHook(CheckBox1.Checked);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
//подготавливаем область памяти: заполняем ее нулями
FillChar(CommonArea^, SizeOf(CommonArea^), 0);
//сообщения от ловушки будут посылаться вызывающему окну
CommonArea^.CausingFmHandle:=Application.Handle;
//устанавливаем процедуру-обработчик сообщений
Application.OnMessage:=AppOnMessage;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
SetKeybrdHook(False);//в любом случае снять ловушку/и
SetMouseHook(False);
end;
procedure TForm1.AppOnMessage(var Msg: TMsg; var Handled: Boolean);
begin
MsgFromKeybrd(Msg, Handled);//в обработку сообщений для клавиатуры
MsgFromMouse(Msg, Handled);//в обработку сообщений для мыши
end;
procedure TForm1.BtnCloseClick(Sender: TObject);
begin
Close;
end;
procedure TForm1.BtnClearClick(Sender: TObject);
begin
Memo1.Clear;
end;
end.
Вспомогательный юнит приложения:
code:
unit UFunc;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,
//this
UExchng;
procedure MsgFromKeybrd(var Msg: TMsg; var Handled: Boolean);
procedure MsgFromMouse(var Msg: TMsg; var Handled: Boolean);
implementation
uses UtstHook2;
//обработка сообщений клавиатуры
procedure MsgFromKeybrd(var Msg: TMsg; var Handled: Boolean);
var
buff: array[0..50] of Char;
str: string;
flags : word;
begin
if Msg.Message = UExchng.WMKeybrdHook then//получили сообщение от клавиатуры
begin
// Получаем наименование нажатой клавиши
GetKeyNameText(Msg.lParam, @Buff, SizeOf(Buff));
str := StrPas(Buff);
flags := Msg.lParam shr 16;
if (flags and KF_UP) <> 0 then
str := str + '_up'
else if (Flags and KF_REPEAT) <> 0 then
str := str + '_rpt'
else str := str + '_dwn';
Form1.Memo1.Lines.Add(str);
Handled := true;
end;//if
end;
//обработка сообщений мыши
procedure MsgFromMouse(var Msg: TMsg; var Handled: Boolean);
var
w : THandle;
hw, hw2 : hwnd;//дескриптор окна
GHw: hwnd;
//
t:TPoint;
buf: array [0..255] of char;
//msg1: PEVENTMSG;
begin
//
{ msg1 := Pointer(Msg.LParam);
case msg1.message of
WM_MOUSEMOVE: Form1.Caption := IntToStr(msg1.ParamL) + #32 + IntToStr(msg1.ParamH);
end; }
//
if Msg.Message = UExchng.WMMouseHook then//получили сообщение от мыши
begin
//получаем наименование нажатых кнопок
case Msg.wParam of
//Если wParam = WM_RBUTTONUP, т.е. нажата прав.кн. мыши, получаем хендл кнопки "Пуск" и скрываем ее
WM_RBUTTONDOWN: begin
Form1.Memo1.Lines.Add('RBtnMs_dwn');
end;
WM_RBUTTONUP: begin
Form1.Memo1.Lines.Add('RBtnMs_up');
end;
WM_RBUTTONDBLCLK:
begin
Form1.Memo1.Lines.Add('RBtnMs_dclk');
end;
//Если wParam = WM_LBUTTONUP, т.е. нажата лев.кн. мыши, получаем хендл кнопки "Пуск" и показываем ее
WM_LBUTTONDOWN: begin
Form1.Memo1.Lines.Add('LBtnMs_dwn');
Form1.Edit2.Text:=IntToStr(CommonArea^.CausedFmHandle);//вывести хендл вызываемого контрола
Form1.Edit3.Text:=IntToStr(CommonArea^.X_);
Form1.Edit4.Text:=IntToStr(CommonArea^.Y_);
end;
WM_LBUTTONUP: begin
Form1.Memo1.Lines.Add('LBtnMs_up');
end;
WM_LBUTTONDBLCLK:
begin
Form1.Memo1.Lines.Add('LBtnMs_dclk');
end;
//Если wParam = WM_MBUTTONUP, т.е. нажата средняя кнопка мыши, получаем указатель на заголовок акт.окна и изменяем его
WM_MBUTTONDOWN: begin
Form1.Memo1.Lines.Add('MBtnMs_dwn');
end;
WM_MBUTTONUP: begin
Form1.Memo1.Lines.Add('MBtnMs_up');
end;
WM_MBUTTONDBLCLK:
begin
Form1.Memo1.Lines.Add('MBtnMs_dclk');
end;
WM_MOUSEMOVE:
begin
// Form1.Edit5.Text:=IntToStr(LoWord(Msg.LParam));//вот это не работает!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Form1.Edit6.Text:=IntToStr(HiWord(Msg.LParam));//не работает!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//Надо так:
Form1.Edit5.Text:=IntToStr(Msg.pt.X);
Form1.Edit6.Text:=IntToStr(Msg.pt.Y);
end;
end;//case
end;//if
end;
end.
В общем, там где WM_MOUSEMOVE должны вылавливаться координаты мыши, но ни фига не вылавливается. 
Редактировал Ighn (30.10.2007 02:08)
|
Incertus animus dimidium sapientiae est - Сомнение - половина мудрости |
|
|
|