SkinMagic 是輕量級 MFC 視覺樣式庫,透過攔截非客戶區繪製 (WM_NCPAINT)、客戶區背景擦除 (WM_ERASEBKGND) 等訊息,套用外部皮膚資源 (位圖/定義檔) 實現全視窗換膚。本文記錄從零整合至 MFC 專案的最小步驟。
SkinMagicLib.h、SkinMagicLib.lib、DETOURS.lib 至專案目錄。KROMO.skn, DEVIOR.skn)。KROMO, DEVIOR 等。
// stdafx.h
#include "SkinMagicLib.h"
BOOL CMyApp::InitInstance() {
// ... 標準初始化 ...
if (!ProcessShellCommand(cmdInfo)) return FALSE;
// === SkinMagic 初始化區塊 ===
VERIFY(1 == InitSkinMagicLib(AfxGetInstanceHandle(), _T("Demo"), NULL, NULL));
VERIFY(1 == LoadSkinFromResource(AfxGetInstanceHandle(), _T("KROMO"), _T("SKINMAGIC")));
VERIFY(1 == SetWindowSkin(m_pMainWnd->m_hWnd, _T("MainFrame")));
VERIFY(1 == SetDialogSkin(_T("Dialog")));
((CMainFrame*)m_pMainWnd)->m_bSkinned = TRUE;
((CMainFrame*)m_pMainWnd)->m_nSkinIndex = 0;
// ============================
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
return TRUE;
}
// 資源選單 IDR_SKIN_MENU 新增項目:KROMO, DEVIOR, ...
void CMainFrame::OnSkinKromo() {
LoadSkinFromResource(AfxGetInstanceHandle(), _T("KROMO"), _T("SKINMAGIC"));
m_nSkinIndex = 0;
}
void CMainFrame::OnSkinDeviOr() {
LoadSkinFromResource(AfxGetInstanceHandle(), _T("DEVIOR"), _T("SKINMAGIC"));
m_nSkinIndex = 1;
}
// 依此類推...
| 函式 | 用途 |
|---|---|
InitSkinMagicLib(hInst, appName, ...) | 初始化庫,appName 用於註冊表儲存使用者偏好 |
LoadSkinFromResource(hInst, skinName, resType) | 從資源載入皮膚 (skinName = 資源 ID) |
LoadSkinFromFile(skinPath) | 從外部檔案載入 (支援使用者自訂皮膚) |
SetWindowSkin(hWnd, className) | 套用至特定視窗類別 (MainFrame, Dialog, ToolBar...) |
SetDialogSkin(className) | 全域套用至所有對話方塊 |
BCGControlBar (功能強大但體積大)、CMFCVisualManager (MFC 內建、Visual Studio 2008+)、SkinSharp (.NET)、Qt Style Sheets (跨平台)。