程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 如何控制其他程序窗體上的窗口控件:中

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

編輯:Delphi

有了回調函數的概念及上面的例子,我們可以繼續了。其實想要找到一個標題已知的窗口句柄,用一個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)));就可以給控件發送文本.其他還可以發送不同的消息可以做很多事情.

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

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved