Есть ли способ переопределить обработчик, вызываемый, когда пользователь щелкает флажок в CListCtrl? (МФЦ)

Я пытаюсь отключить возможность пользователя изменять состояние флажка в элементе управления списком. В настоящее время я меняю состояние прагматично. Я уже обрабатываю сообщение LVN_ITEMCHANGED, и попытка изменить состояние невозможна из-за компоновки остальной части программы. Я также пытался выполнить HitTest, когда пользователь щелкает элемент управления списком и просто сбрасывает там флажок, но это не дает мне точных результатов, которые я ищу.

Отправляется ли конкретное сообщение или функция, которую я могу переопределить, когда пользователь щелкает сам флажок? Я просто хотел бы переопределить обработчик или поймать сообщение, чтобы оно никуда не ушло.


person Chris Dargis    schedule 29.06.2012    source источник


Ответы (1)


Решение:

В итоге я удалил флаг LVS_EX_CHECKBOXES и создал свою собственную реализацию. Таким образом, есть только один способ изменить значки. Чтение ссылки из предыдущего вопроса натолкнуло меня на мысль установить флаг «занят», иначе я получил бы ошибки переполнения стека.

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

Это не так элегантно, как я надеялся, но работает безупречно.

person Chris Dargis    schedule 29.06.2012