⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 treeoptionsctrl.cpp

📁 电驴的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*
Module : TreeOptionsCtrl.cpp
Purpose: Implementation for an MFC class to implement a tree options control 
         similiar to the advanced tab as seen on the "Internet options" dialog in 
         Internet Explorer 4 and later

Created: PJN / 31-03-1999
History: PJN / 21-04-1999 Added full support for enabling / disabling all the item types
         PJN / 05-10-1999 Made class more self contained by internally managing the image list
         PJN / 07-10-1999 1. Added support for including combo boxes aswell as edit boxes into the
                          edit control.
                          2. Added support for customizing the image list to use
         PJN / 29-02-2000 Removed a VC 6 level 4 warning
         PJN / 03-04-2000 Added support for navigation into and out of the combo boxes and edit controls
                          inside the control
         PJN / 10-05-2000 1. Fixed a bug where the text was not being transferred to the control when the 
                          in inplace combo or edit box is active and the tree control gets destroyed.
                          2. Added support for having check box items as children of other check box items
                          3. Setting the check box state of a parent now also sets the check box state 
                          for all child box children.
                          4. Setting the check box state afects the check box state of the parent if that
                          parent is also a check box.
         PJN / 30-05-2000 Code now uses ON_NOTIFY_REFLECT_EX instead of ON_NOTIFY_REFLECT. This allows 
                          derived classes to handle the reflected messages also.
         PJN / 03-07-2000 Now includes support for edit boxes with accompanying spin controls
         PJN / 25-04-2001 1. Creation of the image list is now virtual. This allows customisation such as
                          being able to use high color bitmaps
                          2. Added an option which determines if check box state should be changed when you 
                          click anywhere on an item or just over the checkbox icon
                          3. Updated copyright message
         PJN / 12-08-2001 1. Fixed an issue in GetComboText and GetEditText where the code was modifying the 
                          contents of the combo/edit box when it was being read. This was because that 
                          function is doing double duty as it is called when the child control is about to be 
                          created in place, and you want to remove the text from the tree control and put it 
                          in the child control. Thanks to "Jef" for spotting this.
                          2. Made the code in SetComboText more robust. Thanks to "Jef" for this also.
                          3. Added a DDX method for integers in a edit box. Thanks to Colin Urquhart for this.
                          4. Added an extra member to CTreeOptionsItemData to be used as an item data. This
                          allows you to avoid having to implement multiple derived classes and instead use
                          the item data's I now provide to stash away pointers etc.
         PJN / 27-08-2001 1. Provided a "GetUserItemData" member to provide access to the item data provided 
                          by the class. Thanks to Colin Urquhart for this.
                          2. Fixed a redraw problem which occured when you scrolled using an wheel enabled 
                          mouse. Thanks to "Jef" for spotting this.
                          3. Provided an AutoSelect option which automatically sets focus to child control 
                          in the tree control. Thanks to "Jef" for this suggestion.
                          4. Added full support for CBS_DROPDOWN and CBS_SIMPLE style combo boxes. Thanks
                          to "Jef" for this suggestion.
         PJN / 16-08-2001 1. Provided support for specify a color via CColorDialog.
                          2. Controls are now created to fill the full width of the tree control
                          3. Provided support for specifying a font via CFontDialog
                          4. Provided support for specifying a font name from a combo box
                          5. Provided support for specifying a boolean value from a combo box
         PJN / 27-11-2001 1. Fixed a bug where the message map for OnMouseWheel was setup incorrectly. It 
                          should have been ON_WM_MOUSEWHEEL instead of ON_MESSAGE!!!.
                          2. Allowed passing in the hAfter item for the InsertItem calls. All parms are defaulted 
                          as to not affect any current code.
                          3. Made possible the use of radio button groups followed by other items (in which case 
                          the group is considered complete).
                          4. Added a couple of utility functions at the bottom of the cpp file. Thanks to Mike
                          Funduc for all these updates.
         PJN / 05-11-2001 1. Minor code tidy up following development of the author's CTreeOptionsCtrl class
         PJN / 13-12-2001 1. Fixed an assertion in OnClick. Thanks to "flipposwitch" for spotting the problem
         PJN / 14-02-2002 1. Now allows item data to be associated with any item added to the control
                          2. Fixed issue with return value from GetUserItemData
         PJN / 02-06-2002 1. Moved sample app to VC 6 to facilitate support for IP Address control and date and
                          time controls.
                          2. Fixed a bug where the child controls can get orphaned when a node in the tree 
                          control is expaned or contracted. Thanks to Lauri Ott for spotting this problem.
                          3. Now fully supports the CDateTimeCtrl for editing of dates and times
                          4. Now fully supports the CIPAddressCtrl for editing of IP addresses
                          5. Custom draw support for color browser items is now configurable via an additional
                          parameter of the AddColorBrowser method
         PJN / 24-09-2002 1. Updated documentation which incorrectly stated that the parent of a check box item 
                          must be a group item as inserted with InsertGroup. Thanks to K鰃l Christoph for 
                          spotting this.
                          2. Fixed an issue with "IMPLEMENT_DYNAMIC(CDateTimeCtrl..." not being declared propertly. 
                          Some users reported that it worked ok, while others said that my fix was causing link 
                          problems. The problem should be sorted out for good now. Thanks to K鰃l Christoph for 
                          reporting this.
                          3. Renamed the SetImageListToUse function to "SetImageListResourceIDToUse".
                          4. Provided a GetImageListResourceIDToUse function to match up with the Set function.
                          5. Provided a method to allow the user item data to be changed after an item has 
                          been created.
                          6. Provided some documentation info how how to safely use item data in the control. 
                          Thanks to K鰃l Christoph for reporting this.
                          7. Fixed a potential memory leak in AddComboBox if the function is invoked twice without 
                          an explicit delete of the item first. Thanks to K鰃l Christoph for reporting this.
                          8. Fixed sometypos in the documentation. It incorectly stated that the return type of 
                          member functions InsertGroup, InsertCheckBox, and InsertRadioButton is BOOL when in fact 
                          it is HTREEITEM.  Thanks to K鰃l Christoph for reporting this.
                          9. Improved the look of the disabled checked check button. Thanks to K鰃l Christoph for 
                          reporting this.
                          10. Improved the look of the disabled radio button which is selected. Thanks to K鰃l 
                          Christoph for reporting this.
         PJN / 17-10-2002 1. Added a method to add an "Opaque Browser" to the Tree options control. An
                          Opaque Browser is where the tree options control allows a end user specified
                          structure to be edited by the tree options control without it explicitly
                          knowing what it is editing. 
         PJN / 25-10-2002 1. Updated the download to include the missing files OpaqueShow.cpp/h. Thanks to K鰃l 
                          Christoph for reporting this.
                          2. Made the class more const-correct. e.g. the Get... member functions are now const. 
                          Thanks to K鰃l Christoph for reporting this. Also updated the documentation for this.
                          3. Updated the documentation to refer to the "Opaque Browser" support.
         PJN / 28-10-2002 1. Fixed a bug where upon a combo losing focus it will also result in the associated
                          button control would also be destroyed. Thanks to K鰃l Christoph for reporting this
                          problem. Fixed this bug should also fix an intermittent release bug which was occurring
                          in this area.
         PJN / 30-10-2002 1. Made a number of other methods const. Thanks to K鰃l Christoph for reporting this.
         PJN / 15-11-2002 1. Now allows the Field Data separator i.e. ": " to be configured. Please note that the
                          characters you pick should be avoided in the descriptive text you display for an item 
                          as it is used as the divider between the descriptive text and the actual data to be 
                          edited. Thanks to K鰃l Christoph for this update.
                          2. Fixed an access violation in CTreeOptionsCtrl::OnSelchanged when there is no selected
                          item in the control. Thanks to K鰃l Christoph for this update.
         PJN / 06-03-2003 1. Fixed a memory leak which can occur when the control is used in a property sheet. 
                          Thanks to David Rainey for reporting this problem.
                          2. Fixed another memory leak in the destructor of the CTreeOptionsCtrl class when the
                          test app is closed
         PJN / 14-05-2003 1. Fixed a bug where the OnSelChanged function was getting in the way when the control was 
                          being cleared down, leading to an ASSERT. Thanks to Chen Fu for reporting this problem.
         PJN / 07-06-2003 1. Fixed a bug where the date time control was not reflecting the changes when the child
                          control was displayed. Thanks to Tom Serface for reporting this problem.
         PJN / 17-07-2003 1. Made SetRadioButton methods in CTreeOptionsCtrl virtual to allow further client 
                          customisation.



Copyright (c) 1999 - 2003 by PJ Naughter.  (Web: www.naughter.com, Email: pjna@naughter.com)

All rights reserved.

Copyright / Usage Details:

You are allowed to include the source code in any product (commercial, shareware, freeware or otherwise) 
when your product is released in binary form. You are allowed to modify the source code in any way you want 
except you cannot modify the copyright details at the top of each module. If you want to distribute source 
code with your application, then you are only allowed to distribute versions released by the author. This is 
to maintain a single distribution point for the source code. 

*/


//////////////// Includes ////////////////////////////////////////////

#include "stdafx.h"
#include "resource.h"
#ifndef _SHLOBJ_H_
#pragma message("To avoid this message, please put shlobj.h in your pre compiled header (normally stdafx.h)")
#include <shlobj.h>
#endif
#include "TreeOptionsCtrl.h"



//////////////// Macros / Locals /////////////////////////////////////

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

const UINT TREE_OPTIONS_COMBOBOX_ID = 100;
const UINT TREE_OPTIONS_EDITBOX_ID  = 101;
const UINT TREE_OPTIONS_SPINCTRL_ID = 102;
const UINT TREE_OPTIONS_BROWSEBUTTONCTRL_ID = 103;
const UINT TREE_OPTIONS_STATIC_ID = 104;
const UINT TREE_OPTIONS_DATETIMECTRL_ID  = 105;
const UINT TREE_OPTIONS_IPADDRESSCTRL_ID  = 106;

#define WM_TOC_SETFOCUS_TO_CHILD WM_APP + 1
#define WM_TOC_REPOSITION_CHILD_CONTROL WM_APP + 2



//////////////// Implementation //////////////////////////////////////

IMPLEMENT_DYNAMIC(CTreeOptionsCtrl, CTreeCtrl)

BEGIN_MESSAGE_MAP(CTreeOptionsCtrl, CTreeCtrl)
	//{{AFX_MSG_MAP(CTreeOptionsCtrl)
	ON_WM_LBUTTONDOWN()
	ON_WM_CHAR()
	ON_WM_DESTROY()
	ON_WM_VSCROLL()
	ON_WM_HSCROLL()
	ON_WM_KEYDOWN()
	ON_WM_KILLFOCUS()
	ON_WM_LBUTTONDOWN()
	//}}AFX_MSG_MAP
	ON_WM_MOUSEWHEEL()
	ON_MESSAGE(WM_TOC_SETFOCUS_TO_CHILD, OnSetFocusToChild)
	ON_MESSAGE(WM_TOC_REPOSITION_CHILD_CONTROL, OnRepositionChild)
	ON_NOTIFY_REFLECT_EX(NM_CLICK, OnClick)
	ON_NOTIFY_REFLECT_EX(TVN_SELCHANGED, OnSelchanged)
	ON_NOTIFY_REFLECT_EX(TVN_ITEMEXPANDING, OnItemExpanding)
	ON_NOTIFY_REFLECT_EX(TVN_DELETEITEM, OnDeleteItem)
	ON_NOTIFY_REFLECT_EX(NM_CUSTOMDRAW, OnCustomDraw)
END_MESSAGE_MAP()

CTreeOptionsCtrl::CTreeOptionsCtrl()
{
	m_pCombo = NULL;
	m_pEdit = NULL;
	m_pSpin = NULL;
	m_pButton = NULL;
	m_pDateTime = NULL;
	m_pIPAddress = NULL;
#ifdef IDB_TREE_CTRL_OPTIONS
	m_nilID = IDB_TREE_CTRL_OPTIONS;
#endif
	m_hControlItem = NULL;
	m_bToggleOverIconOnly = FALSE;
	m_bAutoSelect = FALSE;
	m_sSeparator = _T(": ");
	m_bBeingCleared = FALSE;
}

CTreeOptionsCtrl::~CTreeOptionsCtrl()
{
	DestroyOldChildControl();

	ASSERT(m_pCombo == NULL);
	ASSERT(m_pEdit == NULL);
	ASSERT(m_pSpin == NULL);
	ASSERT(m_pButton == NULL);
	ASSERT(m_pDateTime == NULL);
	ASSERT(m_pIPAddress == NULL);
}

LRESULT CTreeOptionsCtrl::OnSetFocusToChild(WPARAM /*wParam*/, LPARAM /*lParam*/)
{
	if (m_pCombo)
		m_pCombo->SetFocus();
	else if (m_pEdit)
		m_pEdit->SetFocus();
	else if (m_pDateTime)
		m_pDateTime->SetFocus();
	else if (m_pIPAddress)
		m_pIPAddress->SetFocus();

	return 0L;  
}

LRESULT CTreeOptionsCtrl::OnRepositionChild(WPARAM /*wParam*/, LPARAM /*lParam*/)
{
	HTREEITEM hItem = GetSelectedItem();
	if (hItem)
	{
		UpdateTreeControlValueFromChildControl(hItem);
		DestroyOldChildControl();
		CreateNewChildControl(hItem);
	}

	return 0L;
}

DWORD CTreeOptionsCtrl::GetUserItemData(HTREEITEM hItem) const
{
	CTreeOptionsItemData* pItemData = (CTreeOptionsItemData*) GetItemData(hItem);
	ASSERT(pItemData);
	return pItemData->m_dwItemData;
}

BOOL CTreeOptionsCtrl::SetUserItemData(HTREEITEM hItem, DWORD dwData)
{
	CTreeOptionsItemData* pItemData = (CTreeOptionsItemData*) GetItemData(hItem);
	ASSERT(pItemData);
	pItemData->m_dwItemData = dwData;
	return TRUE;
}

BOOL CTreeOptionsCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
	//Clean up any controls currently open we used
	if (m_hControlItem)
	{
		UpdateTreeControlValueFromChildControl(m_hControlItem);
		DestroyOldChildControl();
	}

	//Let the parent class do its thing
	return CTreeCtrl::OnMouseWheel(nFlags, zDelta, pt);
}

BOOL CTreeOptionsCtrl::OnDeleteItem(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;

	*pResult = 0;

	//Free up the memory we had allocated in the item data (if needed)
	CTreeOptionsItemData* pItemData = (CTreeOptionsItemData*) GetItemData(pNMTreeView->itemOld.hItem);
	if (pItemData)
		delete pItemData;

	return FALSE;
}

void CTreeOptionsCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags )
{
	if (nChar == VK_RIGHT)
	{
		HTREEITEM hItem = GetSelectedItem();
		if (GetItemData(hItem) && m_hControlItem != NULL)
		{ 
			// if we have a children and VK_RIGHT -> Focus on it !
			CTreeOptionsItemData* pItemData = (CTreeOptionsItemData*) GetItemData(hItem);
			if (pItemData->m_pRuntimeClass1->IsDerivedFrom(RUNTIME_CLASS(CTreeOptionsCombo)))
			{
				if (m_pCombo->IsWindowVisible())
					m_pCombo->SetFocus();
			}
			else if (pItemData->m_pRuntimeClass1->IsDerivedFrom(RUNTIME_CLASS(CTreeOptionsEdit)))
			{
				if (m_pEdit->IsWindowVisible())
					m_pEdit->SetFocus();
			}
			else if (pItemData->m_pRuntimeClass1->IsDerivedFrom(RUNTIME_CLASS(CTreeOptionsDateCtrl)))
			{
				if (m_pDateTime->IsWindowVisible())
					m_pDateTime->SetFocus();
			}
			else if (pItemData->m_pRuntimeClass1->IsDerivedFrom(RUNTIME_CLASS(CTreeOptionsIPAddressCtrl)))
			{
				if (m_pIPAddress->IsWindowVisible())
					m_pIPAddress->SetFocus();
			}
			else if (pItemData->m_pRuntimeClass1->IsDerivedFrom(RUNTIME_CLASS(CTreeOptionsBrowseButton)))
			{
				if (m_pButton->IsWindowVisible())
					m_pButton->SetFocus();
			}
			else
			{
				//Pass on to the parent since we didn't handle it
				CTreeCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
			}
		}
		else
		{
			//Pass on to the parent since we didn't handle it
			CTreeCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
		}
	}
	else
	{
		//Pass on to the parent since we didn't handle it
		CTreeCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
	}
}

void CTreeOptionsCtrl::HandleCheckBox(HTREEITEM hItem, BOOL bCheck)
{
	//Turn of redraw to Q all the changes we're going to make here
	SetRedraw(FALSE);

	//Toggle the state
	VERIFY(SetCheckBox(hItem, !bCheck));

	//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))
			SetCheckBox(hChild, !bCheck);  

		//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);
	if (hParent && IsCheckBox(hParent))
	{
		BOOL bNoCheckBoxesChecked = TRUE;
		BOOL bAllCheckBoxesChecked = TRUE;
		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)
			SetCheckBox(hParent, FALSE);
		else if (bAllCheckBoxesChecked)
		{
			SetCheckBox(hParent, FALSE); //gets rid of the semi state
			SetCheckBox(hParent, TRUE);
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -