2025-11-27 16:46:48 +09:00

795 lines
20 KiB
C++

// ==========================================================================
// Class Implementation : COXPropertiesWnd
// ==========================================================================
// Source file : OXPropertiesWnd.cpp
// 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 "OXPropertiesWnd.h"
#include "OXListEdit.h"
#include "OXMaskedEdit.h"
#include "OXSkins.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#pragma warning(disable : 4355)
/////////////////////////////////////////////////////////////////////////////
// COXPropertiesWnd
COXPropertiesWnd::COXPropertiesWnd() :
m_wndTree(this)
{
m_bSortCategories = TRUE;
m_bCategorized = TRUE;
m_hCurrentProp = NULL;
m_pEditWnd = NULL;
m_hEditProp = NULL;
m_pFrameSkin = NULL;
}
COXPropertiesWnd::~COXPropertiesWnd()
{
m_mapProp2Cat.RemoveAll();
m_mapProp2Desc.RemoveAll();
m_mapProp2Editor.RemoveAll();
m_listCategories.RemoveAll();
}
BEGIN_MESSAGE_MAP(COXPropertiesWnd, CFrameWnd)
//{{AFX_MSG_MAP(COXPropertiesWnd)
ON_WM_CREATE()
ON_WM_SIZE()
ON_COMMAND(ID_CATEGORIZED, OnCategorized)
ON_COMMAND(ID_ALPHABETIC, OnAlphabetic)
ON_WM_PAINT()
ON_UPDATE_COMMAND_UI(ID_CATEGORIZED, OnUpdateCategorized)
ON_UPDATE_COMMAND_UI(ID_ALPHABETIC, OnUpdateAlphabetic)
//}}AFX_MSG_MAP
ON_NOTIFY(LVN_ITEMCHANGED, _TREE_ID, OnItemChanged)
ON_MESSAGE(WM_USER_QUERY_PROPERTIESWND, OnQueryPropertiesWnd)
ON_MESSAGE(WM_USER_STARTEDITING, OnStartEditing)
ON_MESSAGE(WM_USER_ADJUSTLASTCOLUMN, OnUserAdjustLastColumn)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// COXPropertiesWnd message handlers
int COXPropertiesWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
ModifyStyleEx(WS_EX_CLIENTEDGE, 0);
// Create the combo
if (!m_wndCombo.Create(WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST, CRect(0, 0, 0, 300), this, _COMBO_ID))
{
TRACE0("Failed to create the combo box.\n");
return -1; // fail to create
}
// Create the toolbar
if (!m_wndToolBar.Create(this,
WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC,
IDR_PROPERTIES_TOOLBAR) || !m_wndToolBar.LoadToolBar(IDR_PROPERTIES_TOOLBAR))
{
TRACE0("Failed to create toolbar.\n");
return -1; // fail to create
}
m_wndToolBar.SetOwner(this);
// Create the category list
if (!m_wndTree.Create(WS_CHILD | WS_VISIBLE | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_SHOWSELALWAYS,
CRect(0, 0, 0, 0), this, _TREE_ID,
TVOXS_VGRID | TVOXS_HGRID | TVOXS_COLUMNHDR | TVOXS_NOSORTHEADER | TVOXS_NOFOCUSRECT |
TVOXS_EXTENDCOLUMNS | TVOXS_ROWSEL | TVOXS_FLGRID))
{
TRACE0("Failed to create the category list.\n");
return -1; // fail to create
}
// Create the description pane
// Create the combo
if (!m_wndDescription.Create(NULL, NULL, WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), this, _DESCRIPTION_ID))
{
TRACE0("Failed to create the description pane.\n");
return -1; // fail to create
}
m_wndTree.SetHorizontalGridColor(::GetSysColor(COLOR_3DFACE));
m_wndTree.SetVerticalGridColor(::GetSysColor(COLOR_3DFACE));
// Set up the two columns
LV_COLUMN lvc;
memset(&lvc, 0, sizeof(lvc));
lvc.fmt = LVCFMT_LEFT;
lvc.cx = 100;
lvc.pszText = _T("Property");
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
m_wndTree.SetColumn(0,&lvc);
m_wndTree.InsertColumn(1, _T("Value"), LVCFMT_LEFT, 100, 1);
m_wndTree.m_wndEdit.SetBorder(FALSE);
return 0;
}
void COXPropertiesWnd::OnSize(UINT nType, int cx, int cy)
{
CFrameWnd::OnSize(nType, cx, cy);
CRect rectClient;
GetClientRect(rectClient);
m_wndCombo.MoveWindow(rectClient);
// Get the height of the combo box
CRect rectCombo;
m_wndCombo.GetClientRect(rectCombo);
if (!(m_wndCombo.GetStyle() & WS_VISIBLE))
rectCombo.bottom = rectCombo.top;
// Position the toolbar below the combo box
CRect rectToolBar = rectClient;
rectToolBar.top += rectCombo.Height();
rectToolBar.bottom = rectToolBar.top + 25;
m_wndToolBar.MoveWindow(rectToolBar);
if (!(m_wndToolBar.GetStyle() & WS_VISIBLE))
rectToolBar.bottom = rectToolBar.top;
// Position the description pane at the bottom
CRect rectDescription = rectClient;
rectDescription.top = rectDescription.bottom - 50;
m_wndDescription.MoveWindow(rectDescription);
if (!(m_wndDescription.GetStyle() & WS_VISIBLE))
rectDescription.bottom = rectDescription.top;
// Position the tree in the space that remains
CRect rectTree = rectClient;
rectTree.top += rectCombo.Height() + rectToolBar.Height();
rectTree.bottom -= rectDescription.Height();
rectTree.DeflateRect(1, 1);
m_wndTree.MoveWindow(rectTree);
// If an item is being edited reposition the editor
if (m_pEditWnd != NULL)
{
HPROPERTY hSelectedProp = GetSelectedProperty();
CRect rectSubItem;
int iItemIndex = m_wndTree.GetItemIndex(hSelectedProp);
m_wndTree.GetSubItemRect(iItemIndex, 1, LVIR_LABEL, rectSubItem);
rectSubItem.DeflateRect(0, 0, 1, 1);
m_pEditWnd->MoveWindow(rectSubItem);
}
}
void COXPropertiesWnd::OnCategorized()
{
if (m_bCategorized)
return;
m_bCategorized = TRUE;
m_wndTree.ModifyStyle(0, TVS_LINESATROOT);
// Insert the categories
POSITION catpos = m_listCategories.GetHeadPosition();
for(int i=0; i<m_listCategories.GetCount(); i++)
{
InsertCategory(m_listCategories.GetNext(catpos));
}
// Re-insert all properties under their categories
POSITION pos = m_mapProp2Cat.GetStartPosition();
while (pos != NULL)
{
HPROPERTY hProp;
CString strCategory;
m_mapProp2Cat.GetNextAssoc(pos, hProp, strCategory);
// Insert the category if it hasn't been inserted yet
HCATEGORY hCategory = m_wndTree.GetRootItem();
if (strCategory.IsEmpty() == FALSE)
{
hCategory= FindCategory(strCategory);
if (hCategory == NULL)
hCategory = InsertCategory(strCategory);
}
if (hCategory != m_wndTree.GetRootItem())
{
m_wndTree.MoveItem(hProp, hCategory);
m_wndTree.SortChildren(hCategory);
}
}
// Sort
if(m_bSortCategories)
m_wndTree.SortChildren(m_wndTree.GetRootItem());
}
void COXPropertiesWnd::OnAlphabetic()
{
if (!m_bCategorized)
return;
m_bCategorized = FALSE;
m_wndTree.ModifyStyle(TVS_LINESATROOT, 0);
// Remove all categories from the tree and insert all items directly under the root item
// If a root item is not in m_mapProp2Cat when it needs to be removed
HTREEITEM hRoot = m_wndTree.GetRootItem();
if (m_wndTree.ItemHasChildren(hRoot))
{
HCATEGORY hNextCat, hCat = m_wndTree.GetChildItem(hRoot);
while (hCat != NULL)
{
CString strDummy;
hNextCat = m_wndTree.GetNextItem(hCat, TVGN_NEXT);
if (!m_mapProp2Cat.Lookup(hCat, strDummy))
{
// This is a category, so move all its children to the root and delete it
HPROPERTY hNextProp, hProp = m_wndTree.GetChildItem(hCat);
while (hProp != NULL)
{
hNextProp = m_wndTree.GetNextItem(hProp, TVGN_NEXT);
m_wndTree.MoveItem(hProp, hRoot);
hProp = hNextProp;
}
m_wndTree.DeleteItem(hCat);
}
hCat = hNextCat;
}
}
// Now sort all items under the root
m_wndTree.SortChildren(hRoot);
}
HCATEGORY COXPropertiesWnd::InsertCategory(LPCTSTR lpszCategoryName)
{
HCATEGORY hCategory = m_wndTree.InsertItem(lpszCategoryName);
m_wndTree.SetItemBackColor(hCategory, ::GetSysColor(COLOR_3DFACE));
m_wndTree.SetSubItem(hCategory, 1, OX_SUBITEM_BGCOLOR, NULL, 0, NULL, 0, ::GetSysColor(COLOR_3DFACE));
CStringArray saDummy;
m_wndTree.SetEditMode(hCategory, OXET_NOEDIT, saDummy, 0);
m_wndTree.SetEditMode(hCategory, OXET_NOEDIT, saDummy, 1);
m_wndTree.Expand(hCategory, TVE_EXPAND);
return hCategory;
}
HCATEGORY COXPropertiesWnd::FindCategory(LPCTSTR lpszCategory)
{
HTREEITEM hRoot = m_wndTree.GetRootItem();
if (m_wndTree.ItemHasChildren(hRoot))
{
HTREEITEM hNextItem, hChildItem = m_wndTree.GetChildItem(hRoot);
while (hChildItem != NULL)
{
hNextItem = m_wndTree.GetNextItem(hChildItem, TVGN_NEXT);
if (m_wndTree.GetItemText(hChildItem) == lpszCategory)
return hChildItem;
hChildItem = hNextItem;
}
}
return NULL;
}
HPROPERTY COXPropertiesWnd::InsertProperty(LPCTSTR lpszName,
LPCTSTR lpszInitialValue,
LPCTSTR lpszDescription,
LPCTSTR lpszCategory,
CEdit* pEditorClass)
{
if (pEditorClass != NULL)
{
ASSERT(pEditorClass->IsKindOf(RUNTIME_CLASS(CWnd)));
}
HCATEGORY hCategory = NULL;
if (lpszCategory != NULL)
{
hCategory= FindCategory(lpszCategory);
if (hCategory == NULL)
{
hCategory = InsertCategory(lpszCategory);
CString tmpStr = lpszCategory;
m_listCategories.AddTail(tmpStr);
}
}
HPROPERTY hProp = m_wndTree.InsertItem(lpszName, hCategory);
if (hProp == NULL)
return NULL;
// Insert the sub item
m_wndTree.SetSubItem(hProp, 1, 0, NULL);
// Set up the editing mode to none
CStringArray saDummy;
m_wndTree.SetEditMode(hProp, OXET_NOEDIT, saDummy, 0);
m_wndTree.SetEditMode(hProp, OXET_NOEDIT, saDummy, 1);
// Sort
if (hCategory != NULL)
m_wndTree.SortChildren(hCategory);
else
{
if(m_bSortCategories)
m_wndTree.SortChildren(m_wndTree.GetRootItem());
else
m_wndTree.MoveItem(hProp,m_wndTree.GetRootItem(),TVI_FIRST);
}
// Insert an entry in the property to category map
CString strCategory = _T("");
if (hCategory != NULL)
strCategory = m_wndTree.GetItemText(hCategory);
m_mapProp2Cat.SetAt(hProp, strCategory);
// Insert an entry in the property to description map
m_mapProp2Desc.SetAt(hProp, lpszDescription);
// Insert an entry to the editor map
if (pEditorClass != NULL)
m_mapProp2Editor.SetAt(hProp, pEditorClass);
// Set the initial value (if any)
if (lpszInitialValue != NULL)
SetPropertyValue(hProp, lpszInitialValue);
return hProp;
}
BOOL COXPropertiesWnd::DeleteProperty(HPROPERTY hProperty)
{
ASSERT(hProperty != NULL);
FinishEditing();
if (!OnDeleteProperty(hProperty))
return FALSE;
HTREEITEM hParent = m_wndTree.GetParentItem(hProperty);
// Remove the property handle from the maps
m_mapProp2Cat.RemoveKey(hProperty);
m_mapProp2Desc.RemoveKey(hProperty);
m_mapProp2Editor.RemoveKey(hProperty);
BOOL bRes = m_wndTree.DeleteItem((HTREEITEM) hProperty);
if (hParent != m_wndTree.GetRootItem())
{
// The parent is a category
COXTreeItem* pParent = m_wndTree.GetXItem(hParent);
if (pParent->GetChildrenCount() == 0)
{
CString strCategory = m_wndTree.GetItemText(hParent);
if(POSITION pos = m_listCategories.Find(strCategory))
{
m_listCategories.RemoveAt(pos);
}
m_wndTree.DeleteItem(hParent); // delete the empty category
}
}
return bRes;
}
BOOL COXPropertiesWnd::SetPropertyValue(HPROPERTY hProperty, LPCTSTR lpszValue)
{
ASSERT(hProperty != NULL);
return m_wndTree.SetItemText(hProperty, lpszValue, 1);
}
CString COXPropertiesWnd::GetPropertyValue(HPROPERTY hProperty)
{
ASSERT(hProperty != NULL);
return m_wndTree.GetItemText(hProperty, 1);
}
HPROPERTY COXPropertiesWnd::FindProperty(LPCTSTR lpszName, LPCTSTR lpszCategory)
{
// First try to find the category
HCATEGORY hCategory = NULL;
if (lpszCategory != NULL)
hCategory = FindCategory(lpszCategory);
HTREEITEM hParent = hCategory;
if (hParent == NULL)
hParent = m_wndTree.GetRootItem();
// At this point we know that if the property exist it is a child of hParent
if (m_wndTree.ItemHasChildren(hParent))
{
HTREEITEM hNextItem, hChildItem = m_wndTree.GetChildItem(hParent);
while (hChildItem != NULL)
{
hNextItem = m_wndTree.GetNextItem(hChildItem, TVGN_NEXT);
if (m_wndTree.GetItemText(hChildItem) == lpszName)
return hChildItem;
hChildItem = hNextItem;
}
}
return NULL;
}
void COXPropertiesWnd::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
CRect rectClient;
GetClientRect(rectClient);
dc.FillSolidRect(rectClient, GetFrameSkin()->GetBackgroundColor());
CBrush brBackground;
brBackground.CreateSolidBrush(::GetSysColor(COLOR_3DFACE));
dc.FrameRect(rectClient, &brBackground);
// Draw a gray border around the tree
CRect rectTree;
m_wndTree.GetWindowRect(rectTree);
ScreenToClient(rectTree);
rectTree.InflateRect(1, 1);
CBrush brBorder;
brBorder.CreateSolidBrush(GetFrameSkin()->GetBorderColor());
dc.FrameRect(rectTree, &brBorder);
}
void COXPropertiesWnd::PostNcDestroy()
{
// DO NOTHING
}
void COXPropertiesWnd::OnUpdateCategorized(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(m_bCategorized);
}
void COXPropertiesWnd::OnUpdateAlphabetic(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(!m_bCategorized);
}
void COXPropertiesWnd::SetCategorized(BOOL bCategorized)
{
m_bCategorized = bCategorized;
if (bCategorized)
OnCategorized();
else
OnAlphabetic();
}
CComboBoxEx& COXPropertiesWnd::GetComboBoxEx()
{
return m_wndCombo;
}
COXCoolToolBar& COXPropertiesWnd::GetToolBar()
{
return m_wndToolBar;
}
void COXPropertiesWnd::ShowCombo(BOOL bShow)
{
if (bShow)
m_wndCombo.ModifyStyle(0, WS_VISIBLE);
else
m_wndCombo.ModifyStyle(WS_VISIBLE, 0);
}
void COXPropertiesWnd::ShowToolBar(BOOL bShow)
{
if (bShow)
m_wndToolBar.ModifyStyle(0, WS_VISIBLE);
else
m_wndToolBar.ModifyStyle(WS_VISIBLE, 0);
}
void COXPropertiesWnd::ShowDescription(BOOL bShow)
{
if (bShow)
m_wndDescription.ModifyStyle(0, WS_VISIBLE);
else
m_wndDescription.ModifyStyle(WS_VISIBLE, 0);
}
HPROPERTY COXPropertiesWnd::GetSelectedProperty()
{
HTREEITEM hSelected = m_wndTree.GetNextItem(TVI_ROOT, TVGN_FIRSTSELECTED);
if (hSelected == NULL)
return NULL; // no property is selected
CString strDummy;
if (m_mapProp2Cat.Lookup(hSelected, strDummy))
return hSelected; // this is indeed a property;
else
return NULL; // it is a category
}
BOOL COXPropertiesWnd::OnPropertyValueChanged(HPROPERTY /*hProperty*/, LPCTSTR /*lpszOldValue*/, LPCTSTR /*lpszNewValue*/)
{
return TRUE; // accept the new value
}
void COXPropertiesWnd::OnItemChanged(NMHDR* /*pNMHDR*/, LRESULT* /*pResult*/)
{
CString strName, strDescription;
HPROPERTY hSelectedProp = GetSelectedProperty();
if (hSelectedProp == NULL)
{
strName = _T("");
strDescription = _T("");
}
else
{
strName = m_wndTree.GetItemText(hSelectedProp);
m_mapProp2Desc.Lookup(hSelectedProp, strDescription);
SendMessage(WM_USER_STARTEDITING, 0, (LPARAM) hSelectedProp);
}
m_wndDescription.SetDescription(strName, strDescription);
}
LRESULT COXPropertiesWnd::OnQueryPropertiesWnd(WPARAM /*wParam*/, LPARAM /*lParam*/)
{
return TRUE; // yes, this is a COXPropertiesWnd
}
LRESULT COXPropertiesWnd::OnStartEditing(WPARAM /*wParam*/, LPARAM lParam)
{
HPROPERTY hSelectedProp = (HPROPERTY) lParam;
// Finish editing first
if (m_pEditWnd != NULL)
FinishEditing();
else
StartEditing(hSelectedProp);
return 0;
}
void COXPropertiesWnd::StartEditing(HPROPERTY hSelectedProp)
{
// Create the editing control and place it over the sub-item
CEdit* pEditor;
BOOL bFound = m_mapProp2Editor.Lookup(hSelectedProp, pEditor);
if (bFound)
{
m_pEditWnd = pEditor;
CRect rectSubItem;
int iItemIndex = m_wndTree.GetItemIndex(hSelectedProp);
m_wndTree.GetSubItemRect(iItemIndex, 1, LVIR_LABEL, rectSubItem);
rectSubItem.DeflateRect(0, 0, 1, 1);
// Create the editor window if not created already
if (!::IsWindow(m_pEditWnd->m_hWnd))
m_pEditWnd->Create(WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL, rectSubItem, &m_wndTree, _EDITOR_ID);
else
{
m_pEditWnd->MoveWindow(rectSubItem);
m_pEditWnd->ShowWindow(SW_SHOW);
}
m_pEditWnd->SetOwner(&m_wndTree);
m_pEditWnd->SetFont(m_wndTree.GetFont());
// Set the text of the editing window
CString strText = GetPropertyValue(hSelectedProp);
COXEdit* pOXEdit = DYNAMIC_DOWNCAST(COXEdit, m_pEditWnd);
COXMaskedEdit* pOXMaskedEdit = DYNAMIC_DOWNCAST(COXMaskedEdit, m_pEditWnd);
if (pOXEdit != NULL)
{
pOXEdit->EmptyData();
pOXEdit->SetInputData(strText);
}
else if (pOXMaskedEdit != NULL)
pOXMaskedEdit->SetText(strText);
else
m_pEditWnd->SetWindowText(strText);
m_hEditProp = hSelectedProp;
}
}
void COXPropertiesWnd::FinishEditing(BOOL bSave)
{
if (m_hEditProp == NULL) {
return;
}
if (bSave)
{
// Call OnPropertyValueChanged(...) and save the value
CString strText;
COXMaskedEdit* pMaskedEdit = DYNAMIC_DOWNCAST(COXMaskedEdit, m_pEditWnd);
if (pMaskedEdit != NULL)
strText = pMaskedEdit->GetText();
else
m_pEditWnd->GetWindowText(strText);
BOOL bSaveValue = OnPropertyValueChanged(m_hEditProp,
GetPropertyValue(m_hEditProp), strText);
if (bSaveValue)
SetPropertyValue(m_hEditProp, strText);
}
// Hide the editor
m_pEditWnd->ShowWindow(SW_HIDE);
m_pEditWnd = NULL;
m_hEditProp = NULL;
m_wndTree.SelectItem(NULL);
}
BOOL COXPropertiesWnd::PreTranslateMessage(MSG* pMsg)
{
return CFrameWnd::PreTranslateMessage(pMsg);
}
LRESULT COXPropertiesWnd::OnUserAdjustLastColumn(WPARAM /*wParam*/, LPARAM /*lParam*/)
{
// If an item is being edited reposition the editor
if (m_pEditWnd != NULL)
{
HPROPERTY hSelectedProp = GetSelectedProperty();
CRect rectSubItem;
int iItemIndex = m_wndTree.GetItemIndex(hSelectedProp);
m_wndTree.GetSubItemRect(iItemIndex, 1, LVIR_LABEL, rectSubItem);
rectSubItem.DeflateRect(0, 0, 1, 1);
m_pEditWnd->MoveWindow(rectSubItem);
}
return 0;
}
BOOL COXPropertiesWnd::IsDescendant(CWnd* pWndParent, CWnd* pWndChild)
// helper for detecting whether child descendent of parent
// (works with owned popups as well)
{
ASSERT(pWndParent!=NULL);
ASSERT(::IsWindow(pWndParent->GetSafeHwnd()));
ASSERT(pWndChild!=NULL);
ASSERT(::IsWindow(pWndChild->GetSafeHwnd()));
HWND hWndParent=pWndParent->GetSafeHwnd();
HWND hWndChild=pWndChild->GetSafeHwnd();
do
{
if (hWndParent == hWndChild)
return TRUE;
// check for permanent-owned window first
CWnd* pWnd=CWnd::FromHandlePermanent(hWndChild);
if(pWnd!=NULL)
hWndChild=pWnd->GetOwner()->GetSafeHwnd();
else
hWndChild=(::GetWindowLongPtr(hWndChild,GWL_STYLE)&WS_CHILD) ?
::GetParent(hWndChild) : ::GetWindow(hWndChild,GW_OWNER);
} while (hWndChild != NULL);
return FALSE;
}
BOOL COXPropertiesWnd::OnDeleteProperty(HPROPERTY /*hProperty*/)
{
return TRUE;
}
BOOL COXPropertiesWnd::DeleteAll()
{
// Loop through all the properties using the m_mapProp2Cat map
CArray<HPROPERTY, HPROPERTY> arrToBeDeleted;
POSITION pos = m_mapProp2Cat.GetStartPosition();
while (pos != NULL)
{
HPROPERTY hProperty;
CString strCategory;
m_mapProp2Cat.GetNextAssoc(pos, hProperty, strCategory);
arrToBeDeleted.Add(hProperty);
}
BOOL bAllDeleted = TRUE;
for (int i = 0; i < arrToBeDeleted.GetSize(); i++)
if (!DeleteProperty(arrToBeDeleted[i]))
bAllDeleted = FALSE;
return bAllDeleted;
}
COXFrameSkin* COXPropertiesWnd::GetFrameSkin()
{
// Check if the app is derived from COXSkinnedApp
COXSkinnedApp* pSkinnedApp = DYNAMIC_DOWNCAST(COXSkinnedApp, AfxGetApp());
if (pSkinnedApp != NULL && pSkinnedApp->GetCurrentSkin() != NULL)
return pSkinnedApp->GetCurrentSkin()->GetFrameSkin();
else
{
// Create a classic skin for this class if not created already
if (m_pFrameSkin == NULL)
m_pFrameSkin = new COXFrameSkinClassic();
return m_pFrameSkin;
}
}
void COXPropertiesWnd::SetSortCategories(BOOL bSortCategories /*= TRUE*/ )
{
m_bSortCategories = bSortCategories;
}
/*
Used to jump to the next property (if it's the end of the current
category, the first property in the next category gets selected).
Nish - June 14, 2005
*/
BOOL COXPropertiesWnd::SelectNextProperty()
{
HTREEITEM hSelected = m_wndTree.GetNextItem(TVI_ROOT, TVGN_FIRSTSELECTED);
if (hSelected == NULL)
return FALSE; // no property is selected
HTREEITEM hNext = m_wndTree.GetNextItem(hSelected, TVGN_CHILD);
if (hNext == NULL)
hNext = m_wndTree.GetNextItem(hSelected, TVGN_NEXT);
if (hNext == NULL)
hNext = m_wndTree.GetNextItem(m_wndTree.GetParentItem(hSelected), TVGN_NEXT);
if (hNext == NULL)
return FALSE; // no more properties
FinishEditing(FALSE);
m_wndTree.SelectItem(hNext);
m_wndTree.SetItemState(hNext,LVIS_SELECTED, LVIS_SELECTED);
StartEditing(hNext);
if(m_wndTree.ItemHasChildren(hNext))
return SelectNextProperty();
return TRUE;
}