ActiveSkin 4.3 為 ActiveX 控制元件,將 UI 皮膚與業務邏輯分離。支援兩種模式:
actskn43.ocx)IDC_SKINStdAfx.h 引入介面:
#include
#import "actskn43.ocx" no_implementation raw_interfaces_only raw_native_types
using namespace ACTIVESKINLib;
CComQIPtr m_pSkin; // 全域/成員
BOOL CMyDlg::OnInitDialog() {
CDialog::OnInitDialog();
m_pSkin = GetDlgItem(IDC_SKIN)->GetControlUnknown();
m_pSkin->LoadSkin(L"skin\\default.skn"); // 可選:屬性頁預載
m_pSkin->ApplySkin((int)m_hWnd); // 套用至主視窗
return TRUE;
}
void CMyDlg::OnBtnChangeSkin() {
CFileDialog dlg(TRUE, _T("skn"), NULL, OFN_HIDEREADONLY,
_T("ActiveSkin Files (*.skn)|*.skn||"));
if (dlg.DoModal() == IDOK) {
USES_CONVERSION;
m_pSkin->LoadSkin(T2W(dlg.GetPathName()));
m_pSkin->ApplySkin((int)m_hWnd);
}
}
BOOL CAboutDlg::OnInitDialog() {
CDialog::OnInitDialog();
// 取得主視窗的 m_pSkin (透過 AfxGetMainWnd 或全域)
m_pSkin->ApplySkin((int)m_hWnd);
return TRUE;
}
BOOL CChildFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) {
BOOL bRes = CMDIChildWnd::OnCreateClient(lpcs, pContext);
m_pSkin->ApplySkin((long)m_hWnd); // 子視窗建立後套用
return bRes;
}
if (FAILED(m_pSkin->LoadSkin(bstrPath)) ||
FAILED(m_pSkin->ApplySkinByName((long)m_hWnd, L"FreeForm"))) {
MessageBox(_T("皮膚載入失敗"));
PostMessage(WM_CLOSE);
}
ApplySkinByName 第二參數為 SkinBuilder 中定義的 Object Name (如 "FreeForm")ActiveSkin 屬性頁 → Events → 新增訊息對應,產生類似:
// 範例:按鈕點擊事件
void OnSkinEvent(ISkinObject* pObj) {
BSTR bstrName; pObj->GetName(&bstrName);
if (_wcsicmp(bstrName, L"BtnClose") == 0) {
ISkinObject* pScreen = m_pSkin->GetSkinnedWindow(m_hWnd)->FindObject(L"Screen");
// 設定狀態、關閉視窗等
}
SysFreeString(bstrName);
}
| 特性 | SkinForm | SkinFreeForm |
|---|---|---|
| 套用方式 | ApplySkin(hWnd) 自動替換標準控制項 | ApplySkinByName(hWnd, "ObjectName") 手動綁定 |
| 事件處理 | 不影響原訊息流程 | 需訊息泵分發皮膚事件 |
| 靈活度 | 低 (標準視窗元素) | 高 (任意版面、動畫、非矩形視窗) |
| 適用場景 | 傳統 MFC 對話框/框架快速換膚 | 高度客製化 UI、媒體播放器、即時通訊主面板 |
actskn43.ocx 已註冊skin\\neostyle\\theme.ini 等)完整原始碼 (三個範例專案) 請參考本文配套下載。