模块化的开发,将模块合并到一起的时候,遇到了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(, );
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 = -;
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的文字时,光标的位置,总是不正常。能力有限,尚待解决。

转载注明出处:http://www.cnblogs.com/icyJ

C# 将MDI窗口嵌入普通窗口的更多相关文章

  1. 窗口嵌入到另一个窗口(VC和QT都有)

    1.用vc新建一个dialog1工程.属性默认. 2.insert一个dialog2,改为child. 3.在dialog1中包含dialog2头文件,在一个按钮事件中显示dialog2: Cdial ...

  2. 2015.12.14 MDI(多文档窗口结构)设置基本解决,折腾一天,部分解决存在已久的问题。但效果仍不如临时航线的MDI窗体结构。

    创建从一个窗口弹出多个子窗口的结构叫MDI窗体结构 如果不按MDI结构管理,最简单的做法是: 在窗体A上添加菜单或按钮,在菜单或按钮事件中添加弹出B窗体代码: B b = new B(); b.sho ...

  3. 使用MDI窗体实现多窗口效果

    本文章已收录于:   C#MDI窗体实现多窗口效果   Visual C#是微软公司推出的下一代主流程序开发语言,他也是一种功能十分强大的程 序设计语言,正在受到越来越多的编程人员的喜欢.在Visua ...

  4. (转)source insight 窗口嵌入

    昨天用了一下source insight ,都说很强大,也有感觉,但是这个强大的东西往往不是那么容易弄清楚的,或者一下子就好上手的,工具强大,功能复杂多样,一开始不知道怎么入手,以后慢慢来吧,学习是要 ...

  5. 2019-8-15C#MDI窗体实现多窗口效果

    C#MDI窗体实现多窗口效果  Visual C#是微软公司推出的下一代主流程序开发语言,他也是一种功能十分强大的程序设计语言,正在受到越来越多的编程人员的喜欢.在Visual C#中,提供了为实现M ...

  6. MFC单文档视图中嵌入GLFW窗口

    开始学习OpenGL由于有一段时间,但是glfw只有窗口区,虽然通过某种手段(移步这里)可以加入工具栏,但仍然无法作为一个标准的GUI,而直接在MFC或Qt里面使用OpenGL API感觉有诸多制肘, ...

  7. Qt 的MDI 多文档窗口

    一.MDI简介 MDI就是多文档界面(Multi-document Interface,MDI)应用程序 MDI就是在主窗口里创建多个同类型的MDI子窗口,这些MDI子窗口在主窗口里显示,并共享主窗口 ...

  8. windows窗口分析,父窗口,子窗口,所有者窗口

    (本文尝试通过一些简单的实验,来分析Windows的窗口机制,并对微软的设计理由进行一定的猜测,需要读者具备C++.Windows编程及MFC经验,还得有一定动手能力.文中可能出现一些术语不统一的现象 ...

  9. MFC子窗口和父窗口

    转载声明: 本文转载自:http://www.cnblogs.com/BeyondTechnology/archive/2011/03/25/1995934.html 感谢BeyondTechnolo ...

随机推荐

  1. 简单示例:Spring4 整合 单个Redis服务

    1. 引入spring-data-redis.jar API:https://docs.spring.io/spring-data/redis/docs/current/api/org/springf ...

  2. 关于thymeleaf+layout布局的使用方式,spring boot 访问页面(静态页面及jsp页面)

    首先建立相同部分的html,这里我命名为layout.html,放在了`templates/layout'文件夹下,这个路径以后是会用到的,以下是我的layout的代码,比较粗糙. 但是应该会更好的帮 ...

  3. Hadoop创建/删除文件夹出错

    log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFact ...

  4. SaaS多租户模式数据存储方案

    云计算多租户几乎用于所有软件即服务 (Software as a Service, SaaS) 应用程序,因为计算资源是可伸缩的,而且这些资源的分配由实际使用决定.话虽如此,用户可以通过 Intern ...

  5. jQuery学习笔记(Ajax)

    jQuery对Ajax操作进行了封装,在jQuery中$.ajax方法属于最底层的方法,第2层是$.load().$.get().$.post()方法,第3层是$.getScript()和$.getJ ...

  6. Android基础知识之Manifest中的Intent-filter元素

    原文:http://android.eoe.cn/topic/android_sdk :指定活动.服务.或者广播接收者能支持的intent的类型.一个意图过滤器声明了其父组件的能力——一个活动或者服务 ...

  7. eclipse CDT写c++使用文件作为输入源(输入重定向)

    在main函数第一句添加下面. freopen("inputfile","r",stdin); 创建一个inputfile,放project根文件夹下. 注意添 ...

  8. [svc][op]磁盘(结构)容量计算

    磁盘结构和容量计算 fdisk -l显示信息详解 [root@www.linuxidc.com ~]# fdisk -l Disk /dev/sda: bytes heads, sectors/tra ...

  9. FFmpeg(14)-使用NDK、C++完成EGL,display, surface, context的配置和初始化

     EGL 用它开发需要做哪些事情. DIsplay 与原生窗口建立链接.EGL在Android中可以用java调,也可以用C++调. EGLDisplay eglGetDisplay          ...

  10. Virtual Memory$$memory-mapped-files

    Virtual Memory http://csapp.cs.cmu.edu/2e/ch9-preview.pdf https://howtodoinjava.com/java-7/nio/java- ...