Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Hook wanted [D5, Win95/98]


Страницы:   1 2

Mihey_temporary ©   (2004-12-13 23:08:00) 

У кого-нибудь есть навскидку готовый пример глобального хука на мышь, отсылающего программе сообщения при передвижении мыши и нажатии на кнопки? Требуется и хук, и обработка сообщений в главной программе.


Mihey_temporary   (2004-12-14 23:39:00) [21]

Всё равно висит:

Приложение:


unit TestUnit;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
 TTestForm = class(TForm)
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
 private
   procedure CopyData(var Msg: TWMCopyData); message WM_COPYDATA;
 public
   { Public declarations }
 end;

type TSetMouseHook = procedure (WND: HWND); stdcall;
    TRemoveMouseHook = procedure; stdcall;

var
 TestForm: TTestForm;
 hcDll: THandle;
 SetMouseHook: TSetMouseHook;
 RemoveMouseHook: TRemoveMouseHook;

implementation

{$R *.DFM}

procedure TTestForm.CopyData(var Msg: TWMCopyData);
var Coord: TPoint;
begin
 Coord := TMouseHookStruct(Msg.CopyDataStruct^.lpData^).pt;
 Caption := IntToStr(Coord.x) + IntToStr(Coord.y);
 inherited;
end;

procedure TTestForm.FormCreate(Sender: TObject);
begin
 hcDll := LoadLibrary('mousehook.dll');
 If hcDll <= HINSTANCE_ERROR then
  begin
   MessageDlg('You are looser!', mtError, [mbOk], 0);
   Application.Terminate;
  end;
 SetMouseHook := GetProcAddress(hcDll, 'SetMouseHook');
 If not Assigned(SetMouseHook) then
  begin
   MessageDlg('You are looser!', mtError, [mbOk], 0);
   Application.Terminate;
  end;
 RemoveMouseHook := GetProcAddress(hcDll, 'RemoveMouseHook');
 If not Assigned(RemoveMouseHook) then
  begin
   MessageDlg('You are looser!', mtError, [mbOk], 0);
   Application.Terminate;
  end;
 SetMouseHook(Handle);
end;

procedure TTestForm.FormDestroy(Sender: TObject);
begin
 RemoveMouseHook;
 FreeLibrary(hcDll);
end;

end.


Библиотека:


library MouseHook;

uses
 SysUtils, Classes, Windows, Messages;

var
 MouseHooker: HHook;
 BackHandle: HWND;

function MouseProc(Code: Integer; wParam: Word; lParam: Longint): Longint; stdcall;
var copyDataStruct: TCopyDataStruct;
   lAddition: Integer;
begin
 if Code in [HC_ACTION, HC_NOREMOVE] then
  begin
   CopyDataStruct.lpData := Pointer(lParam);
   CopyDataStruct.cbData := SizeOf(TMouseHookStruct);
//    CopyDataStruct.dwData := wParam;
    CopyDataStruct.dwData := GetCurrentThreadId;
   lAddition := Integer(@CopyDataStruct);
   SendMessage(BackHandle, WM_COPYDATA, 0, lAddition);
  end;
 Result := CallNextHookEx(MouseHooker, Code, wParam, lParam);
end;

procedure SetMouseHook(Wnd: HWND);
begin
 BackHandle := Wnd;
 MouseHooker := SetWindowsHookEx(WH_MOUSE, @MouseProc, HInstance, 0);
end;

procedure RemoveMouseHook;
begin
 UnhookWindowsHookEx(MouseHooker);
end;

exports SetMouseHook,
       RemoveMouseHook;

begin

end.


Leonid Troyanovsky   (2004-12-14 23:13:00) [22]


> Mihey_temporary ©   (14.12.04 22:58) [11]
> Беспокоит меня вот это дело:

> > CopyDataStruct.lpData := @lParam;


lpData

Points to data to be passed to the receiving application.
lParam и так содержит указатель на данные, т.е.

CopyDataStruct.lpData := Pointer(lParam);

В dwData обычно указывают окно (для идентификации),
в данном случае можно GetCurrentThreadId

И, потом, какой такой Post? Только SendMessage.
Если свое сообщение + mmf, тоже, кстати Send.

--
С уважением, LVT.


Mihey_temporary   (2004-12-14 22:58:00) [23]

Беспокоит меня вот это дело:


> CopyDataStruct.lpData := @lParam;


Получается, адрес указателя, что-ли.


Mihey_temporary   (2004-12-14 22:56:00) [24]

Что-то не пашет хук и ИМХО ошибка где-то в связке:

В приложении:


procedure TTestForm.CopyData(var Msg: TWMCopyData);
var Coord: TPoint;
begin
 Coord := TMouseHookStruct(Msg.CopyDataStruct^.lpData^).pt;
 Caption := IntToStr(Coord.x) + IntToStr(Coord.y);
 inherited;
end;


В библиотеке:


var
 MouseHooker: HHook;
 BackHandle: HWND;

function MouseProc(Code: Integer; wParam: Word; lParam: Longint): Longint; stdcall;
var copyDataStruct: TCopyDataStruct;
   lAddition: Integer;
begin
 if Code in [HC_ACTION, HC_NOREMOVE] then
  begin
   CopyDataStruct.lpData := @lParam;
   CopyDataStruct.cbData := SizeOf(TMouseHookStruct);
   CopyDataStruct.dwData := wParam;
   lAddition := Integer(@CopyDataStruct);
   PostMessage(BackHandle, WM_COPYDATA, 0, lAddition);
  end;
 Result := CallNextHookEx(MouseHooker, Code, wParam, lParam);
end;


Вылетает с AV.


Юрий Зотов   (2004-12-14 21:45:00) [25]

> Mihey_temporary ©   (14.12.04 21:24) [7]

> А зачем такая сложность с WM_COPYDATA? Почему нужно
> использовать это дело, а не как в том примере.

Потому что хук глобальный. Это значит, что он должен передать данные из одного АП в другое. А длина этих данных такова, что в параметры сообщения их не запихнешь. Значит, если не рассматривать уж слишком вычурные способы, то либо [8], либо WM_COPYDATA, либо обрезать данные до 8 байт и передавать в параметрах.


Leonid Troyanovsky   (2004-12-14 21:32:00) [26]



> Mihey_temporary ©   (14.12.04 21:24) [7]

> А зачем такая сложность с WM_COPYDATA? Почему нужно использовать
> это дело, а не как в том примере. Я хочу своё сообщение!


Добавь в mmf MOUSEHOOKSTRUCT и пользуй.
Только копировать туда надо самому (move).

--
С уважением, LVT.


Mihey_temporary   (2004-12-14 21:24:00) [27]


> Желаю удачи.


Вот так люди переходят на VCL. И всё-таки...


> Вам нужно сделать то же самое, только посылать форме из
> хука нужно не свое сообщение, а WM_COPYDATA, передавая в
> нем в wParam - ноль (идентификатор того, что сообщение пришло
> именно от хука) а в lParam - адрес структуры COPYDATASTRUCT,
> которая в dwData будет содержать само сообщение мыши (оно
> приходит в хук, как wParam), в lpData будет содержать адрес
> структуры MOUSEHOOKSTRUCT (он приходит в хук, как lParam),
> а в cbData будет содержать размер структуры MOUSEHOOKSTRUCT.


А зачем такая сложность с WM_COPYDATA? Почему нужно использовать это дело, а не как в том примере. Я хочу своё сообщение!


Юрий Зотов   (2004-12-14 01:21:00) [28]

> Mihey_temporary ©   (14.12.04 01:19) [5]

Желаю удачи.


Mihey_temporary   (2004-12-14 01:19:00) [29]


> Palladin ©   (14.12.04 00:00) [3]
> Это все безусловно подробно описано в справке WinAPI.


Я ищу лёгкое решение.


Юрий Зотов   (2004-12-14 00:49:00) [30]

> Mihey_temporary ©   (13.12.04 23:55) [2]

http://delphimaster.ru/cgi-bin/forum.pl?id=1102341741&n=0

Вам нужно сделать то же самое, только посылать форме из хука нужно не свое сообщение, а WM_COPYDATA, передавая в нем в wParam - ноль (идентификатор того, что сообщение пришло именно от хука) а в lParam - адрес структуры COPYDATASTRUCT, которая в dwData будет содержать само сообщение мыши (оно приходит в хук, как wParam), в lpData будет содержать адрес структуры MOUSEHOOKSTRUCT (он приходит в хук, как lParam), а в cbData будет содержать размер структуры MOUSEHOOKSTRUCT.

Еще момент - вызывайте CallNextHookEx всегда, независимо от значения nCode.


Palladin   (2004-12-14 00:00:00) [31]

Это все безусловно подробно описано в справке WinAPI.


Mihey_temporary   (2004-12-13 23:55:00) [32]


> Palladin ©   (13.12.04 23:24) [1]


Статья, безусловно, по хукам, но нет конкретно про мышь. Мне больше интересует именно тело мышиной процедуры и обработка сообщений в главной программе.


Palladin   (2004-12-13 23:24:00) [33]

http://www.delphimaster.ru/articles/hooks/index.html


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо