TreeView и CheckBox с тремя состояниями
От: abr Россия  
Дата: 12.05.06 16:41
Оценка:
Здравствуйте!

Извесно что у контрола CheckBox при установленом стиле BS_3STATE кроме checked и unchecked состояний, появляется третие состояние 'grayed'.
А вот в CTreeViewCtrl c checkbox'amи состояний у чекбоксов только 2 checked и unchecked...
Вот собсно и вопрос, как сделать чтоб появилось третье состояние?
Или может у кого уже готовый контрл найдётся...



Best regards
Павел.
Re: TreeView и CheckBox с тремя состояниями
От: Mr.TurboDune  
Дата: 13.05.06 22:18
Оценка:
Здравствуйте, abr, Вы писали:

abr>Здравствуйте!

abr>Извесно что у контрола CheckBox при установленом стиле BS_3STATE кроме checked и unchecked состояний, появляется третие состояние 'grayed'.
abr>А вот в CTreeViewCtrl c checkbox'amи состояний у чекбоксов только 2 checked и unchecked...
abr>Вот собсно и вопрос, как сделать чтоб появилось третье состояние?
abr>Или может у кого уже готовый контрл найдётся...

Это же секретная информация, уже не однократно обсуждавшаяся на форуме!

Флажки у CTreeCtrl по сути всего лишь иконки. Они храняться в списке, который можно получить как CTreeCtrl::GetImageList(TVSIL_STATE). Система при инициализации контрола стилем TVS_CHECKBOXES создаёт этот ImageList и наполняет его всего 2мя иконками.
Поэтому самостоятельно при инициализации своего контрола добавляешь в ImageList третью иконку. Можешь из ресурсов программы, или динамически, нарисовав при помощи функции DrawFrameControl( ). Потом переписываешь функции установки\возвращения состояния флажка. Что-то типа:

enum
{
unchecked = 0,
checked,
half_checked
};

bool CMyTreeCtrl::SetCheck(HTREEITEM hItem, int nCheck /* = checked */)
{
CImageList * pImageList = GetImageList(TVSIL_STATE);

TVITEM item;
item.mask = TVIF_HANDLE | TVIF_STATE;
item.hItem = hItem;
item.stateMask = TVIS_STATEIMAGEMASK;

item.state = INDEXTOSTATEIMAGEMASK(nCheck); // вместо item.state = INDEXTOSTATEIMAGEMASK((fCheck ? 2 : 1));

return ::SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)&item) != 0;
}

UINT CMyTreeCtrl::GetCheck(HTREEITEM hItem) const
{
ASSERT(::IsWindow(m_hWnd));
TVITEM item;
item.mask = TVIF_HANDLE | TVIF_STATE;
item.hItem = hItem;
item.stateMask = TVIS_STATEIMAGEMASK;
VERIFY(::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item));

return (UINT)(item.state >> 12); // вместо return ((BOOL)(item.state >> 12) -1);
}

Только никому не рассказывай
Re[2]: TreeView и CheckBox с тремя состояниями
От: BuHHunyx Беларусь  
Дата: 15.05.06 08:29
Оценка:
Здравствуйте, Mr.TurboDune, Вы писали:

[]

И еще чутка кода:

        CImageList ImageList;

        CClientDC ClientDC(m_TreeViewCtrl);
        CDC CompatibleDC;
        CompatibleDC.CreateCompatibleDC(ClientDC);

        CBitmap Bitmap;
        Bitmap.CreateCompatibleBitmap(ClientDC, iSize * 3, iSize);

        HBITMAP hOldBitmap = CompatibleDC.SelectBitmap(Bitmap);

        const COLORREF clrBgnd = ::GetSysColor(COLOR_WINDOW);//m_TreeViewCtrl.GetBkColor();
        CompatibleDC.FillSolidRect(0, 0, iSize * 3, iSize, clrBgnd);

        CRect rect(0, 0, iSize, iSize);

        CTheme Theme;
        if(CTheme::IsThemingSupported() && Theme.OpenThemeData(m_hWnd, L"Button"))
        {
            rect.OffsetRect(iSize, 0);
            Theme.DrawThemeBackground(CompatibleDC, BP_CHECKBOX, CBS_UNCHECKEDNORMAL, rect, NULL);
            rect.OffsetRect(iSize, 0);
            Theme.DrawThemeBackground(CompatibleDC, BP_CHECKBOX, CBS_CHECKEDNORMAL, rect, NULL);
            rect.OffsetRect(iSize, 0);
            Theme.DrawThemeBackground(CompatibleDC, BP_CHECKBOX, CBS_MIXEDNORMAL, rect, NULL);
        }
        else
        {
            rect.OffsetRect(iSize, 0);
            CompatibleDC.DrawFrameControl(rect, DFC_BUTTON, DFCS_BUTTONCHECK | DFCS_FLAT);
            rect.OffsetRect(iSize, 0);
            CompatibleDC.DrawFrameControl(rect, DFC_BUTTON, DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
            rect.OffsetRect(iSize, 0);
            CompatibleDC.DrawFrameControl(rect, DFC_BUTTON, DFCS_BUTTON3STATE | DFCS_INACTIVE | DFCS_CHECKED | DFCS_FLAT);
        }

        CompatibleDC.SelectBitmap(hOldBitmap);

        ImageList.Add(Bitmap, clrBgnd);

        m_TreeViewCtrl.SetImageList(ImageList.Detach(), TVSIL_STATE);
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.