Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.06.29;
Скачать: CL | DM;

Вниз

Hooks   Найти похожие ветки 

 
VVV-First   (2005-04-26 16:14) [0]

Может кто подскажет мен в следующем вопросе.
Устнанавливаю глобальный хук на клаву. Регистрирую в системе свое событие и затем в функции фильтре (в DLL )при нажатии определенной клавиши передаю это сообщение своему Host- приложению средствами SendMessage(). Если открыть например блокнот то все просто отлично , все нажатые клавиши в блокноте, отлавливаются моим хуком и соответственно передаются в мое Host-приложение. Но вот если открыть например Word то после нажатия нескольких клавишь Word начинает тормозить,а потом и вовсе зависает. Может кто подскажет почему?
Может надо использовать не SendMessage() а PostMessage() ?


 
mgcr ©   (2005-04-26 16:18) [1]


> Может кто подскажет почему?


Потому что хук кривой.


 
VVV-First   (2005-04-26 16:24) [2]


> Потому что хук кривой.

Серьезная такая подсказка:))))))))) Вот это спасибо:)))))
Все прям прояснилось:)))))))))))


 
ANB ©   (2005-04-26 16:56) [3]


mgcr ©   (26.04.05 16:18) [1]
- прав. Хук у тебя и правду кривой. Хочешь по теме - выложи исходник. Тока сначала убери stdcall в procedure DLLEntryPoint(dwReason: Integer);


 
VVV-First   (2005-04-26 16:58) [4]


> Тока сначала убери stdcall в

хмммм  а я читал , что это не только не повредит , а еще и поможет , но всерано пасибо , вечером попробую


 
ANB ©   (2005-04-26 17:18) [5]

МОДЕРАТОРЫ !!!! УБЕРИТЕ СТАТЬЮ ПРО ХУКИ ИЛИ ИСПРАВЬТЕ ПРИМЕР !!! ЭТО УЖЕ ПЯТЫЙ ЧЕЛОВЕК (ВКЛЮЧАЯ МЕНЯ) НАРЫВАЕТСЯ.

> что это не только не повредит , а еще и поможет
- это где ты прочитал ?


 
alpet ©   (2005-04-26 17:54) [6]

Вопрос: заменять DLLEntryPoint с помощью секций intialization/finallization вообще можно ?


 
ANB ©   (2005-04-26 18:04) [7]

Завтра выложу исходник работающей DLL. Пока.


 
mgcr ©   (2005-04-26 18:16) [8]

ANB ©   (26.04.05 17:18) [5]

А голова человеку на что дана ?


 
Eraser ©   (2005-04-26 20:20) [9]

VVV-First

Если лень разбираться в теории, то поищи в нете ещё один пример, благо их сотни...


 
ANB ©   (2005-04-27 09:09) [10]

Это пример хука WH_GETMESSAGE. Правильный и полностью работающий. Обмен с хост-приложением происходит при помощи WM_COPYDATA + Метка своим сообщением. Оказался оптимальным вариантом.

> mgcr ©   (26.04.05 18:16) [8]
> ANB ©   (26.04.05 17:18) [5]
>
> А голова человеку на что дана ?
- мне помогли в этом форуме, почему не помочь другим ?
А проблема в неправильном определении DLLEntryPoint и к теории хуков никакого отношения не имеет. Я сам перелопатил всего Рихтера, а с первого раза не написал.


library Recorder;

uses Windows, Messages, SysUtils;

const
 MMFName : PChar = "Recorder_MMF"; // имя объекта файлового отображения

{структура, поля которой будут отображены в файл подкачки}
type
PGlobalDLLData = ^TGlobalDLLData;
TGlobalDLLData = packed record
 SysHook : HWND; // дескриптор установленной ловушки
 MainRecorderWnd : hWnd; // дескриптор окна рекордера
 MainRecorderProcessID : THandle; // ID процесса рекордера
end;

var
MMFHandle :        THandle;
WM_Recorder_HOOK : Cardinal;
GlobalData :       PGlobalDLLData;

function RecordCallBackProc(Code : Integer;
                           wParam : WPARAM;
                           lParam : LPARAM) : LRESULT; stdcall;
var hCallWnd : HWND;
   ProcessID : THandle;
   EventMsg : TMsg;
   SysHook : THandle;
   MsgData : TCOPYDATASTRUCT;
begin
Result := 0;
SysHook := 0;
try
 // Прочитаем SysHook из разделяемой памяти
 SysHook := GlobalData^.SysHook;
 // Если команда и не наше сообщение
 if (Code <> HC_ACTION) then Exit;
 if (wParam <> PM_REMOVE) then Exit;
 EventMsg := TMsg(Pointer(lParam)^);
 hCallWnd := EventMsg.hwnd;
 // Выкинем лишние сообщения
 if (
    (EventMsg.message = WM_KEYDOWN)
 or (EventMsg.message = WM_SYSKEYDOWN)
 or (EventMsg.message = WM_COMMAND)
 or (EventMsg.message = WM_LBUTTONUP)
 or (EventMsg.message = WM_RBUTTONUP)
 or (EventMsg.message = WM_MBUTTONUP)
 ) then begin
  // Проверим, что события не нашего приложения
  GetWindowThreadProcessId(hCallWnd, ProcessID);
  if (ProcessID = GlobalData^.MainRecorderProcessID) then Exit;
  // Передадим инфу о событии в рекордер
  MsgData.dwData := WM_Recorder_HOOK;
  MsgData.cbData := SizeOf(EventMsg);
  MsgData.lpData := @EventMsg;
  SendMessage(
   GlobalData^.MainRecorderWnd
  ,WM_COPYDATA
  ,hCallWnd
  ,Integer(@MsgData));
 end;
finally
 CallNextHookEx(SysHook, Code, wParam, lParam);
end;
end;

{Процедура установки HOOK-а}
function Set_Hook(hMainWnd : HWND; MainProcessID : THandle) : Boolean; export; stdcall;
begin
// Устанавливаю HOOK
Result := False;
// Поставим хук
GlobalData^.SysHook := SetWindowsHookEx(WH_GETMESSAGE, @RecordCallBackProc,
                                        HInstance, 0);
GlobalData^.MainRecorderWnd := hMainWnd;
GlobalData^.MainRecorderProcessID := MainProcessID;
if (GlobalData^.SysHook = 0)
then
 MessageBox(0, "Ошибка : не удалось установить хук WH_GETMESSAGE !",
            "Сообщение от Recorder.dll", 0)
else Result := True;
end;

{Процедура снятия HOOK-а}
function Reset_Hook() : Boolean; export; stdcall;
begin
// Удаляем функцию-фильтр
Result := False;
// Снимем хук
if (not UnhookWindowsHookEx(GlobalData^.SysHook))
then MessageBox(0, "Ошибка : не удалось снять хук WH_GETMESSAGE !",
                "Сообщение от Recorder.dll", 0)
else Result := True;
end;

procedure OpenGlobalData();
var sMsg : String;
begin
// Зарегистрим наше сообщение
WM_Recorder_HOOK := RegisterWindowMessage("WM_Recorder_HOOK");
// Подключим MMF
MMFHandle:= CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0,
                              SizeOf(TGlobalDLLData), MMFName);
if MMFHandle = 0 then begin
 sMsg := "Ошибка : не удалось создать MMF <" + MMFName + ">";
 MessageBox(0, PChar(sMsg), "Сообщение от Recorder.dll", 0);
 Exit;
end;
GlobalData := MapViewOfFile(MMFHandle, FILE_MAP_ALL_ACCESS, 0, 0,
                            SizeOf(TGlobalDLLData));
if (GlobalData = nil) then begin
 sMsg := "Ошибка : не удалось отобразить MMF <" + MMFName + ">";
 MessageBox(0, PChar(sMsg), "Сообщение от Recorder.dll", 0);
end;
end;

procedure CloseGlobalData();
begin
UnmapViewOfFile(GlobalData);
CloseHandle(MMFHandle);
end;

procedure DLLEntryPoint(dwReason: Integer);
begin
case dwReason of
 DLL_PROCESS_ATTACH : OpenGlobalData();
 DLL_PROCESS_DETACH : CloseGlobalData();
end;
end;

exports Set_Hook, Reset_Hook;

begin
{назначим поцедуру переменной DLLProc}
DLLProc := @DLLEntryPoint;
{вызываем назначенную процедуру для отражения факта присоединения данной
 библиотеки к процессу}
DLLEntryPoint(DLL_PROCESS_ATTACH);
end.


 
Digitman ©   (2005-04-27 09:33) [11]


> alpet ©   (26.04.05 17:54) [6]
> Вопрос: заменять DLLEntryPoint с помощью секций intialization/finallization
> вообще можно ?


а зачем ?
в чем глубокий смысл сего извращения ?


 
alpet ©   (2005-04-28 11:11) [12]

Digitman ©   (27.04.05 09:33) [11]

1. Вечный вопрос.
2. Мультиплатформность разве что... впрочем она обеспечивается назначением обработчика DllProc(Ex).

Собственно ответ - нельзя. Другое дело что юниты подключаемые к DLL вполне сносно отрабатывают секцию initialization по уведомлению DLL_PROCESS_ATTACH, и finalization по уведомлению DLL_PROCESS_DETACH.


 
VVV-First   (2005-04-28 12:41) [13]


> ANB ©   (27.04.05 09:09) [10]

а твоя библиотечка так мою напоминает, но всеравно , дома сравню что не так
А прочитал я статью на сайте  DELPHI WORLD


 
ANB ©   (2005-04-28 16:33) [14]


> а твоя библиотечка так мою напоминает
- с одного места драли :)))



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

Текущий архив: 2005.06.29;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.038 c
1-1117969354
Starcom
2005-06-05 15:02
2005.06.29
В какую библиотеку входят компоненты:


3-1116003967
seregka
2005-05-13 21:06
2005.06.29
Непонятная ошибка


14-1117267775
vajo
2005-05-28 12:09
2005.06.29
монтаж сети


1-1117806282
fagot
2005-06-03 17:44
2005.06.29
Побудка


14-1117458253
evvcom
2005-05-30 17:04
2005.06.29
Весёлое сообщение об ошибке