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

 我来答
百度网友96ffcf7
推荐于2016-05-03 · 知道合伙人互联网行家
百度网友96ffcf7
知道合伙人互联网行家
采纳数:22721 获赞数:118724
从事多年网络方面工作,有丰富的互联网经验。

向TA提问 私信TA
展开全部

实现原理是启动一个应用程序,通过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.
量无海大
推荐于2018-03-01 · 超过56用户采纳过TA的回答
知道小有建树答主
回答量:90
采纳率:0%
帮助的人:145万
展开全部
首先找到其它程序窗口的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;
本回答被网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
Dansem
2011-03-18
知道答主
回答量:6
采纳率:0%
帮助的人:5.5万
展开全部
findWindow可以按窗口标题找到其它应用程序窗体的句柄
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式