Is there a way to override the handler called when a user clicks a checkbox in a CListCtrl? (MFC)

StackOverflow https://stackoverflow.com/questions/11254754

  •  18-06-2021
  •  | 
  •  

Вопрос

I am trying to disable the user's ability to alter the state of a checkbox in a List Control. I am currently changing the state pragmatically. I already handle the LVN_ITEMCHANGED message, and trying to alter the state there isn't an option due to the layout of the rest of the program. I have also tried doing a HitTest when the user clicks in the List Control and simply resetting the checkbox there but that isn't giving me the exact results I am looking for.

Is there a specific message sent or a function I can override when the user clicks the checkbox itself? I would just like to override the handler or catch the message so that it doesn't go anywhere.

Это было полезно?

Решение

Solution:

I ended up removing the LVS_EX_CHECKBOXES flag and created my own implementation. That way the there is only one way to change the icons. Reading the link from the previous question gave me an idea to set a "busy" flag, otherwise I would get stack overflow errors.

// In my dialog class
m_CListCtrl.SetImageList(&m_ImgList, LVSIL_SMALL);    // Custom checkboxes (only two images)

// ...
void CMyDialog::OnLvnItemchangedList(NMHDR *pNMHDR, LRESULT *pResult)
{
   if(busy) { return; }
   // ....
} 

// When calling the SetCheck function:
busy = TRUE;   // Avoid stack overflow errors
m_CListCtrl.SetCheck(index, fCheck);
busy = FALSE;

// I derived a class from CListCtrl and did an override on the get/set check:
class CCustomListCtrl : public CListCtrl
{
    BOOL CCustomListCtrl::SetCheck(int nItem, BOOL fCheck)
    {
        TCHAR szBuf[1024];
        DWORD ccBuf(1024);
        LVITEM lvi;
        lvi.iItem = nItem;
        lvi.iSubItem = 0;
        lvi.mask = LVIF_TEXT | LVIF_IMAGE;
        lvi.pszText = szBuf;
        lvi.cchTextMax = ccBuf;
        GetItem(&lvi);
        lvi.iImage = (int)fCheck;
        SetItem(&lvi);
        return TRUE;
    }
    // Just need to determine which image is set in the list control for the item
    BOOL CCustomListCtrl::GetCheck(int nItem)
    {
        LVITEM lvi;
        lvi.iItem = nItem;
        lvi.iSubItem = 0;
        lvi.mask = LVIF_IMAGE;
        GetItem(&lvi);
        return (BOOL)(lvi.iImage);
    }
}

This is not as elegant as I had hoped, but it works flawlessly.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top