1335 lines
38 KiB
C++
1335 lines
38 KiB
C++
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Copyright (c) 1996-1997 Microsoft Corporation
|
||
|
//
|
||
|
// Module Name:
|
||
|
// TreeView.cpp
|
||
|
//
|
||
|
// Abstract:
|
||
|
// Implementation of the CClusterTreeView class.
|
||
|
//
|
||
|
// Author:
|
||
|
// David Potter (davidp) May 1, 1996
|
||
|
//
|
||
|
// Revision History:
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
#include "CluAdmin.h"
|
||
|
#include "ConstDef.h"
|
||
|
#include "ClusDoc.h"
|
||
|
#include "TreeView.h"
|
||
|
#include "ListView.h"
|
||
|
#include "SplitFrm.h"
|
||
|
#include "TreeItem.inl"
|
||
|
#include "TraceTag.h"
|
||
|
#include "ExcOper.h"
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
#define new DEBUG_NEW
|
||
|
#undef THIS_FILE
|
||
|
static char THIS_FILE[] = __FILE__;
|
||
|
#endif
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// Global Variables
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
CTraceTag g_tagTreeView(_T("UI"), _T("TREE VIEW"), 0);
|
||
|
CTraceTag g_tagTreeDrag(_T("Drag&Drop"), _T("TREE VIEW DRAG"), 0);
|
||
|
CTraceTag g_tagTreeDragMouse(_T("Drag&Drop"), _T("TREE VIEW DRAG MOUSE"), 0);
|
||
|
CTraceTag g_tagTreeViewSelect(_T("UI"), _T("TREE VIEW SELECT"), 0);
|
||
|
#endif
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CClusterTreeView
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
IMPLEMENT_DYNCREATE(CClusterTreeView, CTreeView)
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// Message Maps
|
||
|
|
||
|
BEGIN_MESSAGE_MAP(CClusterTreeView, CTreeView)
|
||
|
//{{AFX_MSG_MAP(CClusterTreeView)
|
||
|
ON_WM_DESTROY()
|
||
|
ON_COMMAND(ID_FILE_RENAME, OnCmdRename)
|
||
|
ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelChanged)
|
||
|
ON_NOTIFY_REFLECT(TVN_BEGINLABELEDIT, OnBeginLabelEdit)
|
||
|
ON_NOTIFY_REFLECT(TVN_ENDLABELEDIT, OnEndLabelEdit)
|
||
|
ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED, OnItemExpanded)
|
||
|
ON_NOTIFY_REFLECT(TVN_BEGINDRAG, OnBeginDrag)
|
||
|
ON_NOTIFY_REFLECT(TVN_BEGINRDRAG, OnBeginDrag)
|
||
|
ON_NOTIFY_REFLECT(TVN_KEYDOWN, OnKeyDown)
|
||
|
//}}AFX_MSG_MAP
|
||
|
END_MESSAGE_MAP()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::CClusterTreeView
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Default constructor.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
CClusterTreeView::CClusterTreeView(void)
|
||
|
{
|
||
|
m_pframe = NULL;
|
||
|
|
||
|
// Initialize label editing.
|
||
|
m_ptiBeingEdited = NULL;
|
||
|
m_bShiftPressed = FALSE;
|
||
|
m_bControlPressed = FALSE;
|
||
|
m_bAltPressed = FALSE;
|
||
|
|
||
|
// Initialize drag & drop.
|
||
|
m_htiDrag = NULL;
|
||
|
m_ptiDrag = NULL;
|
||
|
m_htiDrop = NULL;
|
||
|
|
||
|
} //*** CClusterTreeView::CClusterTreeView()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::~CClusterTreeView
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Destructor.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
CClusterTreeView::~CClusterTreeView(void)
|
||
|
{
|
||
|
} //*** CClusterTreeView::~CClusterTreeView()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::PreCreateWindow
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Called before the window has been created.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// cs CREATESTRUCT
|
||
|
//
|
||
|
// Return Value:
|
||
|
// TRUE Successful.
|
||
|
// FALSE Failed.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL CClusterTreeView::PreCreateWindow(CREATESTRUCT & cs)
|
||
|
{
|
||
|
// TODO: Modify the Window class or styles here by modifying
|
||
|
// the CREATESTRUCT cs
|
||
|
|
||
|
return CTreeView::PreCreateWindow(cs);
|
||
|
|
||
|
} //*** CClusterTreeView::PreCreateWindow()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::Create
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Create the window.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// lpszClassName [IN] Name of the window class to create.
|
||
|
// lpszWindowName [IN] Name of the window (used as the caption).
|
||
|
// dwStyle [IN] Window styles.
|
||
|
// rect [IN] Size and position of the window
|
||
|
// pParentWnd [IN OUT] Parent window.
|
||
|
// nID [IN] ID of the window.
|
||
|
// pContext [IN OUT] Create context of the window.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// 0 Successful.
|
||
|
// !0 Unsuccessful.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL CClusterTreeView::Create(
|
||
|
LPCTSTR lpszClassName,
|
||
|
LPCTSTR lpszWindowName,
|
||
|
DWORD dwStyle,
|
||
|
const RECT & rect,
|
||
|
CWnd * pParentWnd,
|
||
|
UINT nID,
|
||
|
CCreateContext * pContext
|
||
|
)
|
||
|
{
|
||
|
dwStyle |= TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | TVS_EDITLABELS | TVS_SHOWSELALWAYS;
|
||
|
return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
|
||
|
|
||
|
} //*** CClusterTreeView::Create()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::OnDraw
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Called to draw the view.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pDC [IN OUT] Device Context for the view.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CClusterTreeView::OnDraw(IN OUT CDC* pDC)
|
||
|
{
|
||
|
#if 0
|
||
|
CClusterDoc* pDoc = GetDocument();
|
||
|
ASSERT_VALID(pDoc);
|
||
|
|
||
|
// TODO: add draw code for native data here
|
||
|
#endif
|
||
|
} //*** CClusterTreeView::OnDraw()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::OnInitialUpdate
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Do one-time initialization.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CClusterTreeView::OnInitialUpdate(void)
|
||
|
{
|
||
|
CClusterAdminApp * papp = GetClusterAdminApp();
|
||
|
CClusterDoc * pdocCluster = GetDocument();
|
||
|
CString strSelection;
|
||
|
|
||
|
CTreeView::OnInitialUpdate();
|
||
|
|
||
|
// Save the frame pointer.
|
||
|
// ASSERT(m_pframe == NULL);
|
||
|
m_pframe = (CSplitterFrame *) GetParentFrame();
|
||
|
ASSERT_VALID(m_pframe);
|
||
|
ASSERT_KINDOF(CSplitterFrame, m_pframe);
|
||
|
|
||
|
// Tell the tree control about our images. We are using the
|
||
|
// same image list for both normal and state images.
|
||
|
GetTreeCtrl().SetImageList(papp->PilSmallImages(), TVSIL_NORMAL);
|
||
|
// GetTreeCtrl().SetImageList(papp->PilSmallImages(), TVSIL_STATE);
|
||
|
|
||
|
// Read the last selection.
|
||
|
ReadPreviousSelection(strSelection);
|
||
|
|
||
|
// Recursively add items starting with the cluster.
|
||
|
BAddItems(pdocCluster->PtiCluster(), strSelection, TRUE /*bExpanded*/);
|
||
|
|
||
|
// Expand the Cluster item by default.
|
||
|
// pdocCluster->PtiCluster()->BExpand(this, TVE_EXPAND);
|
||
|
|
||
|
} //*** CClusterTreeView::OnInitialUpdate()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::BAddItems
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Add an item and then add all its children.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pti [IN OUT] Item to add to the tree.
|
||
|
// rstrSelection [IN] Previous selection.
|
||
|
// bExpanded [IN] TRUE = add expanded.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// TRUE Parent needs to be expanded.
|
||
|
// FALSE Parent does not need to be expanded.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL CClusterTreeView::BAddItems(
|
||
|
IN OUT CTreeItem * pti,
|
||
|
IN const CString & rstrSelection,
|
||
|
IN BOOL bExpanded // = FALSE
|
||
|
)
|
||
|
{
|
||
|
POSITION posChild;
|
||
|
CTreeItem * ptiChild;
|
||
|
BOOL bRetExpanded = FALSE;
|
||
|
|
||
|
ASSERT_VALID(pti);
|
||
|
|
||
|
// Insert this item into the tree.
|
||
|
pti->HtiInsertInTree(this);
|
||
|
if (bExpanded || pti->BShouldBeExpanded(this))
|
||
|
bRetExpanded = TRUE;
|
||
|
|
||
|
// Add all the child items.
|
||
|
posChild = pti->LptiChildren().GetHeadPosition();
|
||
|
while (posChild != NULL)
|
||
|
{
|
||
|
ptiChild = pti->LptiChildren().GetNext(posChild);
|
||
|
ASSERT_VALID(ptiChild);
|
||
|
bExpanded = BAddItems(ptiChild, rstrSelection);
|
||
|
if (bExpanded)
|
||
|
bRetExpanded = TRUE;
|
||
|
} // while: more child items
|
||
|
|
||
|
if (bRetExpanded)
|
||
|
pti->BExpand(this, TVE_EXPAND);
|
||
|
|
||
|
if (rstrSelection == pti->StrProfileSection())
|
||
|
{
|
||
|
pti->Select(this, TRUE /*bSelectInTrue*/);
|
||
|
bRetExpanded = TRUE;
|
||
|
} // if: this is the selected item
|
||
|
|
||
|
return bRetExpanded;
|
||
|
|
||
|
} //*** CClusterTreeView::BAddItems()
|
||
|
|
||
|
#ifdef NEVER
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::CleanupItems
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Cleanup an item and all its children.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// ptiParent [IN OUT] Parent item to cleanup.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CClusterTreeView::CleanupItems(IN OUT CTreeItem * ptiParent)
|
||
|
{
|
||
|
POSITION posChild;
|
||
|
CTreeItem * ptiChild;
|
||
|
|
||
|
// Cleanup all child items.
|
||
|
if (ptiParent != NULL)
|
||
|
{
|
||
|
posChild = ptiParent->LptiChildren().GetHeadPosition();
|
||
|
while (posChild != NULL)
|
||
|
{
|
||
|
ptiChild = ptiParent->LptiChildren().GetNext(posChild);
|
||
|
ASSERT_VALID(ptiChild);
|
||
|
CleanupItems(ptiChild);
|
||
|
} // while: more items in the list
|
||
|
|
||
|
// Cleanup this item.
|
||
|
ptiParent->PreRemoveFromTree(this);
|
||
|
} // if: parent was specified
|
||
|
|
||
|
} //*** CClusterTreeView::CleanupItems()
|
||
|
#endif
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CClusterTreeView diagnostics
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
void CClusterTreeView::AssertValid(void) const
|
||
|
{
|
||
|
CTreeView::AssertValid();
|
||
|
|
||
|
} //*** CClusterTreeView::AssertValid()
|
||
|
|
||
|
void CClusterTreeView::Dump(CDumpContext & dc) const
|
||
|
{
|
||
|
CTreeView::Dump(dc);
|
||
|
|
||
|
} //*** CClusterTreeView::Dump()
|
||
|
|
||
|
CClusterDoc * CClusterTreeView::GetDocument(void) // non-debug version is inline
|
||
|
{
|
||
|
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CClusterDoc)));
|
||
|
return (CClusterDoc *) m_pDocument;
|
||
|
|
||
|
} //*** CClusterTreeView::GetDocument()
|
||
|
#endif //_DEBUG
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::PtiSelected
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Get the tree item that is selected.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// ptiSelected The selected item or NULL if no item is selected.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
CTreeItem * CClusterTreeView::PtiSelected(void) const
|
||
|
{
|
||
|
HTREEITEM htiSelected;
|
||
|
CTreeItem * ptiSelected;
|
||
|
|
||
|
htiSelected = HtiSelected();
|
||
|
if (htiSelected != NULL)
|
||
|
{
|
||
|
ptiSelected = (CTreeItem *) GetTreeCtrl().GetItemData(htiSelected);
|
||
|
ASSERT_VALID(ptiSelected);
|
||
|
} // if: selected item found
|
||
|
else
|
||
|
ptiSelected = NULL;
|
||
|
|
||
|
return ptiSelected;
|
||
|
|
||
|
} //*** CClusterTreeView::PtiSelected()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::SaveCurrentSelection
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Save the current selection.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CClusterTreeView::SaveCurrentSelection(void)
|
||
|
{
|
||
|
CTreeItem * ptiSelected = PtiSelected();
|
||
|
|
||
|
if (ptiSelected != NULL)
|
||
|
{
|
||
|
CString strSection;
|
||
|
CString strValueName;
|
||
|
|
||
|
ASSERT_VALID(Pframe());
|
||
|
|
||
|
try
|
||
|
{
|
||
|
strSection.Format(
|
||
|
REGPARAM_CONNECTIONS _T("\\%s"),
|
||
|
GetDocument()->StrNode()
|
||
|
);
|
||
|
|
||
|
Pframe()->ConstructProfileValueName(strValueName, REGPARAM_SELECTION);
|
||
|
|
||
|
AfxGetApp()->WriteProfileString(
|
||
|
strSection,
|
||
|
strValueName,
|
||
|
ptiSelected->StrProfileSection()
|
||
|
);
|
||
|
} // try
|
||
|
catch (CException * pe)
|
||
|
{
|
||
|
pe->Delete();
|
||
|
} // catch: CException
|
||
|
} // if: there is a current selection
|
||
|
|
||
|
} //*** CClusterTreeView::SaveCurrentSelection()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::ReadPreviousSelection
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Read the previous selection.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// rstrSelection [OUT] Previous selection read from the user's profile.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CClusterTreeView::ReadPreviousSelection(OUT CString & rstrSelection)
|
||
|
{
|
||
|
CString strSection;
|
||
|
CString strValueName;
|
||
|
|
||
|
ASSERT_VALID(Pframe());
|
||
|
|
||
|
try
|
||
|
{
|
||
|
// Get the selected item.
|
||
|
strSection.Format(
|
||
|
REGPARAM_CONNECTIONS _T("\\%s"),
|
||
|
GetDocument()->StrNode()
|
||
|
);
|
||
|
|
||
|
Pframe()->ConstructProfileValueName(strValueName, REGPARAM_SELECTION);
|
||
|
|
||
|
rstrSelection = AfxGetApp()->GetProfileString(
|
||
|
strSection,
|
||
|
strValueName,
|
||
|
_T("")
|
||
|
);
|
||
|
} // try
|
||
|
catch (CException * pe)
|
||
|
{
|
||
|
pe->Delete();
|
||
|
} // catch: CException
|
||
|
|
||
|
} //*** CClusterTreeView::ReadPreviousSelection()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::OnSelChanged
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Handler method for the TVN_SELCHANGED message.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pNMHDR [IN OUT] WM_NOTIFY structure.
|
||
|
// pResult [OUT] LRESULT in which to return the result of this operation.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CClusterTreeView::OnSelChanged(NMHDR * pNMHDR, LRESULT * pResult)
|
||
|
{
|
||
|
NM_TREEVIEW * pNMTreeView = (NM_TREEVIEW *) pNMHDR;
|
||
|
CTreeItem * ptiSelected;
|
||
|
|
||
|
if (!BDragging())
|
||
|
{
|
||
|
Trace(g_tagTreeViewSelect, _T("OnSelChanged() - BEGIN"));
|
||
|
|
||
|
// Get the selected item.
|
||
|
ptiSelected = (CTreeItem *) pNMTreeView->itemNew.lParam;
|
||
|
ASSERT_VALID(ptiSelected);
|
||
|
|
||
|
// Ask the list view to display the items for this tree item.
|
||
|
ASSERT_VALID(ptiSelected->Pci());
|
||
|
Trace(g_tagTreeViewSelect, _T("OnSelChanged() - '%s' selected"), ptiSelected->Pci()->StrName());
|
||
|
ptiSelected->Select(this, FALSE /*bSelectInTree*/);
|
||
|
|
||
|
// Tell the document of the new selection.
|
||
|
if (m_pDocument != NULL) // this happens on system shutdown
|
||
|
GetDocument()->OnSelChanged(ptiSelected->Pci());
|
||
|
|
||
|
*pResult = 0;
|
||
|
Trace(g_tagTreeViewSelect, _T("OnSelChanged() - END"));
|
||
|
} // if: not dragging
|
||
|
|
||
|
} //*** CClusterTreeView::OnSelChanged()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::OnCmdMsg
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Processes command messages. Attempts to pass them on to a selected
|
||
|
// item first.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// nID [IN] Command ID.
|
||
|
// nCode [IN] Notification code.
|
||
|
// pExtra [IN OUT] Used according to the value of nCode.
|
||
|
// pHandlerInfo [OUT] ???
|
||
|
//
|
||
|
// Return Value:
|
||
|
// TRUE Message has been handled.
|
||
|
// FALSE Message has NOT been handled.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL CClusterTreeView::OnCmdMsg(
|
||
|
UINT nID,
|
||
|
int nCode,
|
||
|
void * pExtra,
|
||
|
AFX_CMDHANDLERINFO * pHandlerInfo
|
||
|
)
|
||
|
{
|
||
|
BOOL bHandled = FALSE;
|
||
|
|
||
|
// If there is a current item selected, give it a chance
|
||
|
// to handle the message.
|
||
|
if (HtiSelected() != NULL)
|
||
|
bHandled = PtiSelected()->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
|
||
|
|
||
|
if (!bHandled)
|
||
|
bHandled = CTreeView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
|
||
|
|
||
|
return bHandled;
|
||
|
|
||
|
} //*** CClusterTreeView::OnCmdMsg()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::PmenuPopup
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Returns a popup menu.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// rpointScreen [IN OUT] Position of the cursor, in screen coordinates.
|
||
|
// rpci [OUT] Pointer in which to return associated cluster item.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// pmenu A popup menu for the item.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
CMenu * CClusterTreeView::PmenuPopup(
|
||
|
IN OUT CPoint & rpointScreen,
|
||
|
OUT CClusterItem *& rpci
|
||
|
)
|
||
|
{
|
||
|
CTreeItem * pti = NULL;
|
||
|
CMenu * pmenu = NULL;
|
||
|
|
||
|
rpci = NULL;
|
||
|
|
||
|
// If there are no coordinates (-1,-1), display a menu for the selected item.
|
||
|
if ((rpointScreen.x == -1) && (rpointScreen.y == -1))
|
||
|
{
|
||
|
CRect rect;
|
||
|
CTreeItem * ptiSelected = PtiSelected();
|
||
|
|
||
|
if ((ptiSelected != NULL)
|
||
|
&& GetTreeCtrl().GetItemRect(HtiSelected(), &rect, FALSE))
|
||
|
{
|
||
|
pti = ptiSelected;
|
||
|
} // if: selected item and it is visible
|
||
|
else
|
||
|
GetWindowRect(&rect);
|
||
|
rpointScreen.x = (rect.right - rect.left) / 2;
|
||
|
rpointScreen.y = (rect.bottom - rect.top) / 2;
|
||
|
ClientToScreen(&rpointScreen);
|
||
|
} // if: no coordinates
|
||
|
else
|
||
|
{
|
||
|
CPoint pointClient;
|
||
|
HTREEITEM hti;
|
||
|
UINT uiFlags;
|
||
|
|
||
|
// Get the coordinates of the point where the user clicked the right mouse
|
||
|
// button. We need in both screen and client coordinates.
|
||
|
pointClient = rpointScreen;
|
||
|
ScreenToClient(&pointClient);
|
||
|
|
||
|
// Get the item under the cursor and get its popup menu.
|
||
|
hti = GetTreeCtrl().HitTest(pointClient, &uiFlags);
|
||
|
if (hti != NULL)
|
||
|
{
|
||
|
// Get the tree item for the item under the cursor.
|
||
|
pti = (CTreeItem *) GetTreeCtrl().GetItemData(hti);
|
||
|
ASSERT_VALID(pti);
|
||
|
|
||
|
// Select the item because that's the only way for it us process the menu.
|
||
|
pti->BSelectItem(this);
|
||
|
} // if: on an item
|
||
|
} // else: coordinates specified
|
||
|
|
||
|
if (pti != NULL)
|
||
|
{
|
||
|
// Get a menu from the item.
|
||
|
pmenu = pti->PmenuPopup();
|
||
|
rpci = pti->Pci();
|
||
|
} // if: item found
|
||
|
|
||
|
return pmenu;
|
||
|
|
||
|
} //*** CClusterTreeView::PmenuPopup()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::OnActivateView
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Called when the view is activated.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// bActivate [IN] Indicates whether the view being activated or deactivated.
|
||
|
// pActivateView [IN OUT] Points to the view object that is being activated.
|
||
|
// peactiveView [IN OUT] Points to the view object that is being deactivated.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CClusterTreeView::OnActivateView(
|
||
|
BOOL bActivate,
|
||
|
CView * pActivateView,
|
||
|
CView * pDeactiveView
|
||
|
)
|
||
|
{
|
||
|
CTreeItem * ptiSelected = PtiSelected();
|
||
|
|
||
|
if (m_pDocument != NULL) // this happens on system shutdown
|
||
|
{
|
||
|
if (bActivate && (ptiSelected != NULL))
|
||
|
{
|
||
|
ASSERT_VALID(ptiSelected->Pci());
|
||
|
Trace(g_tagTreeViewSelect, _T("OnActiveView: '%s' selected"), ptiSelected->Pci()->StrName());
|
||
|
|
||
|
// Tell the document of the new selection.
|
||
|
GetDocument()->OnSelChanged(ptiSelected->Pci());
|
||
|
} // if: we are being activated
|
||
|
} // if: document is available
|
||
|
|
||
|
CTreeView::OnActivateView(bActivate, pActivateView, pDeactiveView);
|
||
|
|
||
|
} //*** CClusterTreeView::OnActivateView()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::OnDestroy
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Handler method for the WM_DESTROY message.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CClusterTreeView::OnDestroy(void)
|
||
|
{
|
||
|
// Clean up the control.
|
||
|
if (m_pDocument != NULL) // this happens on system shutdown
|
||
|
{
|
||
|
// Save the currently selected item.
|
||
|
SaveCurrentSelection();
|
||
|
|
||
|
// Cleanup after ourselves.
|
||
|
// CleanupItems(GetDocument()->PtiCluster());
|
||
|
} // if: the document is still available
|
||
|
|
||
|
CTreeView::OnDestroy();
|
||
|
|
||
|
} //*** CClusterTreeView::OnDestroy()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::OnItemExpanded
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Handler method for the TVN_ITEMEXPANDED message.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pNMHDR Notification message structure.
|
||
|
// pResult Place in which to return the result.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CClusterTreeView::OnItemExpanded(NMHDR * pNMHDR, LRESULT * pResult)
|
||
|
{
|
||
|
NM_TREEVIEW * pNMTreeView = (NM_TREEVIEW *) pNMHDR;
|
||
|
|
||
|
if (pNMTreeView->itemNew.mask & TVIF_STATE)
|
||
|
{
|
||
|
BOOL bExpanded;
|
||
|
CTreeItem * pti;
|
||
|
|
||
|
bExpanded = (pNMTreeView->itemNew.state & TVIS_EXPANDED) != 0;
|
||
|
ASSERT(pNMTreeView->itemNew.mask & TVIF_PARAM);
|
||
|
pti = (CTreeItem *) pNMTreeView->itemNew.lParam;
|
||
|
ASSERT_VALID(pti);
|
||
|
ASSERT_KINDOF(CTreeItem, pti);
|
||
|
pti->SetExpandedState(this, bExpanded);
|
||
|
} // if: expanded state changed.
|
||
|
|
||
|
*pResult = 0;
|
||
|
|
||
|
} //*** CClusterTreeView::OnItemExpanded()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::OnBeginLabelEdit
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Handler method for the TVN_BEGINLABELEDIT message.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pNMHDR Notification message structure.
|
||
|
// pResult Place in which to return the result.
|
||
|
// TRUE = don't edit, FALSE = edit.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CClusterTreeView::OnBeginLabelEdit(NMHDR * pNMHDR, LRESULT * pResult)
|
||
|
{
|
||
|
ASSERT(pNMHDR != NULL);
|
||
|
|
||
|
TV_DISPINFO * pTVDispInfo = (TV_DISPINFO *) pNMHDR;
|
||
|
CTreeItem * pti = (CTreeItem *) pTVDispInfo->item.lParam;
|
||
|
|
||
|
ASSERT(m_ptiBeingEdited == NULL);
|
||
|
ASSERT_VALID(pti);
|
||
|
ASSERT_VALID(pti->Pci());
|
||
|
|
||
|
if (!BDragging() && pti->Pci()->BCanBeEdited())
|
||
|
{
|
||
|
pti->Pci()->OnBeginLabelEdit(GetTreeCtrl().GetEditControl());
|
||
|
m_ptiBeingEdited = pti;
|
||
|
*pResult = FALSE;
|
||
|
} // if: not dragging and object can be edited
|
||
|
else
|
||
|
*pResult = TRUE;
|
||
|
|
||
|
m_bShiftPressed = FALSE;
|
||
|
m_bControlPressed = FALSE;
|
||
|
m_bAltPressed = FALSE;
|
||
|
|
||
|
} //*** CClusterTreeView::OnBeginLabelEdit()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::OnEndLabelEdit
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Handler method for the TVN_ENDLABELEDIT message.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pNMHDR Notification message structure.
|
||
|
// pResult Place in which to return the result.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CClusterTreeView::OnEndLabelEdit(NMHDR * pNMHDR, LRESULT * pResult)
|
||
|
{
|
||
|
ASSERT(pNMHDR != NULL);
|
||
|
|
||
|
TV_DISPINFO * pTVDispInfo = (TV_DISPINFO *) pNMHDR;
|
||
|
CTreeItem * pti = (CTreeItem *) pTVDispInfo->item.lParam;
|
||
|
|
||
|
ASSERT_VALID(pti);
|
||
|
ASSERT(pti == m_ptiBeingEdited);
|
||
|
ASSERT_VALID(pti->Pci());
|
||
|
|
||
|
// If the edit wasn't cancelled, rename it.
|
||
|
if (pTVDispInfo->item.mask & LVIF_TEXT)
|
||
|
{
|
||
|
ASSERT(pti->Pci()->BCanBeEdited());
|
||
|
ASSERT(pTVDispInfo->item.pszText != NULL);
|
||
|
|
||
|
Trace(g_tagTreeView, _T("Ending edit of item '%s' (Saving as '%s')"), pti->Pci()->StrName(), pTVDispInfo->item.pszText);
|
||
|
|
||
|
if ( pti->Pci()->BIsLabelEditValueValid( pTVDispInfo->item.pszText ) )
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
pti->Pci()->Rename(pTVDispInfo->item.pszText);
|
||
|
*pResult = TRUE;
|
||
|
} // try
|
||
|
catch (CException * pe)
|
||
|
{
|
||
|
pe->ReportError();
|
||
|
pe->Delete();
|
||
|
*pResult = FALSE;
|
||
|
} // catch: CException
|
||
|
} // if: name is valid
|
||
|
else
|
||
|
{
|
||
|
*pResult = FALSE;
|
||
|
}
|
||
|
} // if: the edit wasn't cancelled
|
||
|
else
|
||
|
{
|
||
|
Trace(g_tagTreeView, _T("Ending edit of item '%s' (Not Saving)"), pti->Pci()->StrName());
|
||
|
*pResult = TRUE;
|
||
|
} // else: edit was cancelled
|
||
|
|
||
|
m_ptiBeingEdited = NULL;
|
||
|
m_bShiftPressed = FALSE;
|
||
|
m_bControlPressed = FALSE;
|
||
|
m_bAltPressed = FALSE;
|
||
|
|
||
|
} //*** CClusterTreeView::OnEndLabelEdit()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::OnBeginDrag
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Handler method for the TVN_BEGINDRAG and TVN_BEGINRDRAG messages.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pNMHDR Notification message structure.
|
||
|
// pResult Place in which to return the result.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CClusterTreeView::OnBeginDrag(NMHDR * pNMHDR, LRESULT * pResult)
|
||
|
{
|
||
|
CTreeCtrl & rtc = GetTreeCtrl();
|
||
|
CPoint ptScreen;
|
||
|
CPoint ptFrame;
|
||
|
CPoint ptView;
|
||
|
UINT nFlags;
|
||
|
CClusterItem * pci = NULL;
|
||
|
CImageList * pimagelist;
|
||
|
|
||
|
ASSERT_VALID(Pframe());
|
||
|
|
||
|
// Get the current cursor position for identifying the item being dragged.
|
||
|
GetCursorPos(&ptScreen);
|
||
|
ptFrame = ptScreen;
|
||
|
Pframe()->ScreenToClient(&ptFrame);
|
||
|
ptView = ptScreen;
|
||
|
rtc.ScreenToClient(&ptView);
|
||
|
|
||
|
// Get the item being dragged.
|
||
|
{
|
||
|
HTREEITEM hti;
|
||
|
CTreeItem * pti;
|
||
|
|
||
|
hti = rtc.HitTest(ptView, &nFlags);
|
||
|
if (hti == NULL)
|
||
|
return;
|
||
|
|
||
|
pti = (CTreeItem *) rtc.GetItemData(hti);
|
||
|
ASSERT_VALID(pti);
|
||
|
ASSERT_KINDOF(CTreeItem, pti);
|
||
|
ASSERT_VALID(pti->Pci());
|
||
|
|
||
|
// If the item can not be dragged, abort the operation.
|
||
|
if (!pti->Pci()->BCanBeDragged())
|
||
|
return;
|
||
|
|
||
|
// Save info for later.
|
||
|
m_htiDrag = hti;
|
||
|
m_ptiDrag = pti;
|
||
|
m_htiDrop = NULL;
|
||
|
pci = pti->Pci();
|
||
|
} // Get the item being dragged
|
||
|
|
||
|
Trace(g_tagTreeDrag, _T("OnBeginDrag() - Dragging '%s' at (%d,%d)"), m_ptiDrag->StrName(), ptFrame.x, ptFrame.y);
|
||
|
|
||
|
// Create an image list for the image being dragged.
|
||
|
pimagelist = rtc.CreateDragImage(m_htiDrag);
|
||
|
|
||
|
// Let the frame window initialize the drag operation.
|
||
|
Pframe()->BeginDrag(pimagelist, pci, ptFrame, CPoint(0, -16));
|
||
|
|
||
|
*pResult = 0;
|
||
|
|
||
|
} //*** CClusterTreeView::OnBeginDrag(pNMHDR, pResult)
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::OnMouseMoveForDrag
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Handler method for the WM_MOUSEMOVE message during a drag operation.
|
||
|
// This function is only responsible for providing view-specific
|
||
|
// functionality, such as selecting the drop target if it is valid.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// nFlags Indicates whether various virtual keys are down.
|
||
|
// point Specifies the x- and y-coordinate of the cursor in frame
|
||
|
// coordinates.
|
||
|
// pwndDrop Specifies the window under the cursor.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CClusterTreeView::OnMouseMoveForDrag(
|
||
|
IN UINT nFlags,
|
||
|
IN CPoint point,
|
||
|
IN const CWnd * pwndDrop
|
||
|
)
|
||
|
{
|
||
|
ASSERT(BDragging());
|
||
|
ASSERT_VALID(Pframe());
|
||
|
|
||
|
// If we are dragging, select the drop target.
|
||
|
if (BDragging())
|
||
|
{
|
||
|
HTREEITEM hti;
|
||
|
UINT flags;
|
||
|
CPoint ptView;
|
||
|
CTreeCtrl & rtc = GetTreeCtrl();
|
||
|
|
||
|
// Convert the point to view coordinates.
|
||
|
ptView = point;
|
||
|
Pframe()->ClientToScreen(&ptView);
|
||
|
rtc.ScreenToClient(&ptView);
|
||
|
|
||
|
// If this window is the drop target, find the item under the cursor.
|
||
|
if (pwndDrop == &rtc)
|
||
|
{
|
||
|
// If we are over a tree item, highlight it.
|
||
|
hti = rtc.HitTest(ptView, &flags);
|
||
|
if (hti != NULL)
|
||
|
{
|
||
|
CTreeItem * pti;
|
||
|
|
||
|
// Get the item to be highlight.
|
||
|
pti = (CTreeItem *) rtc.GetItemData(hti);
|
||
|
ASSERT_VALID(pti);
|
||
|
ASSERT_KINDOF(CTreeItem, pti);
|
||
|
ASSERT_VALID(pti->Pci());
|
||
|
|
||
|
// If this is not a drop target, change the cursor.
|
||
|
if (pti->Pci()->BCanBeDropTarget(Pframe()->PciDrag()))
|
||
|
Pframe()->ChangeDragCursor(IDC_ARROW);
|
||
|
else
|
||
|
Pframe()->ChangeDragCursor(IDC_NO);
|
||
|
} // if: over a tree item
|
||
|
} // if: this window is the drop target
|
||
|
else
|
||
|
hti = NULL;
|
||
|
|
||
|
// Unlock window updates.
|
||
|
VERIFY(Pimagelist()->DragShowNolock(FALSE /*bShow*/));
|
||
|
|
||
|
// Highlight the new drop target.
|
||
|
rtc.SelectDropTarget(hti);
|
||
|
m_htiDrop = hti;
|
||
|
|
||
|
VERIFY(Pimagelist()->DragShowNolock(TRUE /*bShow*/));
|
||
|
} // if: tree item is being dragged
|
||
|
|
||
|
} //*** CClusterTreeView::OnMouseMoveForDrag()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::OnButtonUpForDrag
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Called to handle a button up event during drag and drop.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// nFlags Indicates whether various virtual keys are down.
|
||
|
// point Specifies the x- and y-coordinate of the cursor.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CClusterTreeView::OnButtonUpForDrag(IN UINT nFlags, IN CPoint point)
|
||
|
{
|
||
|
ASSERT(BDragging());
|
||
|
ASSERT_VALID(Pframe());
|
||
|
ASSERT_VALID(Pframe()->PciDrag());
|
||
|
|
||
|
// If we are dragging, process the drop.
|
||
|
if (BDragging())
|
||
|
{
|
||
|
HTREEITEM hti;
|
||
|
UINT flags;
|
||
|
CPoint ptView;
|
||
|
CTreeCtrl & rtc = GetTreeCtrl();
|
||
|
|
||
|
Trace(g_tagTreeDrag, _T("OnButtonUpForDrag()"));
|
||
|
|
||
|
// Convert the point to view coordinates.
|
||
|
ptView = point;
|
||
|
Pframe()->ClientToScreen(&ptView);
|
||
|
rtc.ScreenToClient(&ptView);
|
||
|
|
||
|
// If we are over a tree item, drop the item being dragged.
|
||
|
hti = rtc.HitTest(ptView, &flags);
|
||
|
if (hti != NULL)
|
||
|
{
|
||
|
CTreeItem * ptiDropTarget;
|
||
|
|
||
|
// Get the item to drop on.
|
||
|
ptiDropTarget = (CTreeItem *) rtc.GetItemData(hti);
|
||
|
ASSERT_VALID(ptiDropTarget);
|
||
|
ASSERT_KINDOF(CTreeItem, ptiDropTarget);
|
||
|
ASSERT_VALID(ptiDropTarget->Pci());
|
||
|
|
||
|
if (ptiDropTarget->Pci() != Pframe()->PciDrag())
|
||
|
ptiDropTarget->Pci()->DropItem(Pframe()->PciDrag());
|
||
|
|
||
|
} // if: over a tree item
|
||
|
} // if: tree item is being dragged
|
||
|
|
||
|
} //*** CClusterTreeView::OnButtonUpForDrag()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::BeginDrag
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Called by the frame to begin a drag operation.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CClusterTreeView::BeginDrag(void)
|
||
|
{
|
||
|
Trace(g_tagTreeDrag, _T("BeginDrag()"));
|
||
|
|
||
|
} //*** CClusterTreeView::BeginDrag()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::EndDrag
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Called by the frame to end a drag operation.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CClusterTreeView::EndDrag(void)
|
||
|
{
|
||
|
// Cleanup.
|
||
|
GetTreeCtrl().SelectDropTarget(NULL);
|
||
|
m_htiDrag = NULL;
|
||
|
m_ptiDrag = NULL;
|
||
|
m_htiDrop = NULL;
|
||
|
|
||
|
Trace(g_tagTreeDrag, _T("EndDrag()"));
|
||
|
|
||
|
} //*** CClusterTreeView::EndDrag()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::PreTranslateMessage
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Translate window messages before they are dispatched.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pMsg Points to a MSG structure that contains the message to process.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// TRUE Message was handled.
|
||
|
// FALSE Message was not handled.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL CClusterTreeView::PreTranslateMessage(MSG * pMsg)
|
||
|
{
|
||
|
BOOL bForward = FALSE;
|
||
|
|
||
|
if (m_ptiBeingEdited != NULL)
|
||
|
{
|
||
|
CEdit * pedit = GetTreeCtrl().GetEditControl();
|
||
|
ASSERT(pedit != NULL);
|
||
|
|
||
|
if (pMsg->message == WM_KEYDOWN)
|
||
|
{
|
||
|
if (pMsg->wParam == VK_SHIFT)
|
||
|
m_bShiftPressed = TRUE;
|
||
|
else if (pMsg->wParam == VK_CONTROL)
|
||
|
{
|
||
|
::CopyMemory(&m_msgControl, pMsg, sizeof(m_msgControl));
|
||
|
m_bControlPressed = TRUE;
|
||
|
} // else if: control key pressed
|
||
|
else if ((pMsg->wParam == VK_RETURN)
|
||
|
|| (pMsg->wParam == VK_ESCAPE)
|
||
|
|| (pMsg->wParam == VK_INSERT)
|
||
|
|| (pMsg->wParam == VK_DELETE)
|
||
|
|| (pMsg->wParam == VK_F1)
|
||
|
|| (pMsg->wParam == VK_F5)
|
||
|
|| (pMsg->wParam == VK_F6)
|
||
|
)
|
||
|
{
|
||
|
Trace(g_tagTreeView, _T("PreTranslateMessage() - Forwarding WM_KEYDOWN - %d '%c', lparam = %08.8x"), pMsg->wParam, pMsg->wParam, pMsg->lParam);
|
||
|
bForward = TRUE;
|
||
|
if (m_bControlPressed)
|
||
|
{
|
||
|
if (pMsg->wParam == VK_RETURN)
|
||
|
pedit->SendMessage(WM_KEYUP, m_msgControl.wParam, m_msgControl.lParam);
|
||
|
} // if: control key pressed
|
||
|
} // else if: editing key pressed
|
||
|
else if ((pMsg->wParam == VK_TAB)
|
||
|
|| (m_bControlPressed
|
||
|
&& (_T('A') <= pMsg->wParam) && (pMsg->wParam <= _T('Y'))
|
||
|
&& (pMsg->wParam != _T('C'))
|
||
|
&& (pMsg->wParam != _T('H'))
|
||
|
&& (pMsg->wParam != _T('M'))
|
||
|
&& (pMsg->wParam != _T('V'))
|
||
|
&& (pMsg->wParam != _T('X'))
|
||
|
)
|
||
|
)
|
||
|
{
|
||
|
Trace(g_tagTreeView, _T("PreTranslateMessage() - Ignoring WM_KEYDOWN - %d '%c', lparam = %08.8x"), pMsg->wParam, pMsg->wParam, pMsg->lParam);
|
||
|
MessageBeep(MB_ICONEXCLAMATION);
|
||
|
return TRUE;
|
||
|
} // else if: key pressed that should be ignored
|
||
|
#ifdef NEVER
|
||
|
else
|
||
|
{
|
||
|
Trace(g_tagTreeView, _T("PreTranslateMessage() - Not forwarding WM_KEYDOWN - %d '%c', lparam = %08.8x"), pMsg->wParam, pMsg->wParam, pMsg->lParam);
|
||
|
} // else: not processing key
|
||
|
#endif
|
||
|
} // if: key pressed while editing label
|
||
|
else if (pMsg->message == WM_SYSKEYDOWN)
|
||
|
{
|
||
|
if (pMsg->wParam == VK_MENU)
|
||
|
m_bAltPressed = TRUE;
|
||
|
else if ((pMsg->wParam == VK_RETURN)
|
||
|
)
|
||
|
{
|
||
|
Trace(g_tagTreeView, _T("PreTranslateMessage() - Forwarding WM_SYSKEYDOWN - %d '%c', lparam = %08.8x"), pMsg->wParam, pMsg->wParam, pMsg->lParam);
|
||
|
bForward = TRUE;
|
||
|
} // else if: editing key pressed
|
||
|
#ifdef NEVER
|
||
|
else
|
||
|
{
|
||
|
Trace(g_tagTreeView, _T("PreTranslateMessage() - Not forwarding WM_SYSKEYDOWN - %d '%c', lparam = %08.8x"), pMsg->wParam, pMsg->wParam, pMsg->lParam);
|
||
|
} // else: not processing key
|
||
|
#endif
|
||
|
} // else if: system key pressed while editing label
|
||
|
if (bForward)
|
||
|
{
|
||
|
pedit->SendMessage(pMsg->message, pMsg->wParam, pMsg->lParam);
|
||
|
return TRUE;
|
||
|
} // if: forwarding the message
|
||
|
else if (pMsg->message == WM_KEYUP)
|
||
|
{
|
||
|
if (pMsg->wParam == VK_SHIFT)
|
||
|
m_bShiftPressed = FALSE;
|
||
|
else if (pMsg->wParam == VK_CONTROL)
|
||
|
m_bControlPressed = FALSE;
|
||
|
} // else if: key up
|
||
|
else if (pMsg->message == WM_SYSKEYUP)
|
||
|
{
|
||
|
if (pMsg->wParam == VK_MENU)
|
||
|
m_bAltPressed = FALSE;
|
||
|
} // else if: system key up
|
||
|
} // if: editing a label
|
||
|
|
||
|
return CTreeView::PreTranslateMessage(pMsg);
|
||
|
|
||
|
} //*** CClusterTreeView::PreTranslateMessage()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::OnCmdRename
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Processes the ID_FILE_RENAME menu command.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CClusterTreeView::OnCmdRename(void)
|
||
|
{
|
||
|
CTreeItem * ptiSelected = PtiSelected();
|
||
|
|
||
|
// If an item has benn selected, begin label editing
|
||
|
if (ptiSelected != NULL)
|
||
|
{
|
||
|
ASSERT_VALID(ptiSelected);
|
||
|
ptiSelected->EditLabel(this);
|
||
|
} // if: an item has the focus
|
||
|
|
||
|
} //*** CClusterTreeView::OnCmdRename()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusterTreeView::OnKeyDown
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Handler method for the TVN_KEYDOWN message.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pNMHDR Notification message structure.
|
||
|
// pResult Place in which to return the result.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CClusterTreeView::OnKeyDown(NMHDR * pNMHDR, LRESULT * pResult)
|
||
|
{
|
||
|
TV_KEYDOWN * pTVKeyDown = (TV_KEYDOWN *) pNMHDR;
|
||
|
|
||
|
if (BDragging() && (pTVKeyDown->wVKey == VK_ESCAPE))
|
||
|
Pframe()->AbortDrag();
|
||
|
|
||
|
*pResult = 0;
|
||
|
|
||
|
} //*** CClusterTreeView::OnKeyDown()
|