Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.221.85.33] |
|
Сообщ.
#1
,
|
|
|
Поставил хук на WH_GETMESSAGE
Как узнать какие клавиши нажимались, если отлавливать сообщения WM_KEYUP, |
Сообщ.
#2
,
|
|
|
Вот фрагмент кода отлавливающего хоткеи при помощи этого хука, тут вроде всё понятно, если надо могу всю прогу выложить
function SetHook(WinHandle: HWND; MsgToSend: Integer): Boolean; stdcall; begin Result := False; if (MMFData = nil) and (MMFHandle = 0) then begin MMFHandle := CreateMMF(MMFName, SizeOf(TMMFData)); if MMFHandle <> 0 then begin MMFData := MapMMF(MMFHandle); if MMFData <> nil then begin MMFData.WinHandle := WinHandle; MMFData.MsgToSend := MsgToSend; MMFData.NextHook := SetWindowsHookEx(WH_GETMESSAGE, MsgFilterFunc, HInstance, 0); if MMFData.NextHook = 0 then UnMapAndCloseMMF else Result := True; end else begin CloseMMF(MMFHandle); MMFHandle := 0; end; end; end; end; //---------------------------------------------------------- function FreeHook: Boolean; stdcall; begin Result := False; if (MMFData <> nil) and (MMFHandle <> 0) then if UnHookWindowsHookEx(MMFData^.NextHook) then Result := UnMapAndCloseMMF; end; //---------------------------------------------------------- function MsgFilterFunc(Code: Integer; wParam, lParam: Longint): Longint; var MMFHandle: THandle; MMFData: PMMFData; Kill: boolean; begin Result := 0; MMFHandle := OpenMMF(MMFName); if MMFHandle <> 0 then begin MMFData := MapMMF(MMFHandle); if MMFData <> nil then begin if (Code < 0) or (wParam = PM_NOREMOVE) then Result := CallNextHookEx(MMFData.NextHook, Code, wParam, lParam) else begin Kill := False; { Example to disable all the start-Key combinations } case TPMsg(lParam)^.message of WM_SYSCOMMAND: // The Win Start Key (or Ctrl+ESC) if TPMsg(lParam)^.wParam = SC_TASKLIST then Kill := True; WM_HOTKEY: case ((TPMsg(lParam)^.lParam and $00FF0000) shr 16) of VK_D, // Win+D ==> Desktop VK_E, // Win+E ==> Explorer VK_F, // Win+F+(Ctrl) ==> Find:All (and Find: Computer) VK_M, // Win+M ==> Minimize all VK_R, // Win+R ==> Run program. VK_F1, // Win+F1 ==> Windows Help VK_PAUSE: // Win+Pause ==> Windows system properties Kill := True; end; end; if Kill then TPMsg(lParam)^.message := WM_NULL; Result := CallNextHookEx(MMFData.NextHook, Code, wParam, lParam) end; UnMapMMF(MMFData); end; CloseMMF(MMFHandle); end; end; |
Сообщ.
#3
,
|
|
|
тут
MMFData.NextHook := SetWindowsHookEx(WH_GETMESSAGE, MsgFilterFunc, HInstance, 0); разве не так надо MMFData.NextHook := SetWindowsHookEx(WH_GETMESSAGE, @MsgFilterFunc, HInstance, 0); Добавлено У меня при установки хука WH_GETMESSAGE, через DLL нельзя удалить хук, если произойдут те события, которые там установлены.. |
Сообщ.
#4
,
|
|
|
Вот полный исходник проги для перехвата хоткеев (кстати убрал от туда MMF без него тоже работает, да и разобраться в коде намного легче), у меня компилиться и нормально работает, и снимается тоже без проблем
Насчёт "@" хз непомню (НА этом компе делфи нет), вроде бы должен быть, хотя не факт... Попробуй скомпилять исходник, который я дал там нет "@", но вроде компилиться, если нет то подставь и всё ... Прикреплённый файлsys.zip (31.29 Кбайт, скачиваний: 263) |
Сообщ.
#5
,
|
|
|
Здравствуйте!
У меня не получается отловить событие WM_SYSCOMMAND и WM_CLOSE своего приложения, реализовать надо именно через ловушку, потому что потом надо будет переделать для "чужого" приложения, использую WH_GETMESSAGE. Бьюсь уже не первый час:( В аттаче исходники, подскажите пожалуйста, что я делаю не так. Заранее спасибо! Прикреплённый файлSetHook.zip (3.42 Кбайт, скачиваний: 180) |
Сообщ.
#6
,
|
|
|
zsergey
C этой темой все бьются не по одному часу..и дню. |
Сообщ.
#7
,
|
|
|
koder и zsergey Попробуйте поиск и фак, если не поможет, тогда пишите.
|
Сообщ.
#8
,
|
|
|
Цитата doom_mm @ кстати убрал от туда MMF без него тоже работает, да и разобраться в коде намного легче лонгично, если софт не предназначен для Win9x Цитата MSDN hhk [in] Windows 95/98/ME: Handle to the current hook. An application receives this handle as a result of a previous call to the SetWindowsHookEx function. Windows NT/XP/2003: Ignored. |
Сообщ.
#9
,
|
|
|
Цитата P.O.D @ koder и zsergey Попробуйте поиск и фак, если не поможет, тогда пишите. Перед тем как писать сюда, я искал в Delphi Word, в "Кулибе" и на этом форуме... безрезультатно |
Сообщ.
#10
,
|
|
|
zsergey, первое что попалось на глаза - ты ставишь локальный хук на свое приложение, а параметры указываешь как при установке глобального:
Цитата Unit1.pas HANDL:=SetWindowsHookEx(WH_GETMESSAGE, @MsgFilterFunc, HInstance, 0); надо так: HANDL:=SetWindowsHookEx(WH_GETMESSAGE, @MsgFilterFunc, 0, GetCurrentThreadId); |
Сообщ.
#11
,
|
|
|
Цитата dumbo @ надо так: ыть не успел. но это будет хук только для одного потока AFAIK, и на другие процессы никак не повлияет |
Сообщ.
#12
,
|
|
|
Спасибо, поправил, но теперь приложение висит после установки ловушки.
|
Сообщ.
#13
,
|
|
|
Цитата zsergey @ но теперь приложение висит после установки ловушки. дык. что сказали, то и делает: Цитата Unit1.pas:45 ... begin Kill := True; case TPMsg(lParam)^.message of ... |
Сообщ.
#14
,
|
|
|
1. вынеси хук в отдельную dll. примеров море
2. код функции-фильтра, которая будет "препятствовать" сворачиванию и закрытию окна программы примерно такой: function MsgFilterFunc(Code: Integer; wParam, lParam: Longint): Longint; stdcall; var Kill: boolean; begin Result := CallNextHookEx( 0, Code, wParam, lParam); kill := False; //здесь стоит добавить проверку на принадлежность окна "целевому" процессу case PMsg(lParam)^.message of WM_NCLBUTTONDOWN: Kill := PMsg(lParam)^.wParam = HTMINBUTTON; WM_SYSCOMMAND: Kill := PMsg(lParam)^.wParam = SC_MINIMIZE; WM_QUIT: Kill := True; end; if Kill then PMsg(lParam)^.message := WM_NULL; end; |