C# SetParent将其他程序嵌入自己的程序
模块化的开发,将模块合并到一起的时候,遇到了Mdi不能添加到其它窗口下的问题。
分两种情况:
将mdi窗口A设成普通窗口B的子控件,需要将A的TopLevel设置成false,但是Mdi窗口的TopLevel必须为顶级;
将mdi窗口A设成mdi窗口B的子窗口,A.MdiParent = B,编译时不通过,窗口不能既是mdi子级,又是mdi父级。
最后通过windows Api强制将mdi窗口A的parent设置成窗口B。

[DllImport("user32.dll", EntryPoint = "SetParent")]
public static extern int SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
MDIParent1 form = new MDIParent1();
SetParent(form.Handle, this.Handle);
form.Location = new Point(0, 0);
form.Size = this.Size;
form.Show();

通过SetParent将mdi窗口强行放到了普通的Form下。
调试的时候,界面上达到了预期的目标,但是发现了另一个新的问题。
焦点在mdi的子窗口上时,mdi窗口上的控件无效,点击事件全部触发不了;焦点在mdi的父窗口上时,mdi窗口的控件又“激活”了。而在单独打开mdi窗口时,完全不存在这个问题。
查询了一下msdn里面的SetParent的说明,发现了如下段:
“For compatibility reasons, SetParent does not modify the WS_CHILD
or WS_POPUP window styles of the window whose parent is being changed. Therefore, it is not possible to change a window from parent to child or from child to parent.”
我的理解是,虽然用SetParent强制将普通窗口设置成mdi的父窗口,但是mdi的子级窗口的属性却没有赋予。
解决的思路,调用另一个windows·Api SetWindowLong强制修改mdi的窗口属性。

private const int GWL_STYLE = -16;
private const int WS_CHILD = 0x40000000;//设置窗口属性为child [DllImport("user32.dll", EntryPoint = "GetWindowLong")]
public static extern int GetWindowLong(IntPtr hwnd, int nIndex); [DllImport("user32.dll", EntryPoint = "SetWindowLong")]
public static extern int SetWindowLong(IntPtr hwnd, int nIndex, int dwNewLong); var s = GetWindowLong(form.Handle, GWL_STYLE);
SetWindowLong(form.Handle, GWL_STYLE, s | WS_CHILD);

至此,问题算解决了。发一个效果图:

补充一个bug:虽然解决了mdiParent获取焦点的问题,后来发现mdiChild获取焦点又不正常了。如果mdiChild,如上图中的Form2界面上有TextBox控件时,修改TextBox的文字时,光标的位置,总是不正常。能力有限,尚待解决。
C# SetParent将其他程序嵌入自己的程序的更多相关文章
- 在winform嵌入外部应用程序
应朋友要求,需要将一个第三方应用程序嵌入到本程序WinForm窗口,以前在VB6时代做过类似的功能,其原理就是利用Windows API中FindWindow函数找到第三方应用程序句柄,再利用SetP ...
- C#将exe运行程序嵌入到自己的winform窗体中
以下例子是将Word打开,然后将它嵌入到winform窗体中,效果如下图:C将exe运行程序嵌入到自己的winform窗体中 - kingmax_res - iSport注意:该方法只适用于com的e ...
- WPF中嵌入普通Win32程序的方法
公司现在在研发基于.Net中WPF技术的产品,由于要兼容旧有产品,比如一些旧有的Win32程序.第三方的Win32程序等等,还要实现自动登录这些外部Win32程序,因此必须能够将这些程序整合到我们的系 ...
- Winform 程序嵌入WPF程序 并发送消息
废话不多说,先看解决方案目录 WindowsFormsDemo是主程序,WpfApp是嵌入的WPF程序,先看WPF程序,程序默认启动的页面是MainWindow.xaml,这里注释掉App.xaml里 ...
- exe程序嵌入Winform窗体
1.新建winform程序,添加一个Panel控件和一个button控件,winform窗体命名为:Mainform: 2.新建一个类文件,方便引用,命名为:exetowinform: 3.Mainf ...
- Qt界面中嵌入其他exe程序的界面,使用Qt5
下面用一个小例子来演示如何在Qt的界面中嵌入其他exe程序的界面,最终效果如下图所示.本文参考了 http://blog.csdn.net/jiaoyaziyang/article/details/4 ...
- 将你的Asp.NET应用程序嵌入到SharePoint
转:http://www.cnblogs.com/Clank/archive/2007/05/21/754073.html 为什么要将Asp.net应用程序嵌入到SharePoint?这个我们不讨论! ...
- WPF应用程序嵌入第三方exe
把其它应用嵌入到C#窗口 源代码-CSDN下载 https://download.csdn.net/download/aiqinghee/10652732 WPF应用程序嵌入第三方exe - gao2 ...
- 把任意的EXE嵌入到自己程序中
把任意的EXE嵌入到自己程序中 taoyuan19822008-08-24上传 Delphi把任意的EXE嵌入到自己程序中的程序 资源积分:0分 下载次数:327 资源类型:其他 资源大小:175 ...
随机推荐
- Git安装和TortoiseGit详细使用教程【基础篇】
标签:tortoisegit 环境:win8.1 64bit 安装准备: 首先你得安装windows下的git msysgit1.9.5 安装版本控制器客户端tortoisegit tortoise ...
- oracle单词
OEM Blackouts n. 黑朦:灯火管制(blackout的复数)Projection n. 投射:规划:突出:发射:推测premium adj. 高价的:优质的 ############## ...
- 深入理解ASP.NET MVC(3)
系列目录 URL是如何通过路由表生成的(outbound) 通常我们被推荐在view设计时使用Html.ActionLink(…)产生链接,这样做的优势就是,url可以根据路由表生成.路由机制的另一个 ...
- Go thrift使用举例
thrift 最初是 facebook 开发使用的 rpc 通信框架,后来贡献给了 apache 基金会,出来得比较早,几乎支持所有的后端语言,使用非常广泛,是不可不知的一个网络框架. 和 grpc ...
- Zookeeper Ha集群简介+jdbcClient访问Ha集群环境
Hadoop-HA机制HA概述high available(高可用) 所谓HA(high available),即高可用(7*24小时不中断服务). 实现高可用最关键的策略是消除单点故障.HA严格来说 ...
- 记录一次linux删除mysql
service mysqld status service mysqld stop ps –ef | grep mysql perl-DBD-MySQL-4.013-3.el6.x86_64 //删除 ...
- sql日期操作
日期格式化函数 ), ): :57AM ), ): ), ): ), ): ), ): ), ): ), ): ), ): , ), ): :: ), ): :::827AM ), ): ), ): ...
- SPI Flash Memory 芯片手册阅读
SPI Flash Memory 芯片手册阅读 信息来源
- Laravel + go-micro + grpc 实践基于 Zipkin 的分布式链路追踪系统 摘自https://mp.weixin.qq.com/s/JkLMNabnYbod-b4syMB3Hw?
分布式调用链跟踪系统,属于监控系统的一类.系统架构逐步演进时,后期形态往往是一个平台由很多不同的服务.组件构成,用户请求过来后,可能会经过其中多个服务,如图 不过,出问题时往往很难排查,如整个请求变慢 ...
- Docker容器技术的PaaS云平台架构设计***
基于微服务架构和Docker容器技术的PaaS云平台建设目标是给我们的开发人员提供一套服务快速开发.部署.运维管理.持续开发持续集成的流程.平台提供基础设施.中间件.数据服务.云服务器等资源,开发人员 ...