Документ взят из кэша поисковой машины. Адрес оригинального документа : http://www.fds-net.ru/showflat.php?Number=6805505&src=arc&showlite=
Дата изменения: Unknown
Дата индексирования: Tue Apr 12 13:29:36 2016
Кодировка: Windows-1251
Выводить координаты мыши через мех-м Хука (Delphi) - Public forum of MSU united student networks
Root | Google | Yandex | Mail.ru | Kommersant | Afisha | LAN Support
  
Technical >> Development (Archive)

Страницы: 1
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 должны вылавливаться координаты мыши, но ни фига не вылавливается. :crazy:





Редактировал Ighn (30.10.2007 02:08)
Incertus animus dimidium sapientiae est - Сомнение - половина мудрости
Страницы: 1

Technical >> Development (Archive)

Дополнительная информация
0 зарегистрированных и 0 анонимных пользователей просматривают этот форум.

Модераторы:  DarkGray 

Печать темы

Права
      Вы можете создавать новые темы
      Вы можете отвечать на сообщения
      HTML отключен
      UBBCode включен

Рейтинг:
Просмотров темы:

Переход в