![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Hook wanted [D5, Win95/98]
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