Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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
3-72031
Aleksandr
2003-01-04 17:18
2003.01.23
Как реструктурировать таблицу Парадокс, не открывая ее?


1-72244
Шишкин Илья
2003-01-13 20:19
2003.01.23
Панель задач


6-72450
LeReve
2002-11-21 17:29
2003.01.23
Что можно узнать через IP? (не считая страну и имя компа!)


1-72360
April
2003-01-12 11:27
2003.01.23
Как с формы удалить все компоненты, кроме как дестроить каждую?


14-72536
БиМ
2003-01-05 07:52
2003.01.23
Virtual & Override





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