模块化的开发,将模块合并到一起的时候,遇到了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的用法的更多相关文章

  1. C#自定义控件:WinForm将其它应用程序窗体嵌入自己内部【转载】

    这是最近在做的一个项目中提到的需求,把一个现有的窗体应用程序界面嵌入到自己开发的窗体中来,看起来就像自己开发的一样(实际上……跟自己开发的还是有一点点区别的,就是内嵌程序和宿主程序的窗口激活状态问题) ...

  2. 【转】C#自定义控件:WinForm将其它应用程序窗体嵌入自己内部

    PS:文末的附件已更新,这次我放到博客园里面了,不会弹出广告,放心下载,O(∩_∩)O谢谢! 这是最近在做的一个项目中提到的需求,把一个现有的窗体应用程序界面嵌入到自己开发的窗体中来,看起来就像自己开 ...

  3. 外部exe窗体嵌入winform

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; u ...

  4. Qt 子窗体嵌入父窗体

    1.创建个子窗体QDialog.在子窗体构造函数添加 Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { u ...

  5. WinForm窗体嵌入

    一.在winform窗体上添加两个控件 1.容器>Panel 2.添加 SideBar.dll (下载链接:http://pan.baidu.com/s/1o6qhf9w) (1)将SideBa ...

  6. c#winform窗体嵌入

    最近开发项目,错误的理解了需求,自己做了个窗体的嵌套,虽然是错误的理解了,但是功能还是实现了,做下标记,需要时可以拿来看看. 新建两个窗体Form1和Form2,现在需要将Form2显示到Form1里 ...

  7. [转载] iframe嵌入网页的用法

    iframe并不是很常用的,在标准的网页中非常少用.但是有朋友经常问到,下面我简单地介绍一下它的用法,你只要熟练掌握这些参数足矣. <iframe>也应该是框架的一种形式,它与<fr ...

  8. C# Winform WPF DeskBand 窗体嵌入任务栏,在任务栏显示文字

    最近写了个小程序,用于将固态硬盘的写入量等信息显示在任务栏,最开始使用Windows API也可以实现,但是当任务栏托盘增加的时候,会被遮盖,最终采用了DeskBand来实现,填了很多坑. 参考的Gi ...

  9. 把一个窗体嵌入到WinForm中进行显示,以CMD窗口为例

    1.添加引用 using System.Runtime.InteropServices; 2. 加入以下代码段 [DllImport("User32.dll ", EntryPoi ...

随机推荐

  1. 数学 它的内容,方法和意义 第三卷 (A. D. 亚历山大洛夫 著)

    第十五章 实变数函数论 1. 绪论 2. 集合论 3. 实数 4. 点集 5. 集合的测度 6. 勒贝格积分 第十六章 线性代数 1. 线性代数的对象和它的工具 2. 线性空间 3. 线性方程组 4. ...

  2. AssemblyVersion和AssemblyFileVersion的区别

    简而言之,AssemblyVersion: 是程序集的版本,.NET的CLR用,用于标识出该dll的版本信息,用于定义强名称的版本号: AssemblyFileVersion: 为编译器生成的文件加入 ...

  3. mvn+spring+webapp模板

    idea新建项目,选择maven-archetype-webapp 在main目录下创建java  resource 文件夹,赋予特殊文件夹 pom.xml 添加 <!--Spring框架核心库 ...

  4. redux 知识点

    redux原理:store中维护了一个state,我们dispatch一个action,接下来reducer根据这个action更新state. react-redux提供两个关键模块:Provide ...

  5. 外观模式face

    5.1 模式优点       外观模式的主要优点如下: (1) 它对客户端屏蔽了子系统组件,减少了客户端所需处理的对象数目,并使得子系统使用起来更加容易.通过引入外观模式,客户端代码将变得很简单,与之 ...

  6. mysql5.5 for linux 安装(转)

    下载地址: http://dev.mysql.com/downloads/mysql/5.5.html#downloads 进入后会有选择系统 选择linux-generic后 又有很多产品选择,我们 ...

  7. c++ 函数中的部分代码执行一次

    编程时有时需要将一段代码中的某一块只执行一次: #include<iostream> using namespace std; int fun1(int a) { static bool ...

  8. ElasticSearch停止启动

    1.查找ES进程 ps -ef | grep elastic 2.杀掉ES进程 kill -9 2382(进程号) 3.重启ES sh elasticsearch -d 注意:elasticsearc ...

  9. USB引脚定义

  10. CentOS7安装部署zabbix3.4操作记录

    CentOS7安装部署zabbix3.4操作记录 1.安装前准备 1.1 查看centos的系统版本 [root@zabbix ~]# cat /etc/redhat-release CentOS L ...