Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 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.



Страницы: 1 вся ветка

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

Наверх





Память: 0.5 MB
Время: 0.006 c
3-94321
rvs
2002-04-09 11:33
2002.04.29
EkRtf


14-94545
kaif
2002-03-21 23:45
2002.04.29
Кто какие предложения вынужден отвергать?


1-94451
agrig
2002-04-15 20:23
2002.04.29
несколько колонок в QReport


1-94396
Swp
2002-04-17 15:49
2002.04.29
Запись и чтение текстового файла.


1-94376
Vovochka
2002-04-17 15:14
2002.04.29
Update for Delphi6





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский