Создать кнопку можно так:| Код | wndBtn := CreateWindowEx (WS_EX_NOPARENTNOTIFY or WS_EX_TOPMOST, 'BUTTON', 'Test', WS_VISIBLE or WS_CHILDWINDOW, 220, 62, 40, 29, wnd, 0, 0, nil); | Здесь wnd - хэндл окна, в котором будет создана кнопка. В данном случае создалась корявая такая кнопка, но ты можешь сделать и красивее... Почитай подробнее об CreateWindowEx, стилях и др...
Далее нужно сделать обработчик нажатия кнопки. Есть два пути, которые я тебе могу предложить: 1) Записать в виртуальное пространство чужого процесса свой обработчик. 2) Поставить ловушку (хук).
Немного расскажу про второй способ. Делаем DLL примерно такого содержания:
| Код | library HookDLL;
uses Windows, Messages, uGlobal;
{$R *.res}
function HookProc (nCode : integer; wP : WPARAM; lP : LPARAM) : LRESULT; stdcall; var msg : ^CWPSTRUCT absolute lP;
begin OpenMap; if nCode >= 0 then if (msg.message = WM_COMMAND) and (msg.lParam = GlobalData.wndButton) then PostMessage (GlobalData.wndMain, WM_USER, msg.hwnd, msg.lParam);
Result := CallNextHookEx (GlobalData.hook, nCode, wP, lP); CloseMap; end;
function InstallHook (wnd : HWND; tid : DWORD; wndBtn : HWND) : HHOOK; begin CreateMap; GlobalData.wndMain := wnd; GlobalData.hook := SetWindowsHookEx (WH_CALLWNDPROC, @HookProc, hInstance, tid); GlobalData.wndButton := wndBtn; Result := GlobalData.hook; end;
procedure UninstallHook; begin if GlobalData.hook <> 0 then UnhookWindowsHookEx (GlobalData.hook); CloseMap; end;
exports InstallHook, UninstallHook;
end. | Вызов InstallHook установит ловушку, UninstallHook - уберёт хук. При клике на кнопку хук проверяет, если нажали на созданную нами кнопку, то шлет сообщение WM_USER окну нашей проги.
Тут используется модуль uGlobal:| Код | unit uGlobal;
interface
uses windows;
type PGlobalData = ^TGlobalData; TGlobalData = record wndMain : HWND; hook : HHOOK; wndButton : HWND; end;
var hGlobalMap : THandle; GlobalData : PGlobalData;
const MapName = 'sharemap1';
procedure CreateMap; procedure OpenMap; procedure CloseMap;
implementation
procedure CreateMap; begin if GlobalData <> nil then CloseMap; hGlobalMap := CreateFileMapping (INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(GlobalData^), MapName); GlobalData := MapViewOfFile (hGlobalMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); ZeroMemory (GlobalData, SizeOf(GlobalData^)); end;
procedure OpenMap; begin if GlobalData <> nil then CloseMap; hGlobalMap := OpenFileMapping (FILE_MAP_ALL_ACCESS, False, MapName); GlobalData := MapViewOfFile (hGlobalMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); end;
procedure CloseMap; begin if GlobalData <> nil then UnmapViewOfFile (GlobalData); GlobalData := nil; if hGlobalMap <> 0 then CloseHandle (hGlobalMap); hGlobalMap := 0; end;
end. | Этот модуль нужен типа для создания куска общедоступной памяти. В этой памяти хранится хэндл окна нашей проги, хэндл хука, и хэндл созданной кнопки.
Ну а дальше сам пример установки хука:
| Код | unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ShellAPI, ExtCtrls;
type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure UserMessage (var msg : TMessage); message WM_USER; private public end;
var Form1: TForm1;
implementation
{$R *.dfm}
var hook : HHOOK;
function InstallHook (wnd : HWND; tid : DWORD; wndBtn : HWND) : HHOOK; external 'HookDLL.dll'; procedure UninstallHook; external 'HookDLL.dll';
procedure TForm1.Button1Click(Sender: TObject); var tid : DWORD; wnd, wndBtn : HWND;
begin ShellExecute (0, 'open', 'calc.exe', nil, nil, SW_SHOWNORMAL); Sleep(1000); wnd := FindWindow(nil, 'Calculator'); if wnd = 0 then exit; tid := GetWindowThreadProcessId (wnd); wndBtn := CreateWindowEx (WS_EX_NOPARENTNOTIFY or WS_EX_TOPMOST, 'BUTTON', 'Test', WS_VISIBLE or WS_CHILDWINDOW, 220, 62, 40, 29, wnd, 0, 0, nil);
hook := InstallHook (Handle, tid, wndBtn); end;
procedure TForm1.FormCreate(Sender: TObject); begin hook := 0; end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin if hook <> 0 then UninstallHook; end;
procedure TForm1.UserMessage (var msg : TMessage); begin ShowMessage ('Clicked!'); end;
end.
| Когда жмешь Button1 запустится калькулятор, и в нём создастся кнопка "Test". Если нажмешь на эту кнопку, твоё приложение получит сообщение WM_USER, и выдаст сообщение...
|