首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

MFC 單文檔多視圖 CTreeView 無法展開/選中異常:非客戶區重繪衝突

     編輯:程式設計疑難解答

現象

自訂 CTreeView 在分割視窗中,樹節點無法展開、選中高亮一閃即逝。相同程式碼在新建單文檔專案正常,僅差異在「重繪非客戶區、移除邊框」。

根本原因分析

重繪非客戶區 (OnNcPaint, OnNcCalcSize) 或修改視窗樣式 (WS_BORDER, WS_EX_CLIENTEDGE) 可能導致:

  1. 樹形控制項接收不到 WM_SETFOCUS/WM_KILLFOCUS,選中狀態無法維持。
  2. 分割視窗佈局計算錯誤,導致 CTreeView 客戶區尺寸為 0 或負值。
  3. 訊息路由中斷,TVN_ITEMEXPANDING 等通知未送達父視窗。

排查步驟

  1. 註解非客戶區重繪程式碼,確認樹形控制項恢復正常 → 定位衝突點。
  2. 檢查 OnCreateClient 分割尺寸計算:
    CRect rect;
    GetClientRect(&rect); // 此時 rect 可能尚未包含非客戶區調整
    // 建議在 OnSize 中動態調整分割比例
  3. 確保樹形控制項樣式包含 TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | TVS_SHOWSELALWAYS。

修正建議

// 在 CMainFrame::OnCreateClient 最後
m_wndSplitter.SetRowInfo(0, rect.Height(), 0); // 明確設定列高
m_wndSplitter.RecalcLayout();

// 非客戶區重繪時,保留 WS_EX_CLIENTEDGE 或手動處理 WM_NCCALCSIZE 返回 0
// 避免客戶區縮減導致視圖不可見

替代方案

若非客戶區自繪為美觀需求,考慮:

  • 使用 CMFCVisualManager 主題機制替代手繪。
  • 將樹形視圖放在 CDockablePane 中,利用 MFC 停靠面板框架自動管理非客戶區。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved