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

Вниз

Как отловить нажатие кнопки в окне чужого приложения?   Найти похожие ветки 

 
Ana ©   (2004-12-02 14:03) [0]

Здравствуйте! Подскажите, пожалуйста, как мне отловить событие нажатия кнопки (TButton), которая находится в окне чужого приложения.
Заранее спасибо!


 
Leonid Troyanovsky   (2004-12-02 14:18) [1]


> Ana ©   (02.12.04 14:03)  
> Здравствуйте! Подскажите, пожалуйста, как мне отловить событие
> нажатия кнопки (TButton), которая находится в окне чужого
> приложения.


А откуда уверенность, что это TButton?

Ну, а вообще-то, нужно подменить оконную процедуру  
(SetWindowLong) ее парента (Windows.GetParent) на предмет
WM_COMMAND c идентификатором оной кнопки (GetDlgCtrlID).
Только делать это надо из системного (dll) хука
(SetWindowsHookEx with WH_GETMESSAGE на целевой поток).
Т.е., установить его можно путем PostThreadMessage
условленного сообщения.
А при снятиии хука нужно вернуть старую оконную процедуру
на место.

--
С уважением, LVT.


 
Ana ©   (2004-12-02 14:48) [2]

Уважаемый LVT!
Не могли ли Вы примерчик продемонстрировать, а то я так не совсем поняла, как это сделать.
Заранее огромное спасибо!


 
Piter ©   (2004-12-02 22:14) [3]

Ana ©   (02.12.04 14:03)

уверен, что это сложно для твоего уровня квалификации. Вот пример DLL, которая внедряется в чужое ВАП:

library piter_hook;

uses
 Windows;

const
 cMMFileName = "piter-hook_{E891D15B-DD53-4BC8-81F4-E0BF8A5573B6}";

type
 PGlobalData = ^TGlobalData;
 TGlobalData = packed record
   HookProcessId: DWORD;
   HookHandle: HHOOK;
   WindowHandle: THandle;
   idMsg: LongWord;
 end;

var
 GlobalData: PGlobalData ;
 MapHandle: THandle;

function DeleteHook(CheckProcess: boolean): boolean;
begin
 Result := false;
 if GlobalData <> nil then
   with GlobalData^ do
     if HookHandle<>0 then
       if (not CheckProcess) or (GetCurrentProcessId = HookProcessId) then
         begin
           Result := UnHookWindowsHookEx(HookHandle) ;
           if Result then
             HookHandle := 0;
         end;
end;

function RemoveShellHook: boolean; stdcall;
begin
 Result := DeleteHook(True);
end;

function ShellProc(nCode: integer; wParam: LongWord;
   lParam: LongWord): integer; stdcall;
begin
 Result := 0;
 if GlobalData <> nil then
   with GlobalData^ do
   begin
     if IsWindow(WindowHandle) then
       SendMessage(WindowHandle, idMsg, wParam, nCode)
     else
       DeleteHook(False);
     CallNextHookEx(HookHandle, nCode, wParam, lParam);
   end;
end;

function SetShellHook(CallbackWindow: THandle;
   idCallBackMessage: LongWord): boolean; stdcall;
begin
 Result := false;
 if GlobalData <> nil then
   with GlobalData^ do
     if ( HookHandle = 0 ) and ( IsWindow(CallbackWindow) ) then
       begin
         HookHandle := SetWindowsHookEx(WH_SHELL, @ShellProc, HInstance, 0);
         Result := HookHandle <> 0;
         if Result then
           begin
             HookProcessId := GetCurrentProcessId ;
             WindowHandle := CallbackWindow ;
             idMsg :=  idCallBackMessage ;
             Result := true;
           end;
       end;
end;

procedure OpenSharedData;
var
 Size: integer;
begin
 Size := SizeOf(TGlobalData);
 MapHandle := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE,
     0, Size, cMMFileName);
 if MapHandle = 0 then exit;
 GlobalData := MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS, 0, 0, Size);
end;

procedure CloseSharedData;
begin
 UnmapViewOfFile(GlobalData);
 CloseHandle(MapHandle);
end;

procedure DLLEntryProc(dwReason: DWord);
begin
 case dwReason of
   DLL_PROCESS_ATTACH: OpenSharedData;
   DLL_PROCESS_DETACH:
     begin
       RemoveShellHook ;
       CloseSharedData;
     end;
 end;
end;

exports
 SetShellHook, RemoveShellHook;

begin
 DLLProc := @DLLEntryProc;
 DLLEntryProc(DLL_PROCESS_ATTACH);
end.


Тебе дальше надо?


 
Leonid Troyanovsky   (2004-12-02 22:20) [4]


> Ana ©   (02.12.04 14:48) [2]

> Не могли ли Вы примерчик продемонстрировать, а то я так
> не совсем поняла, как это сделать.


К сожалению, готового примера у меня нет.
Но, для начала, можно воспользоваться установкой хука в
ответ на сообщение:

http://rsdn.ru/Forum/?mid=305498

И сабклассировать (в хуковой процедуре) парент кнопки,
т.е. получить адрес "старой" оконной процедуры:

olpwndproc := GetWindowLong(hBtnParent, GWL_WNDPROC);

Затем описать (в dll) новую:

function NewWndProc(h: HWND; Msg: UINT; aWParam: WPARAM; aLPARAM: LPARAM): LResult; stdcall;
begin
 if (Msg = WM_COMMAND) and (LoWord(AWParam)= idButton)  then
   {сработала наша кнопка};
 Result := CallWindowProc(oldwndproc, h, Msg, AWParam, ALParam);
end;

а установить ее путем SetWindowLong(hbtnParent, GWL_WNDPROC);
(опять же, из хуковой процедуры).

Ну, и, конечно, следует сказать, что пишу это я прямо
здесь, т.е., воспринимать все оное нужно через призму
компилятора, а еще лучше - сверяясь c msdn.
А если возникнут проблемы, то их, при наличии конкретного кода,
надеюсь,  можно будет последовательно разрешить.

--
С уважением, LVT.


 
Leonid Troyanovsky   (2004-12-03 08:52) [5]


> Leonid Troyanovsky   (02.12.04 22:20) [4]

> Но, для начала, можно воспользоваться установкой хука в
> ответ на сообщение:
>
> http://rsdn.ru/Forum/?mid=305498


Мдя, немного перемудрил на ночь глядя.
Если цель лишь в отслеживании нажатия (не пытаясь отменять),
то достаточно установки SetWindowsHookEx with WH_CALLWNDPROC
or WH_CALLWNPROCRET.

Например, вот так можно предотвращать появление диалога
About.. для Notepad :

----------lib0.dpr------------

library lib0;

uses
 windows, messages;

var
 hhk: HHook;
 hcaller: HWND; // окно, получающее извещения

function GetMsgProc(code: Longint; awparam: WParam; alparam: Lparam):LResult;stdcall;
var
 msg: PCWPRETSTRUCT;
begin
 Result := 0;
 msg := PCWPRETSTRUCT(alparam);
 case msg.message of
   WM_NULL:
     begin
       hcaller := msg.wParam;
       hhk := msg.lParam;
     end;
   WM_INITDIALOG: // при инициализации диалога извещаем caller
     PostMessage(hcaller, WM_USER, 0, msg.hwnd);
 end;
 if hhk <> 0 then
   Result := CallNextHookEx(hhk, code, awparam, alparam);
end;

exports
 GetMsgProc;

begin

end.

----------EOF lib0.dpr------------

Так оную библиотеку используем (блокнот запущен предварительно)


type
 TForm1 = class(TForm)
   Button1: TButton;
   Button2: TButton;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
 private
   { Private declarations }
   procedure WMUser(var msg: TMessage); message WM_USER;
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.DFM}

var
 hhk: HHook;

procedure TForm1.WMUser;
var
 h : HWND;
begin
 h := FindWindowEx(msg.LParam, 0, "Button", "OK");
 PostMessage(h, BM_CLICK, 0, 0);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 h: HWND;
 tid: DWord;
 mh: THandle;
 p: Pointer;
begin
 h := FindWindow("Notepad", nil);
 tid := GetWindowThreadProcessId(h, nil);
 mh := LoadLibrary("Lib0.dll");
 p := GetProcAddress(mh, "GetMsgProc");
 Win32Check(p <> nil);
 hhk := SetWindowsHookEx(WH_CALLWNDPROCRET, p, mh, tid);
 FreeLibrary(mh);
 SendMessage(h, 0, Handle, hhk); // передаем параметры dll
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 UnhookWindowsHookEx(hhk);
end;


--
С уважением, LVT.



Страницы: 1 вся ветка

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

Наверх





Память: 0.48 MB
Время: 0.033 c
14-1104427648
@BraIN
2004-12-30 20:27
2005.01.23
Проблема со зрением


3-1103276807
Sergo
2004-12-17 12:46
2005.01.23
DbLookupComboBox


1-1105433512
Eyfel
2005-01-11 11:51
2005.01.23
копирование файлов в delphi 2005


14-1104765928
Piter
2005-01-03 18:25
2005.01.23
Быстрый способ вырезать строку


1-1104858342
Sun bittern
2005-01-04 20:05
2005.01.23
WIN32_FIND_DATA (большой размер файла)





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