Текущий архив: 2005.06.06;
Скачать: CL | DM;
Вниз
Средняя кнопка мыши Найти похожие ветки
← →
alex-drob (2005-05-19 18:01) [0]Как отследить нажатие средней кнопки мыши не только в своей программе а влюбой другой?
← →
charlie (2005-05-19 18:11) [1]SetWindowsHookEx - примеры есть в интере.
← →
Digitman © (2005-05-19 18:11) [2]хук WH_LL_MOUSE
← →
alex-drob (2005-05-19 18:20) [3]WH_LL_MOUSE - у меня выдаётся ошибка
← →
charlie (2005-05-19 18:24) [4]Потому что WH_MOUSE. Надо справку читать по фнкции просто так не получится. Такой хук реaлизуется через dll
← →
begin...end © (2005-05-19 18:26) [5]> alex-drob (19.05.05 18:20) [3]
WH_MOUSE_LL
← →
Digitman © (2005-05-19 18:37) [6]
> alex-drob (19.05.05 18:20) [3]
сходи в MSDN и посмотри там значение этой константы
← →
charlie (2005-05-19 18:38) [7]
> begin...end © (19.05.05 18:26) [5]
WH_MOUSE_LL
Windows NT/2000/XP: Installs a hook procedure that monitors low-level mouse input events.
А если 98? Работает? А чему равна?
← →
alex-drob (2005-05-19 18:44) [8]
> Такой хук реaлизуется через dll
Я и так это в dll делаю.
← →
alex-drob (2005-05-19 18:48) [9]
> сходи в MSDN и посмотри там значение этой константы
А поподробней можно где именно посмотреть?
← →
charlie (2005-05-19 18:59) [10]WH_MOUSE_LL = 14
WH_MOUSE_LL
Windows NT/2000/XP: Installs a hook procedure that monitors low-level mouse input events. For more information, see the LowLevelMouseProc hook procedure.
LowLevelMouseProc Function
--------------------------------------------------------------------------------
The LowLevelMouseProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. 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 the event.
The HOOKPROC type defines a pointer to this callback function. LowLevelMouseProc is a placeholder for the application-defined or library-defined function name.
Syntax
LRESULT CALLBACK LowLevelMouseProc( int nCode,
WPARAM wParam,
LPARAM lParam
);
Parameters
nCode
[in] Specifies a code the hook procedure uses to determine how to process the message. If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx. This parameter can be one of the following values.
HC_ACTION
The wParam and lParam parameters contain information about a mouse message.
wParam
[in] Specifies the identifier of the mouse message. This parameter can be one of the following messages: WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_RBUTTONDOWN, or WM_RBUTTONUP.
lParam
[in] Pointer to an MSLLHOOKSTRUCT structure.
Return Value
If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.
If nCode is greater than or equal to zero, and the hook procedure did not process the message, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_MOUSE_LL hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure.
Remarks
An application installs the hook procedure by specifying the WH_MOUSE_LL hook type and a pointer to the hook procedure in a call to the SetWindowsHookEx function.
This hook is called in the context of the thread that installed it. The call is made by sending a message to the thread that installed the hook. Therefore, the thread that installed the hook must have a message loop.
The hook procedure should process a message in less time than the data entry specified in the LowLevelHooksTimeout value in the following registry key:
HKEY_CURRENT_USER\Control Panel\Desktop
The value is in milliseconds. If the hook procedure does not return during this interval, the system will pass the message to the next hook.
Note that debug hooks cannot track this type of hook.
Function Information
Header Declared in Winuser.h, include Windows.h
Import library None
Minimum operating systems Windows NT 4.0 SP3
← →
begin...end © (2005-05-19 19:01) [11]> charlie (19.05.05 18:38) [7]
> А если 98? Работает?
Не в курсе. Да и вопрос про XP...
> alex-drob (19.05.05 18:48) [9]
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/hooks/hookre ference/hookfunctions/setwindowshookex.asp и далее по ссылкам.
← →
charlie (2005-05-19 19:15) [12]
> begin...end © (19.05.05 19:01) [11]
Вообще пишут что не работает. А можно ли гарантировать что не будет необходимости запускать приложение под 98. Но это вопрос к вопрошающему.
А под ХР, работает. И локально. Чесно говоря раньше не знал про WH_MOUSE_LL. Очень удобно.
← →
alex-drob (2005-05-19 19:22) [13]А как сделать чтобы все события мышки обрабатывались windows?
← →
charlie (2005-05-19 19:24) [14]Так, не в лом, для примера
const
WH_MOUSE_LL = 14;
var
hHook : THandle;
function MouseProc(n: Integer; w: wParam; l: lParam): lResult; stdcall;
type
PMouseHookStructLL = ^TMouseHookStructLL;
TMouseHookStructLL = packed record
pt: TPoint;
mouseData: DWORD;
flags: DWORD;
time: DWORD;
dwExtraInfo: DWORD;
end;
procedure Process(MHS: TMouseHookStructLL);
begin
if w = WM_MBUTTONDOWN then
Form1.Caption := Format("WM_MBUTTONDOWN AT %d, %d",[MHS.pt.X, MHS.pt.Y])
end;
begin
Process(PMouseHookStructLL(l)^);
Result := CallNextHookEx(hHook, n, w, l);
end;
procedure TForm1.HookItClick(Sender: TObject);
begin
hHook := SetWindowsHookEx(WH_MOUSE_LL, @MouseProc, HInstance, 0);
ShowMessage(SysErrorMessage(GetLastError));
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
if hHook <> 0 then
UnhookWindowsHookEx(hHook);
hHook := 0;
end;
← →
charlie (2005-05-19 19:27) [15]
> alex-drob (19.05.05 19:22) [13]
Так и так обрабатываются. Кстати, я так понимаю, длл не обяз для WM_MOUSE_LL вообще и не обяз для WM_MOUSE при обработке в контексте запущенной задачи, т.е. для внутренних целей.
← →
alex-drob (2005-05-19 19:28) [16]Всем большое спасибо!
← →
alex-drob (2005-05-19 19:31) [17]
> charlie (19.05.05 19:27) [15]
Мне как раз нужно чтобы не только внутри программы работало а всегда.
← →
charlie (2005-05-19 19:43) [18]
> charlie (19.05.05 19:24) [14]
Попробуй, работаетю Сохдая новую форму и пихни туда этот код. Все ништяк.
← →
alex-drob (2005-05-19 19:51) [19]И ещё вопрос можно ли как нибудь зделать чтобы dll с этим кодом
> [14]
загружалась без приложения, гдето слышал что можно в реестр прописать но не помню где. Или с приложением но чтобы оно dll просто загружало а само было маленького размера, а то не охото нинужную форму создавать.
← →
charlie (2005-05-19 20:02) [20]
> alex-drob (19.05.05 19:51) [19]
Можно, делай! Форма необязательна, а только показательна. Только зачем тебе длл? Пусть процесс будет, или прячешь зачем-то?
А если прописать, тогда HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
← →
alex-drob (2005-05-19 20:06) [21]Я вобще хочу сделать чтобы в Windows`е при нажатии на колёсико мышки появлялось моя форма с кнопками под курсором.
Если написать не в dll то при нажатии средней кнопки мыши не чего не происходит.
> Форма необязательна,
А если без формы то приложение сразу же закрывается.
← →
-=SSS=- (2005-05-19 20:19) [22]
> А если без формы то приложение сразу же закрывается.
Поставь примерно такой цикл
Var
Message: TMsg;
begin
repeat
if GetMessage(Message, 0, 0, 0) then
begin
TranslateMessage(Message);
DispatchMessage(Message);
if Message.message = WM_QUERYENDSESSION Then break;
end else break;
until false;
← →
charlie (2005-05-19 20:29) [23]
> -=SSS=- (19.05.05 20:19) [22]
Все равно нужно окно
← →
charlie (2005-05-19 20:43) [24]Ну вот пример. Весит 15 кило
program MouseLL;
uses
Windows,
Messages;
const
WH_MOUSE_LL = 14;
var
BackWndClass : TWndClassEx;
BackWnd : HWND;
Message : TMsg;
MouseHook : THandle;
function MakeBackWnd: HWND;
begin
FillChar(BackWndClass, SizeOf(TWndClassEx), 0);
with BackWndClass do begin
lpfnWndProc := @DefWindowProc;
cbSize := SizeOf(BackWndClass);
style := CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNCLIENT;
hCursor := LoadCursor(HInstance, IDC_ARROW);
hIcon := LoadIcon(0, IDI_ASTERISK);
hbrBackground := COLOR_BTNFACE + 1;
lpszMenuName := nil;
lpszClassName := "BackWindow";
end;
RegisterClassEx(BackWndClass);
BackWnd := CreateWindowEx
(WS_EX_LAYERED or WS_EX_TOOLWINDOW or WS_EX_TOPMOST,
"BackWindow",
"BackWindow",
WS_POPUP,
0,
0,
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN),
0,
0,
Hinstance,
nil);
SetLayeredWindowAttributes(BackWnd, 0, 1, LWA_ALPHA);
Result := BackWnd;
end;
function MouseProc(n: Integer; w: wParam; l: lParam): lResult; stdcall;
type
PMouseHookStructLL = ^TMouseHookStructLL;
TMouseHookStructLL = packed record
pt: TPoint;
mouseData: DWORD;
flags: DWORD;
time: DWORD;
dwExtraInfo: DWORD;
end;
procedure Process(MHS: TMouseHookStructLL);
var
P, P1 : PChar;
begin
if w = WM_MBUTTONDOWN then begin
GetMem(P, 256);
asm
push MHS.pt.X
push MHS.pt.Y
end;
P1 := PChar(P + wsprintf(P, "WM_MBUTTONDOWN AT %d, %d"));
P1^ := #0;
ShowWindow(BackWnd, SW_SHOW);
MessageBox(BackWnd, P, "My message", 64);
FreeMem(P);
ShowWindow(BackWnd, SW_HIDE);
end
else if w = WM_RBUTTONDOWN then begin
ShowWindow(BackWnd, SW_SHOW);
if MessageBox(BackWnd, "Çàâåðøèòü ïðîöåññ?", "Ïðîøó ïîäòâåðæäåíèÿ!", MB_YESNO) = IDYES then
PostQuitMessage(0)
else
ShowWindow(BackWnd, SW_HIDE);
end;
end;
begin
Process(PMouseHookStructLL(l)^);
Result := CallNextHookEx(MouseHook, n, w, l);
end;
procedure HookIt;
begin
MouseHook := SetWindowsHookEx(WH_MOUSE_LL, @MouseProc, HInstance, 0);
end;
procedure UnHookIt;
begin
UnhookWindowsHookEx(MouseHook);
end;
begin
if MakeBackWnd <> 0 then begin
HookIt;
repeat
if GetMessage(Message, BackWnd, 0, 0) then begin
TranslateMessage(Message);
DispatchMessage(Message);
if Message.message = WM_QUERYENDSESSION then
break;
end
else
break;
until false;
UnHookIt;
end;
end.
← →
alex-drob (2005-05-19 20:44) [25]
> -=SSS=- (19.05.05 20:19) [22]
Спасибо, вроде помогло!
← →
charlie (2005-05-19 20:48) [26]Оставь инициализацию структуры BackWndClass в таком виде:
with BackWndClass do begin
lpfnWndProc := @DefWindowProc;
cbSize := SizeOf(BackWndClass);
hCursor := LoadCursor(HInstance, IDC_ARROW);
hbrBackground := COLOR_BTNFACE + 1;
lpszMenuName := nil;
lpszClassName := "BackWindow";
end;
С остальным делай что хочешь и как хочешь, с моей стороны это чистой воды импровизация.
← →
charlie (2005-05-19 20:53) [27]
> alex-drob (19.05.05 20:44) [25]
Хочешь чтоб меньше весило и юзаешь Forms?
← →
alex-drob (2005-05-19 20:59) [28]
> charlie
Вопрос не в том чтоб меньше весело. Без длл не получалось отлавливать нажатие кнопок вне формы. Поэтому я хотел запихнуть форму с меню в DLL а вызывать dll с приложения которое всё время будет загруженно, так вот именно в этом приложении форма была не нужна. А спомощью API я пока не умею создавать кнопки.
В примере [24] всё работает и без dll!
Спасибо всем за помощь!
← →
charlie (2005-05-19 21:05) [29]
> В примере [24] всё работает и без dll!
А то. Удачи.
Страницы: 1 вся ветка
Текущий архив: 2005.06.06;
Скачать: CL | DM;
Память: 0.54 MB
Время: 0.03 c