2016-12-16 73 views
1

列表控件在資源上定義爲單選。帶複選框的CListCtrl問題

問題1

我想對我的CListCtrl的第一列的標題的複選框。在OnInitDialog

m_list.SetExtendedStyle(m_list.GetExtendedStyle() | LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT); 

    CString s; 
    s.LoadString(IDS_COLUMN1); 

    #ifndef HDS_CHECKBOXES 
    // Copied from Microsoft SDKs\Windows\v7.0A\Include\CommCtrl.h 
    #define HDS_CHECKBOXES 0x0400 
    #endif 

    CHeaderCtrl& header = *m_list.GetHeaderCtrl(); 
    header.ModifyStyle(0, HDS_CHECKBOXES); 


    #ifndef HDF_CHECKBOX 
    // Copied from Microsoft SDKs\Windows\v7.0A\Include\CommCtrl.h  
    #define HDF_CHECKBOX 0x0040 
    #endif 

    LVCOLUMN lc = { 0 }; 
    lc.mask = LVCF_FMT |LVCF_WIDTH |LVCF_TEXT | LVCF_SUBITEM; 
    lc.fmt |= HDF_CHECKBOX; 
    lc.cx = 96; 
    lc.pszText = (TCHAR*) (LPCTSTR)s; 

    m_list.InsertColumn(0, &lc); 

如果我添加在擴展|LVS_EX_AUTOCHECKSELECT,我絕對不希望因爲我渴望在檢查行動和選擇的動作將被用於不同的目的,只給出了標題的複選框。

問題2

我需要設置一個布爾值和標誌的東西作爲修飾,當用戶選中或取消選中的項目。但是我不希望在插入項目時發生此操作,例如在表單加載時填充列表,但是它會在沒有我的意圖的情況下觸發,因爲InsertItem觸發OnItemChanged上的「取消選中操作」。

它迫使我調理與m_is_inserting會員標記每次插入:

m_is_inserting = true; 
    m_list.InsertItem(i, m_array[i]->GetName()); 
    m_is_inserting = false; 

,並在LVN_ITEMCHANGED處理

void CMyDialog::OnItemChanged(NMHDR* pNMHDR, LRESULT* pResult) 
{ 
    NMLISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; 

    if (pNMListView->uChanged & LVIF_STATE) 
    { 
     if (pNMListView->uNewState & LVIS_SELECTED) 
      OnSelect(); 
     else 
     { 
      if (pNMListView->iItem != -1) 
      { 
       if ((pNMListView->uNewState & LVIS_STATEIMAGEMASK) == 0x1000) 
       { 
        if (!m_is_inserting) 
        { 
         m_array[pNMListView->iItem]->m_active = false; 
         SetModified(); 
        } 
       } 
       else if ((pNMListView->uNewState & LVIS_STATEIMAGEMASK) == 0x2000) 
       { 
        if (!m_is_inserting) 
        { 
         m_array[pNMListView->iItem]->m_active = true; 
         SetModified(); 
        } 
       } 
      } 
     } 
    } 

    *pResult = 0; 
} 

做出相應的反應是否有更好的方法來區分真實用戶檢查/取消選中InsertItem副作用的操作?

問題3

是否有獲取支票/取消選中狀態更好的象徵性的約定?幻數0x10000x2000是相當無意義的!

在此先感謝。

+0

相關(**問題2 **):http://stackoverflow.com/questions/28582698/differentiate-between-user-click-and-setchecked-in-clistctrl – sergiol

回答

1

首先插入列標題。然後更改HDF_CHECKBOX。例如:

m_list.SetExtendedStyle(LVS_EX_CHECKBOXES| LVS_EX_FULLROWSELECT); 

CHeaderCtrl &header = *m_list.GetHeaderCtrl(); 
header.ModifyStyle(0, HDS_CHECKBOXES); 

m_list.InsertColumn(0, L"Column0", 0, 120, 0); 
m_list.InsertColumn(1, L"Column1", 0, 80, 1); 
m_list.InsertColumn(2, L"Column2", 0, 80, 2); 

HDITEM hdi = { 0 }; 
hdi.mask = HDI_FORMAT; 
header.GetItem(0, &hdi); 
hdi.fmt |= HDF_CHECKBOX; 
header.SetItem(0, &hdi); 

m_list.InsertItem(m_list.GetItemCount(), L"C0", 0); 
m_list.InsertItem(m_list.GetItemCount(), L"C1", 0); 

m_list.SetCheck(0, 1); 
m_list.SetCheck(1, 1); 

當處理通知可以使用GetCheck方法,看看項目被選中與否。例如:

if(pNMListView->uChanged & LVIF_STATE) 
{ 
    if(pNMListView->uNewState & LVIS_SELECTED) 
    { 
     ... 
    } 
    else if(pNMListView->uNewState & LVIS_STATEIMAGEMASK && pNMListView->iItem >= 0) 
    { 
     if(m_list.GetCheck(pNMListView->iItem)) 
      TRACE("%d checked\n", pNMListView->iItem); 
    } 
} 
+0

感謝。您的答案中包含「如何在標題上顯示覆選框」部分(**問題1 **)。尚未嘗試處理通知。注意:'CMFCListCtrl' /'CMFCHeaderCtrlist'的頭部上有一個複選框的功能很可能沒有實現,因爲我在'afxheaderctrl'中找不到'HDS_CHECKBOXES','HDF_CHECKBOX'和'HDF_CHECKED' .cpp | h'和'afxlistctrl.cpp | h'文件! – sergiol