MFC怎樣編寫後台啟動並執行程式 (這個值得一看) 續。。。

來源:互聯網
上載者:User

第一篇連結:http://blog.csdn.net/jax_lee/article/details/6771580

但是我覺得這個更加直接,更加一目瞭然。。

作者:A   Kun   (a_kun@etang.com)

           有很多應用程式要求一起動就隱藏起來,這些程式多作為背景程式運行,希望不影響其他視窗,  
   
  往往只在托盤區顯示一個表徵圖。這些程式通常都是對話方塊程式,而對話方塊在初始化的過程上與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);即將視窗的擴
  展樣式改回來。   
  以上是我的一點經驗總結,有錯誤或不完善的地方還望大家提出指正。歡迎大家與我聯絡。  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.