![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Hook [D7, WinXP]
Igor Zorkov © (2007-11-21 13:36:00)Ставлю Hook на мышь, если форму закрываю кликнув на кнопке close в заголовке формы то форма закрывается через довольно большой промежуток времени, в остальных случаях нормально
Почему такое проиходит и как с этим бороться, подскажите пожалуйста?
вот код dll
library MouseHook;
uses
Windows, Messages, Forms, Controls, Dialogs, SysUtils;
const
WH_MOUSE_LL = 14;
MMFName: PChar = 'MMF';
type
PGlobalDLLData = ^TGlobalDLLData;
TGlobalDLLData = packed record
SysHook: HWND;
Wnd: HWND;
end;
var
GlobalData: PGlobalDLLData;
MMFHandle: THandle;
function SysMsgProc(Code: Integer; wParam: Word; lParam: Longint): Longint; stdcall;
begin
if (Code = HC_ACTION) then
begin
if (wParam = WM_MBUTTONDOWN) then
ShowMessage('MESSAGE')
else
Result:= CallNextHookEx(GlobalData^.SysHook, Code, wParam, lParam);
end;
end;
function StartMouseHook(State: Boolean; Wnd: HWND): Boolean; export; stdcall;
begin
Result:= False;
if State = True then
begin
GlobalData^.SysHook:= SetWindowsHookEx(WH_MOUSE_LL, @SysMsgProc, HInstance, 0);
GlobalData^.Wnd:= Wnd;
if GlobalData^.SysHook <> 0 then
Result:= True;
end
else
begin
UnhookWindowsHookEx(GlobalData^.SysHook);
Result:= False;
end;
end;
function StopMouseHook(): Boolean; export; stdcall;
begin
UnhookWindowsHookEx(GlobalData^.SysHook);
if GlobalData^.SysHook = 0 then
Result:= False
else
Result:= True;
end;
procedure OpenGlobalData();
begin
MMFHandle:= CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(TGlobalDLLData), MMFName);
GlobalData:= MapViewOfFile(MMFHandle, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TGlobalDLLData));
if GlobalData = nil then
CloseHandle(MMFHandle);
end;
procedure CloseGlobalData();
begin
UnmapViewOfFile(GlobalData);
CloseHandle(MMFHandle);
end;
procedure DLLEntryPoint(Reason: DWord); stdcall;
begin
case Reason of
DLL_PROCESS_ATTACH: OpenGlobalData;
DLL_PROCESS_DETACH: CloseGlobalData;
end;
end;
exports StartMouseHook, StopMouseHook;
begin
DLLEntryPoint(DLL_PROCESS_ATTACH);
end.
Igor Zorkov (2007-11-21 17:36:00) [1]
> Rouse_ ©
Спасибо
Rouse_ (2007-11-21 16:36:00) [2]
> Но в обычном приложении то же происходит задержка.
Я же объяснил, это издержки LowLevel... А блокировать просто - не вызывать CallNextHookEx на среднюю кнопку и возвращать 1
Igor Zorkov (2007-11-21 16:35:00) [3]А если делать так то нормально минимизируеться, непонимаю
procedure TForm1.Button1Click(Sender: TObject);
begin
Application.Minimize;
end;
Igor Zorkov (2007-11-21 16:28:00) [4]
> Rouse_ © (21.11.07 16:14) [7]
Но в обычном приложении то же происходит задержка.
А если пользовать WH_MOUSE то как можно блокировать среднюю кнопку мыши?
Rouse_ (2007-11-21 16:14:00) [5]Если решил уж использовать библиотеку - тогда используй обычный WH_MOUSE
Igor Zorkov (2007-11-21 15:48:00) [6]
> Rouse_ © (21.11.07 15:29) [5]
Что же делать? Подскажи пожалуйста
Rouse_ (2007-11-21 15:29:00) [7]Задержка на переключении контекста. Это описано в справке:
The system call this function every time a new mouse input event is about to be posted into a thread input queue. The mouse input can come from the local mouse driver or from calls to the mouse_event function. If the input comes from a call to mouse_event, the input was "injected". However, the WH_MOUSE_LL hook is not injected into another process. Instead, the context switches back to the process that installed the hook and it is called in its original context. Then the context switches back to the application that generated theevent.
Igor Zorkov (2007-11-21 15:08:00) [8]Если делать так
Rouse_ © (21.11.07 14:34) [1] +
if boolean{некая переменная допустим}{если нужно заблокировать кнопку} = True then
Result:= - 1
else
Result:= CallNextHookEx(GlobalData^.SysHook, Code, wParam, lParam);
то блокируеться вся мышь, как же быть?
Igor Zorkov (2007-11-21 15:01:00) [9]
> Rouse_ © (21.11.07 14:38) [2]
> Кстати, зачем ты WH_MOUSE_LL в библиотеке используешь?
function SysMsgProc(Code: Integer; wParam: DWORD; lParam: DWORD): Longint; stdcall;
begin
if (Code = HC_ACTION) then
begin
if (wParam = WM_MBUTTONDOWN) then
begin
if boolean{некая переменная допустим}{если нужно заблокировать кнопку} = True then
Result:= - 1
else
Result:= CallNextHookEx(GlobalData^.SysHook, Code, wParam, lParam);
end else
Result:= CallNextHookEx(GlobalData^.SysHook, Code, wParam, lParam);
end;
end;
> Rouse_ © (21.11.07 14:34) [1]
Сделал так
function SysMsgProc(Code: Integer; wParam: Word; lParam: Longint): Longint; stdcall;
begin
if (Code = HC_ACTION) then
begin
if (wParam = WM_MBUTTONDOWN) then
ShowMessage('MESSAGE')
else
Result:= CallNextHookEx(GlobalData^.SysHook, Code, wParam, lParam);
end
else
Result:= CallNextHookEx(GlobalData^.SysHook, Code, wParam, lParam);
end;
если hook установлен, закрытие или минимизация формы проходит долго, если ставить на WH_MOUSE такого нет
Rouse_ (2007-11-21 14:38:00) [10]Кстати, зачем ты WH_MOUSE_LL в библиотеке используешь? Достаточно обычного приложения. И stdcall убери у DLLEntryPoint, к тому же wParam у SysMsgProc толжен иметь тип DWORD
Rouse_ (2007-11-21 14:34:00) [11]
function SysMsgProc(Code: Integer; wParam: Word; lParam: Longint): Longint; stdcall;
begin
if (Code = HC_ACTION) then
begin
if (wParam = WM_MBUTTONDOWN) then
ShowMessage('MESSAGE')
else
Result:= CallNextHookEx(GlobalData^.SysHook, Code, wParam, lParam);
end
else
Result:= CallNextHookEx(GlobalData^.SysHook, Code, wParam, lParam);
end;