delphi 如何获取其它应用程序窗体中的所有控件句柄

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了delphi 如何获取其它应用程序窗体中的所有控件句柄相关的知识,希望对你有一定的参考价值。

实现原理是启动一个应用程序,通过ProcessID得到窗体句柄,然后对其设定父窗体句柄为本程序某控件句柄(本例是窗体内一个Panel的句柄),这样就达成了内嵌的效果。

新建窗体,上面放置一个Panel控件,名为pnlApp,然后按下面代码编写:

unit frmTestEmbedApp;    
     
interface    
     
uses    
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,    
  Dialogs, ExtCtrls;    
     
type    
     
  TForm1 = class(TForm)    
    pnlApp: TPanel;    
    procedure FormCreate(Sender: TObject);    
    procedure FormClose(Sender: TObject; var Action: TCloseAction);    
    procedure FormResize(Sender: TObject);    
  private    
     Private declarations     
  public    
     Public declarations     
  end;    
     
var    
  Form1: TForm1;    
  hWin: HWND = 0;    
     
implementation    
     
$R *.dfm    
     
type    
  // 存储窗体信息    
  PProcessWindow = ^TProcessWindow;    
  TProcessWindow = record    
    ProcessID: Cardinal;    
    FoundWindow: hWnd;    
  end;    
     
// 窗体枚举函数    
     
function EnumWindowsProc(Wnd: HWND; ProcWndInfo: PProcessWindow): BOOL; stdcall;    
var    
  WndProcessID: Cardinal;    
begin    
  GetWindowThreadProcessId(Wnd, @WndProcessID);    
  if WndProcessID = ProcWndInfo^.ProcessID then begin    
    ProcWndInfo^.FoundWindow := Wnd;    
    Result := False;                                    // 已找到,故停止 EnumWindows    
  end    
  else    
    Result := True;                                     // 继续查找    
end;    
     
// 由 ProcessID 查找窗体 Handle    
     
function GetProcessWindow(ProcessID: Cardinal): HWND;    
var    
  ProcWndInfo: TProcessWindow;    
begin    
  ProcWndInfo.ProcessID := ProcessID;    
  ProcWndInfo.FoundWindow := 0;    
  EnumWindows(@EnumWindowsProc, Integer(@ProcWndInfo)); // 查找窗体    
  Result := ProcWndInfo.FoundWindow;    
end;    
     
// 在 Panel 上内嵌运行程序    
     
function RunAppInPanel(const AppFileName: string; ParentHandle: HWND; var WinHandle: HWND): Boolean;    
var    
  si: STARTUPINFO;    
  pi: TProcessInformation;    
begin    
  Result := False;    
     
  // 启动进程    
  FillChar(si, SizeOf(si), 0);    
  si.cb := SizeOf(si);    
  si.wShowWindow := SW_SHOW;    
  if not CreateProcess(nil, PChar(AppFileName), nil, nil, true,    
    CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, si, pi) then Exit;    
     
  // 等待进程启动    
  WaitForInputIdle(pi.hProcess, 10000);    
     
  // 取得进程的 Handle    
  WinHandle := GetProcessWindow(pi.dwProcessID);    
  if WinHandle > 0 then begin    
    // 设定父窗体    
    Windows.SetParent(WinHandle, ParentHandle);    
     
    // 设定窗体位置    
    SetWindowPos(WinHandle, 0, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOZORDER);    
     
    // 去掉标题栏    
    SetWindowLong(WinHandle, GWL_STYLE, GetWindowLong(WinHandle, GWL_STYLE)    
      and (not WS_CAPTION) and (not WS_BORDER) and (not WS_THICKFRAME));    
     
    Result := True;    
  end;    
     
  // 释放 Handle    
  CloseHandle(pi.hProcess);    
  CloseHandle(pi.hThread);    
end;    
     
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);    
begin    
  // 退出时向内嵌程序发关闭消息    
  if hWin > 0 then PostMessage(hWin, WM_CLOSE, 0, 0);    
end;    
     
procedure TForm1.FormCreate(Sender: TObject);    
const    
  App = \'C:\\Windows\\Notepad.exe\';    
begin    
  pnlApp.Align := alClient;    
     
  // 启动内嵌程序    
  if not RunAppInPanel(App, pnlApp.Handle, hWin) then ShowMessage(\'App not found\');    
end;    
     
procedure TForm1.FormResize(Sender: TObject);    
begin    
  // 保持内嵌程序充满 pnlApp    
  if hWin <> 0 then MoveWindow(hWin, 0, 0, pnlApp.ClientWidth, pnlApp.ClientHeight, True);    
end;    
     
end.
参考技术A 首先找到其它程序窗口的Handle。

定义函数
function GetAllHandle(hwnd: Integer; lparam: Longint):Boolean; stdcall;
var
buffer: array[0..255] of Char;
buffer1: array[0..255] of Char;
s:string;
int:integer;
begin
Result := True;
GetClassName(hwnd,buffer,256);
Form1.listbox1.itmes.add(format('句柄:%d 类名:%s',[hwnd,StrPas(Buffer)]));//写入窗口ListBox中
end;

调用函数
procedure TForm1.Button1Click(Sender: TObject);
var
Handle:THandle;
begin
Handle:=findWindow(nil,'要查找的窗口标题');
EnumChildWindows(Handle, @GetAllHandle, Integer(@Handle));
end;
参考技术B findWindow可以按窗口标题找到其它应用程序窗体的句柄本回答被提问者采纳

如何遍历winform窗体中的所有控件

本文实例讲述了WinForm遍历窗体所有子控件的方法。分享给大家供大家参考,具体如下:
///
<summary>
///
C#
只遍历控件子控件,不遍历孙控件
///当控件有子控件时,需要用递归的方法遍历,才能全部列出控件上的控件
///
</summary>
///
<typeparam
name="T">控件类型</typeparam>
///
<param
name="control">要遍历的控件</param>
///
<param
name="controlsName">控件名</param>
///
<returns></returns>
public
static
T
GetControl<T>(Control
control,
string
controlsName)
where
T
:
Control

if
(control
==
null)
return
null;
Control
_control;
for
(int
i
=
0;
i
<
control.Controls.Count;
i++)

_control
=
control.Controls[i];
参考技术A private
void
getcontrol(control.controlcollection
ctc)

foreach
(control
ct
in
ctc)

//c#
只遍历窗体的子控件,不遍历孙控件
//当窗体上的控件有子控件时,需要用递归的方法遍历,才能全部列出窗体上的控件
if
(ct.haschildren)

getcontrol(ct.controls);


参考技术B 要用递归啊,楼上都是来混分的
//
伪代码
如下
void
EnumControls(Control
container
)

foreach(var
c
in
container.Controls)

//c
is
the
child
control
here
EnumControls(c);


//调用
EnumControls(this);

以上是关于delphi 如何获取其它应用程序窗体中的所有控件句柄的主要内容,如果未能解决你的问题,请参考以下文章

delphi如何关闭启动窗体

delphi 如何获得一个窗体中有多少控件

delphi的窗体窗口

请问如何在delphi from窗体内加网页

delphi 对窗体中的控件进行遍历

delphi 子窗体如何继承主窗体的方法