有了回調函數的概念及上面的例子,我們可以繼續了。其實想要找到一個標題已知的窗口句柄,用一個API函數就可以了:FindWindow.
其函數原形是:
function FindWindow(lpClassName, lpWindowName: PChar): HWND; stdcall;
lpClassName:窗口類名.如果只知道標題,可以為空.窗口類名可以用很多工具獲得.如winsignt32.
lpWindowName:窗口標題.
調用方式舉例:
var wndhwnd:HWND;
wndhwnd:=FindWindow(nil,某窗口標題);
if wndhwnd<>0 then file://找到此窗口句柄.
begin
xxxxx
end
else begin
MessageBox(self.handle,沒找到該窗口句柄,提示,0);
end;
有了這個窗口句柄,就離我們的初始目的不遠了:控制其他窗體上的窗口控件.
同樣,首先要得到其他窗體上窗口控件的句柄.我們用這個API函數:EnumChildWindows.
其函數原形是:
function EnumChildWindows(hWndParent: HWND; lpEnumFunc: TFNWndEnumProc;
lParam: LPARAM): BOOL; stdcall;
這個函數和EnumWindow函數很有些想象.其作用也很相似.它的功能就是列舉窗口句柄為hWndParent的窗體上所有的窗口控件的句柄.同樣也是以回調函數參數的形式給出的.
我們再舉一個實際的例子,來說明這個函數的用法.程序的功能是讓用戶輸入一個窗口標題,然後調用FindWindow函數找到此窗口句柄.通過這個句柄,我們在一個Memo裡顯示該窗口上所有的窗口控件.
同樣先編寫回調函數.
function EnumChildWndProc(AhWnd:LongInt;
AlParam:lParam):boolean;stdcall;
var
WndClassName: array[0..254] of Char;
WndCaption: array[0..254] of Char;
begin
GetClassName(AhWnd,wndClassName,254);
GetWindowText(aHwnd,WndCaption,254);
with form1.memo1 do
begin
lines.add( string(wndClassName));
lines.add( string(wndCaption));
lines.add(-------);
end;
result:=true;
end;
然後在一事件裡調用EnumChildWindows函數.
procedure TForm1.Button1Click(Sender: TObject);
var
hWnd:LongInt;
begin
memo1.Lines.Clear;
Memo1.Lines.Add(Edit1.Text+ 有如下控件類名稱);
hWnd:=FindWindow(nil,pchar(Edit1.Text));
if hWnd<>0 then
begin
EnumChildWindows(hWnd,@EnumChildWndProc,0);
end
else MessageBox(self.handle,沒找到該窗口句柄,提示,0);
end;
程序清單如下:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo; file://用來顯示找到的控件
Label1: TLabel;
Edit1: TEdit; file://輸入標題.
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
function EnumChildWndProc(AhWnd:LongInt;
AlParam:lParam):boolean;stdcall;
implementation
{$R *.dfm}
function EnumChildWndProc(AhWnd:LongInt;
AlParam:lParam):boolean;stdcall;
var
WndClassName: array[0..254] of Char;
WndCaption: array[0..254] of Char;
begin
GetClassName(AhWnd,wndClassName,254);
GetWindowText(aHwnd,WndCaption,254);
with form1.memo1 do
begin
lines.add( string(wndClassName));
lines.add( string(wndCaption));
lines.add(-------);
end;
result:=true;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
hWnd:LongInt;
begin
memo1.Lines.Clear;
Memo1.Lines.Add(Edit1.Text+ 有如下控件類名稱);
hWnd:=FindWindow(nil,pchar(Edit1.Text));
if hWnd<>0 then
begin
EnumChildWindows(hWnd,@EnumChildWndProc,0);
end
else MessageBox(self.handle,沒找到該窗口句柄,提示,0);
end;
end.
有了控件句柄,我們當然就可以隨心所欲了.比如:
SendMessage(hWnd,WM_SETTEXT,0,LongInt(Pchar(sdafdsf)));就可以給控件發送文本.其他還可以發送不同的消息可以做很多事情.
但是,有很大一個問題:假設一個窗體上有很多相同的控件,並且根本沒辦法區分他們,即使我們能找到所有的控件句柄,我們又不能區分到底哪個是我們想要的,同樣是干著急.
我想了很長時間,後來在大富翁裡找到了答案,只要用到一個小技巧,就可以解決了.