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

SonicUI引擎:輕量級高效能UI開發框架核心技術深度解析

     編輯:關於VC++

Windows客戶端開發中,UI實作往往佔據 60% 以上工時。本文介紹自研 SonicUI 引擎核心技術,針對多格式圖片、富文本超連結、自繪按鈕、髒矩形區域刷新、異形視窗(含像素級Alpha)五大高頻痛點,提供零依賴、純GDI+、SSE2優化的輕量解決方案,實測繪圖效率較 CxImage 提升 4-10 倍。

引擎架構總覽

  • 核心導出:單一 GetSonicUI() 工廠函數,返回 ISonicUI* 介面
  • 組件模型:ISonicImage、ISonicString、ISonicPaint、ISonicWndEffect 等介面
  • 委托機制:類似 C# delegate,綁定全域函數/成員函數作為回調
  • 髒矩形優化:所有組件內建區域追蹤,Redraw() 僅重繪變更區域
  • 無視窗繪製:按鈕、超連結等皆為無視窗組件,避免 HWND 開銷

核心功能模組實戰

1. 多格式圖片支援(含 Alpha 通道)

系統 LoadImage 僅支援 BMP/ICO。SonicUI 內建 CxImage 解碼,並將所有浮點運算(旋轉、HSL、灰階)轉為整數 + SSE2 指令優化。


// 三步完成 PNG 透明圖片繪製
ISonicImage* pImg = GetSonicUI()->CreateImage();
pImg->Load(L"C:\\ui\\button_hover.png"); // 支援:PNG/JPG/GIF/BMP/TIF/ICO...
pImg->Draw(hdc, 10, 10);                 // 自動 Alpha Blending
GetSonicUI()->DestroyObject(pImg);
  • 資源載入:pImg->LoadResource(IDR_PNG1, L"IMAGE") —— 資源類型必須命名為 IMAGE
  • DC載入:pImg->LoadFromDC(hdcSrc, rect)
  • 色鍵透明:pImg->SetColorKey(RGB(255,0,255)) —— 指定單一顏色為透明

2. 富文本與超連結(HTML-like 控制字元)

ISonicString 以控制字元實現字體、顏色、超連結、圖文混排,支援滑鼠互動(進入/點擊/離開)。


ISonicString* pStr = GetSonicUI()->CreateString();

// 格式化:/c=顏色, a=超連結URL, font, font_height=16/顯示文字
pStr->Format(L"/c=%x, a='https://hi.csdn.net/zskof', font, font_height=16/點我開啟連結", 
             RGB(0, 0, 255));

// WM_PAINT 中輸出
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
    switch (msg) {
        case WM_PAINT: {
            PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps);
            pStr->TextOut(hdc, 0, 0, hWnd); // 傳 hWnd 讓內部處理滑鼠訊息
            EndPaint(hWnd, &ps);
            break;
        }
    }
    return DefWindowProc(hWnd, msg, wp, lp);
}

控制字元完整語法

圖文混排與圖片超連結


ISonicImage* pImg = GetSonicUI()->CreateImage();
pImg->Load(L"logo.png");

ISonicString* pStr = GetSonicUI()->CreateString();
// /p=ImageID 插入圖片,a=URL 為圖片加超連結
pStr->Format(L"/c=%x/你好,朋友/p=%d, a='https://example.com'/", 
             RGB(0,0,255), pImg->GetObjectId());

3. 自繪按鈕(三態 + 漸變動畫)

無視窗按鈕,透過 ISonicString 承載 Normal/Hover/Click 三態圖片,支援 QQ2009 風格漸變切換。


// 載入三態圖片(或單圖三態平鋪)
ISonicImage* pNormal = GetSonicUI()->CreateImage(); pNormal->Load(BMP_NORMAL); pNormal->SetColorKey(RGB(255,0,255));
ISonicImage* pHover  = GetSonicUI()->CreateImage(); pHover->Load(BMP_HOVER);  pHover->SetColorKey(RGB(255,0,255));
ISonicImage* pClick  = GetSonicUI()->CreateImage(); pClick->Load(BMP_CLICK);  pClick->SetColorKey(RGB(255,0,255));

ISonicString* pBtn = GetSonicUI()->CreateString();
// p=Normal, ph=Hover, pc=Click, linkt=提示文字
pBtn->Format(L"/a, p=%d, ph=%d, pc=%d, linkt='點我移動'/", 
             pNormal->GetObjectId(), pHover->GetObjectId(), pClick->GetObjectId());

// 加上漸變動畫:animation=速度(ms)
pBtn->Format(L"/a, p=%d, ph=%d, pc=%d, linkt='點我', animation=40/", ...);

// 委托點擊事件
void WINAPI OnBtnClick(ISonicString* pStr, LPVOID) {
    g_pEffect->MoveGently(0, 0); // 觸發視窗移動特效
}
pBtn->Delegate(DELEGATE_EVENT_CLICK, NULL, NULL, OnBtnClick);

// WM_PAINT 中輸出
pBtn->TextOut(hdc, x, y, hWnd);

自繪按鈕效果

圖1:三態按鈕 + 漸變動畫效果

4. 髒矩形區域刷新系統

GDI 繪圖效率低,InvalidateRect(hwnd, NULL, TRUE) 全域重繪極其浪費。SonicUI 提供 ISonicPaint 畫布物件,內建髒區域追蹤與自動區域合併。


// 建立畫布(可選擇是否擁有獨立 MemDC)
ISonicPaint* pPaint = GetSonicUI()->CreatePaint();
pPaint->Create(FALSE, width, height); // FALSE=無獨立MemDC,共用目標DC

// 委托自定義繪製邏輯
class CRenderer {
public:
    void OnPaint(ISonicPaint* pPaint, LPVOID) {
        if (!pPaint->GetCurrentPaint()) return;
        HDC hdc = pPaint->GetCurrentPaint()->hdc;
        int x = pPaint->GetCurrentPaint()->x;
        int y = pPaint->GetCurrentPaint()->y;
        // 在此繪製...
    }
};

CRenderer renderer;
pPaint->Delegate(DELEGATE_EVENT_PAINT, NULL, &renderer, &CRenderer::OnPaint);

// 需要重繪時,僅呼叫
pPaint->Redraw(); // 內部自動計算髒區域、合併、僅重繪變更區域

畫布支援直接添加子組件


pPaint->AddObject(pImage);   // 添加圖片
pPaint->AddObject(pString);  // 添加文字
pPaint->AddObject(pSubPaint); // 添加子畫布(巢狀)
// 所有子組件自動享有髒區域優化

5. 異形視窗(含像素級 Alpha 透明)

兩種實現模式,視需求選擇:

模式 A:區域裁剪(SetWindowRgn)


// 根據圖片非透明區域建立 HRGN
HRGN hRgn = pImg->CreateRgn(); // 內部掃描 Alpha > 0 的像素
SetWindowRgn(hWnd, hRgn, TRUE);
  • 優點:相容性好、無層疊視窗限制
  • 缺點:邊緣鋸齒、拖動殘影、不支援半透明

模式 B:分層視窗(WS_EX_LAYERED + UpdateLayeredWindow)——推薦


ISonicWndEffect* pEffect = GetSonicUI()->CreateWndEffect();
// TRUE = 像素級 Alpha 模式(UpdateLayeredWindow)
pEffect->Attach(hWnd, TRUE); 
// 依圖片 Alpha 通道自動裁剪視窗形狀
pEffect->SetShapeByImage(pImg);
  • 優點:完美半透明、邊緣平滑、拖動無殘影、支援淡入淡出
  • 缺點:不支援 WS_CHILD 視窗、需 Win2000+、效能略高

分層視窗文字繪製難題解決

GDI TextOut 不支援 Alpha,直接繪製會出現方塊邊緣。SonicUI 內建字體 Alpha 通道合成:


// ISonicString 內部實現:
// 1. 建立 32-bit DIBSection
// 2. GDI 繪製文字到 DIB
// 3. 像素級合成 Alpha 通道
// 4. UpdateLayeredWindow 送顯
// 使用者無感知,直接 pStr->TextOut(hdc, x, y, hWnd) 即可

異形視窗效果

圖2:像素級 Alpha 異形視窗 + 文字正確合成

效能基準測試(CPU: T2330 1.6GHz)

字元功能範例
/c=RRGGBB文字顏色/c=FF0000/紅字
/font字體名稱/font=微軟正黑體/
/font_height=N字體高度/font_height=14/
/a=URL超連結/a='https://...'/點我
/u=1底線/u=1/底線文字
/p=ImageID插入圖片/p=123/
/animation=MS狀態切換漸變動畫/animation=40/

其他內建組件(篇幅限制略過詳述)

  • ISonicMarquee:跑馬燈/滾動字幕,支援暫停/續播/速度控制
  • ISonicAnimation:關鍵幀動畫,支援缓動函數、循環/反向/彈跳
  • ISonicTooltip:智慧工具提示,自動避開螢幕邊緣
  • ISonicScrollBar:自繪捲軸,支援觸控慣性滾動

設計原則與擴充建議

  1. 輕便:核心 DLL < 500KB,無 MFC/ATL/WTL 依賴,純 Win32 + GDI+
  2. 高效:SSE2 優化、髒矩形、無視窗組件、延遲繪製
  3. 易用:HTML-like 控制字元、委托回調、工廠模式統一建構
  4. 開放:歡迎提交 Issue/PR,共同完善(聯繫作者獲取原始碼合作)

SonicUI 目前為公司內部專案資產,完整源碼暫不公開,但核心技術細節(SSE2 優化策略、髒區域算法、分層視窗文字合成)歡迎技術交流探討。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
操作CxImage (浮點)SonicUI (整數+SSE2)提升倍數
圖片旋轉 90°12.4 ms1.8 ms6.9x
HSL 色調調整8.7 ms1.2 ms7.3x
灰階轉換5.3 ms0.9 ms5.9x
Alpha Blending3.1 ms0.7 ms4.4x