mfc对话框隐藏的几种方法

31 篇文章 1 订阅
对话框隐藏的几种方法 
作者:A Kun (a_kun@etang.com) 
有很多应用程序要求一起动就隐藏起来,这些程序多作为后台程序运行,希望不影响其他窗口, 

往往只在托盘区显示一个图标。这些程序通常都是对话框程序,而对话框在初始化的过程上与SDI 

、MDI的初始化是不同的,对话框只需要DoModule或者是CreateDialog等等对话框函数调用一次便 

可,SDI、MDI则要好几步才行。这样看来,对话框在使用方法上面是隐藏了不少细节的,其中就 

没有SDI、MDI所要求的ShowWindow(nCmdShow)这一步。因此对话框要想一运行就隐藏,并不是很 

直接的。有一些方法可以做到这一点,下面我们就来看看几种方案。 

1.定时器 
最直观,又是最无奈的一个方法就是使用定时器。既然我们在对话框开始显示之前不能用ShowWin 

dow(SW_HIDE)将其隐藏,那就给一个时间让它显示,完了我们在隐藏它。 

方法: 

1.在On InitDialog()函数里设置定时器:(WINDOWS API里面响应消息WM_INITDIALOG) 

SetTimer(1, 1, NULL); 

2.添加处理WM_TIMER的消息处理函数On Timer,添加代码: 

if(nIDEvent == 1) 



DeleteTimer(1); 

ShowWindow(SW_HIDE); 



这种方法的缺点是显而易见的,使用定时器,使得程序的稳定性似乎打一个折扣;窗口是要先显 

示出来的,那么效果就是窗口闪了一下消失。 

2.改变对话框显示状况 
在对话框初始化时改变其显示属性可以让它隐藏起来。方法是调用SetWindowPlacement函数: 


BOOL CDialogExDlg::On InitDialog() 



CDialog::On InitDialog(); 

//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; 

在On InitDialog()里面: 

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::On NcPaint() 



static int i = 2; 

if(i > 0) 



i --; 

ShowWindow(SW_HIDE); 



else 

CDialog::On NcPaint(); 



这里有个问题:为什么要定义静态变量i而且设其值为2呢? 

我们只要窗口隐藏第一次,所以定义这个变量可以判断是否时首次显示窗口。当程序开始运行时 

,系统发送(SendMessage)WM_NCPAINT消息,此时程序的窗口边框应该被显示,但是此时我们没 

有作任何显示的操作,而是将窗口隐藏,ShowWindow(SW_HIDE)将把窗口的WS_VISIBLE属性去掉, 

继续执行,程序将检查WS_VISIBLE属性,如果没有则显示窗口,所以又发送了一个WM_NCPAINT消 

息。所以我们要处理两次WM_NCPAINT消息。 

在需要窗口显示时,调用ShowWindow(SW_SHOW)即可。 

程序执行的结果是,原来处于激活状态的窗口可能会闪动两下,然后仍然处于激活状态。这种处 

理方式比上面的方式要优越得多。 


4.将对话框作为子窗口 
这种方法是采用SDI框架,主窗口始终隐藏,对话框作为主窗口的成员变量,在CMainFrame::On Cr 

eate()里面加入下代码: 

if(!dlg.Create(IDD_MYDIALOG, this)) 



return –1; 



dlg.ShowWindow(SW_HIDE); 

在要显示对话框的地方用dlg.ShowWindow(SW_SHOW);即可。注意,主窗口一定要隐藏,否则对话 

框可能会闪现一下。 

隐藏状态栏窗口 
上面介绍了几种检查对话框的方法,大家如果试过的话可能已经注意到系统状态栏里在程序启动 

时会有程序的图标闪过,在隐藏对话框的时候这个也是要隐藏的,方法很简单: 

在On InitDialog()函数里面加上ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW);即可。在 

要显示窗口的地方加上代码ModifyStyleEx(WS_EX_TOOLWINDOW, WS_EX_APPWINDOW);即将窗口的扩 

展样式改回来。这句话写在ShowWindow(SW_SHOW)之前,否则不管用。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值