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

VC++ CListCtrl 水平滾動條不顯示:非客戶區未重繪,調用 RedrawWindow 修復

     編輯:程式設計綜合問答

現象

CListCtrl 報表模式下,列寬總和超過可視區寬度,但**水平滾動條不顯示**;屬性 No Scroll = False;手動拖動列寬後滾動條才出現。

原因

滾動條屬於**非客戶區 (Non-client Area)**,由系統繪製。動態插入列/調整列寬後,控件未通知非客戶區重繪,導致滾動條狀態不同步。

解決方案

// 插入列/設置列寬後,強制非客戶區重繪
m_listCtrl.SetRedraw(FALSE);
// ... 批量 InsertColumn / SetColumnWidth ...
m_listCtrl.SetRedraw(TRUE);
m_listCtrl.RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW);
// 或更簡單:
m_listCtrl.SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);

關鍵 API

最佳實踐模式

void RefreshListColumns(CListCtrl& list) {
    list.SetRedraw(FALSE);
    list.DeleteAllItems();
    // 重新插入列、設置寬度...
    for (int i = 0; i < colCount; i++) list.SetColumnWidth(i, LVSCW_AUTOSIZE_USEHEADER);
    list.SetRedraw(TRUE);
    list.RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW);
}

避坑提示

  • 不要在 OnPaint/OnNcPaint 手動畫滾動條,極易出錯。
  • 若用 LVS_EX_HEADERDRAGDROP 拖拽列標後也需刷新。
  • MFC CListCtrl 封裝了 ListView 公共控件,行為一致。

核心動作:**動態修改列寬後,調用 RedrawWindow 或 SetWindowPos(..., SWP_FRAMECHANGED) 強制非客戶區重繪**,水平滾動條即刻顯示。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
API作用
RedrawWindow(..., RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW)立即重繪非客戶區 (含滾動條、邊框)
SetWindowPos(..., SWP_FRAMECHANGED)通知系統幀變化,觸發 NC_PAINT
SetScrollInfo(SB_HORZ, ...)手動設置滾動條範圍/頁面大小 (底層控制)