Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Вопрос по глобальному hook.


_BladeR ©   (2003-12-30 04:12:00) 

Доброго времени суток. У меня следующий вопрос, я ставлю из глобальный хук на создание окна, класс которого я знаю, но при исполнении callback функции система не может корректно создать ни одного окна, посмотрите пожалуйста.

Callback function:

function CBTProc(nCode:integer; WParam: word; LParam: LPARAM): longint; stdcall;
type
pCBT_CMD = ^CBT_CREATEWND;
var
pCMDStruct: pCBT_CMD;
begin
if nCode < 0 then
begin
Result:= CallNextHookEx(GlobalData^.mHOOK, nCode, wParam, lParam);
Exit;
end;
if nCode=HCBT_CREATEWND then
begin
New(pCMDStruct);
pCMDStruct := pCBT_CMD(lParam);
if pCMDStruct = nil then begin
MessageBox(0,"Nil pointer","Hook.dll",0);
Result := 0;
Exit;
end;
if pCMDStruct.lpcs^.lpszClass = "Winamp v1.x" then MessageBeep(0);
CallNextHookEx(GlobalData^.mHOOK, nCode, wParam, lParam);
//Release(pCMDStruct);
end;
Result := 0;
end;


Вызов из исполняемого файла:

procedure TfmWctrl.FormShow(Sender: TObject);
var
ver: string;
SetHook: procedure;
hwndWinamp: function : hwnd;
begin
@SetHook := nil;
@hwndWinamp := nil;
hDLL := LoadLibrary(PChar("hook.dll"));
if hDLL > HINSTANCE_ERROR then
begin
@SetHook:=GetProcAddress(Hdll, "SetHook");
@hwndWinamp:=GetProcAddress(Hdll, "hwndWinamp");
hWinamp := hwndWinamp;
SetHook;
end
else
begin
ShowMessage("Unable to load hook.dll");
Exit;
end;
if hWinamp <> 0 then begin
fmWctrl.sbStatus.SimpleText := "Winamp ver." + ver + " is running";
ver := InttoStr(SendMessage(hWinamp,WM_USER,0,0));
else fmWctrl.sbStatus.SimpleText := "Winamp is not running";
end;


Полный листинг DLL:
library hook;

uses
Windows,
Messages,
Sysutils;

{$R *.RES}
const
MMFName: PChar = "CBT_MMF";

type
PGlobalDLLData = ^TGlobalDLLData;
TGlobalDLLData = packed record
mHOOK: HWND;
end;

var
GlobalData: PGlobalDLLData;
MFHandle: THandle;

function hwndWinamp: hwnd;
begin
Result := FindWindow("Winamp v1.x", nil);
end;

function CBTProc(nCode:integer; WParam: word; LParam: LPARAM): longint; stdcall;
type
pCBT_CMD = ^CBT_CREATEWND;
var
pCMDStruct: pCBT_CMD;
begin
if nCode < 0 then
begin
Result:= CallNextHookEx(GlobalData^.mHOOK, nCode, wParam, lParam);
Exit;
end;
if nCode=HCBT_CREATEWND then
begin
New(pCMDStruct);
pCMDStruct := pCBT_CMD(lParam);
if pCMDStruct = nil then begin
MessageBox(0,"Nil pointer","Hook.dll",0);
Result := 0;
Exit;
end;
if pCMDStruct.lpcs^.lpszClass = "Winamp v1.x" then MessageBeep(0);
CallNextHookEx(GlobalData^.mHOOK, nCode, wParam, lParam);
//Release(pCMDStruct);
end;
Result := 0;
end;

procedure SetHook; export;
begin
GlobalData^.mHOOK := SetWindowsHookEx(WH_CBT, @CBTProc, HInstance, 0);
end;

procedure UnsetHook; export;
begin
UnhookWindowsHookEx( GlobalData^.mHOOK );
end;

procedure OpenGlobalData();
begin
MFHandle := CreateFileMapping(DWord(-1), nil, PAGE_READWRITE, 0, SizeOf(TGlobalDLLData), MMFName);
if MFHandle = 0 then raiseLastWin32Error;
GlobalData := MapViewOfFile(MFHandle, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TGlobalDLLData));
if GlobalData = nil then
begin
CloseHandle(MFHandle);
raiseLastWin32Error;
end;

end;

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

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

exports
hwndWinamp, CBTProc, SetHook, UnsetHook;
begin
DLLProc:= @DLLEntryPoint;
DLLEntryPoint(DLL_PROCESS_ATTACH);
end.


Digitman   (2003-12-31 15:31:00) [1]

if stricomp(pCMDStruct.lpcs^.lpszClass, "Winamp v1.x") = 0 then
...
else
...


_BladeR   (2003-12-30 19:40:00) [2]

Я пробовал и такой вариант, тот же результат.
И тем более в SDK сказано:

If the hook procedure returns zero, the window is created normally.

Меня честно говоря смущает вот этот момент:
if pCMDStruct.lpcs^.lpszClass = "Winamp v1.x" ...
Потому, что если его убрать - то все: ок окна создаются, но программа то не реагирует, потому как условия реагирования то нет...
и еще pCMDStruct.lpcs^.lpszClass - это PAnsiChar и каким образом привести его к PChar я не знаю.


jonni   (2003-12-30 08:23:00) [3]

function CBTProc(nCode:integer; WParam: word; LParam: LPARAM): longint; stdcall;
type
------
end;
Result := 0;
end;

a ne dolzhno li bit":

Result:= CallNextHookEx(GlobalData^.mHOOK, nCode, wParam, lParam); ????!!!!!!!!!!!!!!
??????


Наверх

Титульная страница Поиск, карта сайта Написать письмо