zoukankan      html  css  js  c++  java
  • C# 将MDI窗口嵌入普通窗口

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

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

  • 相关阅读:
    Java_JAVA6动态编译的问题
    Java_动态加载类(英文)
    Java_Java Compiler 应用实例
    Java_关于App class loader的总结
    Java_动态加载
    Java_Java SE6调用动态编译
    python捕获Ctrl+C信号
    python使用协程并发
    python使用多进程
    python使用多线程
  • 原文地址:https://www.cnblogs.com/icyJ/p/SetParent.html
Copyright © 2011-2022 走看看