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

簡單易用的視窗子類化工具類 CBasicSubClassWnd 實現解析

     編輯:關於C語言

前言

在多標籤視圖類 CTabView 的設計實現中,作者採用了私有繼承 CBasicSubClassWnd 並重寫其虛函數 SubWindowProc,以捕獲 WM_DRAWITEM 和 TTN_GETDISPINFO 訊息,從而實現 DrawItem 和 UpdateTooltipText 的虛函數回呼機制,支援衍生類的自訂處理。而 CBasicSubClassWnd 本身就是一個視窗子類化類,其核心原理在於鉤子替換目標視窗的訊息處理流程。本文將深入解析這個基於 API + STL 實現的簡易子類化工具類。

核心設計思路

CBasicSubClassWnd 的設計允許同一目標視窗被多個 CBasicSubClassWnd 物件捕獲訊息,但一個 CBasicSubClassWnd 物件只能捕獲一個目標視窗的訊息。SubWindowProc 的返回值決定了訊息是否傳遞給下一個 CBasicSubClassWnd 物件或原視窗程序處理:返回 TRUE 表示允許傳遞,否則攔截訊息。

類結構設計

CBasicSubClassWnd 類

作為外部介面類,提供 Hook 和 Unhook 方法掛鉤/卸載鉤子,核心虛函數 SubWindowProc 供衍生類重寫實現自訂訊息處理邏輯。

CBasicWndInfo 類

內部管理類,維護每個視窗對應的子類化物件鏈表 m_list_scw、原視窗程序 m_oldWndProc 及視窗句柄 m_hWnd。透過靜態 map 管理所有被子類化的視窗資訊,HookWndProc 為統一的鉤子視窗程序,負責分發訊息給掛鉤物件鏈表中的各個處理器。

關鍵實現細節

掛鉤流程

Hook() 方法先檢查是否已掛鉤其他視窗,若是則先解鉤。接著在靜態 map 中查找或建立目標視窗的 CBasicWndInfo,將自身加入該視窗的處理器鏈表。若為首次掛鉤,則透過 SetWindowLong 替換視窗程序為 HookWndProc。

解鉤流程

Unhook() 從對應視窗的處理器鏈表移除自身,若鏈表變空則恢復原視窗程序。

訊息分發機制

HookWndProc 遍歷該視窗的所有處理器,依序呼叫 SubWindowProc。若任一處理器返回 FALSE,則直接返回 0 攔截訊息;否則最後呼叫 CallWindowProc 傳遞給原視窗程序。特殊處理 WM_NCDESTROY 時註釋了清理邏輯,實際使用時需謹慎處理視窗銷毀時的資源釋放。

局限性與改進方向

  • 不支援跨進程視窗捕獲
  • 類非執行緒安全,多執行緒環境下需額外同步機制
  • WM_NCDESTROY 清理邏輯被註釋,可能導致資源洩漏
  • 使用 SetWindowLong 而非 SetWindowLongPtr,64 位元相容性存疑

總結

CBasicSubClassWnd 提供了輕量級的視窗子類化封裝,適合單執行緒、同進程內的訊息攔截需求。實際專案中建議根據具體場景補全執行緒安全、跨進程支援及完整的生命週期管理。

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