hello world

This commit is contained in:
Timothee 'TTimo' Besset
2011-11-22 15:28:15 -06:00
commit fb1609f554
2155 changed files with 1017022 additions and 0 deletions

View File

@@ -0,0 +1,923 @@
// PropTree.cpp : implementation file
//
// Copyright (C) 1998-2001 Scott Ramsay
// sramsay@gonavi.com
// http://www.gonavi.com
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// If you use this code, drop me an email. I'd like to know if you find the code
// useful.
//#include "stdafx.h"
#include "../../../idlib/precompiled.h"
#pragma hdrstop
#include "PropTree.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define PROPTREEITEM_EXPANDCOLUMN 16 // width of the expand column
#define PROPTREEITEM_COLRNG 5 // width of splitter
//static AFX_EXTENSION_MODULE PropTreeDLL = {NULL, NULL};
static const CString strOfficeFontName = _T("Tahoma");
static const CString strDefaultFontName = _T("MS Sans Serif");
HINSTANCE ghInst;
/*extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
TRACE0("PROPTREE.DLL Initializing!\n");
if (!AfxInitExtensionModule(PropTreeDLL, hInstance))
return 0;
new CDynLinkLibrary(PropTreeDLL);
ghInst = hInstance;
}
else if (dwReason == DLL_PROCESS_DETACH)
{
TRACE0("PROPTREE.DLL Terminating!\n");
AfxTermExtensionModule(PropTreeDLL);
}
return 1;
}*/
void InitPropTree(HINSTANCE hInstance) {
ghInst = hInstance;
}
static int CALLBACK FontFamilyProcFonts(const LOGFONT FAR* lplf, const TEXTMETRIC FAR*, ULONG, LPARAM)
{
ASSERT(lplf != NULL);
CString strFont = lplf->lfFaceName;
return strFont.CollateNoCase (strOfficeFontName) == 0 ? 0 : 1;
}
/////////////////////////////////////////////////////////////////////////////
// CPropTree
UINT CPropTree::s_nInstanceCount;
CFont* CPropTree::s_pNormalFont;
CFont* CPropTree::s_pBoldFont;
CPropTreeItem* CPropTree::s_pFound;
CPropTree::CPropTree() :
m_bShowInfo(TRUE),
m_nInfoHeight(50),
m_pVisbleList(NULL),
m_Origin(100,0),
m_nLastUID(1),
m_pFocus(NULL),
m_bDisableInput(FALSE)
{
m_Root.Expand();
// init global resources only once
if (!s_nInstanceCount)
InitGlobalResources();
s_nInstanceCount++;
}
CPropTree::~CPropTree()
{
DeleteAllItems();
s_nInstanceCount--;
// free global resource when ALL CPropTrees are destroyed
if (!s_nInstanceCount)
FreeGlobalResources();
}
BEGIN_MESSAGE_MAP(CPropTree, CWnd)
//{{AFX_MSG_MAP(CPropTree)
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_ENABLE()
ON_WM_SYSCOLORCHANGE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPropTree message handlers
const POINT& CPropTree::GetOrigin()
{
return m_Origin;
}
BOOL CPropTree::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
{
CWnd* pWnd = this;
LPCTSTR pszCreateClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW, ::LoadCursor(NULL, IDC_ARROW));
return pWnd->Create(pszCreateClass, _T(""), dwStyle, rect, pParentWnd, nID);
}
int CPropTree::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
DWORD dwStyle;
CRect rc;
GetClientRect(rc);
// create CPropTreeList
//
dwStyle = WS_VISIBLE|WS_CHILD|WS_VSCROLL;
if (!m_List.Create(dwStyle, rc, this, 100))
{
TRACE0("Failed to create CPropTreeList\n");
return -1;
}
m_List.SetPropOwner(this);
// create CPropTreeInfo
//
dwStyle &= ~WS_VSCROLL;
if (!m_Info.Create(_T(""), dwStyle, rc, this))
{
TRACE0("Failed to create CPropTreeInfo\n");
return -1;
}
m_Info.SetPropOwner(this);
return 0;
}
CWnd* CPropTree::GetCtrlParent()
{
return &m_List;
}
void CPropTree::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
ResizeChildWindows(cx, cy);
}
void CPropTree::ResizeChildWindows(int cx, int cy)
{
if (m_bShowInfo)
{
if (IsWindow(m_List.m_hWnd))
m_List.MoveWindow(0, 0, cx, cy - m_nInfoHeight);
if (IsWindow(m_Info.m_hWnd))
m_Info.MoveWindow(0, cy - m_nInfoHeight, cx, m_nInfoHeight);
}
else
{
if (IsWindow(m_List.m_hWnd))
m_List.MoveWindow(0, 0, cx, cy);
}
}
void CPropTree::InitGlobalResources()
{
NONCLIENTMETRICS info;
info.cbSize = sizeof(info);
::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0);
LOGFONT lf;
memset(&lf, 0, sizeof (LOGFONT));
CWindowDC dc(NULL);
lf.lfCharSet = (BYTE)GetTextCharsetInfo(dc.GetSafeHdc(), NULL, 0);
lf.lfHeight = info.lfMenuFont.lfHeight;
lf.lfWeight = info.lfMenuFont.lfWeight;
lf.lfItalic = info.lfMenuFont.lfItalic;
// check if we should use system font
_tcscpy(lf.lfFaceName, info.lfMenuFont.lfFaceName);
BOOL fUseSystemFont = (info.lfMenuFont.lfCharSet > SYMBOL_CHARSET);
if (!fUseSystemFont)
{
// check for "Tahoma" font existance:
if (::EnumFontFamilies(dc.GetSafeHdc(), NULL, FontFamilyProcFonts, 0)==0)
{
// Found! Use MS Office font!
_tcscpy(lf.lfFaceName, strOfficeFontName);
}
else
{
// Not found. Use default font:
_tcscpy(lf.lfFaceName, strDefaultFontName);
}
}
s_pNormalFont = new CFont;
s_pNormalFont->CreateFontIndirect(&lf);
lf.lfWeight = FW_BOLD;
s_pBoldFont = new CFont;
s_pBoldFont->CreateFontIndirect(&lf);
}
void CPropTree::FreeGlobalResources()
{
if (s_pNormalFont)
{
delete s_pNormalFont;
s_pNormalFont = NULL;
}
if (s_pBoldFont)
{
delete s_pBoldFont;
s_pBoldFont = NULL;
}
}
CFont* CPropTree::GetNormalFont()
{
return s_pNormalFont;
}
CFont* CPropTree::GetBoldFont()
{
return s_pBoldFont;
}
CPropTreeItem* CPropTree::GetFocusedItem()
{
return m_pFocus;
}
CPropTreeItem* CPropTree::GetRootItem()
{
return &m_Root;
}
void CPropTree::ClearVisibleList()
{
m_pVisbleList = NULL;
}
CPropTreeItem* CPropTree::GetVisibleList()
{
return m_pVisbleList;
}
void CPropTree::AddToVisibleList(CPropTreeItem* pItem)
{
if (!pItem)
return;
// check for an empty visible list
if (!m_pVisbleList)
m_pVisbleList = pItem;
else
{
// Add the new item to the end of the list
CPropTreeItem* pNext;
pNext = m_pVisbleList;
while (pNext->GetNextVisible())
pNext = pNext->GetNextVisible();
pNext->SetNextVisible(pItem);
}
pItem->SetNextVisible(NULL);
}
BOOL CPropTree::EnumItems(CPropTreeItem* pItem, ENUMPROPITEMPROC proc, LPARAM lParam)
{
if (!pItem || !proc)
return FALSE;
CPropTreeItem* pNext;
// don't count the root item in any enumerations
if (pItem!=&m_Root && !proc(this, pItem, lParam))
return FALSE;
// recurse thru all child items
pNext = pItem->GetChild();
while (pNext)
{
if (!EnumItems(pNext, proc, lParam))
return FALSE;
pNext = pNext->GetSibling();
}
return TRUE;
}
void CPropTree::SetOriginOffset(LONG nOffset)
{
m_Origin.y = nOffset;
}
void CPropTree::UpdatedItems()
{
if (!IsWindow(m_hWnd))
return;
Invalidate();
m_List.UpdateResize();
m_List.Invalidate();
}
void CPropTree::DeleteAllItems()
{
Delete(NULL);
UpdatedItems();
m_nLastUID = 1; // reset uid counter
}
void CPropTree::DeleteItem(CPropTreeItem* pItem)
{
Delete(pItem);
UpdatedItems();
}
LONG CPropTree::GetColumn()
{
return m_Origin.x;
}
void CPropTree::SetColumn(LONG nColumn)
{
CRect rc;
GetClientRect(rc);
if (rc.IsRectEmpty())
nColumn = __max(PROPTREEITEM_EXPANDCOLUMN, nColumn);
else
nColumn = __min(__max(PROPTREEITEM_EXPANDCOLUMN, nColumn), rc.Width() - PROPTREEITEM_EXPANDCOLUMN);
m_Origin.x = nColumn;
Invalidate();
}
void CPropTree::Delete(CPropTreeItem* pItem)
{
if (pItem && pItem!=&m_Root && SendNotify(PTN_DELETEITEM, pItem))
return;
// passing in a NULL item is the same as calling DeleteAllItems
if (!pItem)
pItem = &m_Root;
// Clear the visible list before anything gets deleted
ClearVisibleList();
// delete children
CPropTreeItem* pIter;
CPropTreeItem* pNext;
pIter = pItem->GetChild();
while (pIter)
{
pNext = pIter->GetSibling();
DeleteItem(pIter);
pIter = pNext;
}
// unlink from tree
if (pItem->GetParent())
{
if (pItem->GetParent()->GetChild()==pItem)
pItem->GetParent()->SetChild(pItem->GetSibling());
else
{
pIter = pItem->GetParent()->GetChild();
while (pIter->GetSibling() && pIter->GetSibling()!=pItem)
pIter = pIter->GetSibling();
if (pIter->GetSibling())
pIter->SetSibling(pItem->GetSibling());
}
}
if (pItem!=&m_Root)
{
if (pItem==GetFocusedItem())
SetFocusedItem(NULL);
delete pItem;
}
}
void CPropTree::SetFocusedItem(CPropTreeItem* pItem)
{
m_pFocus = pItem;
EnsureVisible(m_pFocus);
if (!IsWindow(m_hWnd))
return;
Invalidate();
}
void CPropTree::ShowInfoText(BOOL bShow)
{
m_bShowInfo = bShow;
CRect rc;
GetClientRect(rc);
ResizeChildWindows(rc.Width(), rc.Height());
}
BOOL CPropTree::IsItemVisible(CPropTreeItem* pItem)
{
if (!pItem)
return FALSE;
for (CPropTreeItem* pNext = m_pVisbleList; pNext; pNext = pNext->GetNextVisible())
{
if (pNext==pItem)
return TRUE;
}
return FALSE;
}
void CPropTree::EnsureVisible(CPropTreeItem* pItem)
{
if (!pItem)
return;
// item is not scroll visible (expand all parents)
if (!IsItemVisible(pItem))
{
CPropTreeItem* pParent;
pParent = pItem->GetParent();
while (pParent)
{
pParent->Expand();
pParent = pParent->GetParent();
}
UpdatedItems();
UpdateWindow();
}
ASSERT(IsItemVisible(pItem));
CRect rc;
m_List.GetClientRect(rc);
rc.OffsetRect(0, m_Origin.y);
rc.bottom -= pItem->GetHeight();
CPoint pt;
pt = pItem->GetLocation();
if (!rc.PtInRect(pt))
{
LONG oy;
if (pt.y < rc.top)
oy = pt.y;
else
oy = pt.y - rc.Height() + pItem->GetHeight();
m_List.OnVScroll(SB_THUMBTRACK, oy, NULL);
}
}
CPropTreeItem* CPropTree::InsertItem(CPropTreeItem* pItem, CPropTreeItem* pParent)
{
if (!pItem)
return NULL;
if (!pParent)
pParent = &m_Root;
if (!pParent->GetChild())
pParent->SetChild(pItem);
else
{
// add to end of the sibling list
CPropTreeItem* pNext;
pNext = pParent->GetChild();
while (pNext->GetSibling())
pNext = pNext->GetSibling();
pNext->SetSibling(pItem);
}
pItem->SetParent(pParent);
pItem->SetPropOwner(this);
// auto generate a default ID
pItem->SetCtrlID(m_nLastUID++);
SendNotify(PTN_INSERTITEM, pItem);
UpdatedItems();
return pItem;
}
LONG CPropTree::HitTest(const POINT& pt)
{
POINT p = pt;
CPropTreeItem* pItem;
// convert screen to tree coordinates
p.y += m_Origin.y;
if ((pItem = FindItem(pt))!=NULL)
{
if (!pItem->IsRootLevel() && pt.x >= m_Origin.x - PROPTREEITEM_COLRNG && pt.x <= m_Origin.x + PROPTREEITEM_COLRNG)
return HTCOLUMN;
if (pItem->HitButton(p)) {
return HTBUTTON;
}
if (pt.x > m_Origin.x + PROPTREEITEM_COLRNG)
return HTATTRIBUTE;
if (pItem->HitExpand(p))
return HTEXPAND;
if (pItem->HitCheckBox(p))
return HTCHECKBOX;
return HTLABEL;
}
return HTCLIENT;
}
CPropTreeItem* CPropTree::FindItem(const POINT& pt)
{
CPropTreeItem* pItem;
CPoint p = pt;
// convert screen to tree coordinates
p.y += m_Origin.y;
// search the visible list for the item
for (pItem = m_pVisbleList; pItem; pItem = pItem->GetNextVisible())
{
CPoint ipt = pItem->GetLocation();
if (p.y>=ipt.y && p.y<ipt.y + pItem->GetHeight())
return pItem;
}
return NULL;
}
CPropTreeItem* CPropTree::FindItem(UINT nCtrlID)
{
s_pFound = NULL;
EnumItems(&m_Root, EnumFindItem, nCtrlID);
return s_pFound;
}
BOOL CALLBACK CPropTree::EnumFindItem(CPropTree*, CPropTreeItem* pItem, LPARAM lParam)
{
ASSERT(pItem!=NULL);
if (pItem->GetCtrlID()==(UINT)lParam)
{
s_pFound = pItem;
return FALSE;
}
return TRUE;
}
BOOL CPropTree::IsDisableInput()
{
return m_bDisableInput;
}
void CPropTree::DisableInput(BOOL bDisable)
{
m_bDisableInput = bDisable;
CWnd* pWnd;
if ((pWnd = GetParent())!=NULL)
pWnd->EnableWindow(!bDisable);
}
void CPropTree::SelectItems(CPropTreeItem* pItem, BOOL bSelect)
{
if (!pItem)
pItem = &m_Root;
EnumItems(pItem, EnumSelectAll, (LPARAM)bSelect);
}
CPropTreeItem* CPropTree::FocusFirst()
{
CPropTreeItem *pold;
pold = m_pFocus;
SetFocusedItem(m_pVisbleList);
if (m_pFocus)
{
SelectItems(NULL, FALSE);
m_pFocus->Select();
}
if (pold!=m_pFocus)
SendNotify(PTN_SELCHANGE, m_pFocus);
return m_pFocus;
}
CPropTreeItem* CPropTree::FocusLast()
{
CPropTreeItem* pNext;
CPropTreeItem* pChange;
pChange = m_pFocus;
pNext = m_pVisbleList;
if (pNext)
{
while (pNext->GetNextVisible())
pNext = pNext->GetNextVisible();
SetFocusedItem(pNext);
if (m_pFocus)
{
SelectItems(NULL, FALSE);
m_pFocus->Select();
}
}
if (pChange!=m_pFocus)
SendNotify(PTN_SELCHANGE, m_pFocus);
return pNext;
}
CPropTreeItem* CPropTree::FocusPrev()
{
CPropTreeItem* pNext;
CPropTreeItem* pChange;
pChange = m_pFocus;
if (m_pFocus==NULL)
{
// get the last visible item
pNext = m_pVisbleList;
while (pNext && pNext->GetNextVisible())
pNext = pNext->GetNextVisible();
}
else
{
pNext = m_pVisbleList;
while (pNext && pNext->GetNextVisible()!=m_pFocus)
pNext = pNext->GetNextVisible();
}
if (pNext)
SetFocusedItem(pNext);
if (m_pFocus)
{
SelectItems(NULL, FALSE);
m_pFocus->Select();
}
if (pChange!=m_pFocus)
SendNotify(PTN_SELCHANGE, m_pFocus);
return pNext;
}
CPropTreeItem* CPropTree::FocusNext()
{
CPropTreeItem* pNext;
CPropTreeItem* pChange;
pChange = m_pFocus;
if (m_pFocus==NULL)
pNext = m_pVisbleList;
else
if (m_pFocus->GetNextVisible())
pNext = m_pFocus->GetNextVisible();
else
pNext = NULL;
if (pNext)
SetFocusedItem(pNext);
if (m_pFocus)
{
SelectItems(NULL, FALSE);
m_pFocus->Select();
}
if (pChange!=m_pFocus)
SendNotify(PTN_SELCHANGE, m_pFocus);
return pNext;
}
void CPropTree::UpdateMoveAllItems()
{
EnumItems(&m_Root, EnumMoveAll);
}
void CPropTree::RefreshItems(CPropTreeItem* pItem)
{
if (!pItem)
pItem = &m_Root;
EnumItems(pItem, EnumRefreshAll);
UpdatedItems();
}
BOOL CALLBACK CPropTree::EnumSelectAll(CPropTree*, CPropTreeItem* pItem, LPARAM lParam)
{
if (!pItem)
return FALSE;
pItem->Select((BOOL)lParam);
return TRUE;
}
BOOL CALLBACK CPropTree::EnumRefreshAll(CPropTree*, CPropTreeItem* pItem, LPARAM)
{
if (!pItem)
return FALSE;
pItem->OnRefresh();
return TRUE;
}
BOOL CALLBACK CPropTree::EnumMoveAll(CPropTree*, CPropTreeItem* pItem, LPARAM)
{
if (!pItem)
return FALSE;
pItem->OnMove();
return TRUE;
}
LRESULT CPropTree::SendNotify(UINT nNotifyCode, CPropTreeItem* pItem)
{
if (!IsWindow(m_hWnd))
return 0L;
if (!(GetStyle() & PTS_NOTIFY))
return 0L;
NMPROPTREE nmmp;
LPNMHDR lpnm;
lpnm = NULL;
switch (nNotifyCode)
{
case PTN_INSERTITEM:
case PTN_DELETEITEM:
case PTN_DELETEALLITEMS:
case PTN_ITEMCHANGED:
case PTN_ITEMBUTTONCLICK:
case PTN_SELCHANGE:
case PTN_ITEMEXPANDING:
case PTN_COLUMNCLICK:
case PTN_PROPCLICK:
case PTN_CHECKCLICK:
lpnm = (LPNMHDR)&nmmp;
nmmp.pItem = pItem;
break;
}
if (lpnm)
{
UINT id = (UINT)::GetMenu(m_hWnd);
lpnm->code = nNotifyCode;
lpnm->hwndFrom = m_hWnd;
lpnm->idFrom = id;
return GetParent()->SendMessage(WM_NOTIFY, (WPARAM)id, (LPARAM)lpnm);
}
return 0L;
}
void CPropTree::OnEnable(BOOL bEnable)
{
CWnd::OnEnable(bEnable);
Invalidate();
}
void CPropTree::OnSysColorChange()
{
CWnd::OnSysColorChange();
Invalidate();
}
BOOL CPropTree::IsSingleSelection()
{
// right now only support single selection
return TRUE;
}

View File

@@ -0,0 +1,290 @@
// PropTree.h : header file
//
// Copyright (C) 1998-2001 Scott Ramsay
// sramsay@gonavi.com
// http://www.gonavi.com
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// If you use this code, drop me an email. I'd like to know if you find the code
// useful.
#if !defined(AFX_PROPT_H__386AA426_6FB7_4B4B_9563_C4CC045BB0C9__INCLUDED_)
#define AFX_PROPT_H__386AA426_6FB7_4B4B_9563_C4CC045BB0C9__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
/*#ifdef _PROPTREE_EXPORT
#define PROPTREE_API __declspec(dllexport)
#else
#define PROPTREE_API __declspec(dllimport)
#endif
#ifndef _PROPTREE_DLL
#ifdef _UNICODE
#ifdef _DEBUG
#pragma comment(lib, "PropTreeDU")
#pragma message("Automatically linking with PropTreeDU.dll (Debug Unicode)")
#else
#pragma comment(lib, "PropTreeU")
#pragma message("Automatically linking with PropTreeU.dll (Release Unicode)")
#endif
#else
#ifdef _DEBUG
#pragma comment(lib, "PropTreeD")
#pragma message("Automatically linking with PropTreeD.dll (Debug)")
#else
#pragma comment(lib, "PropTree")
#pragma message("Automatically linking with PropTree.dll (Release)")
#endif
#endif // _UNICODE
#endif // _PROPTREE_DLL
*/
#define PROPTREE_API
#include "PropTreeList.h"
#include "PropTreeInfo.h"
#include "PropTreeItem.h"
#include "PropTreeItemStatic.h"
#include "PropTreeItemEdit.h"
#include "PropTreeItemCombo.h"
#include "PropTreeItemColor.h"
#include "PropTreeItemCheck.h"
#include "PropTreeItemButton.h"
#include "PropTreeItemEditButton.h"
#include "PropTreeItemFileEdit.h"
class CPropTree;
typedef BOOL (CALLBACK* ENUMPROPITEMPROC)(CPropTree*, CPropTreeItem*, LPARAM);
void InitPropTree(HINSTANCE hInstance);
// CPropTree window styles
#define PTS_NOTIFY 0x00000001
// CPropTree HitTest return codes
#define HTPROPFIRST 50
#define HTLABEL (HTPROPFIRST + 0)
#define HTCOLUMN (HTPROPFIRST + 1)
#define HTEXPAND (HTPROPFIRST + 2)
#define HTATTRIBUTE (HTPROPFIRST + 3)
#define HTCHECKBOX (HTPROPFIRST + 4)
#define HTBUTTON (HTPROPFIRST + 5)
// CPropTree WM_NOTIFY notification structure
typedef struct _NMPROPTREE
{
NMHDR hdr;
CPropTreeItem* pItem;
} NMPROPTREE, *PNMPROPTREE, FAR *LPNMPROPTREE;
// CPropTree specific Notification Codes
#define PTN_FIRST (0U-1100U)
#define PTN_INSERTITEM (PTN_FIRST-1)
#define PTN_DELETEITEM (PTN_FIRST-2)
#define PTN_DELETEALLITEMS (PTN_FIRST-3)
#define PTN_ITEMCHANGED (PTN_FIRST-5)
#define PTN_ITEMBUTTONCLICK (PTN_FIRST-6)
#define PTN_SELCHANGE (PTN_FIRST-7)
#define PTN_ITEMEXPANDING (PTN_FIRST-8)
#define PTN_COLUMNCLICK (PTN_FIRST-9)
#define PTN_PROPCLICK (PTN_FIRST-10)
#define PTN_CHECKCLICK (PTN_FIRST-12)
/////////////////////////////////////////////////////////////////////////////
// CPropTree window
class PROPTREE_API CPropTree : public CWnd
{
// Construction
public:
CPropTree();
virtual ~CPropTree();
BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);
// Attributes/Operations
public:
static CFont* GetNormalFont();
static CFont* GetBoldFont();
// Returns the root item of the tree
CPropTreeItem* GetRootItem();
// Returns the focused item or NULL for none
CPropTreeItem* GetFocusedItem();
// Enumerates an item and all its child items
BOOL EnumItems(CPropTreeItem* pItem, ENUMPROPITEMPROC proc, LPARAM lParam = 0L);
// Insert a created CPropTreeItem into the control
CPropTreeItem* InsertItem(CPropTreeItem* pItem, CPropTreeItem* pParent = NULL);
// Delete an item and ALL its children
void DeleteItem(CPropTreeItem* pItem);
// Delete all items from the tree
void DeleteAllItems();
// Return the splitter position
LONG GetColumn();
// Set the splitter position
void SetColumn(LONG nColumn);
// Sets the focused item
void SetFocusedItem(CPropTreeItem* pItem);
// Show or hide the info text
void ShowInfoText(BOOL bShow = TRUE);
// Returns TRUE if the item is visible (its parent is expanded)
BOOL IsItemVisible(CPropTreeItem* pItem);
// Ensures that an item is visible
void EnsureVisible(CPropTreeItem* pItem);
// do a hit test on the control (returns a HTxxxx code)
LONG HitTest(const POINT& pt);
// find an item by a location
CPropTreeItem* FindItem(const POINT& pt);
// find an item by item id
CPropTreeItem* FindItem(UINT nCtrlID);
protected:
// Actual tree control
CPropTreeList m_List;
// Descriptive control
CPropTreeInfo m_Info;
// TRUE to show info control
BOOL m_bShowInfo;
// Height of the info control
LONG m_nInfoHeight;
// Root level tree item
CPropTreeItem m_Root;
// Linked list of visible items
CPropTreeItem* m_pVisbleList;
// Pointer to the focused item (selected)
CPropTreeItem* m_pFocus;
// PropTree scroll position. x = splitter position, y = vscroll position
CPoint m_Origin;
// auto generated last created ID
UINT m_nLastUID;
// Number of CPropTree controls in the current application
static UINT s_nInstanceCount;
static CFont* s_pNormalFont;
static CFont* s_pBoldFont;
BOOL m_bDisableInput;
// Used for enumeration
static CPropTreeItem* s_pFound;
public:
//
// functions used by CPropTreeItem (you normally dont need to call these directly)
//
void AddToVisibleList(CPropTreeItem* pItem);
void ClearVisibleList();
void SetOriginOffset(LONG nOffset);
void UpdatedItems();
void UpdateMoveAllItems();
void RefreshItems(CPropTreeItem* pItem = NULL);
// enable or disable tree input
void DisableInput(BOOL bDisable = TRUE);
BOOL IsDisableInput();
BOOL IsSingleSelection();
CPropTreeItem* GetVisibleList();
CWnd* GetCtrlParent();
const POINT& GetOrigin();
void SelectItems(CPropTreeItem* pItem, BOOL bSelect = TRUE);
// Focus on the first visible item
CPropTreeItem *FocusFirst();
// Focus on the last visible item
CPropTreeItem *FocusLast();
// Focus on the previous item
CPropTreeItem *FocusPrev();
// Focus on the next item
CPropTreeItem *FocusNext();
LRESULT SendNotify(UINT nNotifyCode, CPropTreeItem* pItem = NULL);
protected:
// Resize the child windows to fit the exact dimensions the CPropTree control
void ResizeChildWindows(int cx, int cy);
// Initialize global resources, brushes, fonts, etc.
void InitGlobalResources();
// Free global resources, brushes, fonts, etc.
void FreeGlobalResources();
// Recursive version of DeleteItem
void Delete(CPropTreeItem* pItem);
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CPropTree)
//}}AFX_VIRTUAL
// Implementation
private:
static BOOL CALLBACK EnumFindItem(CPropTree* pProp, CPropTreeItem* pItem, LPARAM lParam);
static BOOL CALLBACK EnumSelectAll(CPropTree*, CPropTreeItem* pItem, LPARAM lParam);
static BOOL CALLBACK EnumMoveAll(CPropTree*, CPropTreeItem* pItem, LPARAM);
static BOOL CALLBACK EnumRefreshAll(CPropTree*, CPropTreeItem* pItem, LPARAM);
// Generated message map functions
protected:
//{{AFX_MSG(CPropTree)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnEnable(BOOL bEnable);
afx_msg void OnSysColorChange();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_PROPT_H__386AA426_6FB7_4B4B_9563_C4CC045BB0C9__INCLUDED_)

View File

@@ -0,0 +1,110 @@
// PropTreeInfo.cpp : implementation file
//
// Copyright (C) 1998-2001 Scott Ramsay
// sramsay@gonavi.com
// http://www.gonavi.com
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// If you use this code, drop me an email. I'd like to know if you find the code
// useful.
//#include "stdafx.h"
#include "../../../idlib/precompiled.h"
#pragma hdrstop
#include "PropTree.h"
#include "../../../sys/win32/rc/proptree_Resource.h"
#include "PropTreeInfo.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CPropTreeInfo
CPropTreeInfo::CPropTreeInfo() :
m_pProp(NULL)
{
}
CPropTreeInfo::~CPropTreeInfo()
{
}
BEGIN_MESSAGE_MAP(CPropTreeInfo, CStatic)
//{{AFX_MSG_MAP(CPropTreeInfo)
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPropTreeInfo message handlers
void CPropTreeInfo::SetPropOwner(CPropTree* pProp)
{
m_pProp = pProp;
}
void CPropTreeInfo::OnPaint()
{
CPaintDC dc(this);
CRect rc;
GetClientRect(rc);
dc.SelectObject(GetSysColorBrush(COLOR_BTNFACE));
dc.PatBlt(rc.left, rc.top, rc.Width(), rc.Height(), PATCOPY);
dc.DrawEdge(&rc, BDR_SUNKENOUTER, BF_RECT);
rc.DeflateRect(4, 4);
ASSERT(m_pProp!=NULL);
CPropTreeItem* pItem = m_pProp->GetFocusedItem();
if (!m_pProp->IsWindowEnabled())
dc.SetTextColor(GetSysColor(COLOR_GRAYTEXT));
else
dc.SetTextColor(GetSysColor(COLOR_BTNTEXT));
dc.SetBkMode(TRANSPARENT);
dc.SelectObject(m_pProp->GetBoldFont());
CString txt;
if (!pItem)
txt.LoadString(IDS_NOITEMSEL);
else
txt = pItem->GetLabelText();
CRect ir;
ir = rc;
// draw label
dc.DrawText(txt, &ir, DT_SINGLELINE|DT_CALCRECT);
dc.DrawText(txt, &ir, DT_SINGLELINE);
ir.top = ir.bottom;
ir.bottom = rc.bottom;
ir.right = rc.right;
if (pItem)
txt = pItem->GetInfoText();
else
txt.LoadString(IDS_SELFORINFO);
dc.SelectObject(m_pProp->GetNormalFont());
dc.DrawText(txt, &ir, DT_WORDBREAK);
}

View File

@@ -0,0 +1,71 @@
#if !defined(AFX_PROPTREEINFO_H__22BD9C18_A68C_4BB8_B7FC_C4A7DA0E1EBF__INCLUDED_)
#define AFX_PROPTREEINFO_H__22BD9C18_A68C_4BB8_B7FC_C4A7DA0E1EBF__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// PropTreeInfo.h : header file
//
//
// Copyright (C) 1998-2001 Scott Ramsay
// sramsay@gonavi.com
// http://www.gonavi.com
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// If you use this code, drop me an email. I'd like to know if you find the code
// useful.
class CPropTree;
/////////////////////////////////////////////////////////////////////////////
// CPropTreeInfo window
class PROPTREE_API CPropTreeInfo : public CStatic
{
// Construction
public:
CPropTreeInfo();
// Attributes
public:
// CPropTree class that this class belongs
void SetPropOwner(CPropTree* pProp);
protected:
CPropTree* m_pProp;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CPropTreeInfo)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CPropTreeInfo();
// Generated message map functions
protected:
//{{AFX_MSG(CPropTreeInfo)
afx_msg void OnPaint();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_PROPTREEINFO_H__22BD9C18_A68C_4BB8_B7FC_C4A7DA0E1EBF__INCLUDED_)

View File

@@ -0,0 +1,590 @@
// PropTreeItem.cpp
//
// Copyright (C) 1998-2001 Scott Ramsay
// sramsay@gonavi.com
// http://www.gonavi.com
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// If you use this code, drop me an email. I'd like to know if you find the code
// useful.
//#include "stdafx.h"
#include "../../../idlib/precompiled.h"
#pragma hdrstop
#include "PropTree.h"
#include "PropTreeItem.h"
#define PROPTREEITEM_DEFHEIGHT 21 // default heigt of an item
#define PROPTREEITEM_SPACE 5 // default horz spacing
#define PROPTREEITEM_EXPANDBOX 9 // size of the expand box
#define PROPTREEITEM_CHECKBOX 14 // size of the check box
#define PROPTREEITEM_EXPANDCOLUMN 16 // width of the expand column
#define PNINDENT 16 // child level indent
#define PROPTREEITEM_EXPANDBOXHALF (PROPTREEITEM_EXPANDBOX/2)
/////////////////////////////////////////////////////////////////////////////
// drawing helper functions
//
// draw a dotted horizontal line
static void _DotHLine(HDC hdc, LONG x, LONG y, LONG w)
{
for (; w>0; w-=2, x+=2)
SetPixel(hdc, x, y, GetSysColor(COLOR_BTNSHADOW));
}
// draw the plus/minus button
static void _DrawExpand(HDC hdc, LONG x, LONG y, BOOL bExpand, BOOL bFill)
{
HPEN hPen;
HPEN oPen;
HBRUSH oBrush;
hPen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNSHADOW));
oPen = (HPEN)SelectObject(hdc, hPen);
oBrush = (HBRUSH)SelectObject(hdc, GetStockObject(bFill ? WHITE_BRUSH : NULL_BRUSH));
Rectangle(hdc, x, y, x + PROPTREEITEM_EXPANDBOX, y + PROPTREEITEM_EXPANDBOX);
SelectObject(hdc, GetStockObject(BLACK_PEN));
if (!bExpand)
{
MoveToEx(hdc, x + PROPTREEITEM_EXPANDBOXHALF, y + 2, NULL);
LineTo(hdc, x + PROPTREEITEM_EXPANDBOXHALF, y + PROPTREEITEM_EXPANDBOX - 2);
}
MoveToEx(hdc, x + 2, y + PROPTREEITEM_EXPANDBOXHALF, NULL);
LineTo(hdc, x + PROPTREEITEM_EXPANDBOX - 2, y + PROPTREEITEM_EXPANDBOXHALF);
SelectObject(hdc, oPen);
SelectObject(hdc, oBrush);
DeleteObject(hPen);
}
/////////////////////////////////////////////////////////////////////////////
// CPropTreeItem
//
CPropTreeItem::CPropTreeItem() :
m_pProp(NULL),
m_sLabel(_T("")),
m_sInfo(_T("")),
m_loc(0,0),
m_rc(0,0,0,0),
m_lParam(0),
m_nCtrlID(0),
m_dwState(0),
m_bActivated(FALSE),
m_bCommitOnce(FALSE),
m_rcExpand(0,0,0,0),
m_rcCheckbox(0,0,0,0),
m_rcButton(0,0,0,0),
m_pParent(NULL),
m_pSibling(NULL),
m_pChild(NULL),
m_pVis(NULL)
{
}
CPropTreeItem::~CPropTreeItem()
{
}
BOOL CPropTreeItem::IsExpanded()
{
return (m_dwState & TreeItemExpanded) ? TRUE : FALSE;
}
BOOL CPropTreeItem::IsSelected()
{
return (m_dwState & TreeItemSelected) ? TRUE : FALSE;
}
BOOL CPropTreeItem::IsChecked()
{
return (m_dwState & TreeItemChecked) ? TRUE : FALSE;
}
BOOL CPropTreeItem::IsReadOnly()
{
return (m_dwState & TreeItemReadOnly) ? TRUE : FALSE;
}
BOOL CPropTreeItem::IsActivated()
{
return (m_dwState & TreeItemActivated) ? TRUE : FALSE;
}
void CPropTreeItem::Select(BOOL bSelect)
{
if (bSelect)
m_dwState |= TreeItemSelected;
else
m_dwState &= ~TreeItemSelected;
}
void CPropTreeItem::Expand(BOOL bExpand)
{
if (bExpand)
m_dwState |= TreeItemExpanded;
else
m_dwState &= ~TreeItemExpanded;
}
void CPropTreeItem::Check(BOOL bCheck)
{
if (bCheck)
m_dwState |= TreeItemChecked;
else
m_dwState &= ~TreeItemChecked;
}
void CPropTreeItem::ReadOnly(BOOL bReadOnly)
{
if (bReadOnly)
m_dwState |= TreeItemReadOnly;
else
m_dwState &= ~TreeItemReadOnly;
}
BOOL CPropTreeItem::IsCheckBox()
{
return (m_dwState & TreeItemCheckbox) ? TRUE : FALSE;
}
void CPropTreeItem::HasCheckBox(BOOL bCheckbox)
{
if (bCheckbox)
m_dwState |= TreeItemCheckbox;
else
m_dwState &= ~TreeItemCheckbox;
}
BOOL CPropTreeItem::HitExpand(const POINT& pt)
{
return m_rcExpand.PtInRect(pt);
}
BOOL CPropTreeItem::HitCheckBox(const POINT& pt)
{
return m_rcCheckbox.PtInRect(pt);
}
BOOL CPropTreeItem::IsRootLevel()
{
ASSERT(m_pProp!=NULL);
return GetParent() == m_pProp->GetRootItem();
}
LONG CPropTreeItem::GetTotalHeight()
{
CPropTreeItem* pItem;
LONG nHeight;
nHeight = GetHeight();
if (IsExpanded())
{
for (pItem = GetChild(); pItem; pItem = pItem->GetSibling())
nHeight += pItem->GetTotalHeight();
}
return nHeight;
}
void CPropTreeItem::SetLabelText(LPCTSTR sLabel)
{
m_sLabel = sLabel;
}
LPCTSTR CPropTreeItem::GetLabelText()
{
return m_sLabel;
}
void CPropTreeItem::SetInfoText(LPCTSTR sInfo)
{
m_sInfo = sInfo;
}
LPCTSTR CPropTreeItem::GetInfoText()
{
return m_sInfo;
}
void CPropTreeItem::SetCtrlID(UINT nCtrlID)
{
m_nCtrlID = nCtrlID;
}
UINT CPropTreeItem::GetCtrlID()
{
return m_nCtrlID;
}
LONG CPropTreeItem::GetHeight()
{
return PROPTREEITEM_DEFHEIGHT;
}
LPARAM CPropTreeItem::GetItemValue()
{
// no items are assocatied with this type
return 0L;
}
void CPropTreeItem::SetItemValue(LPARAM)
{
// no items are assocatied with this type
}
void CPropTreeItem::OnMove()
{
// no attributes, do nothing
}
void CPropTreeItem::OnRefresh()
{
// no attributes, do nothing
}
void CPropTreeItem::OnCommit()
{
// no attributes, do nothing
}
void CPropTreeItem::Activate(int activateType, CPoint point)
{
m_bActivated = TRUE;
m_bCommitOnce = FALSE;
OnActivate(activateType, point);
}
void CPropTreeItem::CommitChanges()
{
m_bActivated = FALSE;
if (m_bCommitOnce)
return;
m_bCommitOnce = TRUE;
ASSERT(m_pProp!=NULL);
OnCommit();
m_pProp->SendNotify(PTN_ITEMCHANGED, this);
m_pProp->RefreshItems(this);
}
void CPropTreeItem::OnActivate(int activateType, CPoint point)
{
// no attributes, do nothing
}
void CPropTreeItem::SetPropOwner(CPropTree* pProp)
{
m_pProp = pProp;
}
const POINT& CPropTreeItem::GetLocation()
{
return m_loc;
}
CPropTreeItem* CPropTreeItem::GetParent()
{
return m_pParent;
}
CPropTreeItem* CPropTreeItem::GetSibling()
{
return m_pSibling;
}
CPropTreeItem* CPropTreeItem::GetChild()
{
return m_pChild;
}
CPropTreeItem* CPropTreeItem::GetNextVisible()
{
return m_pVis;
}
void CPropTreeItem::SetParent(CPropTreeItem* pParent)
{
m_pParent = pParent;
}
void CPropTreeItem::SetSibling(CPropTreeItem* pSibling)
{
m_pSibling = pSibling;
}
void CPropTreeItem::SetChild(CPropTreeItem* pChild)
{
m_pChild = pChild;
}
void CPropTreeItem::SetNextVisible(CPropTreeItem* pVis)
{
m_pVis = pVis;
}
LONG CPropTreeItem::DrawItem(CDC* pDC, const RECT& rc, LONG x, LONG y)
{
CPoint pt;
LONG nTotal, nCol, ey;
CRect drc, ir;
ASSERT(m_pProp!=NULL);
// Add TreeItem the list of visble items
m_pProp->AddToVisibleList(this);
// store the item's location
m_loc = CPoint(x, y);
// store the items rectangle position
m_rc.SetRect(m_pProp->GetOrigin().x + PROPTREEITEM_SPACE, m_loc.y, rc.right, m_loc.y + GetHeight()-1);
m_rc.OffsetRect(0, -m_pProp->GetOrigin().y);
// init temp drawing variables
nTotal = GetHeight();
ey = (nTotal >> 1) - (PROPTREEITEM_EXPANDBOX >> 1) - 2;
bool bCheck = false;
// convert item coordinates to screen coordinates
pt = m_loc;
pt.y -= m_pProp->GetOrigin().y;
nCol = m_pProp->GetOrigin().x;
if (IsRootLevel())
drc.SetRect(pt.x + PROPTREEITEM_EXPANDCOLUMN, pt.y, rc.right, pt.y + nTotal);
else
drc.SetRect(pt.x + PROPTREEITEM_EXPANDCOLUMN, pt.y, nCol, pt.y + nTotal);
// root level items are shaded
if (IsRootLevel())
{
HGDIOBJ hOld = pDC->SelectObject(GetSysColorBrush(COLOR_BTNFACE));
pDC->PatBlt(rc.left, drc.top, rc.right - rc.left + 1, drc.Height(), PATCOPY);
pDC->SelectObject(hOld);
}
// calc/draw expand box position
if (GetChild())
{
m_rcExpand.left = PROPTREEITEM_EXPANDCOLUMN/2 - PROPTREEITEM_EXPANDBOXHALF;
m_rcExpand.top = m_loc.y + ey;
m_rcExpand.right = m_rcExpand.left + PROPTREEITEM_EXPANDBOX - 1;
m_rcExpand.bottom = m_rcExpand.top + PROPTREEITEM_EXPANDBOX - 1;
ir = m_rcExpand;
ir.OffsetRect(0, -m_pProp->GetOrigin().y);
_DrawExpand(pDC->m_hDC, ir.left, ir.top, IsExpanded(), !IsRootLevel());
}
else
m_rcExpand.SetRectEmpty();
// calc/draw check box position
if (IsCheckBox())
{
bCheck = true;
ir.left = drc.left + PROPTREEITEM_SPACE;
ir.top = m_loc.y + ey;
ir.right = ir.left + PROPTREEITEM_CHECKBOX;
ir.bottom = ir.top + PROPTREEITEM_CHECKBOX;
m_rcCheckbox = ir;
}
else
m_rcCheckbox.SetRectEmpty();
HRGN hRgn = NULL;
// create a clipping region for the label
if (!IsRootLevel())
{
hRgn = CreateRectRgn(drc.left, drc.top, drc.right, drc.bottom);
SelectClipRgn(pDC->m_hDC, hRgn);
}
// calc label position
ir = drc;
ir.left += PROPTREEITEM_SPACE;
// offset the label text if item has a check box
if (bCheck)
OffsetRect(&ir, PROPTREEITEM_CHECKBOX + PROPTREEITEM_SPACE * 2, 0);
// draw label
if (!m_sLabel.IsEmpty())
{
if (IsRootLevel())
pDC->SelectObject(CPropTree::GetBoldFont());
else
pDC->SelectObject(CPropTree::GetNormalFont());
pDC->SetTextColor(GetSysColor(COLOR_BTNTEXT));
pDC->SetBkMode(TRANSPARENT);
pDC->DrawText(m_sLabel, &ir, DT_SINGLELINE|DT_VCENTER|DT_CALCRECT);
// draw the text highlighted if selected
if (IsSelected())
{
HGDIOBJ oPen = pDC->SelectObject(GetStockObject(NULL_PEN));
HGDIOBJ oBrush = pDC->SelectObject(GetSysColorBrush(COLOR_HIGHLIGHT));
CRect dr;
dr = drc;
dr.left = PROPTREEITEM_EXPANDCOLUMN;
pDC->Rectangle(&dr);
pDC->SelectObject(oPen);
pDC->SelectObject(oBrush);
pDC->SetTextColor(GetSysColor(COLOR_BTNHIGHLIGHT));
}
// check if we need to draw the text as disabled
if (!m_pProp->IsWindowEnabled())
pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
pDC->DrawText(m_sLabel, &ir, DT_SINGLELINE|DT_VCENTER);
}
// draw check box frame
if (IsCheckBox())
{
ir = m_rcCheckbox;
ir.OffsetRect(0, -m_pProp->GetOrigin().y);
pDC->DrawFrameControl(&ir, DFC_BUTTON, DFCS_BUTTONCHECK | (IsChecked() ? DFCS_CHECKED : 0));
}
// remove clip region
if (hRgn)
{
SelectClipRgn(pDC->m_hDC, NULL);
DeleteObject(hRgn);
}
// draw horzontal sep
_DotHLine(pDC->m_hDC, PROPTREEITEM_EXPANDCOLUMN, pt.y + nTotal - 1, rc.right - PROPTREEITEM_EXPANDCOLUMN + 1);
// draw separators
if (!IsRootLevel())
{
// column sep
CPen pn1(PS_SOLID, 1, GetSysColor(COLOR_BTNSHADOW));
CPen* pOld;
pOld = pDC->SelectObject(&pn1);
pDC->MoveTo(nCol, drc.top);
pDC->LineTo(nCol, drc.bottom);
CPen pn2(PS_SOLID, 1, GetSysColor(COLOR_BTNHIGHLIGHT));
pDC->SelectObject(&pn2);
pDC->MoveTo(nCol + 1, drc.top);
pDC->LineTo(nCol + 1, drc.bottom);
pDC->SelectObject(pOld);
}
// draw attribute
if (!IsRootLevel())
{
// create clip region
hRgn = CreateRectRgn(m_rc.left, m_rc.top, m_rc.right, m_rc.bottom);
SelectClipRgn(pDC->m_hDC, hRgn);
DrawAttribute(pDC, m_rc);
SelectClipRgn(pDC->m_hDC, NULL);
DeleteObject(hRgn);
}
// draw children
if (GetChild() && IsExpanded())
{
y += nTotal;
CPropTreeItem* pNext;
for (pNext = GetChild(); pNext; pNext = pNext->GetSibling())
{
LONG nHeight = pNext->DrawItem(pDC, rc, x + (IsRootLevel() ? 0 : PNINDENT), y);
nTotal += nHeight;
y += nHeight;
}
}
return nTotal;
}
void CPropTreeItem::DrawAttribute(CDC*, const RECT&)
{
// no attributes are assocatied with this type
}

View File

@@ -0,0 +1,203 @@
// PropTreeItem.h
//
// Copyright (C) 1998-2001 Scott Ramsay
// sramsay@gonavi.com
// http://www.gonavi.com
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// If you use this code, drop me an email. I'd like to know if you find the code
// useful.
#ifndef _PROPTREEITEM_H
#define _PROPTREEITEM_H
class CPropTree;
class PROPTREE_API CPropTreeItem
{
// Construction
public:
CPropTreeItem();
virtual ~CPropTreeItem();
// Attributes/Operations
public:
// TreeItem states
BOOL IsExpanded();
BOOL IsSelected();
BOOL IsChecked();
BOOL IsReadOnly();
BOOL IsActivated();
void Select(BOOL bSelect = TRUE);
void Expand(BOOL bExpand = TRUE);
void Check(BOOL bCheck = TRUE);
void ReadOnly(BOOL bReadOnly = TRUE);
// Returns true if the item has a checkbox
BOOL IsCheckBox();
// Pass in true, for the item to have a checkbox
void HasCheckBox(BOOL bCheckbox = TRUE);
// Returns TRUE if the point is on the expand button
BOOL HitExpand(const POINT& pt);
// Returns TRUE if the point is on the check box
BOOL HitCheckBox(const POINT& pt);
// Overrideable - Returns TRUE if the point is on the button
virtual BOOL HitButton(const POINT& pt) { return false;}
// Returns TRUE if the item is on the root level. Root level items don't have attribute areas
BOOL IsRootLevel();
// Returns the total height of the item and all its children
LONG GetTotalHeight();
// Set the items label text
void SetLabelText(LPCTSTR sLabel);
// Return the items label text
LPCTSTR GetLabelText();
// Set the items info (description) text
void SetInfoText(LPCTSTR sInfo);
// Get the items info (description) text
LPCTSTR GetInfoText();
// Set the item's ID
void SetCtrlID(UINT nCtrlID);
// Return the item's ID
UINT GetCtrlID();
// Overrideable - draw the item's non attribute area
virtual LONG DrawItem(CDC* pDC, const RECT& rc, LONG x, LONG y);
// call to mark attribute changes
void CommitChanges();
// call to activate item attribute
enum {
ACTIVATE_TYPE_KEYBOARD,
ACTIVATE_TYPE_MOUSE
};
void Activate(int activateType, CPoint point);
//
// Overrideables
//
// The attribute area needs drawing
virtual void DrawAttribute(CDC* pDC, const RECT& rc);
// Return the height of the item
virtual LONG GetHeight();
// Retrieve the item's attribute value
virtual LPARAM GetItemValue();
// Set the item's attribute value
virtual void SetItemValue(LPARAM lParam);
// Called when attribute area has changed size
virtual void OnMove();
// Called when the item needs to refresh its data
virtual void OnRefresh();
// Called when the item needs to commit its changes
virtual void OnCommit();
// Called to activate the item
virtual void OnActivate(int activateType, CPoint point);
//
// Usually only CPropTree should calls these
//
void SetPropOwner(CPropTree* pProp);
// Return the location of the PropItem
const POINT& GetLocation();
// TreeItem link pointer access
CPropTreeItem* GetParent();
CPropTreeItem* GetSibling();
CPropTreeItem* GetChild();
CPropTreeItem* GetNextVisible();
void SetParent(CPropTreeItem* pParent);
void SetSibling(CPropTreeItem* pSibling);
void SetChild(CPropTreeItem* pChild);
void SetNextVisible(CPropTreeItem* pVis);
protected:
// CPropTree class that this class belongs
CPropTree* m_pProp;
// TreeItem label name
CString m_sLabel;
// Descriptive info text
CString m_sInfo;
// TreeItem location
CPoint m_loc;
// TreeItem attribute size
CRect m_rc;
// user defined LPARAM value
LPARAM m_lParam;
// ID of control item (should be unique)
UINT m_nCtrlID;
protected:
enum TreeItemStates
{
TreeItemSelected = 0x00000001,
TreeItemExpanded = 0x00000002,
TreeItemCheckbox = 0x00000004,
TreeItemChecked = 0x00000008,
TreeItemActivated = 0x00000010,
TreeItemReadOnly = 0x00000020,
};
// TreeItem state
DWORD m_dwState;
// TRUE if item is activated
BOOL m_bActivated;
// TRUE if item has been commited once (activation)
BOOL m_bCommitOnce;
// Rectangle position of the expand button (if contains one)
CRect m_rcExpand;
// Rectangle position of the check box (if contains one)
CRect m_rcCheckbox;
// Rectangle position of the button (if contains one)
CRect m_rcButton;
// link pointers
CPropTreeItem* m_pParent;
CPropTreeItem* m_pSibling;
CPropTreeItem* m_pChild;
CPropTreeItem* m_pVis;
};
#endif // _PROPTREEITEM_H

View File

@@ -0,0 +1,103 @@
// PropTreeItemButton.cpp : implementation file
//
// Copyright (C) 1998-2001 Scott Ramsay
// sramsay@gonavi.com
// http://www.gonavi.com
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// If you use this code, drop me an email. I'd like to know if you find the code
// useful.
//#include "stdafx.h"
#include "../../../idlib/precompiled.h"
#pragma hdrstop
#include "proptree.h"
#include "PropTreeItemButton.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define BUTTON_SIZE 17
/////////////////////////////////////////////////////////////////////////////
// CPropTreeItemButton
CPropTreeItemButton::CPropTreeItemButton() {
mouseDown = false;
}
CPropTreeItemButton::~CPropTreeItemButton() {
}
/////////////////////////////////////////////////////////////////////////////
// CPropTreeItemButton message handlers
LONG CPropTreeItemButton::DrawItem( CDC* pDC, const RECT& rc, LONG x, LONG y )
{
CSize textSize;
CRect textRect;
LONG nTotal = 0;
nTotal = CPropTreeItem::DrawItem( pDC, rc, x, y );
textSize = pDC->GetOutputTextExtent( buttonText );
buttonRect.left = m_rc.right - ( textSize.cx + 12 + 4);
buttonRect.top = m_rc.top + ((m_rc.bottom - m_rc.top)/2)-BUTTON_SIZE/2;
buttonRect.right = buttonRect.left + textSize.cx + 12;
buttonRect.bottom = buttonRect.top + BUTTON_SIZE;
UINT buttonStyle;
if ( (m_dwState & TreeItemChecked) ) {
buttonStyle = DFCS_BUTTONPUSH | DFCS_PUSHED;
} else {
buttonStyle = DFCS_BUTTONPUSH;
}
pDC->DrawFrameControl(&buttonRect, DFC_BUTTON, buttonStyle );
textRect = buttonRect;
textRect.left += 4;
textRect.right -= 8;
pDC->DrawText( buttonText, textRect, DT_SINGLELINE|DT_VCENTER );
//Adjust hit test rect to acount for window scrolling
hitTestRect = buttonRect;
hitTestRect.OffsetRect(0, m_pProp->GetOrigin().y);
return nTotal;
}
void CPropTreeItemButton::DrawAttribute(CDC* pDC, const RECT& rc) {
}
LPARAM CPropTreeItemButton::GetItemValue() {
return (LPARAM)0;
}
void CPropTreeItemButton::SetItemValue(LPARAM lParam) {
}
BOOL CPropTreeItemButton::HitButton( const POINT& pt ) {
return hitTestRect.PtInRect( pt );
}
void CPropTreeItemButton::SetButtonText( LPCSTR text ) {
buttonText = text;
}

View File

@@ -0,0 +1,63 @@
#pragma once
// PropTreeItemButton.h : header file
//
// Copyright (C) 1998-2001 Scott Ramsay
// sramsay@gonavi.com
// http://www.gonavi.com
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// If you use this code, drop me an email. I'd like to know if you find the code
// useful.
#include "PropTreeItem.h"
/////////////////////////////////////////////////////////////////////////////
// CPropTreeItemButton window
class PROPTREE_API CPropTreeItemButton : public CPropTreeItem
{
// Construction
public:
CPropTreeItemButton();
virtual ~CPropTreeItemButton();
// Attributes
public:
// The non-attribute area needs drawing
virtual LONG DrawItem(CDC* pDC, const RECT& rc, LONG x, LONG y);
// The attribute area needs drawing
virtual void DrawAttribute(CDC* pDC, const RECT& rc);
// Retrieve the item's attribute value
virtual LPARAM GetItemValue();
// Set the item's attribute value
virtual void SetItemValue(LPARAM lParam);
// Overrideable - Returns TRUE if the point is on the button
virtual BOOL HitButton(const POINT& pt);
void SetButtonText( LPCSTR text );
protected:
CString buttonText;
CRect buttonRect;
CRect hitTestRect;
bool mouseDown;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

View File

@@ -0,0 +1,161 @@
// PropTreeItemCheck.cpp : implementation file
//
// Copyright (C) 1998-2001 Scott Ramsay
// sramsay@gonavi.com
// http://www.gonavi.com
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// If you use this code, drop me an email. I'd like to know if you find the code
// useful.
//#include "stdafx.h"
#include "../../../idlib/precompiled.h"
#pragma hdrstop
#include "proptree.h"
#include "PropTreeItemCheck.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define CHECK_BOX_SIZE 14
/////////////////////////////////////////////////////////////////////////////
// CPropTreeItemCheck
CPropTreeItemCheck::CPropTreeItemCheck()
{
checkState = 0;
}
CPropTreeItemCheck::~CPropTreeItemCheck()
{
}
BEGIN_MESSAGE_MAP(CPropTreeItemCheck, CButton)
//{{AFX_MSG_MAP(CPropTreeItemCheck)
//}}AFX_MSG_MAP
ON_CONTROL_REFLECT(BN_KILLFOCUS, OnBnKillfocus)
ON_CONTROL_REFLECT(BN_CLICKED, OnBnClicked)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPropTreeItemCheck message handlers
void CPropTreeItemCheck::DrawAttribute(CDC* pDC, const RECT& rc)
{
ASSERT(m_pProp!=NULL);
// verify the window has been created
if (!IsWindow(m_hWnd))
{
TRACE0("CPropTreeItemCombo::DrawAttribute() - The window has not been created\n");
return;
}
checkRect.left = m_rc.left;
checkRect.top = m_rc.top + ((m_rc.bottom - m_rc.top)/2)-CHECK_BOX_SIZE/2;
checkRect.right = checkRect.left + CHECK_BOX_SIZE;
checkRect.bottom = checkRect.top + CHECK_BOX_SIZE;
if(!m_bActivated)
pDC->DrawFrameControl(&checkRect, DFC_BUTTON, DFCS_BUTTONCHECK | DFCS_FLAT |(checkState ? DFCS_CHECKED : 0));
}
void CPropTreeItemCheck::SetCheckState(BOOL state)
{
checkState = state;
SetCheck(checkState ? BST_CHECKED : BST_UNCHECKED);
}
LPARAM CPropTreeItemCheck::GetItemValue()
{
return (LPARAM)GetCheckState();
}
void CPropTreeItemCheck::SetItemValue(LPARAM lParam)
{
SetCheckState((BOOL)lParam);
}
void CPropTreeItemCheck::OnMove()
{
if (IsWindow(m_hWnd))
SetWindowPos(NULL, m_rc.left, m_rc.top, m_rc.Width(), m_rc.Height(), SWP_NOZORDER|SWP_NOACTIVATE);
}
void CPropTreeItemCheck::OnRefresh()
{
}
void CPropTreeItemCheck::OnCommit()
{
ShowWindow(SW_HIDE);
}
void CPropTreeItemCheck::OnActivate(int activateType, CPoint point)
{
if(activateType == CPropTreeItem::ACTIVATE_TYPE_MOUSE) {
//Check where the user clicked
if(point.x < m_rc.left + CHECK_BOX_SIZE) {
SetCheckState(!GetCheckState());
CommitChanges();
} else {
SetWindowPos(NULL, m_rc.left, m_rc.top, m_rc.Width(), m_rc.Height(), SWP_NOZORDER|SWP_SHOWWINDOW);
SetFocus();
}
} else {
SetWindowPos(NULL, m_rc.left, m_rc.top, m_rc.Width(), m_rc.Height(), SWP_NOZORDER|SWP_SHOWWINDOW);
SetFocus();
}
}
bool CPropTreeItemCheck::CreateCheckBox() {
ASSERT(m_pProp!=NULL);
if (IsWindow(m_hWnd))
DestroyWindow();
DWORD dwStyle = (WS_CHILD|BS_CHECKBOX|BS_NOTIFY|BS_FLAT );
if (!Create(NULL, dwStyle, CRect(0,0,0,0), m_pProp->GetCtrlParent(), GetCtrlID()))
{
TRACE0("CPropTreeItemCombo::CreateComboBox() - failed to create combo box\n");
return FALSE;
}
return TRUE;
}
void CPropTreeItemCheck::OnBnKillfocus()
{
CommitChanges();
}
void CPropTreeItemCheck::OnBnClicked()
{
int state = GetCheck();
SetCheckState(GetCheck() == BST_CHECKED ? FALSE : TRUE);
CommitChanges();
}

View File

@@ -0,0 +1,95 @@
#pragma once
// PropTreeItemCheck.h : header file
//
// Copyright (C) 1998-2001 Scott Ramsay
// sramsay@gonavi.com
// http://www.gonavi.com
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// If you use this code, drop me an email. I'd like to know if you find the code
// useful.
#include "PropTreeItem.h"
/////////////////////////////////////////////////////////////////////////////
// CPropTreeItemCheck window
class PROPTREE_API CPropTreeItemCheck : public CButton, public CPropTreeItem
{
// Construction
public:
CPropTreeItemCheck();
virtual ~CPropTreeItemCheck();
// Attributes
public:
// The attribute area needs drawing
virtual void DrawAttribute(CDC* pDC, const RECT& rc);
// Retrieve the item's attribute value
virtual LPARAM GetItemValue();
// Set the item's attribute value
virtual void SetItemValue(LPARAM lParam);
// Called when attribute area has changed size
virtual void OnMove();
// Called when the item needs to refresh its data
virtual void OnRefresh();
// Called when the item needs to commit its changes
virtual void OnCommit();
// Called to activate the item
virtual void OnActivate(int activateType, CPoint point);
bool HitCheckBoxTest(const POINT& pt);
bool CreateCheckBox();
BOOL GetCheckState() { return checkState; };
void SetCheckState(BOOL state);
protected:
BOOL checkState;
CRect checkRect;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CPropTreeItemCheck)
//}}AFX_VIRTUAL
// Implementation
public:
// Generated message map functions
protected:
//{{AFX_MSG(CPropTreeItemCheck)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnKillfocus();
afx_msg void OnBnClicked();
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

View File

@@ -0,0 +1,369 @@
// PropTreeItemColor.cpp : implementation file
//
// Copyright (C) 1998-2001 Scott Ramsay
// sramsay@gonavi.com
// http://www.gonavi.com
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// If you use this code, drop me an email. I'd like to know if you find the code
// useful.
//#include "stdafx.h"
#include "../../../idlib/precompiled.h"
#pragma hdrstop
#include "PropTree.h"
#include "../../../sys/win32/rc/proptree_Resource.h"
#include "PropTreeItemColor.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern HINSTANCE ghInst;
typedef struct _ColorTableEntry
{
COLORREF color;
RECT rcSpot;
} ColorTableEntry;
static ColorTableEntry _crColors[] =
{
{RGB(0x00, 0x00, 0x00)},
{RGB(0xA5, 0x2A, 0x00)},
{RGB(0x00, 0x40, 0x40)},
{RGB(0x00, 0x55, 0x00)},
{RGB(0x00, 0x00, 0x5E)},
{RGB(0x00, 0x00, 0x8B)},
{RGB(0x4B, 0x00, 0x82)},
{RGB(0x28, 0x28, 0x28)},
{RGB(0x8B, 0x00, 0x00)},
{RGB(0xFF, 0x68, 0x20)},
{RGB(0x8B, 0x8B, 0x00)},
{RGB(0x00, 0x93, 0x00)},
{RGB(0x38, 0x8E, 0x8E)},
{RGB(0x00, 0x00, 0xFF)},
{RGB(0x7B, 0x7B, 0xC0)},
{RGB(0x66, 0x66, 0x66)},
{RGB(0xFF, 0x00, 0x00)},
{RGB(0xFF, 0xAD, 0x5B)},
{RGB(0x32, 0xCD, 0x32)},
{RGB(0x3C, 0xB3, 0x71)},
{RGB(0x7F, 0xFF, 0xD4)},
{RGB(0x7D, 0x9E, 0xC0)},
{RGB(0x80, 0x00, 0x80)},
{RGB(0x7F, 0x7F, 0x7F)},
{RGB(0xFF, 0xC0, 0xCB)},
{RGB(0xFF, 0xD7, 0x00)},
{RGB(0xFF, 0xFF, 0x00)},
{RGB(0x00, 0xFF, 0x00)},
{RGB(0x40, 0xE0, 0xD0)},
{RGB(0xC0, 0xFF, 0xFF)},
{RGB(0x48, 0x00, 0x48)},
{RGB(0xC0, 0xC0, 0xC0)},
{RGB(0xFF, 0xE4, 0xE1)},
{RGB(0xD2, 0xB4, 0x8C)},
{RGB(0xFF, 0xFF, 0xE0)},
{RGB(0x98, 0xFB, 0x98)},
{RGB(0xAF, 0xEE, 0xEE)},
{RGB(0x68, 0x83, 0x8B)},
{RGB(0xE6, 0xE6, 0xFA)},
{RGB(0xFF, 0xFF, 0xFF)}
};
static void ColorBox(CDC* pDC, CPoint pt, COLORREF clr, BOOL bHover)
{
CBrush br(clr);
CBrush* obr = pDC->SelectObject(&br);
pDC->PatBlt(pt.x, pt.y, 13, 13, PATCOPY);
pDC->SelectObject(obr);
CRect rc;
rc.SetRect(pt.x - 2, pt.y - 2, pt.x + 15, pt.y + 15);
pDC->DrawEdge(&rc, (bHover) ? BDR_SUNKENOUTER : BDR_RAISEDINNER, BF_RECT);
}
static LONG FindSpot(CPoint point)
{
for (LONG i=0; i<40; i++)
{
if (PtInRect(&_crColors[i].rcSpot, point))
return i;
}
return -1;
}
/////////////////////////////////////////////////////////////////////////////
// CPropTreeItemColor
COLORREF* CPropTreeItemColor::s_pColors = NULL;
CPropTreeItemColor::CPropTreeItemColor() :
m_cColor(0),
m_cPrevColor(0),
m_nSpot(-1),
m_bButton(FALSE),
m_bInDialog(FALSE)
{
}
CPropTreeItemColor::~CPropTreeItemColor()
{
}
BEGIN_MESSAGE_MAP(CPropTreeItemColor, CWnd)
//{{AFX_MSG_MAP(CPropTreeItemColor)
ON_WM_KILLFOCUS()
ON_WM_PAINT()
ON_WM_CLOSE()
ON_WM_MOUSEMOVE()
ON_WM_SETCURSOR()
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPropTreeItemColor message handlers
void CPropTreeItemColor::SetDefaultColorsList(COLORREF* pColors)
{
s_pColors = pColors;
}
void CPropTreeItemColor::DrawAttribute(CDC* pDC, const RECT& rc)
{
ASSERT(m_pProp!=NULL);
CRect r(rc);
pDC->SelectObject(IsReadOnly() ? m_pProp->GetNormalFont() : m_pProp->GetBoldFont());
if (!m_pProp->IsWindowEnabled())
pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
else
pDC->SetTextColor(RGB(0,0,0));
r.top += 1;
r.right = r.left + r.Height() - 1;
CBrush br(m_cColor);
CBrush* pold = pDC->SelectObject(&br);
pDC->PatBlt(r.left, r.top, r.Width(), r.Height(), PATCOPY);
pDC->SelectObject(pold);
pDC->DrawEdge(&r, EDGE_SUNKEN, BF_RECT);
CString s;
r = rc;
r.left += r.Height();
s.Format(_T("R = %d, G = %d, B = %d"), GetRValue(m_cColor),GetGValue(m_cColor), GetBValue(m_cColor));
pDC->DrawText(s, r, DT_SINGLELINE|DT_VCENTER);
}
LPARAM CPropTreeItemColor::GetItemValue()
{
return m_cColor;
}
void CPropTreeItemColor::SetItemValue(LPARAM lParam)
{
m_cColor = lParam;
}
void CPropTreeItemColor::OnMove()
{
}
void CPropTreeItemColor::OnRefresh()
{
}
void CPropTreeItemColor::OnCommit()
{
ShowWindow(SW_HIDE);
}
void CPropTreeItemColor::OnActivate(int activateType, CPoint point)
{
CRect r;
m_cPrevColor = m_cColor;
r = m_rc;
r.right = r.left + 150;
r.bottom = r.top + 120;
ASSERT(m_pProp!=NULL);
m_pProp->GetCtrlParent()->ClientToScreen(r);
if (!IsWindow(m_hWnd))
{
LPCTSTR pszClassName;
pszClassName = AfxRegisterWndClass(CS_VREDRAW|CS_HREDRAW, LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_BTNFACE + 1));
DWORD dwStyle = WS_POPUP|WS_DLGFRAME;
CreateEx(0, pszClassName, _T(""), dwStyle, r, m_pProp->GetCtrlParent(), 0);
m_rcButton.SetRect(40, 94, 110, 114);
}
SetWindowPos(NULL, r.left, r.top, r.Width() + 1, r.Height(), SWP_NOZORDER|SWP_SHOWWINDOW);
SetFocus();
}
void CPropTreeItemColor::OnKillFocus(CWnd* pNewWnd)
{
CWnd::OnKillFocus(pNewWnd);
if (!m_bInDialog)
CommitChanges();
}
void CPropTreeItemColor::OnPaint()
{
CPaintDC dc(this);
CPoint pt;
for (LONG i=0; i<40; i++)
{
pt.x = (i & 7) * 18 + 3;
pt.y = (i >> 3) * 18 + 3;
ColorBox(&dc, pt, _crColors[i].color, m_nSpot==i);
SetRect(&_crColors[i].rcSpot, pt.x, pt.y, pt.x + 13, pt.y + 13);
}
ASSERT(m_pProp!=NULL);
dc.SelectObject(m_pProp->GetNormalFont());
CString s(_T("More Colors"));
dc.SetBkMode(TRANSPARENT);
dc.SetTextColor(GetSysColor(COLOR_BTNTEXT));
dc.DrawText(s, &m_rcButton, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
dc.DrawEdge(&m_rcButton, m_bButton ? BDR_SUNKENOUTER : BDR_RAISEDINNER, BF_RECT);
}
void CPropTreeItemColor::OnClose()
{
CommitChanges();
}
void CPropTreeItemColor::OnMouseMove(UINT, CPoint point)
{
BOOL bButton;
LONG nSpot;
nSpot = FindSpot(point);
if (nSpot!=m_nSpot)
{
Invalidate(FALSE);
m_nSpot = nSpot;
}
bButton = m_rcButton.PtInRect(point);
if (bButton!=m_bButton)
{
m_bButton = bButton;
Invalidate(FALSE);
}
}
BOOL CPropTreeItemColor::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (nHitTest==HTCLIENT)
{
CPoint point;
GetCursorPos(&point);
ScreenToClient(&point);
if (FindSpot(point)!=-1 || m_rcButton.PtInRect(point))
{
SetCursor(LoadCursor(ghInst, MAKEINTRESOURCE(IDC_FPOINT)));
return TRUE;
}
}
return CWnd::OnSetCursor(pWnd, nHitTest, message);
}
void CPropTreeItemColor::OnLButtonDown(UINT, CPoint point)
{
if (m_nSpot!=-1)
{
m_cColor = _crColors[m_nSpot].color;
CommitChanges();
}
else
if (m_rcButton.PtInRect(point))
{
CHOOSECOLOR cc;
COLORREF clr[16];
ZeroMemory(&cc, sizeof(CHOOSECOLOR));
cc.Flags = CC_FULLOPEN|CC_ANYCOLOR|CC_RGBINIT;
cc.lStructSize = sizeof(CHOOSECOLOR);
cc.hwndOwner = m_hWnd;
cc.rgbResult = m_cColor;
cc.lpCustColors = s_pColors ? s_pColors : clr;
memset(clr, 0xff, sizeof(COLORREF) * 16);
clr[0] = m_cColor;
m_bInDialog = TRUE;
ASSERT(m_pProp!=NULL);
m_pProp->DisableInput();
ShowWindow(SW_HIDE);
if (ChooseColor(&cc))
m_cColor = cc.rgbResult;
m_pProp->DisableInput(FALSE);
CommitChanges();
}
}

View File

@@ -0,0 +1,98 @@
#if !defined(AFX_PROPTREEITEMCOLOR_H__50C09AC0_1F02_4150_AA6A_5151345D87A2__INCLUDED_)
#define AFX_PROPTREEITEMCOLOR_H__50C09AC0_1F02_4150_AA6A_5151345D87A2__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// PropTreeItemColor.h : header file
//
// Copyright (C) 1998-2001 Scott Ramsay
// sramsay@gonavi.com
// http://www.gonavi.com
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// If you use this code, drop me an email. I'd like to know if you find the code
// useful.
#include "PropTreeItem.h"
/////////////////////////////////////////////////////////////////////////////
// CPropTreeItemColor window
class PROPTREE_API CPropTreeItemColor : public CWnd, public CPropTreeItem
{
// Construction
public:
CPropTreeItemColor();
virtual ~CPropTreeItemColor();
// Attributes
public:
// The attribute area needs drawing
virtual void DrawAttribute(CDC* pDC, const RECT& rc);
// Retrieve the item's attribute value
virtual LPARAM GetItemValue();
// Set the item's attribute value
virtual void SetItemValue(LPARAM lParam);
// Called when attribute area has changed size
virtual void OnMove();
// Called when the item needs to refresh its data
virtual void OnRefresh();
// Called when the item needs to commit its changes
virtual void OnCommit();
// Called to activate the item
virtual void OnActivate(int activateType, CPoint point);
static void SetDefaultColorsList(COLORREF* pColors);
protected:
COLORREF m_cColor;
COLORREF m_cPrevColor;
CRect m_rcButton;
LONG m_nSpot;
BOOL m_bButton;
BOOL m_bInDialog;
static COLORREF* s_pColors;
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CPropTreeItemColor)
//}}AFX_VIRTUAL
// Implementation
public:
// Generated message map functions
protected:
//{{AFX_MSG(CPropTreeItemColor)
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnPaint();
afx_msg void OnClose();
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_PROPTREEITEMCOLOR_H__50C09AC0_1F02_4150_AA6A_5151345D87A2__INCLUDED_)

View File

@@ -0,0 +1,233 @@
// PropTreeItemCombo.cpp : implementation file
//
// Copyright (C) 1998-2001 Scott Ramsay
// sramsay@gonavi.com
// http://www.gonavi.com
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// If you use this code, drop me an email. I'd like to know if you find the code
// useful.
//#include "stdafx.h"
#include "../../../idlib/precompiled.h"
#pragma hdrstop
#include "PropTree.h"
#include "../../../sys/win32/rc/proptree_Resource.h"
#include "PropTreeItemCombo.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define DROPDOWN_HEIGHT 100
/////////////////////////////////////////////////////////////////////////////
// CPropTreeItemCombo
CPropTreeItemCombo::CPropTreeItemCombo() :
m_lComboData(0),
m_nDropHeight(DROPDOWN_HEIGHT)
{
}
CPropTreeItemCombo::~CPropTreeItemCombo()
{
}
BEGIN_MESSAGE_MAP(CPropTreeItemCombo, CComboBox)
//{{AFX_MSG_MAP(CPropTreeItemCombo)
ON_CONTROL_REFLECT(CBN_SELCHANGE, OnSelchange)
ON_CONTROL_REFLECT(CBN_KILLFOCUS, OnKillfocus)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPropTreeItemCombo message handlers
void CPropTreeItemCombo::DrawAttribute(CDC* pDC, const RECT& rc)
{
ASSERT(m_pProp!=NULL);
// verify the window has been created
if (!IsWindow(m_hWnd))
{
TRACE0("CPropTreeItemCombo::DrawAttribute() - The window has not been created\n");
return;
}
pDC->SelectObject(IsReadOnly() ? m_pProp->GetNormalFont() : m_pProp->GetBoldFont());
pDC->SetTextColor(RGB(0,0,0));
pDC->SetBkMode(TRANSPARENT);
CRect r = rc;
CString s;
LONG idx;
if ((idx = GetCurSel())!=CB_ERR)
GetLBText(idx, s);
else
s = _T("");
pDC->DrawText(s, r, DT_SINGLELINE|DT_VCENTER);
}
LPARAM CPropTreeItemCombo::GetItemValue()
{
return m_lComboData;
}
void CPropTreeItemCombo::SetItemValue(LPARAM lParam)
{
m_lComboData = lParam;
OnRefresh();
}
void CPropTreeItemCombo::OnMove()
{
if (IsWindow(m_hWnd) && IsWindowVisible())
SetWindowPos(NULL, m_rc.left, m_rc.top, m_rc.Width() + 1, m_rc.Height(), SWP_NOZORDER|SWP_SHOWWINDOW);
}
void CPropTreeItemCombo::OnRefresh()
{
LONG idx = FindCBData(m_lComboData);
if (idx!=CB_ERR)
SetCurSel(idx);
}
void CPropTreeItemCombo::OnCommit()
{
LONG idx;
// store combo box item data
if ((idx = GetCurSel())==CB_ERR)
m_lComboData = 0;
else
m_lComboData = (LPARAM)GetItemData(idx);
ShowWindow(SW_HIDE);
}
void CPropTreeItemCombo::OnActivate(int activateType, CPoint point)
{
// activate the combo box
SetWindowPos(NULL, m_rc.left, m_rc.top, m_rc.Width() + 1, m_rc.Height() + m_nDropHeight, SWP_NOZORDER|SWP_SHOWWINDOW);
SetFocus();
if (GetCount())
ShowDropDown(TRUE);
}
BOOL CPropTreeItemCombo::CreateComboBox(DWORD dwStyle)
{
ASSERT(m_pProp!=NULL);
if (IsWindow(m_hWnd))
DestroyWindow();
// force as not visible child window
dwStyle = (WS_CHILD|WS_VSCROLL|dwStyle) & ~WS_VISIBLE;
if (!Create(dwStyle, CRect(0,0,0,0), m_pProp->GetCtrlParent(), GetCtrlID()))
{
TRACE0("CPropTreeItemCombo::CreateComboBox() - failed to create combo box\n");
return FALSE;
}
SendMessage(WM_SETFONT, (WPARAM)m_pProp->GetNormalFont()->m_hObject);
return TRUE;
}
BOOL CPropTreeItemCombo::CreateComboBoxBool()
{
ASSERT(m_pProp!=NULL);
if (IsWindow(m_hWnd))
DestroyWindow();
// force as a non-visible child window
DWORD dwStyle = WS_CHILD|WS_VSCROLL|CBS_SORT|CBS_DROPDOWNLIST;
if (!Create(dwStyle, CRect(0,0,0,0), m_pProp->GetCtrlParent(), GetCtrlID()))
{
TRACE0("CPropTreeItemCombo::CreateComboBoxBool() - failed to create combo box\n");
return FALSE;
}
SendMessage(WM_SETFONT, (WPARAM)m_pProp->GetNormalFont()->m_hObject);
// file the combo box
LONG idx;
CString s;
s.LoadString(IDS_TRUE);
idx = AddString(s);
SetItemData(idx, TRUE);
s.LoadString(IDS_FALSE);
idx = AddString(s);
SetItemData(idx, FALSE);
return TRUE;
}
LONG CPropTreeItemCombo::FindCBData(LPARAM lParam)
{
LONG idx;
for (idx = 0; idx < GetCount(); idx++)
{
if (GetItemData(idx)==(DWORD)lParam)
return idx;
}
return CB_ERR;
}
void CPropTreeItemCombo::OnSelchange()
{
CommitChanges();
}
void CPropTreeItemCombo::OnKillfocus()
{
CommitChanges();
}
void CPropTreeItemCombo::SetDropDownHeight(LONG nDropHeight)
{
m_nDropHeight = nDropHeight;
}
LONG CPropTreeItemCombo::GetDropDownHeight()
{
return m_nDropHeight;
}

View File

@@ -0,0 +1,103 @@
#if !defined(AFX_PROPTREEITEMCOMBO_H__9916BC6F_751F_4B15_996F_3C9F6334A259__INCLUDED_)
#define AFX_PROPTREEITEMCOMBO_H__9916BC6F_751F_4B15_996F_3C9F6334A259__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// PropTreeItemCombo.h : header file
//
// Copyright (C) 1998-2001 Scott Ramsay
// sramsay@gonavi.com
// http://www.gonavi.com
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// If you use this code, drop me an email. I'd like to know if you find the code
// useful.
#include "PropTreeItem.h"
/////////////////////////////////////////////////////////////////////////////
// CPropTreeItemCombo window
class PROPTREE_API CPropTreeItemCombo : public CComboBox, public CPropTreeItem
{
// Construction
public:
CPropTreeItemCombo();
virtual ~CPropTreeItemCombo();
// Attributes
public:
// The attribute area needs drawing
virtual void DrawAttribute(CDC* pDC, const RECT& rc);
// Retrieve the item's attribute value
virtual LPARAM GetItemValue();
// Set the item's attribute value
virtual void SetItemValue(LPARAM lParam);
// Called when attribute area has changed size
virtual void OnMove();
// Called when the item needs to refresh its data
virtual void OnRefresh();
// Called when the item needs to commit its changes
virtual void OnCommit();
// Called to activate the item
virtual void OnActivate(int activateType, CPoint point);
// Create your combo box with your specified styles
BOOL CreateComboBox(DWORD dwStyle = WS_CHILD|WS_VSCROLL|CBS_SORT|CBS_DROPDOWNLIST);
// Create combo box with TRUE/FALSE selections
BOOL CreateComboBoxBool();
// Set the height for the dropdown combo box
void SetDropDownHeight(LONG nDropHeight);
// Get the height of the dropdown combo box
LONG GetDropDownHeight();
protected:
LPARAM m_lComboData;
LONG m_nDropHeight;
// Operations
protected:
LONG FindCBData(LPARAM lParam);
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CPropTreeItemCombo)
//}}AFX_VIRTUAL
// Implementation
public:
// Generated message map functions
protected:
//{{AFX_MSG(CPropTreeItemCombo)
afx_msg void OnSelchange();
afx_msg void OnKillfocus();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_PROPTREEITEMCOMBO_H__9916BC6F_751F_4B15_996F_3C9F6334A259__INCLUDED_)

View File

@@ -0,0 +1,212 @@
// PropTreeItemEdit.cpp : implementation file
//
// Copyright (C) 1998-2001 Scott Ramsay
// sramsay@gonavi.com
// http://www.gonavi.com
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// If you use this code, drop me an email. I'd like to know if you find the code
// useful.
//#include "stdafx.h"
#include "../../../idlib/precompiled.h"
#pragma hdrstop
#include "proptree.h"
#include "PropTreeItemEdit.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CPropTreeItemEdit
CPropTreeItemEdit::CPropTreeItemEdit() :
m_sEdit(_T("")),
m_nFormat(ValueFormatText),
m_bPassword(FALSE),
m_fValue(0.0f)
{
}
CPropTreeItemEdit::~CPropTreeItemEdit()
{
}
BEGIN_MESSAGE_MAP(CPropTreeItemEdit, CEdit)
//{{AFX_MSG_MAP(CPropTreeItemEdit)
ON_WM_GETDLGCODE()
ON_WM_KEYDOWN()
ON_CONTROL_REFLECT(EN_KILLFOCUS, OnKillfocus)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPropTreeItemEdit message handlers
void CPropTreeItemEdit::DrawAttribute(CDC* pDC, const RECT& rc)
{
ASSERT(m_pProp!=NULL);
pDC->SelectObject(IsReadOnly() ? m_pProp->GetNormalFont() : m_pProp->GetBoldFont());
pDC->SetTextColor(RGB(0,0,0));
pDC->SetBkMode(TRANSPARENT);
CRect r = rc;
TCHAR ch;
// can't use GetPasswordChar(), because window may not be created yet
ch = (m_bPassword) ? '*' : '\0';
if (ch)
{
CString s;
s = m_sEdit;
for (LONG i=0; i<s.GetLength();i++)
s.SetAt(i, ch);
pDC->DrawText(s, r, DT_SINGLELINE|DT_VCENTER);
}
else
{
pDC->DrawText(m_sEdit, r, DT_SINGLELINE|DT_VCENTER);
}
}
void CPropTreeItemEdit::SetAsPassword(BOOL bPassword)
{
m_bPassword = bPassword;
}
void CPropTreeItemEdit::SetValueFormat(ValueFormat nFormat)
{
m_nFormat = nFormat;
}
LPARAM CPropTreeItemEdit::GetItemValue()
{
switch (m_nFormat)
{
case ValueFormatNumber:
return _ttoi(m_sEdit);
case ValueFormatFloatPointer:
_stscanf(m_sEdit, _T("%f"), &m_fValue);
return (LPARAM)&m_fValue;
}
return (LPARAM)(LPCTSTR)m_sEdit;
}
void CPropTreeItemEdit::SetItemValue(LPARAM lParam)
{
switch (m_nFormat)
{
case ValueFormatNumber:
m_sEdit.Format(_T("%d"), lParam);
return;
case ValueFormatFloatPointer:
{
TCHAR tmp[MAX_PATH];
m_fValue = *(float*)lParam;
_stprintf(tmp, _T("%f"), m_fValue);
m_sEdit = tmp;
}
return;
}
if (lParam==0L)
{
TRACE0("CPropTreeItemEdit::SetItemValue - Invalid lParam value\n");
return;
}
m_sEdit = (LPCTSTR)lParam;
}
void CPropTreeItemEdit::OnMove()
{
if (IsWindow(m_hWnd))
SetWindowPos(NULL, m_rc.left, m_rc.top, m_rc.Width(), m_rc.Height(), SWP_NOZORDER|SWP_NOACTIVATE);
}
void CPropTreeItemEdit::OnRefresh()
{
if (IsWindow(m_hWnd))
SetWindowText(m_sEdit);
}
void CPropTreeItemEdit::OnCommit()
{
// hide edit control
ShowWindow(SW_HIDE);
// store edit text for GetItemValue
GetWindowText(m_sEdit);
}
void CPropTreeItemEdit::OnActivate(int activateType, CPoint point)
{
// Check if the edit control needs creation
if (!IsWindow(m_hWnd))
{
DWORD dwStyle;
dwStyle = WS_CHILD|ES_AUTOHSCROLL;
Create(dwStyle, m_rc, m_pProp->GetCtrlParent(), GetCtrlID());
}
SendMessage(WM_SETFONT, (WPARAM)m_pProp->GetNormalFont()->m_hObject);
SetPasswordChar((TCHAR)(m_bPassword ? '*' : 0));
SetWindowText(m_sEdit);
SetSel(0, -1);
SetWindowPos(NULL, m_rc.left, m_rc.top, m_rc.Width(), m_rc.Height(), SWP_NOZORDER|SWP_SHOWWINDOW);
SetFocus();
}
UINT CPropTreeItemEdit::OnGetDlgCode()
{
return CEdit::OnGetDlgCode()|DLGC_WANTALLKEYS;
}
void CPropTreeItemEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar==VK_RETURN)
CommitChanges();
CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CPropTreeItemEdit::OnKillfocus()
{
CommitChanges();
}

View File

@@ -0,0 +1,108 @@
#if !defined(AFX_PROPTREEITEMEDIT_H__642536B1_1162_4F99_B09D_9B1BD2CF88B6__INCLUDED_)
#define AFX_PROPTREEITEMEDIT_H__642536B1_1162_4F99_B09D_9B1BD2CF88B6__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// PropTreeItemEdit.h : header file
//
// Copyright (C) 1998-2001 Scott Ramsay
// sramsay@gonavi.com
// http://www.gonavi.com
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// If you use this code, drop me an email. I'd like to know if you find the code
// useful.
#include "PropTreeItem.h"
/////////////////////////////////////////////////////////////////////////////
// CPropTreeItemEdit window
class PROPTREE_API CPropTreeItemEdit : public CEdit, public CPropTreeItem
{
// Construction
public:
CPropTreeItemEdit();
virtual ~CPropTreeItemEdit();
// Attributes
public:
// The attribute area needs drawing
virtual void DrawAttribute(CDC* pDC, const RECT& rc);
// Retrieve the item's attribute value
virtual LPARAM GetItemValue();
// Set the item's attribute value
virtual void SetItemValue(LPARAM lParam);
// Called when attribute area has changed size
virtual void OnMove();
// Called when the item needs to refresh its data
virtual void OnRefresh();
// Called when the item needs to commit its changes
virtual void OnCommit();
// Called to activate the item
virtual void OnActivate(int activateType, CPoint point);
enum ValueFormat
{
ValueFormatText,
ValueFormatNumber,
ValueFormatFloatPointer
};
// Set to specifify format of SetItemValue/GetItemValue
void SetValueFormat(ValueFormat nFormat);
// Set to TRUE for to use a password edit control
void SetAsPassword(BOOL bPassword);
protected:
CString m_sEdit;
float m_fValue;
ValueFormat m_nFormat;
BOOL m_bPassword;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CPropTreeItemEdit)
//}}AFX_VIRTUAL
// Implementation
public:
// Generated message map functions
protected:
//{{AFX_MSG(CPropTreeItemEdit)
afx_msg UINT OnGetDlgCode();
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnKillfocus();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_PROPTREEITEMEDIT_H__642536B1_1162_4F99_B09D_9B1BD2CF88B6__INCLUDED_)

View File

@@ -0,0 +1,259 @@
// PropTreeItemEdit.cpp : implementation file
//
// Copyright (C) 1998-2001 Scott Ramsay
// sramsay@gonavi.com
// http://www.gonavi.com
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// If you use this code, drop me an email. I'd like to know if you find the code
// useful.
//#include "stdafx.h"
#include "../../../idlib/precompiled.h"
#pragma hdrstop
#include "proptree.h"
#include "PropTreeItemEditButton.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define BUTTON_SIZE 17
/////////////////////////////////////////////////////////////////////////////
// CPropTreeItemEditButton
CPropTreeItemEditButton::CPropTreeItemEditButton() :
m_sEdit(_T("")),
m_nFormat(ValueFormatText),
m_bPassword(FALSE),
m_fValue(0.0f)
{
mouseDown = false;
}
CPropTreeItemEditButton::~CPropTreeItemEditButton()
{
}
BEGIN_MESSAGE_MAP(CPropTreeItemEditButton, CEdit)
//{{AFX_MSG_MAP(CPropTreeItemEditButton)
ON_WM_GETDLGCODE()
ON_WM_KEYDOWN()
ON_CONTROL_REFLECT(EN_KILLFOCUS, OnKillfocus)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPropTreeItemEditButton message handlers
LONG CPropTreeItemEditButton::DrawItem( CDC* pDC, const RECT& rc, LONG x, LONG y )
{
CSize textSize;
CRect textRect;
LONG nTotal = 0;
nTotal = CPropTreeItemEdit::DrawItem( pDC, rc, x, y );
textSize = pDC->GetOutputTextExtent( buttonText );
buttonRect.left = m_rc.right - ( textSize.cx + 12 + 4);
buttonRect.top = m_rc.top + ((m_rc.bottom - m_rc.top)/2)-BUTTON_SIZE/2;
buttonRect.right = buttonRect.left + textSize.cx + 12;
buttonRect.bottom = buttonRect.top + BUTTON_SIZE;
UINT buttonStyle;
if ( (m_dwState & TreeItemChecked) ) {
buttonStyle = DFCS_BUTTONPUSH | DFCS_PUSHED;
} else {
buttonStyle = DFCS_BUTTONPUSH;
}
pDC->DrawFrameControl(&buttonRect, DFC_BUTTON, buttonStyle );
textRect = buttonRect;
textRect.left += 4;
textRect.right -= 8;
pDC->DrawText( buttonText, textRect, DT_SINGLELINE|DT_VCENTER );
//Adjust hit test rect to acount for window scrolling
hitTestRect = buttonRect;
hitTestRect.OffsetRect(0, m_pProp->GetOrigin().y);
return nTotal;
}
void CPropTreeItemEditButton::DrawAttribute(CDC* pDC, const RECT& rc)
{
ASSERT(m_pProp!=NULL);
pDC->SelectObject(IsReadOnly() ? m_pProp->GetNormalFont() : m_pProp->GetBoldFont());
pDC->SetTextColor(RGB(0,0,0));
pDC->SetBkMode(TRANSPARENT);
CRect r = rc;
r.right = buttonRect.left - 5;
TCHAR ch;
// can't use GetPasswordChar(), because window may not be created yet
ch = (m_bPassword) ? '*' : '\0';
if (ch)
{
CString s;
s = m_sEdit;
for (LONG i=0; i<s.GetLength();i++)
s.SetAt(i, ch);
pDC->DrawText(s, r, DT_SINGLELINE|DT_VCENTER);
}
else
{
pDC->DrawText(m_sEdit, r, DT_SINGLELINE|DT_VCENTER);
}
}
void CPropTreeItemEditButton::SetAsPassword(BOOL bPassword)
{
m_bPassword = bPassword;
}
void CPropTreeItemEditButton::SetValueFormat(ValueFormat nFormat)
{
m_nFormat = nFormat;
}
LPARAM CPropTreeItemEditButton::GetItemValue()
{
switch (m_nFormat)
{
case ValueFormatNumber:
return _ttoi(m_sEdit);
case ValueFormatFloatPointer:
_stscanf(m_sEdit, _T("%f"), &m_fValue);
return (LPARAM)&m_fValue;
}
return (LPARAM)(LPCTSTR)m_sEdit;
}
void CPropTreeItemEditButton::SetItemValue(LPARAM lParam)
{
switch (m_nFormat)
{
case ValueFormatNumber:
m_sEdit.Format(_T("%d"), lParam);
return;
case ValueFormatFloatPointer:
{
TCHAR tmp[MAX_PATH];
m_fValue = *(float*)lParam;
_stprintf(tmp, _T("%f"), m_fValue);
m_sEdit = tmp;
}
return;
}
if (lParam==0L)
{
TRACE0("CPropTreeItemEditButton::SetItemValue - Invalid lParam value\n");
return;
}
m_sEdit = (LPCTSTR)lParam;
}
void CPropTreeItemEditButton::OnMove()
{
if (IsWindow(m_hWnd))
SetWindowPos(NULL, m_rc.left, m_rc.top, m_rc.Width(), m_rc.Height(), SWP_NOZORDER|SWP_NOACTIVATE);
}
void CPropTreeItemEditButton::OnRefresh()
{
if (IsWindow(m_hWnd))
SetWindowText(m_sEdit);
}
void CPropTreeItemEditButton::OnCommit()
{
// hide edit control
ShowWindow(SW_HIDE);
// store edit text for GetItemValue
GetWindowText(m_sEdit);
}
void CPropTreeItemEditButton::OnActivate(int activateType, CPoint point)
{
// Check if the edit control needs creation
if (!IsWindow(m_hWnd))
{
DWORD dwStyle;
dwStyle = WS_CHILD|ES_AUTOHSCROLL;
Create(dwStyle, m_rc, m_pProp->GetCtrlParent(), GetCtrlID());
SendMessage(WM_SETFONT, (WPARAM)m_pProp->GetNormalFont()->m_hObject);
}
SetPasswordChar((TCHAR)(m_bPassword ? '*' : 0));
SetWindowText(m_sEdit);
SetSel(0, -1);
SetWindowPos(NULL, m_rc.left, m_rc.top, m_rc.Width() - buttonRect.Width() - 5, m_rc.Height(), SWP_NOZORDER|SWP_SHOWWINDOW);
SetFocus();
}
UINT CPropTreeItemEditButton::OnGetDlgCode()
{
return CEdit::OnGetDlgCode()|DLGC_WANTALLKEYS;
}
void CPropTreeItemEditButton::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar==VK_RETURN)
CommitChanges();
CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CPropTreeItemEditButton::OnKillfocus()
{
CommitChanges();
}
BOOL CPropTreeItemEditButton::HitButton( const POINT& pt ) {
return hitTestRect.PtInRect( pt );
}
void CPropTreeItemEditButton::SetButtonText( LPCSTR text ) {
buttonText = text;
}

View File

@@ -0,0 +1,125 @@
#ifndef __PROP_TREE_ITEM_EDIT_BUTTON_H__
#define __PROP_TREE_ITEM_EDIT_BUTTON_H__
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// PropTreeItemEdit.h : header file
//
// Copyright (C) 1998-2001 Scott Ramsay
// sramsay@gonavi.com
// http://www.gonavi.com
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// If you use this code, drop me an email. I'd like to know if you find the code
// useful.
#include "PropTreeItem.h"
//#include "PropTreeItemEdit.h"
/////////////////////////////////////////////////////////////////////////////
// CPropTreeItemEditButton window
class PROPTREE_API CPropTreeItemEditButton : public CPropTreeItemEdit
{
// Construction
public:
CPropTreeItemEditButton();
virtual ~CPropTreeItemEditButton();
// Attributes
public:
// The non-attribute area needs drawing
virtual LONG DrawItem(CDC* pDC, const RECT& rc, LONG x, LONG y);
// The attribute area needs drawing
virtual void DrawAttribute(CDC* pDC, const RECT& rc);
// Retrieve the item's attribute value
virtual LPARAM GetItemValue();
// Set the item's attribute value
virtual void SetItemValue(LPARAM lParam);
// Called when attribute area has changed size
virtual void OnMove();
// Called when the item needs to refresh its data
virtual void OnRefresh();
// Called when the item needs to commit its changes
virtual void OnCommit();
// Called to activate the item
virtual void OnActivate(int activateType, CPoint point);
enum ValueFormat
{
ValueFormatText,
ValueFormatNumber,
ValueFormatFloatPointer
};
// Set to specifify format of SetItemValue/GetItemValue
void SetValueFormat(ValueFormat nFormat);
// Set to TRUE for to use a password edit control
void SetAsPassword(BOOL bPassword);
// Overrideable - Returns TRUE if the point is on the button
virtual BOOL HitButton(const POINT& pt);
void SetButtonText( LPCSTR text );
protected:
CString m_sEdit;
float m_fValue;
ValueFormat m_nFormat;
BOOL m_bPassword;
CString buttonText;
CRect buttonRect;
CRect hitTestRect;
bool mouseDown;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CPropTreeItemEditButton)
//}}AFX_VIRTUAL
// Implementation
public:
// Generated message map functions
protected:
//{{AFX_MSG(CPropTreeItemEditButton)
afx_msg UINT OnGetDlgCode();
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnKillfocus();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // __PROP_TREE_ITEM_EDIT_BUTTON_H__

View File

@@ -0,0 +1,130 @@
// PropTreeItemFileEdit.cpp : implementation file
//#include "stdafx.h"
#include "../../../idlib/precompiled.h"
#pragma hdrstop
#include "proptree.h"
#include "PropTreeItemFileEdit.h"
#include "../../../sys/win32/rc/proptree_Resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CPropTreeItemFileEdit
CPropTreeItemFileEdit::CPropTreeItemFileEdit() {
}
CPropTreeItemFileEdit::~CPropTreeItemFileEdit() {
}
BEGIN_MESSAGE_MAP(CPropTreeItemFileEdit, CPropTreeItemEdit)
//{{AFX_MSG_MAP(CPropTreeItemFileEdit)
//}}AFX_MSG_MAP
ON_WM_CONTEXTMENU()
ON_WM_CREATE()
ON_COMMAND(ID_EDITMENU_INSERTFILE, OnInsertFile)
ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
ON_COMMAND(ID_EDIT_CUT, OnEditCut)
ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
ON_COMMAND(ID_EDIT_DELETE, OnEditDelete)
ON_COMMAND(ID_EDIT_SELECTALL, OnEditSelectAll)
END_MESSAGE_MAP()
void CPropTreeItemFileEdit::OnContextMenu(CWnd* pWnd, CPoint point) {
CMenu FloatingMenu;
VERIFY(FloatingMenu.LoadMenu(IDR_ME_EDIT_MENU));
CMenu* pPopupMenu = FloatingMenu.GetSubMenu (0);
if(CanUndo()) {
pPopupMenu->EnableMenuItem(ID_EDIT_UNDO, MF_BYCOMMAND | MF_ENABLED);
} else {
pPopupMenu->EnableMenuItem(ID_EDIT_UNDO, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
}
DWORD dwSel = GetSel();
if(HIWORD(dwSel) != LOWORD(dwSel)) {
pPopupMenu->EnableMenuItem(ID_EDIT_CUT, MF_BYCOMMAND | MF_ENABLED);
pPopupMenu->EnableMenuItem(ID_EDIT_COPY, MF_BYCOMMAND | MF_ENABLED);
pPopupMenu->EnableMenuItem(ID_EDIT_DELETE, MF_BYCOMMAND | MF_ENABLED);
} else {
pPopupMenu->EnableMenuItem(ID_EDIT_CUT, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
pPopupMenu->EnableMenuItem(ID_EDIT_COPY, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
pPopupMenu->EnableMenuItem(ID_EDIT_DELETE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
}
pPopupMenu->TrackPopupMenu (TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
}
int CPropTreeItemFileEdit::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CPropTreeItemEdit::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
return 0;
}
void CPropTreeItemFileEdit::OnInsertFile() {
CFileDialog dlg(TRUE);
dlg.m_ofn.Flags |= OFN_FILEMUSTEXIST;
int startSel, endSel;
GetSel(startSel, endSel);
if( dlg.DoModal()== IDOK) {
idStr currentText = (char*)GetItemValue();
idStr newText = currentText.Left(startSel) + currentText.Right(currentText.Length() - endSel);
idStr filename = fileSystem->OSPathToRelativePath(dlg.m_ofn.lpstrFile);
filename.BackSlashesToSlashes();
newText.Insert(filename, startSel);
SetItemValue((LPARAM)newText.c_str());
m_pProp->RefreshItems(this);
m_pProp->SendNotify(PTN_ITEMCHANGED, this);
}
}
void CPropTreeItemFileEdit::OnEditUndo() {
Undo();
}
void CPropTreeItemFileEdit::OnEditCut() {
Cut();
}
void CPropTreeItemFileEdit::OnEditCopy() {
Copy();
}
void CPropTreeItemFileEdit::OnEditPaste() {
Paste();
}
void CPropTreeItemFileEdit::OnEditDelete() {
Clear();
}
void CPropTreeItemFileEdit::OnEditSelectAll() {
SetSel(0, -1);
}

View File

@@ -0,0 +1,54 @@
#ifndef __PROP_TREE_ITEM_FILE_EDIT_H__
#define __PROP_TREE_ITEM_FILE_EDIT_H__
#if _MSC_VER > 1000
#pragma once
#endif
//#include "PropTreeItem.h"
//#include "PropTreeItemEdit.h"
class PROPTREE_API CPropTreeItemFileEdit : public CPropTreeItemEdit
{
// Construction
public:
CPropTreeItemFileEdit();
virtual ~CPropTreeItemFileEdit();
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CPropTreeItemFileEdit)
//}}AFX_VIRTUAL
// Implementation
public:
// Generated message map functions
protected:
//{{AFX_MSG(CPropTreeItemFileEdit)
//}}AFX_MSG
afx_msg void OnInsertFile();
afx_msg void OnEditUndo();
afx_msg void OnEditCut();
afx_msg void OnEditCopy();
afx_msg void OnEditPaste();
afx_msg void OnEditDelete();
afx_msg void OnEditSelectAll();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
#endif

View File

@@ -0,0 +1,67 @@
// PropTreeItemStatic.cpp
//
// Copyright (C) 1998-2001 Scott Ramsay
// sramsay@gonavi.com
// http://www.gonavi.com
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// If you use this code, drop me an email. I'd like to know if you find the code
// useful.
//#include "stdafx.h"
#include "../../../idlib/precompiled.h"
#pragma hdrstop
#include "PropTree.h"
#include "PropTreeItemStatic.h"
CPropTreeItemStatic::CPropTreeItemStatic() :
m_sAttribute(_T(""))
{
}
CPropTreeItemStatic::~CPropTreeItemStatic()
{
}
void CPropTreeItemStatic::DrawAttribute(CDC* pDC, const RECT& rc)
{
ASSERT(m_pProp!=NULL);
pDC->SelectObject(m_pProp->GetNormalFont());
pDC->SetTextColor(RGB(0,0,0));
pDC->SetBkMode(TRANSPARENT);
CRect r = rc;
pDC->DrawText(m_sAttribute, r, DT_SINGLELINE|DT_VCENTER);
}
LPARAM CPropTreeItemStatic::GetItemValue()
{
return (LPARAM)(LPCTSTR)m_sAttribute;
}
void CPropTreeItemStatic::SetItemValue(LPARAM lParam)
{
if (lParam==0L)
{
TRACE0("CPropTreeItemStatic::SetItemValue() - Invalid lParam value\n");
return;
}
m_sAttribute = (LPCTSTR)lParam;
}

View File

@@ -0,0 +1,45 @@
// PropTreeItemStatic.h
//
// Copyright (C) 1998-2001 Scott Ramsay
// sramsay@gonavi.com
// http://www.gonavi.com
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// If you use this code, drop me an email. I'd like to know if you find the code
// useful.
#ifndef _PROPTREEITEMSTATIC_H
#define _PROPTREEITEMSTATIC_H
#include "PropTreeItem.h"
class PROPTREE_API CPropTreeItemStatic : public CPropTreeItem
{
public:
CPropTreeItemStatic();
virtual ~CPropTreeItemStatic();
public:
// The attribute area needs drawing
virtual void DrawAttribute(CDC* pDC, const RECT& rc);
// Retrieve the item's attribute value (in this case the CString)
virtual LPARAM GetItemValue();
// Set the item's attribute value
virtual void SetItemValue(LPARAM lParam);
protected:
CString m_sAttribute;
};
#endif // _PROPTREEITEMSTATIC_H

View File

@@ -0,0 +1,635 @@
// PropTreeList.cpp : implementation file
//
// Copyright (C) 1998-2001 Scott Ramsay
// sramsay@gonavi.com
// http://www.gonavi.com
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// If you use this code, drop me an email. I'd like to know if you find the code
// useful.
//#include "stdafx.h"
#include "../../../idlib/precompiled.h"
#pragma hdrstop
#include "PropTree.h"
#include "../../../sys/win32/rc/proptree_Resource.h"
#include "PropTreeList.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define PROPTREEITEM_EXPANDCOLUMN 16 // width of the expand column
#define PROPTREEITEM_COLRNG 5 // width of splitter
#define PROPTREEITEM_DEFHEIGHT 21 // default heigt of an item
extern HINSTANCE ghInst;
/////////////////////////////////////////////////////////////////////////////
// CPropTreeList
CPropTreeList::CPropTreeList() :
m_pProp(NULL),
m_BackBufferSize(0,0),
m_bColDrag(FALSE),
m_nPrevCol(0)
{
}
CPropTreeList::~CPropTreeList()
{
}
BEGIN_MESSAGE_MAP(CPropTreeList, CWnd)
//{{AFX_MSG_MAP(CPropTreeList)
ON_WM_SIZE()
ON_WM_PAINT()
ON_WM_SETCURSOR()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDBLCLK()
ON_WM_MOUSEMOVE()
ON_WM_MOUSEWHEEL()
ON_WM_KEYDOWN()
ON_WM_GETDLGCODE()
ON_WM_VSCROLL()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPropTreeList message handlers
void CPropTreeList::SetPropOwner(CPropTree* pProp)
{
m_pProp = pProp;
}
BOOL CPropTreeList::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
{
CWnd* pWnd = this;
LPCTSTR pszCreateClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, ::LoadCursor(NULL, IDC_ARROW));
return pWnd->Create(pszCreateClass, _T(""), dwStyle, rect, pParentWnd, nID);
}
void CPropTreeList::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
RecreateBackBuffer(cx, cy);
if (m_pProp)
{
UpdateResize();
Invalidate();
UpdateWindow();
// inform all items that a resize has been made
m_pProp->UpdateMoveAllItems();
}
}
void CPropTreeList::RecreateBackBuffer(int cx, int cy)
{
if (m_BackBufferSize.cx<cx || m_BackBufferSize.cy<cy)
{
m_BackBufferSize = CSize(cx, cy);
CWindowDC dc(NULL);
int nPlanes = dc.GetDeviceCaps(PLANES);
int nBitCount = dc.GetDeviceCaps(BITSPIXEL);
m_BackBuffer.DeleteObject();
m_BackBuffer.CreateBitmap(cx, cy, nPlanes, nBitCount, NULL);
}
}
void CPropTreeList::UpdateResize()
{
SCROLLINFO si;
LONG nHeight;
CRect rc;
ASSERT(m_pProp!=NULL);
GetClientRect(rc);
nHeight = rc.Height() + 1;
ZeroMemory(&si, sizeof(SCROLLINFO));
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_RANGE|SIF_PAGE;
si.nMin = 0;
si.nMax = m_pProp->GetRootItem()->GetTotalHeight();
si.nPage = nHeight;
if ((int)si.nPage>si.nMax)
m_pProp->SetOriginOffset(0);
SetScrollInfo(SB_VERT, &si, TRUE);
// force set column for clipping
m_pProp->SetColumn(m_pProp->GetColumn());
}
void CPropTreeList::OnPaint()
{
CPaintDC dc(this);
CDC memdc;
CBitmap* pOldBitmap;
ASSERT(m_pProp!=NULL);
m_pProp->ClearVisibleList();
memdc.CreateCompatibleDC(&dc);
pOldBitmap = memdc.SelectObject(&m_BackBuffer);
CRect rc;
GetClientRect(rc);
// draw control background
memdc.SelectObject(GetSysColorBrush(COLOR_BTNFACE));
memdc.PatBlt(rc.left, rc.top, rc.Width(), rc.Height(), PATCOPY);
// draw control inside fill color
rc.DeflateRect(2,2);
memdc.PatBlt(rc.left, rc.top, rc.Width(), rc.Height(), m_pProp->IsWindowEnabled() ? WHITENESS : PATCOPY);
rc.InflateRect(2,2);
// draw expand column
memdc.SelectObject(GetSysColorBrush(COLOR_BTNFACE));
memdc.PatBlt(0, 0, PROPTREEITEM_EXPANDCOLUMN, rc.Height(), PATCOPY);
// draw edge
memdc.DrawEdge(&rc, BDR_SUNKENOUTER, BF_RECT);
CPropTreeItem* pItem;
LONG nTotal = 0;
ASSERT(m_pProp->GetRootItem()!=NULL);
rc.DeflateRect(2,2);
// create clip region
HRGN hRgn = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);
SelectClipRgn(memdc.m_hDC, hRgn);
// draw all items
for (pItem = m_pProp->GetRootItem()->GetChild(); pItem; pItem = pItem->GetSibling())
{
LONG nHeight = pItem->DrawItem(&memdc, rc, 0, nTotal);
nTotal += nHeight;
}
// remove clip region
SelectClipRgn(memdc.m_hDC, NULL);
DeleteObject(hRgn);
// copy back buffer to the display
dc.GetClipBox(&rc);
dc.BitBlt(rc.left, rc.top, rc.Width(), rc.Height(), &memdc, rc.left, rc.top, SRCCOPY);
memdc.DeleteDC();
}
BOOL CPropTreeList::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (nHitTest==HTCLIENT)
{
CPoint pt;
ASSERT(m_pProp!=NULL);
GetCursorPos(&pt);
ScreenToClient(&pt);
switch (m_pProp->HitTest(pt))
{
case HTCOLUMN:
SetCursor(LoadCursor(ghInst, MAKEINTRESOURCE(IDC_SPLITTER)));
return TRUE;
case HTCHECKBOX:
case HTBUTTON:
case HTEXPAND:
SetCursor(LoadCursor(ghInst, MAKEINTRESOURCE(IDC_FPOINT)));
return TRUE;
}
}
return CWnd::OnSetCursor(pWnd, nHitTest, message);
}
void CPropTreeList::OnLButtonDown(UINT, CPoint point)
{
ASSERT(m_pProp!=NULL);
if (m_pProp->IsDisableInput())
return;
m_pProp->SendNotify(NM_CLICK);
if (!m_pProp->IsWindowEnabled())
return;
SetFocus();
LONG nHit = m_pProp->HitTest(point);
CPropTreeItem* pItem;
CRect rc;
CDC* pDC;
switch (nHit)
{
case HTCOLUMN:
if (m_pProp->SendNotify(PTN_COLUMNCLICK))
break;
m_bColDrag = TRUE;
SetCapture();
m_nPrevCol = m_pProp->GetOrigin().x;
// paint drag line
pDC = GetDC();
GetClientRect(rc);
pDC->PatBlt(m_nPrevCol - PROPTREEITEM_COLRNG/2, 0, PROPTREEITEM_COLRNG, rc.bottom, PATINVERT);
ReleaseDC(pDC);
break;
case HTCHECKBOX:
if ((pItem = m_pProp->FindItem(point))!=NULL)
{
pItem->Check(!pItem->IsChecked());
m_pProp->SendNotify(PTN_CHECKCLICK, pItem);
Invalidate();
}
break;
case HTBUTTON:
if ((pItem = m_pProp->FindItem(point))!=NULL)
{
pItem->Check();
m_pProp->SendNotify(PTN_ITEMBUTTONCLICK, pItem);
Invalidate();
}
break;
case HTEXPAND:
if ((pItem = m_pProp->FindItem(point))!=NULL)
{
if (pItem->GetChild() && !m_pProp->SendNotify(PTN_ITEMEXPANDING, pItem))
{
pItem->Expand(!pItem->IsExpanded());
UpdateResize();
Invalidate();
UpdateWindow();
CheckVisibleFocus();
}
}
break;
default:
if ((pItem = m_pProp->FindItem(point))!=NULL)
{
CPropTreeItem* pOldFocus = m_pProp->GetFocusedItem();
m_pProp->SelectItems(NULL, FALSE);
m_pProp->SetFocusedItem(pItem);
pItem->Select();
Invalidate();
if (pItem!=pOldFocus)
m_pProp->SendNotify(PTN_SELCHANGE, pItem);
if (nHit==HTATTRIBUTE && !pItem->IsRootLevel())
{
if (!m_pProp->SendNotify(PTN_PROPCLICK, pItem) && !pItem->IsReadOnly())
pItem->Activate(CPropTreeItem::ACTIVATE_TYPE_MOUSE, point);
}
}
else
{
m_pProp->SelectItems(NULL, FALSE);
m_pProp->SetFocusedItem(NULL);
m_pProp->SendNotify(PTN_SELCHANGE);
Invalidate();
}
break;
}
}
void CPropTreeList::OnLButtonUp(UINT, CPoint point)
{
if (m_bColDrag)
{
CDC* pDC = GetDC();
CRect rc;
GetClientRect(rc);
pDC->PatBlt(m_nPrevCol - PROPTREEITEM_COLRNG/2, 0, PROPTREEITEM_COLRNG, rc.bottom, PATINVERT);
ReleaseDC(pDC);
m_bColDrag = FALSE;
ReleaseCapture();
m_pProp->SetColumn(point.x);
m_pProp->UpdateMoveAllItems();
Invalidate();
} else {
LONG nHit = m_pProp->HitTest(point);
CPropTreeItem* pItem;
switch (nHit)
{
case HTBUTTON:
if ((pItem = m_pProp->FindItem(point))!=NULL)
{
pItem->Check( FALSE );
Invalidate();
}
break;
default:
break;
}
}
}
void CPropTreeList::OnLButtonDblClk(UINT, CPoint point)
{
ASSERT(m_pProp!=NULL);
m_pProp->SendNotify(NM_DBLCLK);
CPropTreeItem* pItem;
CPropTreeItem* pOldFocus;
if ((pItem = m_pProp->FindItem(point))!=NULL && pItem->GetChild())
{
switch (m_pProp->HitTest(point))
{
case HTCOLUMN:
break;
case HTCHECKBOX:
pItem->Check(!pItem->IsChecked());
m_pProp->SendNotify(PTN_CHECKCLICK, pItem);
Invalidate();
break;
case HTATTRIBUTE:
if (!pItem->IsRootLevel())
break;
// pass thru to default
default:
pOldFocus = m_pProp->GetFocusedItem();
m_pProp->SelectItems(NULL, FALSE);
m_pProp->SetFocusedItem(pItem);
pItem->Select();
if (pItem!=pOldFocus)
m_pProp->SendNotify(PTN_SELCHANGE, pItem);
// pass thru to HTEXPAND
case HTEXPAND:
if (!m_pProp->SendNotify(PTN_ITEMEXPANDING, pItem))
{
pItem->Expand(!pItem->IsExpanded());
UpdateResize();
Invalidate();
UpdateWindow();
CheckVisibleFocus();
}
break;
}
}
}
void CPropTreeList::OnMouseMove(UINT, CPoint point)
{
if (m_bColDrag)
{
CDC* pDC = GetDC();
CRect rc;
GetClientRect(rc);
pDC->PatBlt(m_nPrevCol - PROPTREEITEM_COLRNG/2, 0, PROPTREEITEM_COLRNG, rc.bottom, PATINVERT);
pDC->PatBlt(point.x - PROPTREEITEM_COLRNG/2, 0, PROPTREEITEM_COLRNG, rc.bottom, PATINVERT);
m_nPrevCol = point.x;
ReleaseDC(pDC);
}
}
BOOL CPropTreeList::OnMouseWheel(UINT, short zDelta, CPoint)
{
SCROLLINFO si;
ZeroMemory(&si, sizeof(SCROLLINFO));
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_RANGE;
GetScrollInfo(SB_VERT, &si);
CRect rc;
GetClientRect(rc);
if (si.nMax - si.nMin < rc.Height())
return TRUE;
SetFocus();
OnVScroll(zDelta < 0 ? SB_LINEDOWN : SB_LINEUP, 0, NULL);
return TRUE;
}
void CPropTreeList::OnKeyDown(UINT nChar, UINT, UINT)
{
CPropTreeItem* pItem;
ASSERT(m_pProp!=NULL);
if (m_pProp->IsDisableInput() || !m_pProp->IsWindowEnabled())
return;
switch (nChar)
{
case VK_RETURN:
if ((pItem = m_pProp->GetFocusedItem())!=NULL && !pItem->IsRootLevel() && !pItem->IsReadOnly())
{
pItem->Activate(CPropTreeItem::ACTIVATE_TYPE_KEYBOARD, CPoint(0,0));
}
break;
case VK_HOME:
if (m_pProp->FocusFirst())
Invalidate();
break;
case VK_END:
if (m_pProp->FocusLast())
Invalidate();
break;
case VK_LEFT:
if ((pItem = m_pProp->GetFocusedItem())!=NULL)
{
if (!m_pProp->SendNotify(PTN_ITEMEXPANDING, pItem))
{
if (pItem->GetChild() && pItem->IsExpanded())
{
pItem->Expand(FALSE);
UpdateResize();
Invalidate();
UpdateWindow();
CheckVisibleFocus();
break;
}
}
}
else
break;
// pass thru to next case VK_UP
case VK_UP:
if (m_pProp->FocusPrev())
Invalidate();
break;
case VK_RIGHT:
if ((pItem = m_pProp->GetFocusedItem())!=NULL)
{
if (!m_pProp->SendNotify(PTN_ITEMEXPANDING, pItem))
{
if (pItem->GetChild() && !pItem->IsExpanded())
{
pItem->Expand();
UpdateResize();
Invalidate();
UpdateWindow();
CheckVisibleFocus();
break;
}
}
}
else
break;
// pass thru to next case VK_DOWN
case VK_DOWN:
if (m_pProp->FocusNext())
Invalidate();
break;
}
}
UINT CPropTreeList::OnGetDlgCode()
{
return DLGC_WANTARROWS|DLGC_WANTCHARS|DLGC_WANTALLKEYS;
}
void CPropTreeList::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar*)
{
SCROLLINFO si;
CRect rc;
LONG nHeight;
SetFocus();
GetClientRect(rc);
nHeight = rc.Height() + 1;
ZeroMemory(&si, sizeof(SCROLLINFO));
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_RANGE;
GetScrollInfo(SB_VERT, &si);
LONG ny = m_pProp->GetOrigin().y;
switch (nSBCode)
{
case SB_LINEDOWN:
ny += PROPTREEITEM_DEFHEIGHT;
break;
case SB_LINEUP:
ny -= PROPTREEITEM_DEFHEIGHT;
break;
case SB_PAGEDOWN:
ny += nHeight;
break;
case SB_PAGEUP:
ny -= nHeight;
break;
case SB_THUMBTRACK:
ny = nPos;
break;
}
ny = __min(__max(ny, si.nMin), si.nMax - nHeight);
m_pProp->SetOriginOffset(ny);
si.fMask = SIF_POS;
si.nPos = ny;
SetScrollInfo(SB_VERT, &si, TRUE);
Invalidate();
}
void CPropTreeList::CheckVisibleFocus()
{
ASSERT(m_pProp!=NULL);
CPropTreeItem* pItem;
if ((pItem = m_pProp->GetFocusedItem())==NULL)
return;
if (!m_pProp->IsItemVisible(pItem))
{
if (m_pProp->IsSingleSelection())
pItem->Select(FALSE);
m_pProp->SetFocusedItem(NULL);
m_pProp->SendNotify(PTN_SELCHANGE, NULL);
Invalidate();
}
}

View File

@@ -0,0 +1,99 @@
#if !defined(AFX_PROPTREELIST_H__2E09E831_09F5_44AA_B41D_9C4BF495873C__INCLUDED_)
#define AFX_PROPTREELIST_H__2E09E831_09F5_44AA_B41D_9C4BF495873C__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// PropTreeList.h : header file
//
// Copyright (C) 1998-2001 Scott Ramsay
// sramsay@gonavi.com
// http://www.gonavi.com
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// If you use this code, drop me an email. I'd like to know if you find the code
// useful.
class CPropTree;
/////////////////////////////////////////////////////////////////////////////
// CPropTreeList window
class PROPTREE_API CPropTreeList : public CWnd
{
// Construction
public:
CPropTreeList();
virtual ~CPropTreeList();
BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);
// Attributes
public:
void SetPropOwner(CPropTree* pProp);
protected:
// CPropTree class that this class belongs
CPropTree* m_pProp;
// bitmap back buffer for flicker free drawing
CBitmap m_BackBuffer;
// current diminsions of the back buffer
CSize m_BackBufferSize;
// splitter pevious position
LONG m_nPrevCol;
// TRUE if we are dragging the splitter
BOOL m_bColDrag;
// Operations
public:
void UpdateResize();
protected:
void RecreateBackBuffer(int cx, int cy);
void CheckVisibleFocus();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CPropTreeList)
//}}AFX_VIRTUAL
// Implementation
public:
// Generated message map functions
protected:
//{{AFX_MSG(CPropTreeList)
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnPaint();
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg UINT OnGetDlgCode();
//}}AFX_MSG
public:
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_PROPTREELIST_H__2E09E831_09F5_44AA_B41D_9C4BF495873C__INCLUDED_)

View File

@@ -0,0 +1,103 @@
// CPropTreeView.cpp : implementation file
//
//#include "stdafx.h"
#include "../../../idlib/precompiled.h"
#pragma hdrstop
#include "PropTreeView.h"
// CPropTreeView
IMPLEMENT_DYNCREATE(CPropTreeView, CFormView)
CPropTreeView::CPropTreeView()
: CFormView((LPCTSTR) NULL)
{
}
CPropTreeView::~CPropTreeView()
{
}
BEGIN_MESSAGE_MAP(CPropTreeView, CView)
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_PAINT()
END_MESSAGE_MAP()
// CPropTreeView drawing
void CPropTreeView::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: add draw code here
}
// CPropTreeView diagnostics
#ifdef _DEBUG
void CPropTreeView::AssertValid() const
{
CView::AssertValid();
}
void CPropTreeView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
#endif //_DEBUG
BOOL CPropTreeView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName,
DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
UINT nID, CCreateContext* pContext)
{
// create the view window itself
m_pCreateContext = pContext;
if (!CView::Create(lpszClassName, lpszWindowName,
dwStyle, rect, pParentWnd, nID, pContext))
{
return FALSE;
}
return TRUE;
}
// CPropTreeView message handlers
int CPropTreeView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
DWORD dwStyle;
CRect rc;
// PTS_NOTIFY - CPropTree will send notification messages to the parent window
dwStyle = WS_CHILD|WS_VISIBLE|PTS_NOTIFY;
// Init the control's size to cover the entire client area
GetClientRect(rc);
// Create CPropTree control
m_Tree.Create(dwStyle, rc, this, IDC_PROPERTYTREE);
return 0;
}
void CPropTreeView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
if (::IsWindow(m_Tree.GetSafeHwnd()))
m_Tree.SetWindowPos(NULL, -1, -1, cx, cy, SWP_NOMOVE|SWP_NOZORDER);
}
void CPropTreeView::OnPaint()
{
Default();
}

View File

@@ -0,0 +1,41 @@
#pragma once
#include "PropTree.h"
// CPropTreeView view
#define IDC_PROPERTYTREE 100
class CPropTreeView : public CFormView
{
DECLARE_DYNCREATE(CPropTreeView)
protected:
CPropTree m_Tree;
protected:
CPropTreeView(); // protected constructor used by dynamic creation
virtual ~CPropTreeView();
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
CPropTree& GetPropertyTreeCtrl() { return m_Tree; };
protected:
DECLARE_MESSAGE_MAP()
public:
virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName,
DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID,
CCreateContext* pContext = NULL);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnPaint();
};