軟體啟動時顯示一張精美的啟動畫面,不僅能展示品牌形象,還能在載入資源時緩解使用者等待焦慮。本文介紹一個封裝良好、開箱即用的 CSplashWnd 類,支援真彩色 JPG、GIF、BMP 圖片,並能在畫面中央動態顯示初始化進度文字,極大簡化了開發流程。
IPicture COM 介面)。ShowSplash() -> ShowText() -> CloseSplash()。class CSplashWnd : public CWnd {
public:
CSplashWnd(LPCTSTR lpszFileName); // 建構並載入圖片
BOOL ShowSplash(); // 顯示啟動畫面
void ShowText(LPCTSTR lpStr); // 畫面中央顯示文字
void CloseSplash(); // 關閉並銷毀視窗
// ...
};
CPicture 類 (Paul DiLascia 作品),內部使用 ATL CComQIPtr<IPicture> 管理 COM 介面,透過 OleLoadPicture 從檔案/資源/串流載入圖片,支援 HIMETRIC 單位轉換像素繪製。CreateEx 建立 WS_POPUP | WS_VISIBLE 視窗,大小依圖片實際尺寸,CenterWindow() 置中。OnPaint 中呼叫 pic.Render() 繪製圖片,ShowText 透過 TextOut 在中央疊加文字。PreTranslateAppMessage 攔截鍵盤/滑鼠訊息自動關閉。fileIsValid=FALSE,ShowSplash 直接返回 false,不彈出錯誤視窗,由呼叫端決定處理方式。#include// MFC 核心 #include // ATL 智慧指標 CComQIPtr #include // CArchiveStream (載入資源用) #include "stdafx.h" // 專案預編譯標頭
BOOL CMyApp::InitInstance() {
// ... 標準 MFC 初始化代碼 ...
if (!ProcessShellCommand(cmdInfo)) return FALSE;
// === 啟動畫面顯示流程 ===
CSplashWnd* pSplash = new CSplashWnd(_T("splash.jpg")); // 同目錄或完整路徑
if (pSplash->ShowSplash()) {
Sleep(750); // 模擬初始化耗時,或在此執行真實初始化並呼叫 ShowText
// pSplash->ShowText(_T("正在載入資料庫連線..."));
}
pSplash->CloseSplash();
delete pSplash;
pSplash = NULL;
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
return TRUE;
}
// CPicture 類 (封裝 IPicture)
class CPicture {
public:
BOOL Load(LPCTSTR pszPathName); // 從檔案載入
BOOL Load(IStream* pstm); // 從串流載入 (核心)
CSize GetImageSize(CDC* pDC) const;
BOOL Render(CDC* pDC, CRect rc, LPCRECT prcMFBounds=NULL) const;
// ...
protected:
CComQIPtr m_spIPicture;
HRESULT m_hr;
};
// CSplashWnd 類
class CSplashWnd : public CWnd {
// ... 訊息映射: ON_WM_CREATE, ON_WM_PAINT, ON_WM_TIMER ...
private:
int width, height;
CPicture pic;
BOOL fileIsValid;
};
// 建構函數:載入圖片並取得尺寸
CSplashWnd::CSplashWnd(LPCTSTR lpszFileName) {
fileIsValid = pic.Load(lpszFileName);
if (fileIsValid) {
CSize sz = pic.GetImageSize(NULL);
width = sz.cx; height = sz.cy;
}
}
// 顯示視窗
BOOL CSplashWnd::ShowSplash() {
if (!fileIsValid) return FALSE;
if (!Create(AfxGetMainWnd())) return FALSE;
UpdateWindow();
return TRUE;
}
// 建立無邊框彈出視窗
BOOL CSplashWnd::Create(CWnd* pParentWnd) {
return CreateEx(0, AfxRegisterWndClass(0, AfxGetApp()->LoadStandardCursor(IDC_ARROW)),
NULL, WS_POPUP | WS_VISIBLE, 0, 0, width, height, pParentWnd->GetSafeHwnd(), NULL);
}
// 繪製圖片
void CSplashWnd::OnPaint() {
CPaintDC dc(this);
CRect rc(0,0,0,0);
pic.Render(&dc, rc); // 自動填滿客戶區
}
// 顯示中央文字
void CSplashWnd::ShowText(LPCTSTR lpStr) {
Invalidate();
CPaintDC dc(this);
dc.SetBkMode(TRANSPARENT);
SIZE sz = dc.GetTextExtent(lpStr, lstrlen(lpStr));
dc.TextOut((width - sz.cx)/2, height/2, lpStr);
}

這個 CSplashWnd 類已在多個實際專案驗證,穩定可靠。歡迎指正交流 (Email: zhengxiliu@sohu.com)。