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

  • 相关阅读:
    css中单位的使用
    css中max-width和min-width的应用
    css-样式初始化
    html中map标签和area标签的应用
    html中常见的小问题(1)
    防止图片被盗用
    关于thinkphp的__construct和_initialize
    禁用cookie后如何使用session还有session_id的使用
    is_null(self::$_instance) && self::$_instance = new self();
    echo、print、print_r、printf、sprintf、var_dump的区别
  • 原文地址:https://www.cnblogs.com/icyJ/p/SetParent.html
Copyright © 2011-2022 走看看