Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.06.26;
Скачать: [xml.tar.bz2];

Вниз

Где ошибка при завершении Hook и как занести данные в TPoint?   Найти похожие ветки 

 
Dr. Andrew   (2003-06-07 13:30) [0]

В данном примере если отпустить левую кнопку мыши вне формы и попытаться закрыть форму "виснет" даже сама Делфи 7.
Задача такова - перемещая левую кнопку мыши по экрану, даже за пределы формы (левая кнопка мыши в нажатом состоянии, экранные координаты зафиксировать при отпускании левой кнопки мыши в некой глобальной переменной APoint типа TPoint (эти значения затем будут обрабатываться другими процедурами моей программы) и остановить процесс, т.е. корректно ликвидировать как можно быстрее Hook и все что с ним связано!
Вопрос - где ошибка в алгоритме при завершении Hook и как изменить приведенный алгоритм к решению задачи с применением глобальной переменной APoint типа TPoint, как привязать влючение/выключение Hook (и всех связанных с ним процессов!), например к кнопке ToolButton(Down:= true; Down:= false)?

unit Unit1;

interface

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

type
TForm1 = class(TForm)
CheckBox1: TCheckBox;
CheckBox2: TCheckBox;
CheckBox3: TCheckBox;
Edit1: TEdit;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
APoint: TPoint;

implementation

{$R *.dfm}

var
HookHandle: hHook;

function HookProc(Code: integer; WParam: word; LParam: Longint): Longint; stdcall;
var
msg: PEVENTMSG;
key: integer;
begin
if Code >= 0 then begin
result := 0;
msg := Pointer(LParam);
with Form1 do
case msg.message of
WM_MOUSEMOVE: Caption := IntToStr(msg.ParamL) + #32 + IntToStr(msg.ParamH);
WM_LBUTTONDOWN: CheckBox1.Checked := true;
WM_LBUTTONUP: CheckBox1.Checked := false;
WM_RBUTTONDOWN: CheckBox2.Checked := true;
WM_RBUTTONUP: CheckBox2.Checked := false;
WM_KEYUP: CheckBox3.Checked := false;
WM_KEYDOWN: begin
CheckBox3.Checked := true;
key := msg.paramL and 255;
if key in [48..57, 65..90]
then Edit1.Text := Edit1.Text + chr(key);
end;
end;
end else
result := CallNextHookEx(HookHandle, code, WParam, LParam);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Form1.FormStyle := fsStayOnTop;
CheckBox1.Enabled := false;
CheckBox1.Caption := "left button";
CheckBox2.Enabled := false;
CheckBox2.Caption := "right button";
CheckBox3.Enabled := false;
CheckBox3.Caption := "keyboard";
HookHandle := SetWindowsHookEx(WH_JOURNALRECORD, @HookProc, HInstance, 0);
Edit1.Text := "";
Edit1.Enabled := false;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
if HookHandle > 0 then
UnhookWindowsHookEx(HookHandle);
end;


 
Song   (2003-06-07 14:21) [1]

Общесистемный хук должен быть в dll.


 
Dr. Andrew   (2003-06-07 14:52) [2]

А как практически это реализовать? Можете выложить пример?


 
Song   (2003-06-07 15:00) [3]

Вверху есть раздел "Статьи". Там есть статья "Хуки. Аспекты реализации". Вот её прочитай, к ней есть примеры.


 
Dr. Andrew   (2003-06-07 16:28) [4]

Song
Примеры приведенной статьи в Делфи 7 не работают. Все время выпадает ошибка "Ошибка загрузки DLL"!

Мастерам-профессионалам!
Может все таки найдется мастер, который сможет мне помочь без ссылок в конкретной задаче и конкретным алгоритмом!!!


 
Song   (2003-06-07 16:58) [5]

А ты ничего не менял? Всё так как в статье?
Проверь на какой строчке ошибка выдаётся.
К слову говоря хука нас###ть какая у тебя Дельфи.


 
Yanis   (2003-06-07 17:15) [6]

To Dr. Andrew © (07.06.03 13:30)
До боли знакомый код, где то я его видел!!!


 
Юрий Зотов   (2003-06-07 17:26) [7]

> Dr. Andrew © (07.06.03 16:28)

> Примеры приведенной статьи в Делфи 7 не работают. Все время
> выпадает ошибка "Ошибка загрузки DLL"!

Эти примеры проверялись уже очень многими и до сих пор работали. Вероятно, дело все же не в них.

Ладно, вот пример решения Вашей задачи (DLL и приложение). Если и он не заработает - увы, тогда помочь Вам смогут только книги.

============== DLL ===================

library MouseHookDLL;

uses
Windows, Messages;

const
MapID = "Global Mouse Hook Demo";

type
PData = ^TData;
TData = record
AppWnd: HWND;
OldHook: HHOOK
end;

var
HMap: THandle = 0;
Data: PData = nil;

procedure DLLEntryPoint(dwReason: DWORD); stdcall;
begin
case dwReason of
DLL_PROCESS_ATTACH:
begin
HMap := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(TData), MapID);
Data := MapViewOfFile(HMap, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TData))
end;
DLL_PROCESS_DETACH:
begin
UnMapViewOfFile(Data);
CloseHandle(HMap)
end
end
end;

function MouseHookProc(Code: Integer; Msg: WPARAM; PInfo: LPARAM): LRESULT; stdcall;
begin
if Msg = WM_LBUTTONUP then
with PMouseHookStruct(PInfo)^ do
SendMessage(Data^.AppWnd, WM_USER + 100, Pt.X, Pt.Y);
Result := CallNextHookEx(Data^.OldHook, Code, Msg, PInfo)
end;

function SetMouseHook(Wnd: HWND): BOOL; stdcall;
begin
if Data <> nil then
begin
Data^.AppWnd := Wnd;
Data^.OldHook := SetWindowsHookEx(WH_MOUSE, @MouseHookProc, HInstance, 0);
Result := Data^.OldHook <> 0
end
else Result := False
end;

function RemoveMouseHook: BOOL; stdcall;
begin
Result := UnhookWindowsHookEx(Data^.OldHook)
end;

exports
SetMouseHook,
RemoveMouseHook;

begin
if DLLProc = nil then DLLProc := @DLLEntryPoint;
DLLEntryPoint(DLL_PROCESS_ATTACH)
end.

=========== Приложение (DPR стандартный) ===============

unit MouseHookAppUnit;

interface

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

type
TAppMainForm = class(TForm)
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
procedure WMUser100(var Message: TMessage); message WM_USER + 100;
protected
procedure CreateWnd; override;
end;

var
AppMainForm: TAppMainForm;

implementation

{$R *.DFM}

const
DLLName = "MouseHookDLL.dll";

function SetMouseHook(Wnd: HWND): BOOL; stdcall; external DLLName name "SetMouseHook";
function RemoveMouseHook: BOOL; stdcall; external DLLName name "RemoveMouseHook";

{ TAppMainForm }

procedure TAppMainForm.WMUser100(var Message: TMessage);
begin
with Message do Caption := Format("X = %d, Y = %d", [WParam, LParam])
end;

procedure TAppMainForm.CreateWnd;
begin
inherited;
if not SetMouseHook(Handle) then
MessageBox(Handle, "Unable to set hook", PChar(Application.Title), MB_OK or MB_ICONHAND)
end;

procedure TAppMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if not RemoveMouseHook then
MessageBox(Handle, "Unable to remove hook", PChar(Application.Title), MB_OK or MB_ICONHAND)
end;

end.




 
Dr. Andrew   (2003-06-07 18:27) [8]

Юрий Зотов
На строке:
if DLLProc = nil then DLLProc := @DLLEntryPoint;
при выполнении команды Project | Build выпадает сообщение об ошибке:
[Error] MouseHookDLL.dpr(75): Not enough actual parameters

Что я делаю не так? Или ошибка в коде?
А как соотнести координаты с глобальной переменной TPoint в главном проекте.


 
Palladin   (2003-06-07 18:49) [9]

if @DLLProc = nil then DLLProc := @DLLEntryPoint;


 
Dr. Andrew   (2003-06-07 19:16) [10]

Юрий Зотов. Palladin.
Спасибо за помощь!!!
Все примеры в основе привязаны к форме, а Вы могли бы привести пример привязки отключения\включения Hook от, например кнопочного компонента?
Пример заработал, но вот эта проблема мне не дает возможности сдвинуться с мертвой точки.
И еще вопрос - сейчас считывание координат присходит при MouseUp, а как прописать, чтобы при включении Hook происходило считывание экранных координат при MouseMove, а при отпускании кнопки мыши данные фиксировались в переменной TPoint?


 
Dr. Andrew   (2003-06-07 19:28) [11]

Как можно изменить процедуру:

function MouseHookProc(Code: Integer; Msg: WPARAM; PInfo: LPARAM): LRESULT; stdcall;
begin
if Msg = WM_LBUTTONUP then
with PMouseHookStruct(PInfo)^ do
SendMessage(Data^.AppWnd, WM_USER + 100, Pt.X, Pt.Y);
Result := CallNextHookEx(Data^.OldHook, Code, Msg, PInfo)
end;

чтобы при включении Hook происходило постоянное считывание экранных координат при MouseMove, а при отпускании кнопки мыши считывание прерывалось, Hook уничтожался и данные фиксировались в переменной TPoint?



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

Форум: "Основная";
Текущий архив: 2003.06.26;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.025 c
1-84230
DJ Vano
2003-06-13 02:25
2003.06.26
TMemo и TScrollBar


1-84397
YuraKiller
2003-06-07 22:18
2003.06.26
Как обнулить таймер?


14-84730
SpoinT
2003-06-05 15:33
2003.06.26
Как изменить заголовок файла exe


14-84737
BDRON
2003-06-05 23:09
2003.06.26
Масштабирование формы


3-83882
GavAl
2003-06-02 18:02
2003.06.26
Filter





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский