MFC隱藏主視窗的方法
隱藏基於對話方塊的MFC應用程式視窗的方法
(推薦這個方法,非常好用)
很多人可能會將視窗創建出來,然後用一個 ShowWindow(SW_HIDE) 的方法去隱藏視窗,當然這是可以做到隱藏的功能,但是有一點不足的地方就是視窗在隱藏之前會有一下短瞬的閃爍,而以下這種方法可以解決這種問題:
在 C***App::InitInstance() 的函式中將以下的這一段註釋掉:
C***Dlg dlg; m_pMainWnd = &dlg; int nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: Place code here to handle when the dialog is // dismissed with OK } else if (nResponse == IDCANCEL) { // TODO: Place code here to handle when the dialog is // dismissed with Cancel } // Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump. return FALSE;
換成:
C***Dlg *dlg = new C***Dlg; m_pMainWnd = dlg; return dlg->Create(IDD_***_DIALOG);
同時將 IDD_***_DIALOG 的對話方塊資源的 "More Stytles" 屬性頁的 Visible 屬性的勾去掉即可。這是我認為最簡單的一種方法,還有另外一種方法,就是在工作區的資源選單中插入一個新的對話方塊,然後用 ClassWizard 新建一個與之對應的類, 而下面
C***Dlg *dlg = new C***Dlg; m_pMainWnd = dlg; return dlg->Create(IDD_***_DIALOG);
這裡的C***Dlg和IDD_***_DIALOG改為與你新建的對話方塊的對應即可,方法的原理與上面的一樣,只是麻煩了一點點而已.
隱藏基於單文件的MFC應用程式視窗的方法
1) 最簡單的方法是從網上的找到的,可行,好用
CMainFrame::ActiveFrame() { nCmdShow= SW_HIDE; CFrameWnd::ActivateFrame(nCmdShow); } C??App::Initstance() { m_pMainWnd->ShowWindow(SW_HIDE); //UpdateWindow(); }
因為 MFC 有兩個步驟來顯示 SDI 主視窗, 所有必須在這兩個地方都 SW_HIDE, 否則就會閃動。即便 HWND 沒有 WS_VISIBLE 屬性, 用ShowWindow(SW_SHOW) 還是可以顯示該 HWND 的, 所以vcbear的方法有問題。這裡的ActiveFrame函式可以在ClassWizard中新增.
2)第二種方法則相對繁瑣得多
第一步,將CMainFrame的建構函式改為public屬性(預設是protected的)
第二步,將C***App::InitInstance()裡面的下面程式碼註釋掉:
CSingleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CTestHideDoc), RUNTIME_CLASS(CMainFrame), // main SDI frame window RUNTIME_CLASS(CTestHideView)); AddDocTemplate(pDocTemplate); // Parse command line for standard shell commands, DDE, file open CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); // Dispatch commands specified on the command line if (!ProcessShellCommand(cmdInfo)) return FALSE; // The one and only window has been initialized, so show and update it. m_pMainWnd->ShowWindow(SW_SHOW); m_pMainWnd->UpdateWindow();
換成以下的程式碼:
m_pMainWnd = new CMainFrame(); BOOL bRet = ((CMainFrame *)m_pMainWnd)->LoadFrame(IDR_MAINFRAME); if (bRet) { m_pMainWnd->UpdateWindow(); } else { if (m_pMainWnd) { delete m_pMainWnd; m_pMainWnd = NULL; } }
這樣子編繹出來的程式執行時便不會有主視窗。
縱觀上面的隱藏視窗的方法,除了使用ShowWIndow(SW_HIDE)的方法之外,其實都是將程式中m_pMainWnd指標換一下面目,原來是正常顯示的,就改為不顯示,或者用其它的對話方塊或者自身新建一個不同類別的框架指標.
我一開始的疑惑是既然C***App會有自已的執行緒和訊息迴圈機制,那麼為什麼還必要要這麼一個框架類CMainFrame作為它的支撐呢?後來查了一下原始碼發現在C***App類的Run()函式裡面有這麼一段(關於Run函式這裡不做詳細講解,有興趣可以去檢視"深入淺出MFC"):
int CWinApp::Run() { if (m_pMainWnd == NULL && AfxOleGetUserCtrl()) { // Not launched /Embedding or /Automation, but has no main window! TRACE0("Warning: m_pMainWnd is NULL in CWinApp::Run - quitting application.\n"); AfxPostQuitMessage(0); } return CWinThread::Run(); }
呵呵,原來只要 m_pMainWnd 不為 NULL, 則主執行緒就可以轉起來.至此,所有的問題就迎刃而解。