777 lines
17 KiB
C++
777 lines
17 KiB
C++
// ==========================================================================
|
|
// Class Implementation : COXOptionTreeCtrl
|
|
// ==========================================================================
|
|
|
|
// Header file : OXOptionTreeCtrl.h
|
|
|
|
// Version: 9.3
|
|
|
|
// This software along with its related components, documentation and files ("The Libraries")
|
|
// is © 1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is
|
|
// governed by a software license agreement ("Agreement"). Copies of the Agreement are
|
|
// available at The Code Project (www.codeproject.com), as part of the package you downloaded
|
|
// to obtain this file, or directly from our office. For a copy of the license governing
|
|
// this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900.
|
|
|
|
// //////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
#include "stdafx.h"
|
|
#include "OXOptionTreeCtrl.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#ifndef TVM_SETBKCOLOR
|
|
#define TVM_SETBKCOLOR (TV_FIRST + 29)
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// COXOptionTreeCtrl
|
|
|
|
COXOptionTreeCtrl::COXOptionTreeCtrl() :
|
|
m_bUseHighContrast(FALSE)
|
|
{
|
|
}
|
|
|
|
COXOptionTreeCtrl::~COXOptionTreeCtrl()
|
|
{
|
|
ASSERT(m_mapItems.GetCount()==0);
|
|
ASSERT(m_mapReadOnlyItems.GetCount()==0);
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(COXOptionTreeCtrl, CTreeCtrl)
|
|
//{{AFX_MSG_MAP(COXOptionTreeCtrl)
|
|
ON_NOTIFY_REFLECT_EX(TVN_KEYDOWN, OnKeydown)
|
|
ON_WM_CHAR()
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_CREATE()
|
|
ON_NOTIFY_REFLECT_EX(TVN_DELETEITEM,OnDeleteItem)
|
|
ON_WM_SETTINGCHANGE()
|
|
//}}AFX_MSG_MAP
|
|
ON_MESSAGE(TVM_SETBKCOLOR,OnSetBkColor)
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// COXOptionTreeCtrl message handlers
|
|
|
|
BOOL COXOptionTreeCtrl::OnKeydown(NMHDR* pNMHDR, LRESULT* pResult)
|
|
{
|
|
TV_KEYDOWN* pTVKeyDown=(TV_KEYDOWN*)pNMHDR;
|
|
*pResult=0;
|
|
|
|
if(pTVKeyDown->wVKey==VK_SPACE)
|
|
{
|
|
HTREEITEM hItem=GetSelectedItem();
|
|
if(hItem!=NULL && !IsReadOnly(hItem))
|
|
{
|
|
ToggleItem(hItem);
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void COXOptionTreeCtrl::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
{
|
|
// TODO: Add your message handler code here and/or call default
|
|
|
|
// prevents beep
|
|
if(nChar!=VK_SPACE)
|
|
{
|
|
CTreeCtrl::OnChar(nChar,nRepCnt,nFlags);
|
|
}
|
|
}
|
|
|
|
void COXOptionTreeCtrl::OnLButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
// TODO: Add your message handler code here and/or call default
|
|
HTREEITEM hItem=GetClickedOptionItem();
|
|
|
|
if(hItem!=NULL && !IsReadOnly(hItem))
|
|
{
|
|
if(::GetFocus()!=GetSafeHwnd())
|
|
SetFocus();
|
|
|
|
ToggleItem(hItem);
|
|
SelectItem(hItem);
|
|
}
|
|
else
|
|
{
|
|
CTreeCtrl::OnLButtonDown(nFlags,point);
|
|
}
|
|
}
|
|
|
|
void COXOptionTreeCtrl::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
|
|
{
|
|
CheckHightContrast();
|
|
SetImageList(GetImageList(),TVSIL_NORMAL);
|
|
|
|
CWnd::OnSettingChange(uFlags, lpszSection);
|
|
}
|
|
|
|
|
|
LRESULT COXOptionTreeCtrl::OnSetBkColor(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
UNREFERENCED_PARAMETER(wParam);
|
|
UNREFERENCED_PARAMETER(lParam);
|
|
|
|
LRESULT lResult=Default();
|
|
|
|
CheckHightContrast();
|
|
SetImageList(GetImageList(),TVSIL_NORMAL);
|
|
|
|
return lResult;
|
|
}
|
|
|
|
|
|
void COXOptionTreeCtrl::PreSubclassWindow()
|
|
{
|
|
// TODO: Add your specialized code here and/or call the base class
|
|
_AFX_THREAD_STATE* pThreadState=AfxGetThreadState();
|
|
// hook not already in progress
|
|
if(pThreadState->m_pWndInit==NULL)
|
|
{
|
|
if(!Initialize())
|
|
{
|
|
TRACE(_T("COXOptionTreeCtrl::PreSubclassWindow: failed to initialize the control\n"));
|
|
}
|
|
}
|
|
|
|
CTreeCtrl::PreSubclassWindow();
|
|
}
|
|
|
|
int COXOptionTreeCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
|
|
{
|
|
if(CTreeCtrl::OnCreate(lpCreateStruct) == -1)
|
|
return -1;
|
|
|
|
// TODO: Add your specialized creation code here
|
|
if(!Initialize())
|
|
{
|
|
TRACE(_T("COXOptionTreeCtrl::OnCreate: failed to initialize the control\n"));
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
BOOL COXOptionTreeCtrl::OnDeleteItem(NMHDR* pNotifyStruct, LRESULT* result)
|
|
{
|
|
LPNMTREEVIEW lpNMTV=(LPNMTREEVIEW)pNotifyStruct;
|
|
ASSERT(lpNMTV!=NULL);
|
|
UINT nID=GetIDFromItem(lpNMTV->itemOld.hItem);
|
|
m_mapItems.RemoveKey(nID);
|
|
m_mapReadOnlyItems.RemoveKey(lpNMTV->itemOld.hItem);
|
|
*result=0;
|
|
return FALSE;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
void COXOptionTreeCtrl::ToggleItem(HTREEITEM hItem)
|
|
{
|
|
ASSERT(hItem!=NULL);
|
|
|
|
UpdateWindow();
|
|
|
|
if(IsCheckBox(hItem))
|
|
{
|
|
if(GetCheck(hItem)==OTITEM_CHECKED)
|
|
{
|
|
SetCheckBox(hItem,OTITEM_UNCHECKED);
|
|
}
|
|
else
|
|
{
|
|
SetCheckBox(hItem,OTITEM_CHECKED);
|
|
}
|
|
// Send MODIFIED message to parent if needed.
|
|
}
|
|
else if (IsRadioButton(hItem))
|
|
{
|
|
if(GetCheck(hItem)==OTITEM_UNCHECKED)
|
|
{
|
|
SetRadioButton(hItem,OTITEM_CHECKED);
|
|
// Send MODIFIED message to parent if needed.
|
|
}
|
|
}
|
|
|
|
// avoid unnecessary flicker
|
|
RECT rect;
|
|
GetItemRect(hItem,&rect,TRUE);
|
|
ValidateRect(&rect);
|
|
}
|
|
|
|
|
|
HTREEITEM COXOptionTreeCtrl::GetClickedOptionItem() const
|
|
{
|
|
ASSERT(::IsWindow(GetSafeHwnd()));
|
|
|
|
// Get the current cursor coordinate
|
|
CPoint pt;
|
|
::GetCursorPos(&pt);
|
|
ScreenToClient(&pt);
|
|
|
|
UINT nFlags=NULL;
|
|
HTREEITEM hItem=HitTest(pt,&nFlags);
|
|
if(nFlags&TVHT_ONITEM && (IsCheckBox(hItem) || IsRadioButton(hItem)))
|
|
{
|
|
if((GetStyle()&TVS_EDITLABELS)==TVS_EDITLABELS && (nFlags&TVHT_ONITEMLABEL))
|
|
return NULL;
|
|
return hItem;
|
|
}
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
|
|
HTREEITEM COXOptionTreeCtrl::AddControlGroup(LPCTSTR pszText,
|
|
HTREEITEM hParent/*=NULL*/,
|
|
BOOL bExpanded/*=TRUE*/,
|
|
int nImageIndex/*=-1*/,
|
|
int nSelectedImageIndex/*=-1*/,
|
|
HTREEITEM hInsertAfter/*=TVI_LAST*/)
|
|
{
|
|
TV_INSERTSTRUCT tvs;
|
|
|
|
tvs.hParent=hParent;
|
|
tvs.hInsertAfter=hInsertAfter;
|
|
tvs.item.mask=TVIF_CHILDREN|TVIF_STATE|TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
|
|
|
|
tvs.item.state=(bExpanded ? TVIS_EXPANDED : 0);
|
|
tvs.item.stateMask=tvs.item.state;
|
|
tvs.item.cChildren=1;
|
|
|
|
tvs.item.pszText = (LPTSTR)pszText;
|
|
|
|
tvs.item.iImage=nImageIndex;
|
|
tvs.item.iSelectedImage=nSelectedImageIndex;
|
|
|
|
return InsertItem(&tvs);
|
|
}
|
|
|
|
|
|
HTREEITEM COXOptionTreeCtrl::AddCheckBox(UINT uID, LPCTSTR pszText,
|
|
HTREEITEM hParent,
|
|
int nCheck/*=OTITEM_UNCHECKED*/,
|
|
HTREEITEM hInsertAfter/*=TVI_LAST*/,
|
|
BOOL bReadOnly/*=FALSE*/)
|
|
{
|
|
if(uID==NULL || GetItemFromID(uID)!=NULL)
|
|
{
|
|
TRACE(_T("COXOptionTreeCtrl::AddCheckBox: invalid/duplicated ID\n"));
|
|
ASSERT(FALSE);// Give a chance to debug.
|
|
return NULL;
|
|
}
|
|
|
|
TV_INSERTSTRUCT tvs;
|
|
|
|
tvs.hParent=hParent;
|
|
tvs.hInsertAfter=hInsertAfter;
|
|
tvs.item.mask=TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_TEXT;
|
|
|
|
tvs.item.pszText=(LPTSTR)pszText;
|
|
tvs.item.iImage=((nCheck==OTITEM_CHECKED) ?
|
|
CHECKED_IMAGE_INDEX : UNCHECKED_IMAGE_INDEX);
|
|
tvs.item.iSelectedImage=tvs.item.iImage;
|
|
|
|
return AddOptionItem(uID,&tvs,bReadOnly);
|
|
}
|
|
|
|
|
|
HTREEITEM COXOptionTreeCtrl::AddRadioButton(UINT uID, LPCTSTR pszText,
|
|
HTREEITEM hParent,
|
|
int nCheck/*=OTITEM_UNCHECKED*/,
|
|
HTREEITEM hInsertAfter/*=TVI_LAST*/,
|
|
BOOL bReadOnly/*=FALSE*/)
|
|
{
|
|
if(uID==NULL || GetItemFromID(uID)!=NULL)
|
|
{
|
|
TRACE(_T("COXOptionTreeCtrl::AddRadioButt: invalid/duplicated ID\n"));
|
|
ASSERT(FALSE);// Give a chance to debug.
|
|
return NULL;
|
|
}
|
|
|
|
TV_INSERTSTRUCT tvs;
|
|
|
|
tvs.hParent=hParent;
|
|
tvs.hInsertAfter=hInsertAfter;
|
|
tvs.item.mask=TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_TEXT;
|
|
|
|
tvs.item.pszText=(LPTSTR)pszText;
|
|
tvs.item.iImage=((nCheck==OTITEM_CHECKED) ?
|
|
RADIO_IMAGE_INDEX : UNRADIOED_IMAGE_INDEX);
|
|
tvs.item.iSelectedImage=tvs.item.iImage;
|
|
|
|
return AddOptionItem(uID,&tvs,bReadOnly);
|
|
}
|
|
|
|
|
|
HTREEITEM COXOptionTreeCtrl::AddOptionItem(UINT uID, LPTV_INSERTSTRUCT ptvs,
|
|
BOOL bReadOnly/*=FALSE*/)
|
|
{
|
|
HTREEITEM hItem=InsertItem(ptvs);
|
|
if(hItem!=NULL)
|
|
{
|
|
m_mapItems.SetAt(uID,hItem);
|
|
m_mapReadOnlyItems.SetAt(hItem,bReadOnly);
|
|
}
|
|
return hItem;
|
|
}
|
|
|
|
|
|
HTREEITEM COXOptionTreeCtrl::GetItemFromID(UINT uID) const
|
|
{
|
|
HTREEITEM hItem=NULL;
|
|
m_mapItems.Lookup(uID, (void*&)hItem);
|
|
return hItem;
|
|
}
|
|
|
|
|
|
UINT COXOptionTreeCtrl::GetIDFromItem(HTREEITEM hItemFrom) const
|
|
{
|
|
UINT uID;
|
|
HTREEITEM hItem;
|
|
|
|
for(POSITION pos=m_mapItems.GetStartPosition(); pos!=NULL; )
|
|
{
|
|
m_mapItems.GetNextAssoc(pos,uID,(void*&)hItem);
|
|
if(hItem==hItemFrom)
|
|
return uID;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
void COXOptionTreeCtrl::SetCheck(UINT uID, int nCheck)
|
|
{
|
|
ASSERT(nCheck==OTITEM_UNCHECKED || nCheck==OTITEM_CHECKED);
|
|
|
|
HTREEITEM hItem=GetItemFromID(uID);
|
|
if(hItem!=NULL)
|
|
{
|
|
SetCheck(hItem,nCheck);
|
|
}
|
|
else
|
|
{
|
|
TRACE(_T("COXOptionTreeCtrl::SetCheck: item with specified ID wasn't found\n"));
|
|
}
|
|
}
|
|
|
|
|
|
void COXOptionTreeCtrl::SetCheck(HTREEITEM hItem, int nCheck)
|
|
{
|
|
ASSERT(nCheck==OTITEM_UNCHECKED || nCheck==OTITEM_CHECKED);
|
|
ASSERT(hItem!=NULL);
|
|
|
|
if(GetCheck(hItem)==nCheck)
|
|
{
|
|
// Already Set. Just return.
|
|
return;
|
|
}
|
|
|
|
if(IsCheckBox(hItem))
|
|
{
|
|
SetCheckBox(hItem,nCheck);
|
|
}
|
|
else if(IsRadioButton(hItem))
|
|
{
|
|
SetRadioButton(hItem,nCheck);
|
|
}
|
|
}
|
|
|
|
|
|
void COXOptionTreeCtrl::SetCheckBox(HTREEITEM hItem, int nCheck)
|
|
{
|
|
ASSERT(hItem!=NULL);
|
|
ASSERT(IsCheckBox(hItem));
|
|
|
|
int nImage=-1;
|
|
switch(nCheck)
|
|
{
|
|
case OTITEM_UNCHECKED:
|
|
nImage=UNCHECKED_IMAGE_INDEX;
|
|
break;
|
|
case OTITEM_CHECKED:
|
|
nImage=CHECKED_IMAGE_INDEX;
|
|
break;
|
|
default:
|
|
ASSERT(FALSE);
|
|
}
|
|
|
|
int nOldCheck=GetCheck(hItem);
|
|
|
|
VERIFY(SetItemImage(hItem,nImage,nImage));
|
|
|
|
// notify parent
|
|
NotifyOptionChanged(hItem,nOldCheck,nCheck);
|
|
}
|
|
|
|
|
|
void COXOptionTreeCtrl::SetRadioButton(HTREEITEM hItem, int nCheck)
|
|
{
|
|
ASSERT(hItem!=NULL);
|
|
ASSERT(IsRadioButton(hItem));
|
|
|
|
int nImage=-1;
|
|
|
|
switch(nCheck)
|
|
{
|
|
case OTITEM_UNCHECKED:
|
|
{
|
|
nImage=UNRADIOED_IMAGE_INDEX;
|
|
break;
|
|
}
|
|
case OTITEM_CHECKED:
|
|
{
|
|
nImage=RADIO_IMAGE_INDEX;
|
|
HTREEITEM hsibling=hItem;
|
|
|
|
// Set all other radio buttons ABOVE to OFF
|
|
while((hsibling=GetPrevSiblingItem(hsibling))!=NULL)
|
|
{
|
|
if(!IsRadioButton(hsibling))
|
|
break;
|
|
if(GetCheck(hsibling)!=OTITEM_UNCHECKED)
|
|
SetRadioButton(hsibling,OTITEM_UNCHECKED);
|
|
}
|
|
|
|
hsibling=hItem;
|
|
// Set all other radio buttons BELOW to OFF
|
|
while((hsibling=GetNextSiblingItem(hsibling))!=NULL)
|
|
{
|
|
if(!IsRadioButton(hsibling))
|
|
break;
|
|
if(GetCheck(hsibling)!=OTITEM_UNCHECKED)
|
|
SetRadioButton(hsibling,OTITEM_UNCHECKED);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
ASSERT(FALSE);
|
|
}
|
|
|
|
int nOldCheck=GetCheck(hItem);
|
|
|
|
VERIFY(SetItemImage(hItem,nImage,nImage));
|
|
|
|
// notify parent
|
|
NotifyOptionChanged(hItem,nOldCheck,nCheck);
|
|
}
|
|
|
|
|
|
int COXOptionTreeCtrl::GetCheck(UINT uID) const
|
|
{
|
|
HTREEITEM hItem=GetItemFromID(uID);
|
|
return GetCheck(hItem);
|
|
}
|
|
|
|
|
|
int COXOptionTreeCtrl::GetCheck(HTREEITEM hItem) const
|
|
{
|
|
int nImage=-1;
|
|
int nSelectedImage=-1;
|
|
VERIFY(GetItemImage(hItem,nImage,nSelectedImage));
|
|
|
|
if(nImage==UNCHECKED_IMAGE_INDEX || nImage==UNRADIOED_IMAGE_INDEX)
|
|
{
|
|
return OTITEM_UNCHECKED;
|
|
}
|
|
|
|
if(nImage==CHECKED_IMAGE_INDEX || nImage==RADIO_IMAGE_INDEX)
|
|
{
|
|
return OTITEM_CHECKED;
|
|
}
|
|
|
|
ASSERT(FALSE);
|
|
return -1;
|
|
}
|
|
|
|
|
|
BOOL COXOptionTreeCtrl::IsCheckBox(HTREEITEM hItem) const
|
|
{
|
|
ASSERT(hItem!=NULL);
|
|
|
|
int nImage=-1;
|
|
int nSelectedImage=-1;
|
|
VERIFY(GetItemImage(hItem,nImage,nSelectedImage));
|
|
|
|
if(nImage==CHECKED_IMAGE_INDEX || nImage==UNCHECKED_IMAGE_INDEX)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL COXOptionTreeCtrl::IsRadioButton(HTREEITEM hItem) const
|
|
{
|
|
ASSERT(hItem!=NULL);
|
|
|
|
int nImage=-1;
|
|
int nSelectedImage=-1;
|
|
VERIFY(GetItemImage(hItem,nImage,nSelectedImage));
|
|
|
|
if(nImage==RADIO_IMAGE_INDEX || nImage==UNRADIOED_IMAGE_INDEX)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
void COXOptionTreeCtrl::SetReadOnly(UINT uID, BOOL bReadOnly)
|
|
{
|
|
HTREEITEM hItem=GetItemFromID(uID);
|
|
if(hItem!=NULL)
|
|
{
|
|
SetReadOnly(hItem,bReadOnly);
|
|
}
|
|
else
|
|
{
|
|
TRACE(_T("COXOptionTreeCtrl::SetReadOnly: item with specified ID wasn't found\n"));
|
|
}
|
|
}
|
|
|
|
|
|
void COXOptionTreeCtrl::SetReadOnly(HTREEITEM hItem, BOOL bReadOnly)
|
|
{
|
|
ASSERT(hItem!=NULL);
|
|
|
|
if(IsCheckBox(hItem) || IsRadioButton(hItem))
|
|
{
|
|
m_mapReadOnlyItems.SetAt(hItem,bReadOnly);
|
|
}
|
|
}
|
|
|
|
|
|
BOOL COXOptionTreeCtrl::IsReadOnly(HTREEITEM hItem) const
|
|
{
|
|
ASSERT(hItem!=NULL);
|
|
|
|
BOOL bReadOnly=FALSE;
|
|
if(m_mapReadOnlyItems.Lookup(hItem,bReadOnly))
|
|
{
|
|
return bReadOnly;
|
|
}
|
|
else
|
|
{
|
|
ASSERT(!(IsCheckBox(hItem) || IsRadioButton(hItem)));
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
UINT COXOptionTreeCtrl::GetCheckedRadioButton(UINT uIDFirstButton,
|
|
UINT uIDLastButton) const
|
|
{
|
|
HTREEITEM hItemFirst=GetItemFromID(uIDFirstButton);
|
|
HTREEITEM hItemLast=GetItemFromID(uIDLastButton);
|
|
ASSERT(hItemFirst!=NULL && hItemLast!=NULL);
|
|
|
|
// Just checking....
|
|
HTREEITEM hsibling = hItemFirst;
|
|
do
|
|
{
|
|
if(GetCheck(hsibling)!=OTITEM_UNCHECKED)
|
|
{
|
|
return GetIDFromItem(hsibling);
|
|
}
|
|
|
|
if (hsibling == hItemLast)
|
|
{
|
|
break;
|
|
}
|
|
|
|
hsibling = GetNextSiblingItem(hsibling);
|
|
|
|
} while(hsibling!=NULL);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
void COXOptionTreeCtrl::CheckRadioButton(UINT uIDCheckButton)
|
|
{
|
|
SetCheck(uIDCheckButton,OTITEM_CHECKED);
|
|
}
|
|
|
|
|
|
BOOL COXOptionTreeCtrl::Initialize()
|
|
{
|
|
ASSERT(::IsWindow(GetSafeHwnd()));
|
|
|
|
if((HIMAGELIST)m_imageList==NULL)
|
|
{
|
|
if(!m_imageList.Create(IDB_OX_OPTIONTREE_IMAGELIST,16,0,RGB(192,192,192)))
|
|
{
|
|
TRACE(_T("COXOptionTreeCtrl::Initialize: failed to create image list\n"));
|
|
ASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if((HIMAGELIST)m_imageListHighContrast==NULL)
|
|
{
|
|
if(!m_imageListHighContrast.
|
|
Create(IDB_OX_OPTIONTREE_HIGHCONTRAST_IMAGELIST,16,0,RGB(192,192,192)))
|
|
{
|
|
TRACE(_T("COXOptionTreeCtrl::Initialize: failed to create image list\n"));
|
|
ASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
CheckHightContrast();
|
|
SetImageList(GetImageList(),TVSIL_NORMAL);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
int COXOptionTreeCtrl::AddImage(LPCTSTR lpszImageResourceID,
|
|
COLORREF clrMask/*=RGB(192,192,192)*/,
|
|
LPCTSTR lpszHighContrastImageResourceID/*=NULL*/,
|
|
COLORREF clrHighContrastMask/*=RGB(192,192,192)*/)
|
|
{
|
|
CBitmap bitmap;
|
|
bitmap.LoadBitmap(lpszImageResourceID);
|
|
int nImageIndex=m_imageList.Add(&bitmap,clrMask);
|
|
if(lpszHighContrastImageResourceID==NULL)
|
|
{
|
|
VERIFY(m_imageListHighContrast.Add(&bitmap,clrMask)==nImageIndex);
|
|
}
|
|
else
|
|
{
|
|
CBitmap bitmapHighContrast;
|
|
bitmapHighContrast.LoadBitmap(lpszHighContrastImageResourceID);
|
|
VERIFY(m_imageListHighContrast.
|
|
Add(&bitmapHighContrast,clrHighContrastMask)==nImageIndex);
|
|
bitmapHighContrast.DeleteObject();
|
|
}
|
|
bitmap.DeleteObject();
|
|
|
|
return nImageIndex;
|
|
}
|
|
|
|
|
|
// Save to registry state of check boxes and radio buttons
|
|
BOOL COXOptionTreeCtrl::SaveState(LPCTSTR lpszSubKey, LPCTSTR lpszValueName) const
|
|
{
|
|
#ifndef _MAC
|
|
CWinApp* pApp=AfxGetApp();
|
|
CString sProfileName;
|
|
sProfileName.Format(_T("%s_%s"),lpszSubKey,lpszValueName);
|
|
|
|
UINT uID=NULL;
|
|
HTREEITEM hItem=NULL;
|
|
CString sItemID(_T(""));
|
|
for(POSITION pos=m_mapItems.GetStartPosition(); pos!=NULL; )
|
|
{
|
|
m_mapItems.GetNextAssoc(pos,uID,(void*&)hItem);
|
|
ASSERT(hItem!=NULL && uID!=NULL && (IsCheckBox(hItem) || IsRadioButton(hItem)));
|
|
sItemID.Format(_T("%d"),uID);
|
|
pApp->WriteProfileInt(sProfileName,sItemID,GetCheck(hItem));
|
|
}
|
|
|
|
return TRUE;
|
|
#else
|
|
return FALSE;
|
|
#endif
|
|
}
|
|
|
|
// Load from registry state of check boxes and radio buttons
|
|
BOOL COXOptionTreeCtrl::LoadState(LPCTSTR lpszSubKey, LPCTSTR lpszValueName)
|
|
{
|
|
#ifndef _MAC
|
|
CWinApp* pApp=AfxGetApp();
|
|
CString sProfileName;
|
|
sProfileName.Format(_T("%s_%s"),lpszSubKey,lpszValueName);
|
|
|
|
UINT uID=NULL;
|
|
HTREEITEM hItem=NULL;
|
|
CString sItemID(_T(""));
|
|
for(POSITION pos=m_mapItems.GetStartPosition(); pos!=NULL; )
|
|
{
|
|
m_mapItems.GetNextAssoc(pos,uID,(void*&)hItem);
|
|
ASSERT(hItem!=NULL && uID!=NULL && (IsCheckBox(hItem) || IsRadioButton(hItem)));
|
|
sItemID.Format(_T("%d"),uID);
|
|
int nCheck=pApp->GetProfileInt(sProfileName,sItemID,-1);
|
|
if(nCheck!=-1)
|
|
SetCheck(hItem,nCheck);
|
|
}
|
|
|
|
return TRUE;
|
|
#else
|
|
return FALSE;
|
|
#endif
|
|
}
|
|
|
|
|
|
LRESULT COXOptionTreeCtrl::NotifyOptionChanged(HTREEITEM hItem, int nOldCheck,
|
|
int nNewCheck)
|
|
{
|
|
ASSERT(nOldCheck==OTITEM_UNCHECKED || nOldCheck==OTITEM_CHECKED);
|
|
ASSERT(nNewCheck==OTITEM_UNCHECKED || nNewCheck==OTITEM_CHECKED);
|
|
ASSERT(hItem!=NULL);
|
|
ASSERT(IsCheckBox(hItem) || IsRadioButton(hItem));
|
|
|
|
UINT uID=GetIDFromItem(hItem);
|
|
ASSERT(uID!=NULL);
|
|
|
|
// notify parent
|
|
CWnd* pParentWnd=GetParent();
|
|
if(pParentWnd!=NULL)
|
|
{
|
|
NMOPTIONTREE nmot;
|
|
nmot.hdr.hwndFrom=GetSafeHwnd();
|
|
nmot.hdr.idFrom=GetDlgCtrlID();
|
|
nmot.hdr.code=OTN_OPTIONCHANGED;
|
|
nmot.hItem=hItem;
|
|
nmot.uItemID=uID;
|
|
nmot.nOldCheck=nOldCheck;
|
|
nmot.nNewCheck=nNewCheck;
|
|
|
|
return (pParentWnd->SendMessage(WM_NOTIFY,(WPARAM)nmot.hdr.idFrom,
|
|
(LPARAM)&nmot));
|
|
}
|
|
else
|
|
return (LRESULT)0;
|
|
}
|
|
|
|
|
|
void COXOptionTreeCtrl::CheckHightContrast()
|
|
{
|
|
COLORREF clrBack=(COLORREF)-1;
|
|
#if _MFC_VER>0x0421
|
|
if(::IsWindow(GetSafeHwnd()))
|
|
{
|
|
clrBack=GetBkColor();
|
|
}
|
|
#endif
|
|
if(clrBack==(COLORREF)-1)
|
|
{
|
|
clrBack=::GetSysColor(COLOR_WINDOW);
|
|
}
|
|
|
|
m_bUseHighContrast=(GetRValue(clrBack)+GetGValue(clrBack)+GetBValue(clrBack)<300);
|
|
}
|
|
|
|
|
|
|
|
BOOL COXOptionTreeCtrl::DeleteAllItems()
|
|
{
|
|
m_mapItems.RemoveAll();
|
|
return(CTreeCtrl::DeleteAllItems());
|
|
|
|
}
|