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

C++Builder 軟體換膚技術實作:XML 驅動的非矩形視窗與控件皮膚系統

     編輯:VC 教學

架構概覽

將「介面佈局邏輯」與「視覺表現資源」完全分離:

  • 程式端:定義控件名稱、層級、事件邏輯,運行時讀取 XML 載入皮膚資源,動態建立/調整控件位置、大小、狀態圖片。
  • 美術端:繪製整張皮膚大圖 (Atlas),並編寫 XML 描述每個控件在圖集中的座標、尺寸、九宮格邊距、狀態圖片 (Normal/Hover/Down/Disabled/Focus) 位置。
  • 橋樑:XML 結構定義 (Schema) 雙方共同遵守。

XML 結構範例

<?xml version="1.0" encoding="UTF-8"?>
<Skin>
  <ImageFile>LoginSkin.png</ImageFile>  <!-- 整張圖集 -->
  <Controls>
    <Control name="BtnMin" type="Button">
      <Size><Width>18</Width><Height>18</Height></Size>
      <FormPos><Left>302</Left><Top>2</Top></FormPos>
      <States>
        <Normal><Left>0</Left><Top>268</Top></Normal>
        <Hover><Left>0</Left><Top>291</Top></Hover>
        <Down><Left>0</Left><Top>314</Top></Down>
        <Disabled/>
        <Focus/>
      </States>
    </Control>
    <Control name="BtnClose" type="Button"> ... </Control>
    <Control name="EdtUser" type="Edit"> ... </Control>
    <Control name="EdtPass" type="Edit" password="true"> ... </Control>
    <Control name="BtnLogin" type="Button"> ... </Control>
  </Controls>
  <Window>
    <Size><Width>350</Width><Height>200</Height></Size>
    <Region><!-- 非矩形視窗區域,可為圓角矩形、多邊形、位圖透明色 --></Region>
  </Window>
</Skin>

核心類別設計

class TSkinManager {
    Graphics::TBitmap* FAtlas;          // 載入的圖集
    TStringList* FControlDefs;          // 解析後的控件定義
public:
    bool LoadSkin(const AnsiString& XmlFile);
    void ApplySkin(TWinControl* Parent);  // 遞迴套用至表單所有子控件
    Graphics::TBitmap* GetStateBitmap(const AnsiString& CtrlName, const AnsiString& State);
    TRect GetControlRect(const AnsiString& CtrlName);
    // 九宮格繪製支援
    void DrawNinePatch(TCanvas* Canvas, TRect DstRect, Graphics::TBitmap* SrcBmp, TRect SrcRect, TRect Margins);
};

class TSkinForm : public TForm {
    TSkinManager* SkinMgr;
protected:
    virtual void __fastcall CreateParams(TCreateParams& Params) {
        TForm::CreateParams(Params);
        Params.Style &= ~WS_CAPTION;  // 移除標題列
        Params.ExStyle |= WS_EX_LAYERED;  // 分層視窗支援透明/非矩形
    }
    virtual void __fastcall Paint() {
        // 繪製背景、九宮格邊框、標題列區域等
    }
    virtual void __fastcall WndProc(TMessage& Msg) {
        // 處理 WM_NCHITTEST 實現拖曳、縮放、系統選單
    }
public:
    __fastcall TSkinForm(TComponent* Owner) : TForm(Owner) {
        SkinMgr = new TSkinManager();
    }
    bool LoadSkin(const AnsiString& XmlFile) { return SkinMgr->LoadSkin(XmlFile); }
};

關鍵技術點

  • 非矩形視窗:WS_EX_LAYERED + SetLayeredWindowAttributes (色鍵透明) 或 UpdateLayeredWindow (Alpha 混合,需 Win2000+)。
  • 九宮格縮放:保持邊框、圓角不變形,僅拉伸中間區域。適合按鈕、面板、輸入框背景。
  • 狀態切換:滑鼠進入/離開/按下/釋放/焦點切換時,即時替換控件背景圖片 (OwnerDraw) 或重繪。
  • 效能:圖集載入一次,狀態圖片透過 CopyRect 從圖集切出,避免重複解碼 PNG。
  • 動態換膚:運行時呼叫 LoadSkin(newXml) 即時切換,無需重啟。

部署建議

  • 皮膚資源 (XML + PNG) 放置於應用程式目錄 Skins\ 子資料夾。
  • 提供預設皮膚內嵌於 EXE 資源 (RC_DATA),首次執行解壓至磁碟。
  • 支援使用者自訂皮膚:開放 XML Schema、提供皮膚編輯器工具。

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