首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

ActiveSkin 4.3 在 VC++ 中實現軟體換膚:SkinForm/SkinFreeForm 兩種模式完整範例

     編輯:關於VC++

ActiveSkin 簡介

ActiveSkin 4.3 為 ActiveX 控制元件,將 UI 皮膚與業務邏輯分離。支援兩種模式:

  • SkinForm:標準視窗換膚,自動替換標題列、按鈕、邊框等非客戶區
  • SkinFreeForm:自由形式皮膚,需手動處理皮膚物件事件、狀態

環境準備

  1. 安裝 ActiveSkin 4.3 (註冊 actskn43.ocx)
  2. VC 專案 → 加入元件 → ActiveSkin Control → 對話框拖入,ID IDC_SKIN
  3. StdAfx.h 引入介面:
    
    #include 
    #import "actskn43.ocx" no_implementation raw_interfaces_only raw_native_types
    using namespace ACTIVESKINLib;
        

範例一:標準對話框 SkinForm

初始化


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);
    }
}

非主視窗 (About Box 等) 同步換膚


BOOL CAboutDlg::OnInitDialog() {
    CDialog::OnInitDialog();
    // 取得主視窗的 m_pSkin (透過 AfxGetMainWnd 或全域)
    m_pSkin->ApplySkin((int)m_hWnd);
    return TRUE;
}

範例二:MDI 子視窗 SkinForm


BOOL CChildFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) {
    BOOL bRes = CMDIChildWnd::OnCreateClient(lpcs, pContext);
    m_pSkin->ApplySkin((long)m_hWnd); // 子視窗建立後套用
    return bRes;
}

範例三:SkinFreeForm 事件驅動模式

套用皮膚


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 vs SkinFreeForm 差異總結

特性SkinFormSkinFreeForm
套用方式ApplySkin(hWnd) 自動替換標準控制項ApplySkinByName(hWnd, "ObjectName") 手動綁定
事件處理不影響原訊息流程需訊息泵分發皮膚事件
靈活度低 (標準視窗元素)高 (任意版面、動畫、非矩形視窗)
適用場景傳統 MFC 對話框/框架快速換膚高度客製化 UI、媒體播放器、即時通訊主面板

注意事項

  • 範例執行前需安裝 ActiveSkin 4.3 並確認 actskn43.ocx 已註冊
  • 皮膚檔路徑需依實際調整 (skin\\neostyle\\theme.ini 等)
  • 高 DPI 環境下位圖可能模糊,建議提供 @2x/@3x 資源
  • ActiveSkin 官網已停止更新,新專案建議考慮 Duilib、DuiLib、Qt、WPF 等現代 UI 框架

完整原始碼 (三個範例專案) 請參考本文配套下載。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved