📄 treeoptionsctrlex.cpp
字号:
//this file is part of eMule
//Copyright (C)2002 Merkur ( devs@emule-project.net / http://www.emule-project.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "stdafx.h"
#include "TreeOptionsCtrlEx.h"
#include "VisualStylesXP.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
BEGIN_MESSAGE_MAP(CTreeOptionsCtrlEx, CTreeOptionsCtrl)
ON_WM_DESTROY()
END_MESSAGE_MAP()
CTreeOptionsCtrlEx::CTreeOptionsCtrlEx(UINT uImageListColorFlags)
{
m_uImageListColorFlags = uImageListColorFlags;
//SetAutoSelect(TRUE); // does not work!?
SetToggleOverIconOnly(TRUE);
}
CTreeOptionsCtrlEx::~CTreeOptionsCtrlEx(void)
{
}
void CTreeOptionsCtrlEx::HandleCheckBox(HTREEITEM hItem, BOOL bCheck)
{
//Turn of redraw to Q all the changes we're going to make here
SetRedraw(FALSE);
//Toggle the state
BOOL bOldState;
GetCheckBox(hItem, bOldState);
VERIFY(SetCheckBox(hItem, !bCheck));
if (bOldState != !bCheck)
NotifyParent(BN_CLICKED, hItem);
//If the item has children, then iterate through them and for all items
//which are check boxes set their state to be the same as the parent
HTREEITEM hChild = GetNextItem(hItem, TVGN_CHILD);
while (hChild)
{
if (IsCheckBox(hChild)){
BOOL bThisChecked;
GetCheckBox(hChild, bThisChecked);
SetCheckBox(hChild, !bCheck);
if (bThisChecked != !bCheck)
NotifyParent(BN_CLICKED, hChild);
}
//Move on to the next item
hChild = GetNextItem(hChild, TVGN_NEXT);
}
//Get the parent item and if it is a checkbox, then iterate through
//all its children and if all the checkboxes are checked, then also
//automatically check the parent. If no checkboxes are checked, then
//also automatically uncheck the parent.
HTREEITEM hParent = GetNextItem(hItem, TVGN_PARENT);
UpdateCheckBoxGroup(hParent);
//Reset the redraw flag
SetRedraw(TRUE);
}
void CTreeOptionsCtrlEx::UpdateCheckBoxGroup(HTREEITEM hItem)
{
SetRedraw(FALSE);
//Iterate through all children and if all the checkboxes are checked, then also
//automatically check the item. If no checkboxes are checked, then
//also automatically uncheck the item.
HTREEITEM hParent = hItem;
if (hParent && IsCheckBox(hParent))
{
BOOL bNoCheckBoxesChecked = TRUE;
BOOL bAllCheckBoxesChecked = TRUE;
HTREEITEM hChild = GetNextItem(hParent, TVGN_CHILD);
while (hChild)
{
if (IsCheckBox(hChild))
{
BOOL bThisChecked;
VERIFY(GetCheckBox(hChild, bThisChecked));
bNoCheckBoxesChecked = bNoCheckBoxesChecked && !bThisChecked;
bAllCheckBoxesChecked = bAllCheckBoxesChecked && bThisChecked;
}
//Move on to the next item
hChild = GetNextItem(hChild, TVGN_NEXT);
}
if (bNoCheckBoxesChecked)
{
BOOL bOldState;
GetCheckBox(hParent, bOldState);
SetCheckBox(hParent, FALSE);
if (bOldState != FALSE)
NotifyParent(BN_CLICKED, hParent);
}
else if (bAllCheckBoxesChecked)
{
BOOL bOldState;
GetCheckBox(hParent, bOldState);
SetCheckBox(hParent, FALSE); //gets rid of the semi state
SetCheckBox(hParent, TRUE);
if (bOldState != TRUE)
NotifyParent(BN_CLICKED, hParent);
}
else
{
BOOL bEnable;
VERIFY(GetCheckBoxEnable(hParent, bEnable));
SetEnabledSemiCheckBox(hParent, bEnable);
}
}
//Reset the redraw flag
SetRedraw(TRUE);
}
BOOL CTreeOptionsCtrlEx::SetRadioButton(HTREEITEM hParent, int nIndex)
{
//Validate our parameters
ASSERT(IsGroup(hParent)); //Parent item must be a group item
//Iterate through the child items and turn on the specified one and turn off all the other ones
HTREEITEM hChild = GetNextItem(hParent, TVGN_CHILD);
//Turn of redraw to Q all the changes we're going to make here
SetRedraw(FALSE);
int i=0;
BOOL bCheckedSomeItem = FALSE;
while (hChild)
{
//if we reach a non radio button then break out of the loop
if (!IsRadioButton(hChild))
break;
if (i == nIndex)
{
//Turn this item on
BOOL bOldState;
GetRadioButton(hChild, bOldState);
VERIFY(SetItemImage(hChild, 3, 3));
bCheckedSomeItem = TRUE;
if (!bOldState)
NotifyParent(BN_CLICKED, hChild);
}
else
{
BOOL bEnable;
VERIFY(GetRadioButtonEnable(hChild, bEnable));
//Turn this item off
if (bEnable)
VERIFY(SetItemImage(hChild, 2, 2));
else
VERIFY(SetItemImage(hChild, 4, 4));
}
//Move on to the next item
hChild = GetNextItem(hChild, TVGN_NEXT);
++i;
}
ASSERT(bCheckedSomeItem); //You specified an index which does not exist
//Reset the redraw flag
SetRedraw(TRUE);
return TRUE;
}
BOOL CTreeOptionsCtrlEx::SetRadioButton(HTREEITEM hItem)
{
//Validate our parameters
ASSERT(IsRadioButton(hItem)); //Must be a radio item to check it
//Iterate through the sibling items and turn them all off except this one
HTREEITEM hParent = GetNextItem(hItem, TVGN_PARENT);
ASSERT(IsGroup(hParent)); //Parent item must be a group item
//Iterate through the child items and turn on the specified one and turn off all the other ones
HTREEITEM hChild = GetNextItem(hParent, TVGN_CHILD);
//Turn of redraw to Q all the changes we're going to make here
SetRedraw(FALSE);
while (hChild)
{
//if we reach a non radio button then break out of the loop
if (!IsRadioButton(hChild))
break;
if (hChild == hItem)
{
//Turn this item on
BOOL bOldState;
GetRadioButton(hChild, bOldState);
BOOL bSuccess = SetItemImage(hChild, 3, 3);
ASSERT(bSuccess);
if (!bOldState)
NotifyParent(BN_CLICKED, hChild);
}
else
{
BOOL bEnable;
VERIFY(GetRadioButtonEnable(hChild, bEnable));
//Turn this item off
if (bEnable)
VERIFY(SetItemImage(hChild, 2, 2));
else
VERIFY(SetItemImage(hChild, 6, 6));
}
//Move on to the next item
hChild = GetNextItem(hChild, TVGN_NEXT);
}
//Reset the redraw flag
SetRedraw(TRUE);
return TRUE;
}
BOOL CTreeOptionsCtrlEx::NotifyParent(UINT uCode, HTREEITEM hItem)
{
CWnd* pWnd = GetParent();
if (!pWnd)
return FALSE;
TREEOPTSCTRLNOTIFY ton;
ton.nmhdr.hwndFrom = m_hWnd;
ton.nmhdr.idFrom = GetWindowLong(m_hWnd, GWL_ID);
ton.nmhdr.code = uCode;
ton.hItem = hItem;
return pWnd->SendMessage(WM_TREEOPTSCTRL_NOTIFY, GetWindowLong(m_hWnd, GWL_ID), (LPARAM)&ton);
}
void CTreeOptionsCtrlEx::OnCreateImageList()
{
CDC* pDCScreen = GetDC();
if (pDCScreen)
{
const int iBmpWidth = 16;
const int iBmpHeight = 17;
const int iBitmaps = 13;
CBitmap bmpControls;
if (bmpControls.CreateCompatibleBitmap(pDCScreen, iBmpWidth*iBitmaps, iBmpHeight))
{
if (m_ilTree.Create(iBmpWidth, iBmpHeight, m_uImageListColorFlags | ILC_MASK, 0, 1))
{
CDC dcMem;
if (dcMem.CreateCompatibleDC(pDCScreen))
{
HTHEME hTheme = (g_xpStyle.IsThemeActive() && g_xpStyle.IsAppThemed()) ? g_xpStyle.OpenThemeData(NULL, L"BUTTON") : NULL;
CBitmap* pOldBmp = dcMem.SelectObject(&bmpControls);
dcMem.FillSolidRect(0, 0, iBmpWidth*iBitmaps, iBmpHeight, GetSysColor(COLOR_WINDOW));
//int iCtrlWidth = iBmpWidth - 2;
//int iCtrlHeight = iBmpHeight - 2;
int iCtrlWidth = 16 - 3;
int iCtrlHeight = 16 - 3;
int iCtrlLeft = (iBmpWidth - iCtrlWidth) / 2;
int iCtrlTop = (iBmpHeight - iCtrlHeight) / 2;
// checkbox
CRect rcBmp(0, 0, 0+iBmpWidth, 0+iBmpHeight);
CRect rcCtrl(iCtrlLeft, iCtrlTop, iCtrlLeft+iCtrlWidth, iCtrlTop+iCtrlHeight);
if (hTheme){
g_xpStyle.DrawThemeBackground(hTheme, dcMem, BP_CHECKBOX, CBS_UNCHECKEDNORMAL, &rcCtrl, NULL);
g_xpStyle.DrawThemeEdge(hTheme, dcMem, BP_CHECKBOX, CBS_UNCHECKEDNORMAL, &rcCtrl, 0, 0, NULL);
}
else
dcMem.DrawFrameControl(&rcCtrl, DFC_BUTTON, DFCS_BUTTONCHECK | DFCS_FLAT);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -