精华内容
下载资源
问答
  • MDI窗口

    2007-12-14 19:19:07
    祥解演示多窗口程序源码 C#
  • 易语言MDI窗口源码

    2020-07-22 10:39:46
    易语言MDI窗口源码,MDI窗口,MDI窗口函数回调子程序,子窗口函数回调子程序,取当前活动窗口句柄子程序,执行整数型子程序,执行逻辑型型子程序,创建MDI客户区,创建MDI子窗口,设置为子窗口,MDI客户区移动,取MDI客户区尺寸...
  • MDI窗口案例

    2018-07-27 12:49:51
    本程序使用了MDI窗口,通过简单的例子可以使PB初学者快速学会MID窗体的使用,另外里面涉及了自定义按钮的案例,窗口居中的案例
  • 易语言仿MDI窗口源码

    2020-07-23 21:53:21
    易语言仿MDI窗口源码,仿MDI窗口,初始化,新建子窗口,SetWindowLongA,SetWindowTextA
  • 易语言创建MDI窗口

    2018-01-31 18:50:21
    易语言创建MDI窗口,便于在制作SHE内存皮肤时验证在MDI创建下得到的皮肤效果
  • 易语言MDI窗口源码
  • 易语言仿MDI窗口源码.rar
  • 梦优勿扰的MDI窗口支持库
  • 本文主要介绍了如何让窗口和 MDI窗口一启动就最大化和最小化
  • 易语言源码易语言MDI窗口源码.rar
  • 易语言仿MDI窗口源码
  • 云外归鸟的MDI窗口支持库
  • Dll调用MDI窗口.rar

    2019-06-12 11:01:53
    Dll调用MDI窗口.rar
  • 易语言源码易语言仿MDI窗口源码.rar
  • 创建MDI窗口

    2015-06-02 20:54:38
    MDI窗口包含一个框架窗口和若干子窗口。 实际上,框架窗口本身是一个普通主窗口,不过它的客户去被一个特殊窗口覆盖。 这个特殊窗口是系统预定义的“窗口类”,类名称为:"MDICLIENT"。它负责各个MDI子窗口的管理...

    一、概述
    MDI窗口包含一个框架窗口和若干子窗口。
    实际上,框架窗口本身是一个普通主窗口,不过它的客户去被一个特殊窗口覆盖。
    这个特殊窗口是系统预定义的“窗口类”,类名称为:"MDICLIENT"。它负责各个MDI子窗口的管理。


     二、窗口建立
    1.注册一个MDI框架窗口类,提供MDI框架窗口消息处理函数
    MDI框架窗口消息处理函数中,将未处理消息交由DefFrameProc处理

    //MDI框架窗口消息处理函数
    LRESULT CALLBACK MDIFrameWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
     //...
     
     //其他消息交给由系统提供的缺省框架处理函数DefFrameProc
     //其中,第二个参数是客户区窗口句柄
     return ::DefFrameProc (hwnd,hwndClient, message, wParam, lParam) ;
    }

    2.注册多个MDI子窗口类、对应提供各MDI子窗口的消息处理函数
    子窗口消息处理函数中,将未处理消息交由MDIDefMDIChildProc处理

    //MDI子窗口消息处理函数
    LRESULT CALLBACK MDIChildWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
     //...
     //...
     
     //其他消息交给由系统提供的缺省MDI子窗口处理函数
     return ::DefMDIChildProc (hwnd, message, wParam, lParam) ;
    }
    

    3.在框架窗口的客户区建立MDI管理子窗口
    MDI子窗口的管理实际上是由框架窗口客户区的"MDILIENT"窗口完成的。
    这是一个系统预定义的窗口。

    在主窗口收到WM_CREATE消息后:

    case WM_CREATE:
    {
     hinst=((LPCREATESTRUCT) lParam)->hInstance;
       
     //填充CLIENTCREATESTRUCT结构
     CLIENTCREATESTRUCT clientcreate ;
     clientcreate.hWindowMenu  = hMenuInitWindow ;   //用于添加窗口列表的菜单句柄
     clientcreate.idFirstChild = 50000 ; //起始ID
    
     hwndClient =CreateWindowEx(0,
      "MDICLIENT", //类名称为"MDICLIENT"
      NULL,
      WS_CHILD |WS_CLIPCHILDREN| WS_VISIBLE,
      0,
      0,
      0,
      0,
      hwnd,
      (HMENU)1,//ID
      hinst, //实例句柄
      &clientcreate); //参数
    }
    return 0;

    窗口的大小没有关系,缺省的框架窗口消息处理函数为让它覆盖整个客户区。 
    MDI客户区窗口建立后,通过向它发送消息管理子窗口的建立、销毁、排列等等。


    4.MDI子窗口的建立
    可以在菜单中添加命令项,以建立子窗口。
    框架窗口的消息处理函数收到命令后,向MDI客户区窗口发建立命令。

    case ID_NEW:
    {
     MDICREATESTRUCT mdicreate;
     mdicreate.szClass = szMDIChildName ; //MDI子窗口的类名称
     mdicreate.szTitle = TEXT ("Hello") ;
     mdicreate.hOwner  = hinst ;
     mdicreate.x       = CW_USEDEFAULT ;
     mdicreate.y       = CW_USEDEFAULT ;
     mdicreate.cx      = CW_USEDEFAULT ;
     mdicreate.cy      = CW_USEDEFAULT ;
     mdicreate.style   = 0 ;
     mdicreate.lParam  = 0 ;
     SendMessage (
      hwndClient, //MDI客户区窗口句柄
      WM_MDICREATE, //创建MDI子窗口
      0,
      (LPARAM) (LPMDICREATESTRUCT) &mdicreate //创建参数
      ) ;
    
    }
    break;

     三、消息循环中处理针对MDI的热键
    在消息循环中,用TranslateMDISysAccel处理针对MDI的热键。

    while (GetMessage (&msg, NULL, 0, 0))
    {
         if (!TranslateMDISysAccel (hwndClient, &msg) &&
             !TranslateAccelerator (hwndFrame, hAccel, &msg))
         {
              TranslateMessage (&msg) ;
              DispatchMessage (&msg) ;
         }
    }

     四、命令的流向
    框架窗口在收到WM_COMMAND等通知消息后,应该给当前激活的MDI窗口提供处理机会。

    case WM_COMMAND:
    switch (LOWORD (wParam))
    {
     //针对框架的命令
     case ID_ONE:  
      //...
      return 0;
     //针对MDI子窗口管理的命令  
     case IDM_WINDOW_TILE: 
      SendMessage (hwndClient, WM_MDITILE, 0, 0) ;
      return 0 ;
     
     //针对子窗口的命令又子窗口去处理               
     default:
      hwndChild = (HWND) SendMessage (hwndClient,
                                                   WM_MDIGETACTIVE, 0, 0) ;
      if (IsWindow (hwndChild))
       SendMessage (hwndChild, WM_COMMAND, wParam, lParam) ;
                   
                   break ;        //..and then to DefFrameProc
    }
    break ;  //跳出针对WM_COMMAND的case分支,又DefFrameProc处理剩下的命令

     五、子窗口的管理
    1.概述
    给MDI客户区窗口发控制消息即可
    如:

    case WM_COMMAND:
    switch (LOWORD (wParam))
    {
     case IDM_WINDOW_TILE:
      SendMessage (hwndClient, WM_MDITILE, 0, 0) ;
      return 0 ;
                   
     case IDM_WINDOW_CASCADE:
      SendMessage (hwndClient, WM_MDICASCADE, 0, 0) ;
      return 0 ;
                   
     case IDM_WINDOW_ARRANGE:
      SendMessage (hwndClient, WM_MDIICONARRANGE, 0, 0) ;   
      return 0;
                   
            //...
            //...
    }
    break;

    2.当前子窗口的关闭
    关闭当前激活窗口时,先向该窗口发送查询消息:WM_QUERYENDSESSION。
    子窗口的消息处理循环中响应此消息,作关闭前的一些处理,若能关闭,返回真
    否则返回假。
    框架窗口中根据此返回值决定是否关闭窗口。

    如果用户直接按下子窗口的关闭按钮,则WM_CLOSE消息直接发送到了子窗口消息处理函数。

    例如:
    框架窗口命令处理中:

    case IDM_FILE_CLOSE:          
    //获得当前激活窗口
    hwndChild = (HWND) SendMessage (hwndClient, WM_MDIGETACTIVE, 0, 0);
    //询问通过后,销毁窗口
    if (SendMessage (hwndChild, WM_QUERYENDSESSION, 0, 0))
         SendMessage (hwndClient, WM_MDIDESTROY, (WPARAM) hwndChild, 0);
    return 0;

    子窗口的消息处理函数中:

    LRESULT CALLBACK HelloWndProc (HWND hwnd, UINT message, 
                                   WPARAM wParam, LPARAM lParam)
    {
         switch (message)
         {
     //...
     //...
    
         case WM_QUERYENDSESSION:
         case WM_CLOSE:
              if (IDOK != MessageBox (hwnd, TEXT ("OK to close window?"),
                                      TEXT ("Hello"), 
                                      MB_ICONQUESTION | MB_OKCANCEL))
                   return 0 ;
                   
              break ;   // i.e., call DefMDIChildProc
         }
         return DefMDIChildProc (hwnd, message, wParam, lParam) ;
    }

    3.关闭所有子窗口
    当使用命令方式关闭所有子窗口时,需要枚举所有子窗口进行关闭。
    例:
    框架窗口响应命令:

    case IDM_WINDOW_CLOSEALL:    
     //针对所有子窗口执行CloseEnumProc
     EnumChildWindows (hwndClient, CloseEnumProc, 0) ;
     return 0 ;

    枚举函数:

    BOOL CALLBACK CloseEnumProc (HWND hwnd, LPARAM lParam)
    {
         if (GetWindow (hwnd, GW_OWNER))         // Check for icon title
              return TRUE ;
         
         SendMessage (GetParent (hwnd), WM_MDIRESTORE, (WPARAM) hwnd, 0) ;
         
         if (!SendMessage (hwnd, WM_QUERYENDSESSION, 0, 0))
              return TRUE ;
         
         SendMessage (GetParent (hwnd), WM_MDIDESTROY, (WPARAM) hwnd, 0) ;
         return TRUE ;
    }

     六、菜单控制
    在MDI程序中,可以根据激活的子窗口而切换框架窗口的菜单。
    并且,可以将窗口列表添加到菜单中去。所添加的菜单项命令是又框架对应的缺省消息处理函数完成的。
    1.为每种窗口类准备一套菜单资源
    2.装载菜单,得到菜单句柄
    3.框架在建立时,使用框架菜单的句柄作为参数。
    4.子窗口在激活时,加载自己菜单到框架窗口
    失去焦点时,还原框架菜单。
    使用向MDI客户区窗口发送WM_MDISETMENU或WM_MDISETMENU消息。
    wParam为菜单句柄,lParam为欲添加窗口列表的子菜单句柄

    case WM_MDIACTIVATE:
             //激活时,设置框架菜单
             if (lParam == (LPARAM) hwnd)
                   SendMessage (hwndClient, WM_MDISETMENU,
                                (WPARAM) hMenuHello, (LPARAM) hMenuHelloWindow) ;
                   
                   
              //失去焦点时,将框架菜单还原
             if (lParam != (LPARAM) hwnd)
                   SendMessage (hwndClient, WM_MDISETMENU, (WPARAM) hMenuInit,
                                (LPARAM) hMenuInitWindow) ;
                   
              DrawMenuBar (hwndFrame) ;
              
              //注: hwndFrame的得到方法:
              //hwndClient = GetParent (hwnd) ;
              //hwndFrame  = GetParent (hwndClient) ;
              
              return 0 ;
    展开全文
  • 用dll实现MDI窗口

    2012-04-28 10:00:52
    用dll实现MDI窗口
  • visual c++制作界面漂亮的MDI窗口.zip
  • MDI窗口加上背景色

    2012-06-08 10:35:55
    MDI窗口加上背景色,背景图片的描画,参看pfnNewWndProc
  • C# 将MDI窗口嵌入普通窗口 模块化的开发,将模块合并到一起的时候,遇到了Mdi不能添加到其它窗口下的问题。 分两种情况: 将mdi窗口A设成普通窗口B的子控件,需要将A的TopLevel设置成false,但是Mdi窗口...

    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

    Top
    推荐
    收藏
    关注
    评论
    分类:  开发 - .NET/C#
    标签:  c#setparentmdi
    0
    « 上一篇: c# 自动计算字符串的宽度
    » 下一篇: .net 循环引用是否会造成内存泄漏
    展开全文
  • FLEX- MDI窗口开发实例

    2015-07-24 21:20:47
    FLEX- MDI窗口开发实例
  • MDI窗口管理的动态窗口排列?怎么将窗口排列成层叠、平铺和分割这些效果?
  • vs.net风格的MDI窗口.rar

    2011-06-15 10:12:58
    vs.net风格的MDI窗口.rar vs.net风格的MDI窗口.rar vs.net风格的MDI窗口.rar
  • MDI窗口列表管理器的窗口操作,怎么根据用户选择的窗口结束对应执行这个窗口的程序呢?
  • MDI窗口的菜单怎么把文档的菜单放在MDI的子窗口上?怎么让主窗口和子窗口的菜单条分开显示?
  • PBMDI窗口添加控件后,打开窗户后,会被主窗口控件覆盖,使得子窗口显示存在问题。很好的解决PB的mdi窗口添加控件不能显示窗口的问题(PB9.03和PB11.5都验证通过)
  • MDI窗口的创建

    2020-01-01 17:50:12
    创建MDI窗口,将Form中的属性IsMdiContainer=True 接收键盘的按键值: KeyPreview= Ture 窗体大小不自动缩放: AutoScaleMoce=None 调用子窗体: Form2 form2 = new Form2(); form2.FormBorderStyle = ...

    创建MDI窗口,将Form中的属性IsMdiContainer=True

    接收键盘的按键值:
    KeyPreview= Ture

    窗体大小不自动缩放:
    AutoScaleMoce=None

    调用子窗体:

                Form2 form2 = new Form2();
                form2.FormBorderStyle = FormBorderStyle.None;//无边框
                form2.MdiParent = this;//父窗体
                form2.Dock = DockStyle.Fill;//最大化
                form2.Show();//显示窗体
    
    展开全文
  • MDI窗口的背景图片

    2008-05-10 09:05:35
    MDI窗口的背景图片
  • .net WPF实现MDI窗口效果示例
  • 本文将通过一个真实的示例向您展示如何使WTL的MDI窗口成为ATL控件。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 13,874
精华内容 5,549
关键字:

mdi窗口