// ThreeCheckBoxTreeCtrl.cpp : 实现文件
//
#include "stdafx.h"
#include "ThreeCheckBoxTreeCtrl.h"
#include "afxpopupmenu.h"
// CThreeCheckBoxTreeCtrl
IMPLEMENT_DYNAMIC(CThreeCheckBoxTreeCtrl, CTreeCtrl)
CThreeCheckBoxTreeCtrl::CThreeCheckBoxTreeCtrl()
{
m_pImageList = NULL;
}
CThreeCheckBoxTreeCtrl::~CThreeCheckBoxTreeCtrl()
{
if(m_pImageList != NULL)
delete m_pImageList;
}
BEGIN_MESSAGE_MAP(CThreeCheckBoxTreeCtrl, CTreeCtrl)
ON_WM_LBUTTONDOWN()
ON_NOTIFY_REFLECT(NM_RCLICK, OnRClick)
ON_WM_RBUTTONUP()
ON_COMMAND(ID_TREE_SELECT_ALL, &CThreeCheckBoxTreeCtrl::OnTreeSelectAll)
ON_COMMAND(ID_TREE_SELECT_NONE, &CThreeCheckBoxTreeCtrl::OnTreeSelectNone)
ON_COMMAND(ID_TREE_SELECT_ELSE, &CThreeCheckBoxTreeCtrl::OnTreeSelectElse)
ON_COMMAND(ID_TREE_EXPAND, &CThreeCheckBoxTreeCtrl::OnTreeExpand)
ON_COMMAND(ID_TREE_UN_EXPAND, &CThreeCheckBoxTreeCtrl::OnTreeUnExpand)
END_MESSAGE_MAP()
// CThreeCheckBoxTreeCtrl 消息处理程序
void CThreeCheckBoxTreeCtrl::InitImageList()
{
m_pImageList = new CImageList();
m_pImageList->Create(13, 13, ILC_COLORDDB|ILC_MASK, 2,2);
CBitmap bitmap0, bitmap1, bitmap2, bitmap3;
bitmap0.LoadBitmap(IDB_SELECT_NO);
m_pImageList->Add(&bitmap0, RGB(255,255,255));
bitmap1.LoadBitmap(IDB_SELECT_NONE);
m_pImageList->Add(&bitmap1, RGB(255,255,255));
bitmap2.LoadBitmap(IDB_SELECT_ALL);
m_pImageList->Add(&bitmap2, RGB(255,255,255));
bitmap3.LoadBitmap(IDB_SELECT_SOME);
m_pImageList->Add(&bitmap3, RGB(255,255,255));
SetImageList(m_pImageList, TVSIL_STATE);
}
//清除所有选择
void CThreeCheckBoxTreeCtrl::ResetCheck()
{
HTREEITEM hItem;
hItem = GetRootItem();
if(hItem == NULL) return;
while(hItem)
{
SetCheck(hItem, FALSE);
hItem = GetNextItemEx(hItem);
}
}
void CThreeCheckBoxTreeCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
//AfxMessageBox("click");
HTREEITEM hItem;
UINT uFlag;
BOOL isCheck;
hItem = HitTest(point, &uFlag);
if(uFlag & TVHT_ONITEM)
{
isCheck = !GetCheck(hItem);
SetCheck(hItem, isCheck);
if(isCheck)
SetItemState( hItem, INDEXTOSTATEIMAGEMASK(2), TVIS_STATEIMAGEMASK);
else
SetItemState( hItem, INDEXTOSTATEIMAGEMASK(1), TVIS_STATEIMAGEMASK);
SetCheckChild(hItem, isCheck);
SetCheckParent(hItem);
//InitCheckState();
//AfxMessageBox("按钮上");
//return;
}
if(uFlag & TVHT_ONITEMSTATEICON) //状态图标, 点击复选框的时候
return;
CTreeCtrl::OnLButtonDown(nFlags, point);
}
void CThreeCheckBoxTreeCtrl::OnRClick(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
//AFX_MANAGE_STATE(AfxGetStaticModuleState());
CPoint pt;
GetCursorPos(&pt);
CMenu popmenu;
if(!popmenu.LoadMenu(IDR_MENU_TREE))
AfxMessageBox("Load Menu failed");
CMenu *pMenu = popmenu.GetSubMenu(0);
if(pMenu != NULL)
{
CMFCPopupMenu *p = new CMFCPopupMenu;
if(p != NULL)
{
p->EnableMenuLogo(0);
p->SetAutoDestroy(TRUE);
p->Create(this, pt.x, pt.y, pMenu->Detach(), TRUE, TRUE);
p->SetForegroundWindow();
}
}
// popmenu.GetSubMenu(0)->TrackPopupMenu(TPM_RIGHTBUTTON, pt.x, pt.y, this);
// popmenu.DestroyMenu();
}
void CThreeCheckBoxTreeCtrl::SetCheckChild(HTREEITEM hItem, BOOL IsCheck)
{
HTREEITEM ht;
ht = GetChildItem(hItem);
if(ht != NULL)
{
SetCheck(ht, IsCheck);
if(IsCheck)
SetItemState( hItem, INDEXTOSTATEIMAGEMASK(2), TVIS_STATEIMAGEMASK);
else
SetItemState( hItem, INDEXTOSTATEIMAGEMASK(1), TVIS_STATEIMAGEMASK);
SetCheckChild(ht, IsCheck);
//兄弟项
ht= GetNextSiblingItem(ht);
while(ht)
{
SetCheck(ht, IsCheck);
if(IsCheck)
SetItemState( hItem, INDEXTOSTATEIMAGEMASK(2), TVIS_STATEIMAGEMASK);
else
SetItemState( hItem, INDEXTOSTATEIMAGEMASK(1), TVIS_STATEIMAGEMASK);
SetCheckChild(ht, IsCheck);
ht = GetNextSiblingItem(ht);
}
}
}
void CThreeCheckBoxTreeCtrl::SetCheckParent(HTREEITEM hItem)
{
HTREEITEM hNextSiblingItem, hPrevSiblingItem, hParentItem;
//AfxMessageBox(GetItemText(hItem));
hParentItem=GetParentItem(hItem);
if(hParentItem == NULL) return;
int uState = 1; //初始不选中
BOOL IsCheck = GetCheck(hItem);
BOOL bCheck = IsCheck;
//查找当前节点下一个兄弟节点的选择状态
hNextSiblingItem=GetNextSiblingItem(hItem);
while(hNextSiblingItem!=NULL)
{
bCheck = GetCheck(hNextSiblingItem);
if(bCheck != IsCheck) break;
hNextSiblingItem=GetNextSiblingItem(hNextSiblingItem);
}
if(bCheck == IsCheck) //开始查找上一个兄弟节点的状态
{
hPrevSiblingItem=GetPrevSiblingItem(hItem);
while(hPrevSiblingItem!=NULL)
{
bCheck = GetCheck(hPrevSiblingItem);
if(bCheck != IsCheck) break;
hPrevSiblingItem=GetPrevSiblingItem(hPrevSiblingItem);
}
}
if(bCheck == IsCheck)
{
SetCheck(hParentItem, IsCheck);
switch(IsCheck)
{
case 0:
SetItemState( hParentItem, INDEXTOSTATEIMAGEMASK(1), TVIS_STATEIMAGEMASK);
break;
case 1:
SetItemState( hParentItem, INDEXTOSTATEIMAGEMASK(2), TVIS_STATEIMAGEMASK);
break;
case 2:
SetItemState( hParentItem, INDEXTOSTATEIMAGEMASK(3), TVIS_STATEIMAGEMASK);
break;
}
// if(IsCheck)
// SetItemState( hParentItem, INDEXTOSTATEIMAGEMASK(2), TVIS_STATEIMAGEMASK);
// else
// SetItemState( hParentItem, INDEXTOSTATEIMAGEMASK(1), TVIS_STATEIMAGEMASK);
SetCheckParent(hParentItem);
}
else
{
SetCheck(hParentItem, FALSE);
SetItemState( hParentItem, INDEXTOSTATEIMAGEMASK(3), TVIS_STATEIMAGEMASK);
//AfxMessageBox(GetItemText(hParentItem));
SetCheckParent(hParentItem);
}
}
void CThreeCheckBoxTreeCtrl::InitCheckState()
{
HTREEITEM hItem;
hItem = GetRootItem();
if(hItem == NULL) return;
while(hItem)
{
if(!ItemHasChildren(hItem))
SetCheckParent(hItem);
hItem = GetNextItemEx(hItem);
}
}
HTREEITEM CThreeCheckBoxTreeCtrl::GetNextItemEx(HTREEITEM hItem)
{
HTREEITEM ht;
ht = GetChildItem(hItem);
if(ht != NULL) return ht;
ht = GetNextSiblingItem(hItem);
if(ht != NULL) return ht;
ht = GetNextSiblingItem(GetParentItem(hItem));
if(ht != NULL) return ht;
ht = GetNextSiblingItem(GetParentItem(GetParentItem(hItem)));
if(ht != NULL) return ht;
return NULL;
}
void CThreeCheckBoxTreeCtrl::OnTreeSelectAll()
{
HTREEITEM hItem;
hItem = GetRootItem();
if(hItem == NULL) return;
while(hItem)
{
SetCheck(hItem, TRUE);
hItem = GetNextItemEx(hItem);
}
}
void CThreeCheckBoxTreeCtrl::OnTreeSelectNone()
{
ResetCheck();
}
void CThreeCheckBoxTreeCtrl::OnTreeSelectElse()
{
HTREEITEM hItem;
hItem = GetRootItem();
if(hItem == NULL) return;
while(hItem)
{
SetCheck(hItem, !GetCheck(hItem));
hItem = GetNextItemEx(hItem);
}
InitCheckState();
}
void CThreeCheckBoxTreeCtrl::OnTreeExpand()
{
HTREEITEM hItem;
//展开所有项
hItem = GetRootItem();
while (hItem)
{
if(ItemHasChildren(hItem)) Expand(hItem, TVE_EXPAND);
hItem =GetNextItem(hItem, TVGN_NEXTVISIBLE);
}
}
void CThreeCheckBoxTreeCtrl::OnTreeUnExpand()
{
UnExpand();
// HTREEITEM hItem;
// hItem = GetRootItem();
// while (hItem)
// {
// if(ItemHasChildren(hItem)) Expand(hItem, TVE_COLLAPSE);
// hItem = GetNextItem(hItem, TVGN_NEXTVISIBLE);
// }
}
void CThreeCheckBoxTreeCtrl::UnExpand(HTREEITEM hItem)
{
if(hItem == NULL)
{
hItem = GetRootItem();
}
if(hItem==NULL)
return;
HTREEITEM ht;
//ht = GetNextItemEx(hItem);
ht = GetNextItem(hItem, TVGN_NEXTVISIBLE);
if(ht != NULL)
{
UnExpand(ht);
if(GetItemState(ht, TVIS_EXPANDED)&TVIS_EXPANDED)
{
// UINT x = GetItemState(ht, TVIS_EXPANDED);
// CString temp;
// temp.Format(" state = %d", x);
// AfxMessageBox(GetItemText(ht) + temp);
Expand(ht, TVE_COLLAPSE);
}
}
else
{
return;
}
// HTREEITEM ht;
// ht = GetChildItem(hItem);
// if(ht != NULL) //如