Delphi SetParent 嵌入其他应用程序
[代码]Delphi实现窗体内嵌其他应用程序窗体
实现原理是启动一个应用程序,通过ProcessID得到窗体句柄,然后对其设定父窗体句柄为本程序某控件句柄(本例是窗体内一个Panel的句柄),这样就达成了内嵌的效果。
本文实现的是内嵌一个记事本程序,如下图:

在实现细节上需要注意几点:
- 为了美化程序的嵌入效果,需要隐藏其标题栏
- 在外部窗体大小变化时,需要内嵌的窗体也随之变化大小
- 外部程序退出时,内嵌的程序也要退出
下面是例子程序。新建窗体,上面放置一个Panel控件,名为pnlApp,然后按下面代码编写:
unit frmTestEmbedApp; |
interface |
uses |
Windows, |
Dialogs, |
type |
TForm1class(TForm) |
pnlApp: |
procedure FormCreate(Sender: |
procedure FormClose(Sender:var Action: |
procedure FormResize(Sender: |
private |
{ |
public |
{ |
end; |
var |
Form1: |
hWin:0; |
implementation |
{$R |
type |
// |
PProcessWindow |
TProcessWindowrecord |
ProcessID: Cardinal; |
FoundWindow: |
end; |
// |
function EnumWindowsProc(Wnd: |
var |
WndProcessID: Cardinal; |
begin |
GetWindowThreadProcessId(Wnd, |
if WndProcessIDthen begin |
ProcWndInfo^.FoundWindow |
ResultFalse; // |
end |
else |
ResultTrue; // |
end; |
// |
function GetProcessWindow(ProcessID: Cardinal): |
var |
ProcWndInfo: |
begin |
ProcWndInfo.ProcessID |
ProcWndInfo.FoundWindow0; |
EnumWindows(@EnumWindowsProc, Integer(@ProcWndInfo)); // |
Result.FoundWindow; |
end; |
// |
function RunAppInPanel(const AppFileName: string;var WinHandle:Boolean; |
var |
si: |
pi: |
begin |
ResultFalse; |
// |
FillChar(si,0); |
si.cb |
si.wShowWindow |
if not CreateProcess(nil, PChar(AppFileName), nil, nil, true, |
CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil,then Exit; |
// |
WaitForInputIdle(pi.hProcess, 10000); |
// |
WinHandle.dwProcessID); |
if WinHandle0 then begin |
// |
Windows.SetParent(WinHandle, |
// |
SetWindowPos(WinHandle, 0, 0, 0, 0, 0,or SWP_NOZORDER); |
// |
SetWindowLong(WinHandle, |
and (not WS_CAPTION) and (not WS_BORDER) and (not WS_THICKFRAME)); |
ResultTrue; |
end; |
// |
CloseHandle(pi.hProcess); |
CloseHandle(pi.hThread); |
end; |
procedure TForm1.FormClose(Sender:var Action: |
begin |
// |
if hWin0 then PostMessage(hWin,0, 0); |
end; |
procedure TForm1.FormCreate(Sender: |
const |
App'C:\Windows\Notepad.exe'; |
begin |
pnlApp.Align |
// |
if not RunAppInPanel(App,.Handle,then ShowMessage('App); |
end; |
procedure TForm1.FormResize(Sender: |
begin |
// |
if hWin0 then MoveWindow(hWin, 0, 0,.ClientWidth,.ClientHeight, True); |
end; |
end. |
这种方式也存在几个问题:
问题1:如果程序有Splash窗体先显示,则实际窗体无法内嵌,因为仅将Splash窗体的父窗体设定为本程序的控件句柄,后续窗体无法设定。
解决方法:可以通过轮询方式查询后续窗体,并设定其父窗体为本程序的控件句柄。
问题2:点击内嵌程序的窗体,则本程序的标题栏失去焦点
解决方法:不详。
问题3:点击内嵌程序的窗体,按下ALT+F4,则内嵌程序退出,仅留下本程序
解决方法:可以通过Hook方式拦截ALT+F4。
Delphi SetParent 嵌入其他应用程序的更多相关文章
- WPF中嵌入普通Win32程序的方法
公司现在在研发基于.Net中WPF技术的产品,由于要兼容旧有产品,比如一些旧有的Win32程序.第三方的Win32程序等等,还要实现自动登录这些外部Win32程序,因此必须能够将这些程序整合到我们的系 ...
- 在winform嵌入外部应用程序
应朋友要求,需要将一个第三方应用程序嵌入到本程序WinForm窗口,以前在VB6时代做过类似的功能,其原理就是利用Windows API中FindWindow函数找到第三方应用程序句柄,再利用SetP ...
- WPF 同一窗口内的多线程/多进程 UI(使用 SetParent 嵌入另一个窗口)
原文 WPF 同一窗口内的多线程/多进程 UI(使用 SetParent 嵌入另一个窗口) WPF 的 UI 逻辑只在同一个线程中,这是学习 WPF 开发中大家几乎都会学习到的经验.如果希望做不同线程 ...
- 把任意的EXE嵌入到自己程序中
把任意的EXE嵌入到自己程序中 taoyuan19822008-08-24上传 Delphi把任意的EXE嵌入到自己程序中的程序 资源积分:0分 下载次数:327 资源类型:其他 资源大小:175 ...
- Qt界面中嵌入其他exe程序的界面,使用Qt5
下面用一个小例子来演示如何在Qt的界面中嵌入其他exe程序的界面,最终效果如下图所示.本文参考了 http://blog.csdn.net/jiaoyaziyang/article/details/4 ...
- Delphi 在任务栏隐藏程序图标
Delphi 在任务栏隐藏程序图标 方法一:1.修改工程文件中的“Application.MainFormOnTaskbar := True;”为“Application.MainFormOnTask ...
- Delphi Excel导入 的通用程序转载
Delphi Excel导入 的通用程序 (-- ::)转载▼ 标签: it 分类: Delphi相关 步骤: 连excel(自己知道其格式,最好是没个字段在数据一一对应) 读excel数据,填入到数 ...
- Delphi - Indy TIdHTTP方式创建程序外壳 - 实现可执行程序的自动升级
Delphi 实现可执行程序的自动升级 准备工作: 1:Delphi调用TIdHTTP方式开发程序,生成程序打包外壳 说明:程序工程命名为ERP_Update 界面布局如下: 代码实现如下: unit ...
- C# SetParent将其他程序嵌入自己的程序
模块化的开发,将模块合并到一起的时候,遇到了Mdi不能添加到其它窗口下的问题. 分两种情况: 将mdi窗口A设成普通窗口B的子控件,需要将A的TopLevel设置成false,但是Mdi窗口的TopL ...
随机推荐
- Unity5 图形系统介绍 学习
- What happens to our code? JavaScript 代码是怎样执行的
1. 我们的代码第一步会被parser 语法分析程序分析. 如果没有报错之后 2. 生产SyntaxTree, 我们的代码会转换成machine code 3. 最终 我们的代码会被运行出来. 下面的 ...
- 短信验证登陆-中国网建提供的SMS短信平台
一.JAVA发送手机短信常见的有三种方式(如下所列): 使用webservice接口发送手机短信,这个可以使用sina提供的webservice进行发送,但是需要进行注册 使用短信mao的方式进行短信 ...
- 我发起了一个 支持 PostgreSql 的 外围设施 的 .Net 开源项目
目标 : 让 PostgreSql 成为 通用的 跨平台 的 数据库 , 成为 开发者 喜爱 的 利器 . 要做的事 , 当然 , PostgreSql 本身现在不用我们去做什么 . 一个 数据库 ...
- pri 知识点
pri github:https://github.com/prijs/pri 添加路由后动态导入,使用的是 react-loadable:https://github.com/jamiebuilds ...
- Bitvise 使用公私玥免密登陆 服务器
远程机linux 首先需要把 生成 公私玥,并且把公钥 写到 远程linux 主机的,你要登陆的用户下面 的.ssh 文件里面的authorized_keys 文件里面.这个参考我的另一篇关于linu ...
- Host does not support domain type kvm for virtualization type 'hvm' arch 'x86_64'
kvm创建虚拟机报错: qemu-img create -f qcow2 /tmp/centos.qcow2 10G virt-install --virt-type kvm --name cento ...
- Hibernate更新删除数据后,再查询数据依然存在的解决办法
删除数据后,重新查询了数据库,DB中记录已经删除了,但是数据依然能查询到,网上都说是Hibernate的缓冲问题. 我对session进行了clear,flush,并且在事务和查询中都对session ...
- max_result_window
PUT http://192.168.1.12:9200/_settings { "index": { "max_result_window": "1 ...
- CentOS6.4 添加php-fpm系统服务
简介: php-fpm安装完成后默认不会注册为系统服务,所以需要手工添加系统服务脚本.在/etc/init.d目录下新建php-fpm文件,并更改权限其即可. 1.检测/usr/local/php/v ...