Странное поведение CTreeViewCtrl и SetCheckState
От: ZealPack Россия  
Дата: 19.12.14 10:54
Оценка:
VS2008, 2010.

Есть примитивный WTL-диалог с деревом на нём. У дерева включено свойства "показывать чек-боксы".

class CMainDlg : public CDialogImpl<CMainDlg>
{
public:

    enum { IDD = IDD_MAINDLG };
    // разное....
    // ......


    HTREEITEM htiRoot;
};



при инициализации делаю так:
LRESULT CMainDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
    WTL::CTreeViewCtrl tree;
    tree.Attach( GetDlgItem(IDC_TREE1) );
    htiRoot = tree.InsertItem( L"All Items", TVI_ROOT, TVI_LAST);
    // добавляю ещё итемы
    tree.Expand( htiRoot );
    tree.SetCheckState( htiRoot, TRUE );
    tree.Detach();
    return TRUE;
}


по идее, должен выбраться корневой итем. Этого не происходит. А вот если отложить установку флажка на несколько миллисекунд, например, сделать так:
LRESULT CMainDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
    WTL::CTreeViewCtrl tree;
    tree.Attach( GetDlgItem(IDC_TREE1) );
    htiRoot = tree.InsertItem( L"All Items", TVI_ROOT, TVI_LAST);
    tree.Detach();

    // заводим будильник
    SetTimer(99, 250);

    return TRUE;
}

LRESULT CMainDlg::OnTimer(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
    if( wParam != 99 ) return 0;
    KillTimer(99);
    WTL::CTreeViewCtrl tree;
    tree.Attach( GetDlgItem(IDC_TREE1) );
    tree.SetCheckState( htiRoot, TRUE );
    tree.Detach();
    return 0;
}


то итем выбирается. Почему итем не выбирается из OnInitDialog?
Re: Странное поведение CTreeViewCtrl и SetCheckState
От: ZealPack Россия  
Дата: 19.12.14 11:56
Оценка:
Самое интересное, если сделать GetCheckState, получаем разные результаты:

LRESULT CMainDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
    WTL::CTreeViewCtrl tree;
    tree.Attach( GetDlgItem(IDC_TREE1) );
    htiRoot = tree.InsertItem( L"All Items", TVI_ROOT, TVI_LAST);
    // добавляю ещё итемы
    tree.Expand( htiRoot );
    tree.SetCheckState( htiRoot, TRUE );

    // проверяем, получаем bb = TRUE
    BOOL bb = tree.GetCheckState( htiRoot );
    TRACE(L"CheckState = %i", int(bb) );

    tree.Detach();
    return TRUE;
}

LRESULT CMainDlg::OnBnClickedButton2(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
    WTL::CTreeViewCtrl tree;
    tree.Attach( GetDlgItem(IDC_TREE1) );

    // проверяем, получаем bb = FALSE
    BOOL bb = tree.GetCheckState( htiRoot );
    TRACE(L"CheckState = %i", int(bb) );

    tree.Detach();
    return 0;
}


в OnInitDialog имеем bb = TRUE, а потом, нажав кнопку, получаем bb = FALSE. Т.е. состояние всё-таки устанавливается, а потом сбрасывается.
Re: Странное поведение CTreeViewCtrl и SetCheckState
От: rus blood Россия  
Дата: 19.12.14 21:47
Оценка:
Здравствуйте, ZealPack, Вы писали:

ZP>VS2008, 2010.


В MSDN в статье про стили для TVS_CHECKBOXES есть фраза

If you want to use this style, you must set the TVS_CHECKBOXES style with SetWindowLong after you create the treeview control, and before you populate the tree. Otherwise, the checkboxes might appear unchecked, depending on timing issues.

Какие-то timing issues ...

Можно половить TVN_ITEMCHANGED и посмотреть, кто и когда меняет состояние айтема (сбрасывает check).
Имею скафандр — готов путешествовать!
Re[2]: Странное поведение CTreeViewCtrl и SetCheckState
От: ZealPack Россия  
Дата: 22.12.14 17:13
Оценка:
Стиль TVS_CHECKBOXES стоит. Но на всяк случай сделал ещё раз SetWindowLong, перед populate — один хрен, не помогло. Судя по всему, эти timing issues и влияют на то, что они начинают заполняться через 200мс.
Re[3]: Странное поведение CTreeViewCtrl и SetCheckState
От: Skipy Rich Россия  
Дата: 07.05.15 08:54
Оценка: +1
Здравствуйте, ZealPack, Вы писали:

ZP>Судя по всему, эти timing issues и влияют на то, что они начинают заполняться через 200мс.


Тут, скорее, не в миллисекундах дело, а в последовательности сообщений контролу. Попробуй установить check state с помощью PostMessage, дабы сие действо произошло уже после полной инициализации и контрола и диалога.
Re: Странное поведение CTreeViewCtrl и SetCheckState
От: Vain Россия google.ru
Дата: 06.01.16 12:23
Оценка:
Здравствуйте, ZealPack, Вы писали:

ZP>VS2008, 2010.

ZP>то итем выбирается. Почему итем не выбирается из OnInitDialog?
Там по ходу по таймеру в очередь кидаются времязатратные операции, т.к. лист всё-таки может быть гигантских размеров, что возможно может привести к блокировкам GUI при синхронном заполнении.
Гдё-то видел пример как обработчик проверяет заполненность очереди на события для листа и если там есть какие-то стороннии эвенты, то кидает в очередь свой эвент и после ловит его и опять проверяет очередь. И только после того как очередь обработалась листом делает свои изменения. Это всё вроде как нужно, чтобы отcлеживать изменения на листе и не встревать со своими изменениями если предыдущие не завершились, если он ещё в состоянии апдейта находится, как-то так.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.