2016-12-16 2 views
1

Das List Control ist als Einzelauswahl für die Ressourcen definiert.CListCtrl mit Kontrollkästchen Fragen

Frage 1

Ich möchte auf die Überschrift der ersten Spalte meiner CListCtrl eine Checkbox haben. Auf den OnInitDialog Ich habe

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); 

Es ist nur das Kontrollkästchen des Header an, wenn ich in den erweiterten |LVS_EX_AUTOCHECKSELECT hinzufügen, was ich möchte auf jeden Fall nicht, weil ich wünsche, dass Aktion und Auswahl Aktion Überprüfung wird für verschiedene Zwecke verwendet werden.

Frage 2

Ich brauche eine boolean und Marke, was zu setzen, wie wenn der Benutzer überprüft geändert oder unchecks ein Element aus. Aber ich möchte nicht, dass diese Aktion beim Einfügen von Elementen auftritt, zum Beispiel beim Füllen der Liste beim Laden von Formularen, aber sie wird ohne meine Absicht ausgelöst, da InsertItem eine Aktion "Aktion deaktivieren" unter OnItemChanged auslöst.

Es verpflichtet mich mit einer m_is_inserting Mitglied Flagge jeden Einsatz zu konditionieren:

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

und reagiert entsprechend auf dem LVN_ITEMCHANGED Handler

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; 
} 

Gibt es einen besseren Weg, eine echte Benutzerprüfung zu unterscheiden/Deaktivieren Sie die Aktion von einem Nebeneffekt?

Frage 3

Gibt es eine besseren symbolische Konvention den Scheck/uncheck Zustand für immer? Die magischen Nummern 0x1000 und 0x2000 sind ziemlich bedeutungslos!

Vielen Dank im Voraus.

+0

Verwandte (** Frage 2 **): http://stackoverflow.com/questions/28582698/differentiate-between-user-click-and-setchecked-in-clistctrl – sergiol

Antwort

1

Fügen Sie zuerst die Spaltenüberschriften ein. Dann ändern Sie die HDF_CHECKBOX. Zum Beispiel:

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); 

Wenn die Benachrichtigung der Handhabung können Sie die GetCheck Methode verwenden, um zu sehen, wenn das Element aktiviert ist oder nicht. Beispiel:

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

Dank. Sie haben die Frage "Wie stelle ich ein Kontrollkästchen in der Kopfzeile an" (** Frage 1 **) meiner Frage beantwortet. Habe die Handhabung der Benachrichtigung noch nicht versucht. Randnotiz: Es ist sehr wahrscheinlich, dass ein Kontrollkästchen für 'CMFCListCtrl' /' CMFCHeaderCtrlist' in der Kopfzeile nicht implementiert ist, da ich 'HDS_CHECKBOXES',' HDF_CHECKBOX' und 'HDF_CHECKED' nicht auf' afxheaderctrl finde .cpp | h'und 'afxlistctrl.cpp | h' Dateien! – sergiol

Verwandte Themen