MFC 內建 Splash Screen 元件僅支援位圖資源,且操作繁瑣。本文整合 Paul DiLascia 的 CPicture 類別 (封裝 IPicture COM 介面),支援 JPG/GIF/BMP 多種格式,封裝為 CSplashWnd,提供極簡介面:ShowSplash()、ShowText()、CloseSplash(),並自動處理鍵盤/滑鼠提前關閉。
IPicture 是 OLE 標準介面,可從檔案/資源/串流載入 JPG/GIF/BMP/WMF/EMF 等格式。CPicture 使用 ATL 智慧指標 CComQIPtr<IPicture> 管理生命週期。Load(LPCTSTR) 載入檔案,Render(CDC*, CRect) 繪製至 DC,GetImageSize() 取得像素尺寸。
class CSplashWnd : public CWnd {
public:
CSplashWnd(LPCTSTR lpszFileName); // 載入圖檔
BOOL ShowSplash(); // 顯示置中視窗
void ShowText(LPCTSTR lpStr); // 畫面中央顯示文字
void CloseSplash(); // 關閉視窗
static BOOL PreTranslateAppMessage(MSG* pMsg); // 攔截鍵盤/滑鼠關閉
protected:
afx_msg int OnCreate(LPCREATESTRUCT);
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP()
private:
CPicture m_pic; BOOL m_fileValid; int m_width, m_height;
};
CSplashWnd::CSplashWnd(LPCTSTR lpszFileName) {
m_fileValid = m_pic.Load(lpszFileName);
if (m_fileValid) {
CSize sz = m_pic.GetImageSize(NULL);
m_width = sz.cx; m_height = sz.cy;
}
}
BOOL CSplashWnd::ShowSplash() {
if (!m_fileValid) return FALSE;
if (!CreateEx(0, AfxRegisterWndClass(0, AfxGetApp()->LoadStandardCursor(IDC_ARROW)),
NULL, WS_POPUP|WS_VISIBLE, 0,0,m_width,m_height,
AfxGetMainWnd()->GetSafeHwnd(), NULL))
return FALSE;
UpdateWindow(); CenterWindow(); return TRUE;
}
void CSplashWnd::OnPaint() {
CPaintDC dc(this); CRect rc(0,0,0,0);
m_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((m_width-sz.cx)/2, m_height/2, lpStr);
}
BOOL CSplashWnd::PreTranslateAppMessage(MSG* pMsg) {
if (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) {
CloseSplash(); return TRUE;
}
return FALSE;
}
BOOL CMyApp::InitInstance() {
// ... 標準初始化 ...
CSplashWnd* pSplash = new CSplashWnd("splash.jpg"); // 同目錄或絕對路徑
pSplash->ShowSplash();
Sleep(1500); // 模擬初始化耗時
pSplash->ShowText("正在載入模組...");
Sleep(500);
pSplash->ShowText("初始化完成");
Sleep(500);
pSplash->CloseSplash();
delete pSplash;
m_pMainWnd->ShowWindow(SW_SHOW);
return TRUE;
}
#include <atlbase.h> (ATL 智慧指標)#include <afxwin.h> (MFC 核心)#include <afxpriv2.h> (CArchiveStream)| 方案 | 支援格式 | 程式碼複雜度 | 相依性 |
|---|---|---|---|
| MFC 內建 Splash | 僅 BMP 資源 | 中 (需修改產生碼) | 無 |
| GDI+ | JPG/PNG/TIFF/... | 高 (需 GDI+ 初始化) | gdiplus.dll |
| 本文 CSplashWnd | JPG/GIF/BMP/WMF/EMF | 低 (單一類別) | OLE (系統內建) |
CSplashWnd + CPicture 提供了最輕量、零額外相依、多格式支援的啟動畫面方案。原始碼僅兩個檔案 (Splash.h/cpp),可直接拖入任何 VC6/VC2005+ 專案使用,適合快速專案原型與正式產品。