Форум: "WinAPI";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.04.29;
Скачать: [xml.tar.bz2];




Вниз

Как словить курсор? 


Керик   (2002-01-04 05:54) [0]

Помогите, кто знает! Я делаю мышиного шпиона,
но у меня не получается проследить за ней, точнее
получается, но только в области окна. Помогите,
плиз, кто знает, как сделать, чтобы винда сообщала
мноей проге о смене места нахождения мышиного курсора.



False_Delirium   (2002-01-04 06:33) [1]

С порта считывай напрямую......либо постоянно вызывай GetCursorPos,но это весьма некорректный подход.

Лучше сделай хук на всю систему и при передачи WM_MouseMove активизируй шпиЁнА..:)..



Dimaond Cat   (2002-01-05 03:30) [2]

Длл-ка
library Mouse;

uses
Windows,
Messages;
var
HookHandle: HHOOK = 0;

//функция обрабатывающая сообщения (мышиные)
function MouseProc(Code, W,l : Integer): LongInt; stdcall;
var
j,i:integer;
begin
if Code =HC_ACTION
then
//в принципе тут можно производить обработку и отсекание ненужных сообщений
//что-то типа if w=wm_nchittest then
begin
//составляем дополнительные параметры для нашего сообщения.
i:=makelparam(TMOUSEHOOKSTRUCT(Pointer(L)^).pt.x,TMOUSEHOOKSTRUCT(Pointer(L)^).pt.y);
j:=makeWparam(TMOUSEHOOKSTRUCT(Pointer(L)^).hwnd,w);
//отправляем сообщение наше программе.
SendMessage(FindWindow(nil,"MouseHook"), WM_USER,j ,i); // Уведомляем программу об этом.
end;
Result := CallNextHookEx(HookHandle, Code, W,L )
end;

function SetHook: LongBool; stdcall;
begin
//установка ловушки
HookHandle := SetWindowsHookEx(WH_Mouse, MouseProc, HInstance, 0);
Result := HookHandle <> 0 ;
end;

function RemoveHook: LongBool; stdcall;
begin
Result := UnHookWindowsHookEx(HookHandle)
//снятие ловушки
end;

exports
SetHook, RemoveHook; //экспортируемые функции
begin
end.

сама прога

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Forms,
Controls, StdCtrls, Classes;
type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
procedure user(var message:Tmessage) ; message wm_user;
{ Public declarations }
end;

var
Form1: TForm1;
function SetHook:longbool;stdcall; external "mouse" ;
function RemoveHook:longbool;stdcall; external "mouse" ;
// можно конечно и динамически подключать длл, но мне больше нравится так.
implementation
var
i:integer=0;
{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
Form1.Caption:="MouseHook"; // длл посылает сообщения нашему окну, ореинтируясь
//на его название
SetHook;// включаем ловушку, тут по идее надо бы сделать проверку запустилась она или нет
//т.е. если эта функция фернула False то ловушка не включилась.
end;

procedure tForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
RemoveHook;// не забываем выключить ловушку по завершению программы
end;

procedure TForm1.user(var message:Tmessage);
{Эта процедура срабатывает каждый раз, когда в нашей библиотеке
проходит мышиное сообщение, соответственно тут можно просматривать какое сообщение
прошло, также это можно сделать и в самой длл-ке }
var
c:array [0..max_path] of char;
begin

i:=i+1;
label1.Caption:="К данному моменту мышь намотала "+inttostr(i)+" пикселей";
label2.Caption:="Координаты мыши по горизонтали = "+inttostr(message.LParamLo);
label3.Caption:="Координаты мыши по вертикали = "+inttostr(message.LParamHi);
label4.caption:="Дескриптор окна под мышью = "+inttostr(message.Wparamlo);
GetWindowText(message.Wparamlo,c,Sizeof(c));
label5.Caption:="Название окна под мышью = "+c;
GetClassName(message.Wparamlo,c,Sizeof(c));
label6.Caption:="Название класса окна под мышью = "+c;
Label7.Caption:=inttostr(message.WParamHi);
{как видно из показаний лейблов можно отслеживать любые сообщения лейбл №7 показывает
(в десятичном представлении) номер сообщения, в файле messages, если в него заглянуть,
можно увидить какому сообщению соответствует данное цифровое сочетание, только там
эти сочетания представленны в 16-ричном представлении}
end;
{Вобще-то если это должна быть программа типа шпиона , то лучше
делеать ее не используя VCL, тогда ее размер будет минимальным.}
end.



ksvvv   (2002-02-23 19:18) [3]

Скопировал эту прогу - скомпилировал - не фурычит
Ну не хочет она мышь перехватывать!
Может, скинешь мне на мыло рабочий вариант?
Вениамин



copyr25   (2002-02-23 19:38) [4]

Не, всё нормально работает. И даже название класса выдаёт:))



Raptor   (2002-02-23 23:03) [5]

Ясен перец, что не фуричит. В этом примере есть один, но очень серьезный недочет. Dimaond Cat забыл (или не знает), что он ставит глобальный хук и ДЛЛ, в которой он находится, подгружается в адресные пространства всех процессов. А в разных адресных пространствах значение переменной HookHandle будет разным. Это может покатить в Win2k и выше, так как там цепочка хуков запоминается системой и если при вызове CallNextHookТо предается неправильный параметр, он автоматически исправляется.
Но в Win9x это скорее всего не покатит.
Лучше всего возьми готовый пример клавиатурного хука в FAQ ( http://delphi.mastak.ru/cgi-bin/faq.pl?look=1&id=988619882&n=15) и пределай его под WH_MOUSE.



copyr25   (2002-02-24 20:21) [6]

library mhook;

uses
SysUtils, Classes, Windows, Messages;
var
HookHandle: HHOOK = 0;

//функция обрабатывающая сообщения (мышиные)
function MouseProc(Code, W,l : Integer): LongInt; stdcall;
var
j,i:integer;
begin
if Code =HC_ACTION
then
//в принципе тут можно производить обработку и отсекание ненужных сообщений
//что-то типа if w=wm_nchittest then
begin
//составляем дополнительные параметры для нашего сообщения.

i:=makelparam(TMOUSEHOOKSTRUCT(Pointer(L)^).pt.x,TMOUSEHOOKSTRUCT(Pointer(L)^).pt.y);
j:=makeWparam(TMOUSEHOOKSTRUCT(Pointer(L)^).hwnd,w);
//отправляем сообщение наше программе.
SendMessage(FindWindow(nil,"MouseHook"), WM_USER,j ,i); // Уведомляем программу об этом.
end;
Result := CallNextHookEx(HookHandle, Code, W,L )
end;

function SetHook: LongBool; stdcall;
begin
//установка ловушки
HookHandle := SetWindowsHookEx(WH_Mouse, MouseProc, HInstance, 0);
Result := HookHandle <> 0 ;
end;

function RemoveHook: LongBool; stdcall;
begin
Result := UnHookWindowsHookEx(HookHandle)
//снятие ловушки
end;

exports
SetHook, RemoveHook; //экспортируемые функции
begin
end.



copyr25   (2002-02-24 20:23) [7]

unit Unit1;

interface

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

type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
procedure user(var message:Tmessage) ; message wm_user;
end;

var
Form1: TForm1;
function SetHook:longbool;stdcall; external "mhook" ;
function RemoveHook:longbool;stdcall; external "mhook" ;
implementation
var i:integer=0;
{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
Form1.Caption:="MouseHook"; // длл посылает сообщения нашему окну, ориентируясь
//на его название
SetHook;// включаем ловушку, тут по идее надо бы сделать проверку запустилась она или нет
//т.е. если эта функция фернула False то ловушка не включилась.
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
RemoveHook;// не забываем выключить ловушку по завершению программы
end;
procedure TForm1.user(var message:Tmessage);
{Эта процедура срабатывает каждый раз, когда в нашей библиотеке
проходит мышиное сообщение, соответственно тут можно просматривать какое сообщение
прошло, также это можно сделать и в самой длл-ке }
var
c:array [0..max_path] of char;
begin

i:=i+1;
label1.Caption:="К данному моменту мышь намотала "+inttostr(i)+" пикселей";
label2.Caption:="Координаты мыши по горизонтали = "+inttostr(message.LParamLo);
label3.Caption:="Координаты мыши по вертикали = "+inttostr(message.LParamHi);
label4.caption:="Дескриптор окна под мышью = "+inttostr(message.Wparamlo);
GetWindowText(message.Wparamlo,c,Sizeof(c));
label5.Caption:="Название окна под мышью = "+c;
GetClassName(message.Wparamlo,c,Sizeof(c));
label6.Caption:="Название класса окна под мышью = "+c;
Label7.Caption:=inttostr(message.WParamHi);
{как видно из показаний лейблов можно отслеживать любые сообщения лейбл №7 показывает
(в десятичном представлении) номер сообщения, в файле messages, если в него заглянуть,
можно увидить какому сообщению соответствует данное цифровое сочетание, только там
эти сочетания представленны в 16-ричном представлении}
end;
{Вобще-то если это должна быть программа типа шпиона , то лучше
делеать ее не используя VCL, тогда ее размер будет минимальным.}
end.



Dimaond Cat   (2002-02-25 00:11) [8]

2 Raptor не надо на меня телегу катить, эта прога работала под win95 & win98 но боюсь что по win2 работать как раз и не будет хотя..., а насчет CallnextHookEx , видимо ты не внимательно просмотрел исходник, я вообще никак не использую хендл хука, я пропускаю его таким какой он есть на все последующие хуки стоящие в цепочке
2 ksvvv а есть ли какоенибудь сообщение об ошибке?



Raptor   (2002-02-25 11:18) [9]

2 Raptor не надо на меня телегу катить, эта прога работала под win95 & win98 но боюсь что по win2 работать как раз и не будет хотя..., а насчет CallnextHookEx , видимо ты не внимательно просмотрел исходник, я вообще никак не использую хендл хука, я пропускаю его таким какой он есть на все последующие хуки стоящие в цепочке

Нда-а, видно ты и в самом деле не полностью понимаешь механизм хуков, и что такое разделение адресных пространств процессов. Как это ты вообще никак не используешь хендл хука? А разве это не строчки из твоего кода:

HookHandle := SetWindowsHookEx(WH_Mouse, MouseProc, HInstance, 0);
Result := UnHookWindowsHookEx(HookHandle)
Result := CallNextHookEx(HookHandle, Code, W,L )

Здесь ты используешь переменную HookHandle, значение которой получаешь при вызове SetWindowsHookEx. Так как это глобальный хук и ДЛЛ с хуком подгружается в адр. простр. всех процессов (а эта переменная не зашарена для всех процессов), то на месте этой переменной в любом другом процессе будет что угодно, любой мусор, который оказался по адресу HookHandle в этом процессе.
То, что эта прога у тебя работает, скорее исключение, чем правило. Потому и не удивительно, что у некоторых эта прога не работает.



Dimaond Cat   (2002-02-26 21:52) [10]

не согласен, есть предположение что SetWindowsHookEx возвращает абсолютное значение (непосредственно хендл хука) , а не просто адрес, который действительно в разных процессах будет просто кучей мусора по отношению к моей программе.Но спорить не буду вполне возможно что ты прав. Пойду спрошу у Зотова.....



Dimaond Cat   (2002-02-26 21:53) [11]

не согласен, есть предположение что SetWindowsHookEx возвращает абсолютное значение (непосредственно хендл хука) , а не просто адрес, который действительно в разных процессах будет просто кучей мусора по отношению к моей программе.Но спорить не буду вполне возможно что ты прав. Пойду спрошу у Зотова..... хотя сначала почитаю хелп (чего и всем желаю :о) )



Dimaond Cat   (2002-02-26 21:57) [12]

Return Values

If the function succeeds, the return value is the handle of the hook procedure.




Форум: "WinAPI";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.04.29;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.78 MB
Время: 0.038 c
4-94639           Grim Rider            2002-02-20 13:20  2002.04.29  
Hook


1-94385           inko                  2002-04-17 15:41  2002.04.29  
Выгрузка из памяти DLL файлов.


1-94495           Sukhov                2002-04-16 16:43  2002.04.29  
Получение почты, а точнее приаттаченных файлов с помощью FastNet


14-94567          Dmitriy_0             2002-03-25 09:38  2002.04.29  
Как записать файл на все станции в Windows networking


7-94599           Иоффе                 2002-01-15 15:54  2002.04.29  
Вырубление компа