2015-02-18 5 views
0

У меня есть CListCtrl с флажками, которые мне нужно включить или отключить на основе какого-то внешнего фактора. Однако, когда у меня есть больше элементов в списке, которые можно отобразить, я не могу использовать EnableWindow (FALSE) в элементе управления, так как он также отключает полосу прокрутки.Проведите различие между щелчком пользователя и SetChecked() в CListCtrl

Итак, я искал и придумал следующий код в карте сообщений:

ON_NOTIFY(LVN_ITEMCHANGED, IDC_CHECKBOX_LIST, OnCheckboxChanged) 

Функция обратного вызова реализуется как:

void CUserPropertiesDialog::OnCheckboxChanged(NMHDR* pNMHDR, LRESULT* pResult) 
{ 
    NM_LISTVIEW* pNMListView = (NM_LISTVIEW*) pNMHDR; 
    LVHITTESTINFO hitInfo; 

    hitInfo.pt = pNMListView->ptAction; 
    int nItem = m_checkBoxList.HitTest(&hitInfo); 
    if (hitInfo.flags != LVHT_ONITEMSTATEICON) return; 

    std::string groupName = static_cast<LPCTSTR>(m_checkBoxList.GetItemText(nItem, 0)); 

    if (!CCharmUserAdminGUIApp::getTheCharmUserAdminGUIApp().isAdministrator()) 
    { 
     if (pNMListView->uChanged & LVIF_STATE) 
     { 
      if (((pNMListView->uNewState & INDEXTOSTATEIMAGEMASK(2)) != 0) && ((pNMListView->uOldState & INDEXTOSTATEIMAGEMASK(1)) != 0)) 
      { 
       CH_INFO1("CUserPropertiesDialog::OnCheckboxChanged - CheckBox Now Selected", groupName); 
      } 
      else if (((pNMListView->uNewState & INDEXTOSTATEIMAGEMASK(1)) != 0) && ((pNMListView->uOldState & INDEXTOSTATEIMAGEMASK(2)) != 0)) 
      { 
       CH_INFO1("CUserPropertiesDialog::OnCheckboxChanged - CheckBox Now Unselected", groupName); 
      } 
     } 
    } 
} 

Проблема заключается в том, что эта функция называется когда пользователь нажимает флажок (хорошо!), но также, когда вызывается функция SetChecked() из кода.

Я надеялся, что проверка на hitInfo.flags позволит мне рассказать клик и функцию отдельно, но это не тот случай.

Есть ли, помимо установки какого-либо глобального флага до/после вызова функции и использования в обратном вызове, любой другой способ определить, используется ли щелчок или вызов функции?

+0

Если вам нужно включить/отключить на основе какого-либо условия, почему имеет значение, что полоса прокрутки (и весь элемент управления) отключена? Похоже, вы выполняете нестандартное поведение пользовательского интерфейса. – rrirower

+0

Почему этот нестандартный? Я хочу видеть все записи в списке, но я не хочу их переключать. Аналогично отображению поля «Редактировать», но отключите функции редактирования. –

+0

Почему используется 'INDEXTOSTATEIMAGEMASK'? Вы должны использовать 'LVIS_STATEIMAGEMASK' – sergiol

ответ

0

Я использую ту же программу inmy, и я использовал флаг.

Но я использую LVN_ITEMCHANGING. С помощью этого сообщения я могу предотвратить любые изменения.

Я переписал SetCheck (даже если он не является виртуальным) и установите флаг перед изменением статуса элемента списка. Внутренняя процедура OnItemChanging Routine видит установленный флаг и позволяет изменять. Флаг сразу очищается после возвращения.

Итак, если одно и то же действие выполняется с помощью мыши, флаг не установлен, и вам нужно проверить другой способ.

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

+0

Я выбрал аналогичное решение с флаг, который переключается до/после 'SetCheck()', и это работает, но он чувствует себя немного неуклюжим. –

+0

Да, это так. Но даже поиск последнего полученного сообщения Window не поможет. Вам нужен контекст «действия». Одним из контекстов является «программное действие», один из контекстов - «действие пользователя». – xMRi