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

深入C++ Builder元件開發(一):VCL繼承體系與繪圖機制基礎

     編輯:關於C++

開發環境建議

  • C++ Builder 6 + Update 4(穩定版本)
  • Windows 2000/XP 或更新:BCB 在 Win9x 極不穩定,且線上說明索引超過 9x 限制導致顯示不全。
  • Delphi 6 (完整安裝):將 VCL Source 目錄加入 Search Path,按 Ctrl+點擊即可跳轉原始碼,比任何 grep 工具都方便。

選擇正確的祖先類別:四大鐵律

需求建議祖先理由
有介面、需處理鍵盤、非容器TCustomControl擁有視窗控制代碼(HWND)、可獲取焦點、完整訊息循環
有介面、不需鍵盤、需滑鼠TGraphicControl無 HWND、輕量、繪圖由父視窗代管、無法獲取焦點
無介面、非視覺元件TComponent如 TOpenDialog、TTimer,只參與元件流式儲存
擴充既有控制項(如 TPanel)TCustomPanel 而非 TPanel可控制屬性可見性;建構子/解構子為虛擬,利於多型銷毀

本系列重點講解前兩類;後兩類相對單純略過。

繪製自己:重寫 Paint() 而非攔截 WM_PAINT

VCL 已在 TGraphicControl.WMPaint 封裝好流程:

procedure TGraphicControl.WMPaint(var Message: TWMPaint);
begin
  if Message.DC <> 0 then begin
    Canvas.Lock;
    try
      Canvas.Handle := Message.DC;
      try
        Paint;  // 虛擬函數,衍生類別重寫此處
      finally
        Canvas.Handle := 0;
      end;
    finally
      Canvas.Unlock;
    end;
  end;
end;

所有專業級元件皆透過 重寫 Paint() 繪圖,優點:

  • 自動處理 Canvas 鎖定/解鎖與 HDC 指派。
  • 設計時/執行時行為一致。
  • 配合 Invalidate() 觸發重繪,VCL 會合併區域、節流重繪。

為什麼用 Invalidate() 而非 Repaint()?

  • Repaint():立即強制重繪,可能造成閃爍與效能浪費。
  • Invalidate():標記區域失效,讓訊息佇列在適當時機合併重繪,平滑高效。
void __fastcall TLine::SetLineWidth(int value) {
  if (FLineWidth != value) {
    FLineWidth = value;
    Invalidate();  // 最佳實務
  }
}

高效率繪圖技巧預告

下一篇將介紹:

  • 雙重緩衝(Canvas->CopyRect + 記憶體位圖)消除閃爍。
  • 剪輯區域(ClipRect)限制繪圖範圍。
  • 筆刷/筆預建立與快取,避免 Paint 內重複建立 GDI 物件。
  • 使用 StretchDraw、DrawFocusRect 等優化 API。

訊息機制參考資源

CKER 的經典文章《VCL 訊息機制深度解析》:
CSDN 連結

元件開發的核心就是「處理訊息、發布事件」。基礎訊息處理(WM_*)前述文章已涵蓋,接下來將深入 CN_/CM_ 內部訊息、自訂事件、屬性編輯器等進階主題。

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