Форум: "WinAPI";
Текущий архив: 2003.01.23;
Скачать: [xml.tar.bz2];
ВнизХук на окно Найти похожие ветки
← →
alex134 (2002-11-30 18:22) [0]Пытаюсь поставить хук на создание окна. Ничего не получается...
Вот код:
library Hook;
uses
Windows, SysUtils;
{$R *.res}
const
WM_USER = $0400; // Скопировано из messages.pas
WM_KEYBHOOK = WM_USER + 346;
var
KeyboardHook: HHOOK;
f : TextFile;
function CBTProc(hCode: Integer; wParam: Longint; lParam: Longint): LRESULT; stdcall;
var
Wnd: THandle;
CreateWndStruct : ^tagCBT_CREATEWNDA;
cx,cy,x,y : integer;
name : string;
begin
if hCode = HCBT_CREATEWND then
begin
Wnd := FindWindow(nil, "freedomhook");
if Wnd > 0 then
begin
CreateWndStruct:=Ptr(lParam);
cx:=CreateWndStruct.lpcs.cx;
cy:=CreateWndStruct.lpcs.cy;
x:=CreateWndStruct.lpcs.x;
y:=CreateWndStruct.lpcs.y;
name:=CreateWndStruct.lpcs.lpszName;
Writeln(f, "name="+name+" cx="+IntToStr(cx)+" cy="+IntToStr(cy)+" x="+IntToStr(x)+" y="+IntToStr(y));
PostMessage(Wnd, WM_KEYBHOOK, wParam, lParam);
Result:=0;
end;
end;
Result := CallNextHookEx(KeyboardHook, hCode, wParam, lParam);
end;
function SetKeyboardHook: Boolean; stdcall; export;
begin
KeyboardHook := SetWindowsHookEx(WH_CBT, @CBTProc, HInstance, 0);
AssignFile(f, "d:\hook.txt");
Rewrite(f);
Result := KeyboardHook <> 0;
end;
function RemoveKeyboardHook: Boolean; stdcall; export;
begin
Result := UnhookWindowsHookEx(KeyboardHook);
CloseFile(f);
end;
exports SetKeyboardHook, RemoveKeyboardHook;
begin
end.
Использую WH_CBT вместо WH_SHELL т.к. надо знать кэпшн создаваемого окна.
← →
Morfein (2002-11-30 21:27) [1]Скорее всего, тебе надо вынести функции SetKeyboardHook() и RemoveKeyboardHook() в отдельную прогу...
И тогда дописать в SetKeyboardHook() загрузку Hook.dll и получение адреса функции CBTProc().
← →
alex134 (2002-12-01 15:10) [2]Я думаю, что проблема с name, но не знаю что не так :(
← →
kostik78ua (2002-12-01 17:41) [3]> Использую WH_CBT вместо WH_SHELL т.к. надо знать кэпшн создаваемого окна.
Я все равно считаю, что надо испльзовать WH_SHELL. Именно ОН для этого предназначен. А кэпшн создаваемого окна можно узнать просто: GetWindowText.
> name:=CreateWndStruct.lpcs.lpszName
Для преобразования PChar в строку испльзуй SetString или StrPas
← →
alex134 (2002-12-01 18:18) [4]Моя задача - написать программу, которая будет манипулировать некоторыми (в соотв. с заголовком) окнами (прятать, перемещать за пределы экрана или вообще убивать) так, чтобы этих окон не было заметно на экране. Т.е. чтобы окна даже не успели мелькнуть.
Пример: как только появляется окно с заголовком "TTTWindow" его надо
переместить в точку -1000, -1000.
--
Чем тут будет полезен WH_SHELL? Похоже, WH_CBT вообще нормально не пашет :(
← →
alex134 (2002-12-02 19:14) [5]Есть люди, разобравшиеся с хуками CBT?
← →
Snap (2002-12-03 21:59) [6]Основная проблема при написании хуков состоит в том что у процессов разные адресные простаранства. То есть все переменные объявленные в твоей ДЛЛ в разных процессах будут разныими, а в большинстве из них будут нулями, то есть просто проинициализованными переменными. Вынеси все переменные в прогу, которая будет устанавливать хук.
← →
Bsl (2002-12-04 08:07) [7]Всю информацию надо выносить в SharedMemory - т.о. и загруженные в чужом адресном пространстве библиотеки и твоя прога смогут работать с одними данными - ты сможешь передавать в библиотеки параметры событий.
Я делал именно так - в ответ на событие в чужом процессе я отправлял событие окну, установившему hook, а Handle и все параметры брал с помощью SharedMemory.
(в Delphi есть модуль как пользовать shared memory).
← →
alex134 (2002-12-04 19:28) [8]Спасибо, попробую.
← →
alex134 (2002-12-06 20:27) [9]Учел Ваши поправки и исправил код:
Код библиотеки с хуком:
library Hook;
uses
Windows, SysUtils;
{$R *.res}
const
WM_USER = $0400; //
WM_KEYBHOOK = WM_USER + 346;
MMFName: PChar = "MyMMF"; // имя объекта файлового отображения
type
PGlobalDLLData = ^TGlobalDLLData;
TGlobalDLLData = packed record
WindowName : ShortString; // имя окна
WindowH: HWND; // дескриптор окна
end;
var
KeyboardHook: HHOOK;
GlobalData: PGlobalDLLData;
MMFHandle: THandle;
function CBTProc(hCode: Integer; wParam: Longint; lParam: Longint): LRESULT; stdcall;
var
Wnd: THandle;
name : String;
WinH : THandle;
CBTStruct : PCBTCreateWnd;
begin
if hCode = HCBT_CREATEWND then
begin
MMFHandle:= CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(TGlobalDLLData), MMFName);
if MMFHandle = 0 then
MessageBox(0, "Can""t open FileMapping", "Message from freedomhook", 0)
else begin
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 freedomhook", 0);
end
else
begin
CBTStruct:=Ptr(lParam);
name:=StrPas(CBTStruct^.lpcs.lpszName);
WinH :=wParam;
GlobalData^.WindowName:=name;
GlobalData^.WindowH:=WinH;
FlushViewOfFile(GlobalData, SizeOf(TGlobalDLLData));
wnd:=findwindow(nil, "freedomhook");
if wnd>0 then SendMessage(wnd,WM_KEYBHOOK, 0, 0);
end;
UnmapViewOfFile(GlobalData);
CloseHandle(MMFHandle);
end;
end;
Result := CallNextHookEx(KeyboardHook, hCode, wParam, lParam);
end;
function SetKeyboardHook: Boolean; stdcall; export;
begin
KeyboardHook := SetWindowsHookEx(WH_CBT, @CBTProc, HInstance, 0);
Result := KeyboardHook <> 0;
end;
function RemoveKeyboardHook: Boolean; stdcall; export;
begin
Result := UnhookWindowsHookEx(KeyboardHook);
end;
exports SetKeyboardHook, RemoveKeyboardHook;
begin
end.
Код главной программы (пустая форма с Memo):
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Hook;
const
WM_USER = $0400; //
WM_KEYBHOOK = WM_USER + 346;
MMFName: PChar = "MyMMF"; // имя объекта файлового отображения
type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
procedure WMKEYBHOOK(var Msg: TMessage); message WM_KEYBHOOK;
public
{ Public declarations }
end;
type
PGlobalDLLData = ^TGlobalDLLData;
TGlobalDLLData = packed record
WindowName : ShortString; // имя окна
WindowH: HWND; // дескриптор окна
end;
var
Form1: TForm1;
GlobalData: PGlobalDLLData;
MMFHandle: THandle;
implementation
{$R *.dfm}
procedure TForm1.WMKEYBHOOK(var Msg: TMessage);
begin
Memo1.Lines.Add(GlobalData^.WindowName+" "+IntToStr(GlobalData^.WindowH));
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
if not SetKeyboardHook then Application.Terminate;
GlobalData:=nil;
MMFHandle:= CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(TGlobalDLLData), MMFName);
if MMFHandle = 0 then
MessageBox(0, "Can""t create FileMapping", "Message from freedomhook", 0)
else begin
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 freedomhook", 0);
end;
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
RemoveKeyboardHook;
UnmapViewOfFile(GlobalData);
CloseHandle(MMFHandle);
end;
end.
Программа отслеживает создание окон в системе, и передает заголовок и handle создавшегося окна главной программе.
В большинстве случаев имя заголовка пустое, однако, при создании интересующих меня окон оно содержит название окна - т.е. с этим проблем нет. Однако, работает все "не гладко" как хотелось бы - некоторые окна не открываются, похоже подвисают.
Например, при запуске ACDSee ее окно не показывается и программа продолжает "висеть" в памяти.
Один раз шелл заглючил. В чем ошибка мастера?
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2003.01.23;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.007 c