2011-06-19
以前做一個項目,要求程式啟動的時候主對話框是隐藏的。當時不知道怎麼做,修改視窗風格、視窗類、OnInitDialog裡ShowWindow、Create函數、WM_CREATE消息、PreCreateWindow等等都嘗試了,沒什麼用,相當郁悶。後來有在網上找到一個解決方案,算是解決了當時的燃眉之急,但是我覺得這個方案并不令人滿意,至少我覺得它太複雜了。
下面是網上搜尋到的解決方案:(現在也不知道是出自哪裡了)
//===========================================================
要想使 MFC對話框程式啟動的時候直接隐藏(或者最小化到tray)有如下辦法
1 在OnInitDialog ()中
SetTimer(1,100,null)
在OnTimer(UINT nIDEvent) 中
if( nIDEvent==1)
{
ShowWindow(sw_hide);
KillTimer(1);
}
///這種方法 會出現 程式在顯示器上 閃一下的效果。。即使 timer 時間很短 ,也會有。
2 重載 WM_WINDOWPOSCHANGING
在重載函數内實作:
OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
{
if( !m_bShowWindow)
lpwndpos->flags &= ~SWP_SHOWWINDOW;
CDialog::OnWindowPosChanging(lpwndpos);
// TODO: Add your message handler code here
}
m_bShowWindow 是我的一個變量,初始值為false
// 如果 m_bShowWindow 一直為false ,那麼程式就見不到人了。。
是以應該給 True
在OnInitDialog ()中
SetTimer(1,1000,null)
在OnTimer(UINT nIDEvent) 中
if( nIDEvent==1)
{
m_bShowWindow =true;
KillTimer(1);
}
//使用這種方法 程式不會閃一下。。。
//===========================================================
一個偶然的機會,在研究用什麼方法讓工作列不顯示圖示時終于發現了這個問題的最終應該也是最正确的解決方案。
原來MFC對話框主視窗是在WinApp的InitInstance裡建立的。
建立一個名為OkCancel的MFC對話框程式,預設的theApp.InitInstance代碼是:
COkCancelApp theApp;
BOOL COkCancelApp::InitInstance()
{
...
...
COkCancelDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal(); //使用的是DoModal方法,是以就是為什麼對話框總是顯示了
...
...
}
把以上代碼修改成自建消息循環的代碼:
BOOL COkCancelApp::InitInstance()
{
...
...
COkCancelDlg* pd=new COkCancelDlg;
m_pMainWnd=pd;
pd->Create(IDD_OKCANCEL_DIALOG); //編輯對話框時設定為首次不可見,或者調用ShowWindow(0),但是後者效果不好
MSG msg;
while(::GetMessage(&msg,pd->m_hWnd,0,0)) //GetMessage還有因為錯誤傳回-1的情況,但是這裡暫時不理會這種情況
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
pd->DestroyWindow();
delete pd;
m_pMainWnd=0;
...
...
}
以上的消息循環其實就是标準的Win32程式的消息循環。
但是以上代碼會造成對話框在點關閉後隻是隐藏而不是關閉,那麼就要在對話框類裡需要退出的位置向自己發送WM_QUIT消息,一般可以選擇在OnCancel()函數裡:
void COkCancelDlg::OnCancel()
{
CDialog::OnCancel();
this->PostMessage(WM_QUIT,0,0); //最好放在CDialog::OnCancel()的後面,但是這裡不能由PostQuitMessage代替,不知道為什麼。
}
----------------------------------------------------------------------------------------------------
另外隐藏工作列圖示,像QQ的做法就是建立一個隐藏的視窗,再以它為父視窗建立一個對話框視窗(雖然設定為工具欄風格也可以,但那樣有豬多不爽)。我們的MFC對話框程式可以這麼做:
BOOL COkCancelApp::InitInstance()
{
...
...
CDialog* pd=new CDialog;
pd->Create(IDD_DIALOG1); //IDD_DIALOG1是一個不顯示的對話框資源ID
COkCancelDlg dlg(pd);
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
pd->DestroyWindow();
delete pd;
...
...
}
以上方法其實很簡單的,不知道為什麼在網上找不到資料。