如何控制其他程序窗體上的窗口控件(中)

其實想要找到一個標題已知的窗口句柄,用一個API函數就可以了:FindWindow.

其函數原形是:

function FindWindow(lpClassName, lpWindowName: PChar): HWND; stdcall;

lpClassName:窗口類名.如果只知道標題,可以爲空.窗口類名可以用很多工具獲得.如winsignt32.
lpWindowName:窗口標題.

調用方式舉例:

var wndhwnd:HWND;
wndhwnd:=FindWindow(nil,'某窗口標題');
if wndhwnd<>0 then  //找到此窗口句柄.
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;  //用來顯示找到的控件
    Label1: TLabel; 
    Edit1: TEdit;  //輸入標題.
    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')));就可以給控件發送文本.其他還可以發送不同的消息可以做很多事情.

但是,有很大一個問題:假設一個窗體上有很多相同的控件,並且根本沒辦法區分他們,即使我們能找到所有的控件句柄,我們又不能區分到底哪個是我們想要的,同樣是乾着急.

我想了很長時間,後來在大富翁裏找到了答案,只要用到一個小技巧,就可以解決了.

發佈了26 篇原創文章 · 獲贊 6 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章