How to get edited subitem index of list control in MFC application

Viewed 261

I'm writing a dialog based MFC application on Visual Studio 2017 in C++.

In the dialog I have a list control. I want to know which column the user changes if he edits the list.

the list control looks like this:

enter image description here

So if I edit the cell Channel Mode B I expect the value of the cell to be row = 2 and col = 1. I've tried using the following code:

In the mask field of LVCOLUMN I've enabled the following flag:

LVCOLUMN lvColumn;
lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;

In the MESSAGE_MAP I've added the following notification:

ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, &CEditableListControlDlg::OnLvnItemchangedList1)

and the handler I've written is:

void CEditableListControlDlg::OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
    
    
    
    if (pNMLV->uChanged & LVIF_STATE)
    {
        
        if ((pNMLV->uNewState) & LVIS_SELECTED)
        {
            int iItem = pNMLV->iItem;
            int subItem = pNMLV->iSubItem;
        }
    }
    *pResult = 0;
}

In this code the variable iItem is the row selected and subItem is the column selected. What interests me is to get the pNMLV->iSubItem. My problem is that the value of the subItem variable is always zero, which mean it hasn't been selected by Microsoft Docs Documentation here

How can I get the index of the sub-item which been edited?

Thank you.

1 Answers

When you select a different line, the message will respond. If you select the same row and different columns, the message will not respond repeatedly. So, the iSubItem will be always 0 when you only change the column.

You could refer to the following example.

void CSdfsdfDlg::OnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult) 
{
    NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
    // TODO: Add your control notification handler code here
     
    if ((pNMListView-> uChanged   &   LVIF_STATE)   &&   (pNMListView-> uNewState   &   LVIS_SELECTED)) 
    {
        DWORD   dwPos =GetMessagePos(); 
        CPoint   point(LOWORD(dwPos),HIWORD(dwPos)); 
         
        m_lst.ScreenToClient(&point);   
         
        LVHITTESTINFO lvinfo; 
        lvinfo.pt = point; 
        lvinfo.flags = LVHT_ABOVE; 
         
        int  nItem = m_lst.SubItemHitTest(&lvinfo); 
        if(nItem!=-1) 
        { 
            CString strtemp; 
            strtemp.Format( "the row is %d and the column is %d ", lvinfo.iItem, lvinfo.iSubItem); 
            MessageBox(strtemp);
        } 
         
    }
 
 
    *pResult = 0;
} 
Related