VC++中如何隐藏主对话框?

    技术2022-05-11  27

    以下是在论坛中找到的帖子, 解决了标题中的问题:

      我使用第3种方法解决了问题。

    对话框在初始化的过程上与 SDI MDI 的初始化是不同的,对话框只需要 DoModule 或者是 CreateDialog 等等对话框函数调用一次便可, SDI MDI 则要好几步才行。这样看来,对话框在使用方法上面是隐藏了不少细节的,其中就没有 SDI MDI 所要求的 ShowWindow (nCmdShow) 这一步。因此对话框要想一运行就隐藏,并不是很直接的。有一些方法可以做到这一点,下面我们就来看看几种方案。   1 .定时器 最直观,又是最无奈的一个方法就是使用定时器。既然我们在对话框开始显示之前不能用 ShowWindow(SW_HIDE) 将其隐藏,那就给一个时间让它显示,完了我们在隐藏它。   方法:   1. OnInitDialog() 函数里设置定时器:( WINDOWS API 里面响应消息 WM_INITDIALOG   SetTimer(1, 1, NULL);   2. 添加处理 WM_TIMER 的消息处理函数 OnTimer, 添加代码:   if(nIDEvent == 1)   {   DeleteTimer(1);   ShowWindow(SW_HIDE);   }   这种方法的缺点是显而易见的,使用定时器,使得程序的稳定性似乎打一个折扣;窗口是要先显示出来的,那么效果就是窗口闪了一下消失。   2 .改变对话框显示状况 在对话框初始化时改变其显示属性可以让它隐藏起来。方法是调用 SetWindowPlacement 函数:     BOOL CDialogExDlg::OnInitDialog()   {   CDialog::OnInitDialog();   //DO something     WINDOWPLACEMENT wp;   wp.length=sizeof(WINDOWPLACEMENT);   wp.flags=WPF_RESTORETOMAXIMIZED;   wp.showCmd=SW_HIDE;   SetWindowPlacement(&wp);   return TRUE;   }       在需要显示时(通常是响应热键或者托盘图标的鼠标消息):     WINDOWPLACEMENT wp;   wp.length=sizeof(WINDOWPLACEMENT);   wp.flags=WPF_RESTORETOMAXIMIZED;   wp.showCmd=SW_SHOW;   SetWindowPlacement(&wp);     这样的效果很不理想:窗口显示在屏幕的左上角,并且是只有标题栏,要正常显示,还需加上如下代码:   定义一个成员变量 CRect rect;   OnInitDialog() 里面:   GetWindowRect(&rect);   在需要显示的地方:   SetWindowPos(&wndNoTopMost, wndRc.left, wndRc.top, wndRc.right, wndRc.bottom, SWP_SHOWWINDOW);   CenterWindow();   即使这样,效果还是很差。   这种方法还有一个弊端是当程序开始运行并且隐藏起来后,原来激活的窗口变成了非激活状态了,而当对话框显示出来后,对话框自身也是非激活状态的。     3 .不绘制窗口 当对话框显示时将要响应消息 WM_PAINT 绘制客户区,相应消息 WM_NCPAINT 绘制窗口边框。我们在窗口第一次自绘自身时隐藏窗口,可以收到比较良好的效果。由于窗口是先画窗口边框,所以我们仅需处理 WM_NCPAINT 即可。代码如下:   添加 WM_NCPAINT 处理函数。   void CMyDialog::OnNcPaint()   {   static int i = 2;   if(i > 0)   {   i --;   ShowWindow(SW_HIDE);   }   else   CDialog::OnNcPaint();   }   这里有个问题:为什么要定义静态变量 i 而且设其值为 2 呢?   我们只要窗口隐藏第一次,所以定义这个变量可以判断是否时首次显示窗口。当程序开始运行时,系统发送( SendMessage WM_NCPAINT 消息,此时程序的窗口边框应该被显示,但是此时我们没有作任何显示的操作,而是将窗口隐藏, ShowWindow(SW_HIDE) 将把窗口的 WS_VISIBLE 属性去掉,继续执行,程序将检查 WS_VISIBLE 属性,如果没有则显示窗口,所以又发送了一个 WM_NCPAINT 消息。所以我们要处理两次 WM_NCPAINT 消息。   在需要窗口显示时,调用 ShowWindow(SW_SHOW) 即可。   程序执行的结果是,原来处于激活状态的窗口可能会闪动两下,然后仍然处于激活状态。这种处理方式比上面的方式要优越得多。     4 .将对话框作为子窗口 这种方法是采用 SDI 框架,主窗口始终隐藏,对话框作为主窗口的成员变量,在 CMainFrame::OnCreate() 里面加入下代码:   if(!dlg.Create(IDD_MYDIALOG, this))   {   return –1;   }   dlg.ShowWindow(SW_HIDE);   在要显示对话框的地方用 dlg.ShowWindow(SW_SHOW); 即可。注意,主窗口一定要隐藏,否则对话框可能会闪现一下。   隐藏状态栏窗口 上面介绍了几种检查对话框的方法,大家如果试过的话可能已经注意到系统状态栏里在程序启动时会有程序的图标闪过,在隐藏对话框的时候这个也是要隐藏的,方法很简单:   OnInitDialog() 函数里面加上 ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW); 即可。在要显示窗口的地方加上代码 ModifyStyleEx(WS_EX_TOOLWINDOW, WS_EX_APPWINDOW); 即将窗口的扩展样式改回来。  

     


    最新回复(0)