問題
有的程序員希望能夠在應用程序裝入前以及顯示主窗口後的幾秒鐘內顯示 About 框。這樣的實現在專業 Windows 應用程序中比比皆是。但在—般的應用程序中也需要實現此功能,而且還需要 About 框在顯示一定時間後自動消失。或者在用戶點擊應用程序的主窗口後消失。
那麼,如何利用 Windows API 函數來創建滿足這些要求的 About 框呢?
方法
在程序開始前的幾秒鐘裡顯示 About 框的思想並非是新想法,此思想同樣用於顯示扉屏,即在程序裝入時顯示彩色圖畫給用戶觀看。但在本節中,只關心如何顯示文本信息,如版本信息或所有權信息。
要創建自動消失的 About 框,實際上需要創建無模式對話框。所謂無模式對話框就是沒有屬主和非“ 模式”的對話框,即在對話框顯示的同時其他應用程序照常可以運行。
步驟
按照下列步驟實現一個例子程序。運行此例子程序,將顯示出一個 About 框。在主窗口出現時點擊主窗口用戶區中的任何地方,對話框將消失,如果用戶等待 5s,對話框也會消失的。
實現例子程序的具體步驟如下:
1.在 Visual C++ 中,利用 AppWizard 創建新的項目文件,並命名新的項目文件為 Ld144。
2.進入 ClassWizard,點擊按鈕 Add Class。新類命名為 CSplash,並選擇類 CDialog 作為此類的基類,忽略關於沒有為此類定義對話框模板標識符的警告信息,生成新類。
3.在 ClassWizard 中,從下拉列表中選擇類 CSplash,從對象列表中選擇對象 CSplash,從消息列表中選擇消息 WM_INITDIALOG,點擊按鈕 Add Function,在 CSplash 的方法 OnInitDialog 中添加下列代碼:
BOOL CSplash::OnInitDialog()
{
CDialog::OnInitDialog();
CenterWindow();
return TRUE; // return TRUE unless you set the focus to a control
}
4.在文件 Splash.cpp 中添加下列代碼:
BOOL CSplash::Create(CWnd* pParentWnd)
{
if(!CDialog::Create(CSplash::IDD, pParentWnd))
{
TRACE0("Warning:creation of CSplashWnd Dialog failed!");
return FALSE;
}
return TRUE;
}
5.在類 CSplash 的頭文件中做下列改動,改動的代碼用暗紅色字體表示:
class CSplash : public CDialog
{
// Construction
public:
CSplash(CWnd* pParent = NULL); // standard constructor
BOOL Create(CWnd* pParentWnd);
// Dialog Data
//{{AFX_DATA(CSplash)
enum { IDD = IDD_ABOUTBOX };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
6.接著,在應用程序的源文件 Ld144.h 中,添加用暗紅色字體表示的行。
class CLd1App : public CWinApp
{
private:
CSplash m_splash;
DWord m_dwSplashTime;
public:
CLd144App();
7.在文件 Ld144.cpp 的方法 InitInstance 中做如下修改,修改的行用暗紅色字體表示:
BOOL CLd1App::InitInstance()
{
if(m_splash.Create(m_pMainWnd))
{
m_splash.ShowWindow(SW_SHOW);
m_splash.UpdateWindow();
}
m_dwSplashTime=::GetCurrentTime();
AfxEnableControlContainer();
... ...
// The main window has been initialized, so show and update it.
pMainFrame->ShowWindow(m_nCmdShow);
pMainFrame->UpdateWindow();
m_splash.BringWindowToTop();
return TRUE;
}
8.進入 ClassWizard,從下拉組合框中選擇應用程序對象 CLd144App。從對象列表中選擇對象 CLd144App,從消息列表中選擇消息 OnIdle。把下面的代碼添加到類 CLd144App 的方法 OnIdle 中。
BOOL CLd144App::OnIdle(LONG lCount)
{
BOOL bResult=CWinApp::OnIdle(lCount);
if(m_splash.m_hWnd!=NULL)
{
if(::GetCurrentTime()-m_dwSplashTime>5000)
{
m_splash.DestroyWindow();
m_pMainWnd->UpdateWindow();
}
else
bResult=TRUE;
}
return bResult;
}
9.進入 ClassWizard,從下拉組合框中選擇應用程序對象 CLd144App。從對象列表中選擇對象 CLd144App,從消息列表中選擇消息 PreTranslateMessage。把下面的代碼添加到類 CLd144App 的方法 OnIdle 中。
BOOL CLd144App::PreTranslateMessage(MSG* pMsg)
{
BOOL bResult=CWinApp::PreTranslateMessage(pMsg);
if(m_splash.m_hWnd!=NULL&&
pMsg->message==WM_KEYDOWN//
pMsg->message==WM_SYSKEYDOWN//
pMsg->message==WM_LBUTTONDOWN//
pMsg->message==WM_RBUTTONDOWN//
pMsg->message==WM_MBUTTONDOWN//
pMsg->message==WM_NCLBUTTONDOWN//
pMsg->message==WM_NCRBUTTONDOWN//
pMsg->message==WM_NCMBUTTONDOWN)
{
m_splash.DestroyWindow();
m_pMainWnd->UpdateWindow();
}
return bResult;
}
10.編譯並運行此例子程序。
用法
當例子程序啟動時,在例子程序對象類的方法 InitInstance 中創建無模式對話框(用作 About 框)。一旦此對話框被創建,則在創建主窗口時將被自動置於窗口的前面,接著顯示在那裡直到用戶等待 5s(5x1000ms)或者點擊鼠標,或者按下某鍵後才消失。
如果用戶點擊鼠標或按下某鍵,則調用例子程序對象的方法 PreTranslateMessage,此方法檢查 About 框窗口是否存在,如果存在,則撤消此窗口,更新主窗口並使程序繼續執行。
如果用戶等待 5s,則調用方法 OnIdle,每當系統有空閒時間來執行例子程序的空閒處理時就調用此方法。在本節的例子程序中,方法 OnIdle 用來檢查撤消窗口的時間是否到了,如果到了,則撤消 About 框窗口,而程序繼續執行。