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

Вниз

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 вся ветка

Форум: "WinAPI";
Текущий архив: 2005.06.29;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.038 c
1-1118072378
Nimbus
2005-06-06 19:39
2005.06.29
Свойство "parent" для формы, размещённой в DLL?


14-1117306783
P.N.P.
2005-05-28 22:59
2005.06.29
Орешник


1-1118065199
Gashish
2005-06-06 17:39
2005.06.29
Перенос модели в из 3d max в Delphi


14-1117695099
Суслик
2005-06-02 10:51
2005.06.29
вроде смешно :)


14-1117508878
Mike Kouzmine
2005-05-31 07:07
2005.06.29
Такая Европа нам не нужна!





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