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

VC6/MFC 取得 CListCtrl 選取列第一欄資料的正確寫法

     編輯:程式設計綜合問答

錯誤程式碼分析

void CMFCConnectSqlDlg::OnRclickLISTData(NMHDR* pNMHDR, LRESULT* pResult)
{
    CMFCConnectSqlDlg CSqlDlga; // ❌ 錯誤:重新建構一個全新的對話框物件
    int nSelRows = CSqlDlga.m_List_Value.GetSelectedCount(); // 操作的是新物件的控制項,非當前視窗
    // ...
    theApp.M_ID = _ttoi(CSqlDlga.m_List_Value.GetItemText(n, 0));
}

Debug Assertion Failed 發生原因:CSqlDlga 是區域變數,其 m_List_Value 未經 SubclassDlgItem 或 DoDataExchange 關聯到真實視窗控制項,操作未初始化的 CListCtrl 觸發斷言。

正確寫法:使用 this 指向當前對話框實例

void CMFCConnectSqlDlg::OnRclickLISTData(NMHDR* pNMHDR, LRESULT* pResult)
{
    // ✅ 直接使用 this->m_List_Value(或 m_List_Value)
    int nSelRows = m_List_Value.GetSelectedCount();
    if (nSelRows == 0) return;

    POSITION pos = m_List_Value.GetFirstSelectedItemPosition();
    while (pos != NULL)
    {
        int nItem = m_List_Value.GetNextSelectedItem(pos);
        CString strText = m_List_Value.GetItemText(nItem, 0); // 第 0 欄
        int nID = _ttoi(strText);
        theApp.M_ID = nID; // 或儲存至陣列/容器處理多選
    }

    *pResult = 0;
}

關鍵點總結

錯誤做法正確做法
CMFCConnectSqlDlg dlg; dlg.m_List...this->m_List_Value 或直接 m_List_Value
忽略 POSITION 迴圈處理多選GetFirstSelectedItemPosition + GetNextSelectedItem 迴圈
用 GetNextItem(-1, LVNI_SELECTED|LVNI_FOCUSED) 只取單一多選時需迴圈,單選可用 GetNextItem(-1, LVNI_SELECTED)
直接 _ttoi 轉換可能失敗建議 int nID; if (strText.IsEmpty() || !IsNumeric(strText)) return; nID = _ttoi(strText);

完整多選範例:收集所有選取列的第一欄 ID

void CMFCConnectSqlDlg::OnRclickLISTData(NMHDR* pNMHDR, LRESULT* pResult)
{
    std::vector selectedIDs;
    POSITION pos = m_List_Value.GetFirstSelectedItemPosition();
    while (pos)
    {
        int nItem = m_List_Value.GetNextSelectedItem(pos);
        CString txt = m_List_Value.GetItemText(nItem, 0);
        if (!txt.IsEmpty())
            selectedIDs.push_back(_ttoi(txt));
    }

    if (!selectedIDs.empty())
    {
        theApp.M_ID = selectedIDs[0]; // 單一值需求
        // 或 theApp.SelectedIDs = selectedIDs; // 多值需求
    }
    *pResult = 0;
}

VC6 特有提醒

  • CListCtrl::GetItemText 回傳 CString,VC6 下需包含 afxwin.h。
  • 若在 OnRclick 中彈出選單,記得 ClientToScreen 轉換滑鼠座標。
  • VC6 專案若升級至 VS2019+,建議改用 CListCtrl::GetItemText(int, int, CString&) 參考形式避免臨時物件複製。

總結

絕對不要在訊息處理函數中重新建構對話框類別實例。永遠使用 this(隱含或顯式)存取當前視窗的控制項成員變數。配合 POSITION 迴圈正確處理多選情況,即可穩定取得 CListCtrl 選取列的任意欄位資料。

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