Форум: "WinAPI";
Текущий архив: 2004.08.15;
Скачать: [xml.tar.bz2];
ВнизОшибка хука при нажатии WIN+D Найти похожие ветки
← →
bar (2004-07-06 10:34) [0]Ставлю хук в поток эксплорера все работает но при нажатии на WIN+D (сворачивании окон) вылетает диалоговое окошко:
Инструкция по адресу 0xff640227 обратилась к памяти по адресу 0xff640227. Памят не может быть “read”
и потом ещо диалог
Runtime error 216 at FF640227
Если кто знает в чем глюк скажите пожалуйста. А то я уже все FAQ перерыл и кучу статей про Hook все делаю как там описано а глючит.
Код библиотеки с хуком.
library keyhook;
uses
Windows, KOL,
Messages;
const
MMFName : PChar = "KeyMMF"; // имя объекта файлового отображения
{структура, поля которой будут отображены в файл подкачки}
type
PGlobalDLLData = ^TGlobalDLLData;
TGlobalDLLData = packed record
SysHook: HWND; // дескриптор установленной ловушки
MyAppWnd: HWND; // дескриптор нашего приложения
end;
var
GlobalData : PGlobalDLLData;
MMFHandle : THandle;
WM_MYKEYHOOK : Cardinal;
ds : THANDLE;
function Proc(Code: integer; // hook code
wParam: WPARAM; // current-process flag
lParam: LPARAM // address of structure with message data
): LRESULT; stdcall;
var
msg : TMsg;
begin
result := 0;
if not assigned(GlobalData) then exit;
if code < 0 then begin
Result := CallNextHookEx(GlobalData^.SysHook, Code, wParam, lParam);
Exit;
end;
// try
if Pointer(lParam) <> nil then begin
msg := Tmsg(Pointer(lParam)^);
if msg.hwnd = ds then
SendMessage(GlobalData^.MyAppWnd, WM_MYKEYHOOK, msg.message, msg.wParam);
end;
// except
// end;
{можно и так, что бы не сохранять дескриптор главного приложения}
//SendMessage(HWND_BROADCAST, WM_MYKEYHOOK, wParam, AppWnd);
//end;
CallNextHookEx(GlobalData^.SysHook, Code, wParam, lParam);
Result := 0;
end;
{Процедура установки HOOK-а}
function SetHook(switch: Boolean; hMainProg: HWND; ThreadID: Cardinal): integer; export; stdcall;
begin
if switch = true then begin
{Устанавливаю HOOK, если он не установлен (switch=true). }
ShowMessage(format("%x", [ThreadID]));
ds := FindWindow("Progman", "Program Manager");
ds := FindWindowEx(ds, HWND(nil), "SHELLDLL_DefView", "");
{ if ds <> 0 then
GlobalData.SysHook :=
SetWindowsHookEx(WH_GETMESSAGE, @Proc, HInstance, GetWindowThreadProcessId(ds, nil))
else exit; }
GlobalData^.SysHook := SetWindowsHookEx(WH_GETMESSAGE, @Proc, HInstance, 0);
GlobalData^.MyAppWnd := hMainProg;
if GlobalData^.SysHook <> 0 then
MessageBox(0, "KEYBOARD HOOK установлен !", "Message from keyhook.dll", 0)
else
MessageBox(0, "HOOK установить не удалось !", "Message from keyhook.dll", 0);
end
else begin
{Удаляю функцию-фильтр, если она установлена (т.е. switch=false). }
if UnhookWindowsHookEx(GlobalData^.SysHook) then begin
MessageBox(0, "HOOK снят !", "Message from keyhook.dll", 0);
GlobalData^.SysHook := 0;
end
else
MessageBox(0, "HOOK снять не удалось !", "Message from keyhook.dll", 0);
end;
result := GlobalData^.SysHook;
end;
procedure OpenGlobalData();
begin
{регестрируем свой тип сообщения в системе}
WM_MYKEYHOOK := RegisterWindowMessage("WM_MYKEYHOOK");
{получаем объект файлового отображения}
// MMFHandle:= CreateFileMapping(DWord(-1), nil, PAGE_READWRITE, 0, SizeOf(TGlobalDLLData), MMFName); // можно так, но лучше: см. след. строку
MMFHandle := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(TGlobalDLLData), MMFName);
if MMFHandle = 0 then begin
MessageBox(0, "Can""t create FileMapping", "Message from keyhook.dll", 0);
Exit;
end;
{отображаем глобальные данные на АП вызывающего процесса и получаем указатель
на начало выделенного пространства}
GlobalData := MapViewOfFile(MMFHandle, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TGlobalDLLData));
if GlobalData = nil then begin
CloseHandle(MMFHandle);
MessageBox(0, "Can""t make MapViewOfFile", "Message from keyhook.dll", 0);
Exit;
end;
ds := FindWindow("Progman", "Program Manager");
ds := FindWindowEx(ds, HWND(nil), "SHELLDLL_DefView", "");
end;
procedure CloseGlobalData();
begin
UnmapViewOfFile(GlobalData);
CloseHandle(MMFHandle);
end;
procedure DLLEntryPoint(dwReason: DWord); stdcall;
begin
case dwReason of
DLL_PROCESS_ATTACH: OpenGlobalData;
DLL_PROCESS_DETACH: CloseGlobalData;
end;
end;
exports SetHook;
begin
//MessageBox(0, PChar(Application.ExeName), "Message from keyhook.dll", 0);
{назначим поцедуру переменной DLLProc}
DLLProc := @DLLEntryPoint;
{вызываем назначенную процедуру для отражения факта присоединения данной
библиотеки к процессу}
DLLEntryPoint(DLL_PROCESS_ATTACH);
end.
← →
Cobalt © (2004-07-06 10:49) [1]А если не ставить хук- то ОК?
А если ставить, но ничего не делать в хуке - ок?
Короче, отлаживай, пока не найдёшь...
← →
bar (2004-07-06 11:03) [2]>>А если ставить, но ничего не делать в хуке - ок?
Нет
даже если так, function Proc(Code: integer; // hook code
wParam: WPARAM; // current-process flag
lParam: LPARAM // address of structure with message data
): LRESULT; stdcall;
begin
result := 0;
end;
то все равно глючит. Может может эксплореру в момент сворачивания окон по WIN+D посылается какоето сообщение которое хук не может обоаботать? Или у меня код неправильный?
← →
Cobalt © (2004-07-06 18:52) [3]1) А если не ставить хук?
3) Если вместо Send - Post?
И 2) как насчёт
code
Specifies whether the hook procedure must process the message. If code is HC_ACTION, the hook procedure must process the message. If code 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.
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2004.08.15;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.045 c