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

List Control 列表項目上下移動實現:刪除重插法完整教學

     編輯:關於VC++

核心思路

取得選中項索引 → 讀取全欄文字 → DeleteItem → InsertItem 於目標位置 → 恢復選中狀態。簡單高效,適合報表模式 CListCtrl。

關鍵程式碼

記錄選中索引


void CLCDemoDlg::OnClickList(NMHDR* pNMHDR, LRESULT* pResult) {
    POSITION pos = m_listCtrl.GetFirstSelectedItemPosition();
    IndexInFieldList = m_listCtrl.GetNextSelectedItem(pos);
    *pResult = 0;
}

向上移動


void CLCDemoDlg::OnButtonUp() {
    m_listCtrl.SetFocus();
    if (IndexInFieldList <= 0) { AfxMessageBox(_T("已在第一行!")); return; }

    CString c1 = m_listCtrl.GetItemText(IndexInFieldList, 0);
    CString c2 = m_listCtrl.GetItemText(IndexInFieldList, 1);
    CString c3 = m_listCtrl.GetItemText(IndexInFieldList, 2);

    m_listCtrl.DeleteItem(IndexInFieldList);
    int n = m_listCtrl.InsertItem(IndexInFieldList-1, c1);
    m_listCtrl.SetItemText(n, 1, c2);
    m_listCtrl.SetItemText(n, 2, c3);

    IndexInFieldList--;
    UINT flag = LVIS_SELECTED | LVIS_FOCUSED;
    m_listCtrl.SetItemState(IndexInFieldList, flag, flag);
}

向下移動 (邏輯對稱)


void CLCDemoDlg::OnButtonDown() {
    m_listCtrl.SetFocus();
    int cnt = m_listCtrl.GetItemCount();
    if (IndexInFieldList < 0 || IndexInFieldList >= cnt-1) {
        AfxMessageBox(_T("已在最後一行!")); return;
    }
    // 同樣讀取三欄文字
    m_listCtrl.DeleteItem(IndexInFieldList);
    int n = m_listCtrl.InsertItem(IndexInFieldList+1, c1);
    m_listCtrl.SetItemText(n, 1, c2);
    m_listCtrl.SetItemText(n, 2, c3);
    IndexInFieldList++;
    m_listCtrl.SetItemState(IndexInFieldList, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
}

進階優化

  • 支援多選項目批次移動:收集所有選中索引,由大到小排序後依序操作,避免索引偏移錯誤
  • 保留 lParam、圖示索引、狀態旗標:GetItem/SetItem 複製完整 LVITEM
  • 加入鍵盤快捷鍵 (Alt+Up/Down) 與拖放支援 (LVS_EX_DRAGDROP)
  • 大量資料時考慮虛擬清單模式 (LVS_OWNERDATA) 配合資料模型移動

執行畫面

初始狀態 移動後

環境:VC6.0 / Windows XP 編譯通過。

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