VC创建启动即隐藏的对话框(转)

来源:互联网 发布:美国枪击案与网络恶搞 编辑:程序博客网 时间:2024/05/01 14:37
 
VC创建启动即隐藏的对话框(转)
2011-08-19 11:29
有很多应用程序要求一起动就隐藏起来,这些程序多作为后台程序运行,希望不影响其他 窗口,往往只在托盘区显示一个图标。这些程序通常都是对话框程序,而对话框在初始化的过程上与SDI、MDI的初始化是不同的,对话框只需要 DoModule或者是CreateDialog等等对话框函数调用一次便可,SDI、MDI则要好几步才行。这样看来,对话框在使用方法上面是隐藏了不 少细节的,其中就没有SDI、MDI所要求的ShowWindow(nCmdShow)这一步。因此对话框要想一运行就隐藏,并不是很直接的。有一些方法 可以做到这一点,下面我们就来看看几种方案。
  1.定时器
  最直观,又是最无奈的一个方法就是使用定时器。既然我们在对话框开始显示之前不 能用ShowWindow(SW_HIDE)将其隐藏,那就给一个时间让它显示,完了我们在隐藏它。
  方法:
  1.在OnInitDialog()函数里设置定时器:(WINDOWS API里面响应消息WM_IN99vDIALOG)
  SetTimer(11, 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(
%26;amp;wp);
  
return TRUE;
  }


  在需要显示时(通常是响应热键或者托盘图标的鼠标消息):


 

  WINDOWPLACEMENT wp;
   wp.length
=sizeof(WINDOWPLACEMENT);
   wp.flags
=WPF_RESTORETOMAXIMIZED;
   wp.showCmd
=SW_SHOW;
   SetWindowPlacement(
%26;amp;wp);


  这样的效果很不理想:窗口显示在屏幕的左上角,并且是只有标题栏,要正常显示, 还需加上如下代码:
  定义一个成员变量CRect rect;
  在OnInitDialog()里面:
  GetWindowRect(%26;amp;rect);


  在需要显示的地方:


 

  SetWindowPos(%26;amp;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);即将窗口的扩展样式改回来。
  以上各种方法转自网络。我自己实验了下觉得下面的方法还不错
  在OnInitDialog()里填下下面几句话


 

  //隐藏界面
  MoveWindow(0,0,0,0);
   ShowWindow(SW_HIDE);
   ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW);