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

WinForms 介面開發 (五):視窗閃爍問題優化與自訂標題列按鈕實作

     編輯:關於.NET

承接上一篇「還原視窗本貌」,本文解決自繪視窗常見的閃爍問題,並示範如何實作類似 Foxmail 風格的自訂標題列按鈕 (最小化、最大化、關閉) 與彩色主題繪製。

閃爍根因與解決策略

WinForms 自繪視窗閃爍主因在於 OnPaint / WM_PAINT 過度觸發與繪製區域過大。優化方向:

  1. 減少重繪次數:啟用 WS_EX_COMPOSITED 雙緩衝樣式、覆寫 CreateParams 設定 WS_CLIPCHILDREN / WS_CLIPSIBLINGS。
  2. 縮小裁剪區域:在 NcPaint (非客戶區繪製) 中精確計算 Region,排除客戶區,僅繪製邊框、標題列、按鈕。
  3. 離螢幕緩衝:使用 BufferedGraphics 先繪製至記憶體位圖,再一次性 Blit 至螢幕 DC。

自訂標題列按鈕繪製實作

主視窗 (MainForm) 採用完整自繪非客戶區 (Non-Client Area);子視窗則保留系統預設標題列,僅套用皮膚色彩。核心程式碼結構:

// 非客戶區繪製入口
private bool NcPaint(SkinningForm form, SkinEngine engine)
{
    // 1. 取得視窗矩形、建立 Graphics (GetDCEx + DCX_CACHE | DCX_CLIPSIBLINGS | DCX_WINDOW)
    // 2. 計算裁剪區域:排除客戶區,僅保留邊框與標題列區域
    // 3. 離螢幕緩衝:BufferedGraphicsContext.Allocate
    // 4. 依序繪製:
    //    - 標題列背景 (engine.SkinAppearance.DrawCaptionBackground)
    //    - 視窗圖示 (DrawIcon)
    //    - 標題文字 (DrawCaptionText)
    //    - 控制盒按鈕 (DrawCaptionControlBox)  ← 自訂按鈕邏輯核心
    //    - 視窗邊框 (engine.SkinAppearance.DrawBorder)
    // 5. 清理資源 (ReleaseDC, Dispose Region/Graphics)
}

按鈕狀態機與熱追蹤

  • 按鈕區域矩陣:Rectangle[] captionButtons = { closeBtn, maxBtn, minBtn }。
  • 滑鼠移入/移出/按下/釋放 對應 WM_NCMOUSEMOVE, WM_NCMOUSELEAVE, WM_NCLBUTTONDOWN, WM_NCLBUTTONUP 更新按鈕狀態 (Normal/Hover/Pressed)。
  • 重繪時依狀態選取對應筆刷/筆畫 (漸層、邊框、圖示),實現 Foxmail 風格立體效果。

子視窗簡化策略

子視窗 (ChildForm) 不繁複自繪非客戶區,僅:

  • 設定 FormBorderStyle = None 並自行繪製單色邊框。
  • 客戶區背景色統一由 SkinEngine.SkinColor.Back 控制。
  • 標題列按鈕交由系統處理 (若保留) 或簡化為最小化圖示。

效果對比

主視窗優化後效果:無閃爍、彩色標題列、自訂按鈕

子視窗效果:簡潔邊框、統一膚色

下一步預告

下一篇將實作「動態換膚」:執行時期切換 SkinEngine 色彩方案,驗證架構擴充性。

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