|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1999 - 1999
//
// File: trobimpl.cpp
//
//--------------------------------------------------------------------------
// trobimpl.cpp : implementation file
//
#include "stdafx.h"
#include "amc.h"
#include "trobimpl.h"
/////////////////////////////////////////////////////////////////////////////
// CTreeObserverTreeImpl
CTreeObserverTreeImpl::CTreeObserverTreeImpl() : m_pTreeSrc(NULL), m_dwStyle(0), m_tidRoot(NULL) { }
CTreeObserverTreeImpl::~CTreeObserverTreeImpl() { }
HRESULT CTreeObserverTreeImpl::SetStyle(DWORD dwStyle) { ASSERT((dwStyle & ~(TOBSRV_HIDEROOT | TOBSRV_FOLDERSONLY)) == 0);
m_dwStyle = dwStyle;
return S_OK; }
HRESULT CTreeObserverTreeImpl::SetTreeSource(CTreeSource* pTreeSrc) { // Window may be gone before source is disconnected
if (IsWindow(m_hWnd)) DeleteAllItems();
m_pTreeSrc = pTreeSrc;
if (pTreeSrc == NULL) return S_OK;
// Must have window before populating tree
ASSERT(IsWindow(m_hWnd));
// populate top level of tree
TREEITEMID tidRoot = m_pTreeSrc->GetRootItem(); if (tidRoot != NULL) { // Trigger handler as though item were just added
ItemAdded(tidRoot); }
return S_OK; }
TREEITEMID CTreeObserverTreeImpl::GetSelection() { HTREEITEM hti = GetSelectedItem(); if (hti) return static_cast<TREEITEMID>(GetItemData(hti)); else return NULL; }
void CTreeObserverTreeImpl::SetSelection(TREEITEMID tid) { ASSERT(m_pTreeSrc != NULL);
HTREEITEM hti = FindHTI(tid, TRUE); ASSERT(hti != NULL);
SelectItem(hti); EnsureVisible(hti); }
void CTreeObserverTreeImpl::ExpandItem(TREEITEMID tid) { ASSERT(m_pTreeSrc != NULL); HTREEITEM hti = FindHTI(tid, TRUE);
if (hti != NULL) Expand(hti, TVE_EXPAND); }
BOOL CTreeObserverTreeImpl::IsItemExpanded(TREEITEMID tid) { ASSERT(m_pTreeSrc != NULL); HTREEITEM hti = FindHTI(tid, TRUE);
return (IsItemExpanded(hti)); }
HTREEITEM CTreeObserverTreeImpl::FindChildHTI(HTREEITEM htiParent, TREEITEMID tid) { HTREEITEM htiTemp;
if (htiParent == TVI_ROOT) htiTemp = GetRootItem(); else htiTemp = GetChildItem(htiParent);
while (htiTemp && GetItemData(htiTemp) != tid) { htiTemp = GetNextSiblingItem(htiTemp); }
return htiTemp; }
HTREEITEM CTreeObserverTreeImpl::FindHTI(TREEITEMID tid, BOOL bAutoExpand) { ASSERT(m_pTreeSrc != NULL);
if (tid == NULL || (tid == m_tidRoot && RootHidden())) return TVI_ROOT;
HTREEITEM htiParent = FindHTI(m_pTreeSrc->GetParentItem(tid), bAutoExpand); if (htiParent == NULL) return NULL;
if (bAutoExpand && !WasItemExpanded(htiParent)) Expand(htiParent, TVE_EXPAND);
return FindChildHTI(htiParent, tid); }
HTREEITEM CTreeObserverTreeImpl::AddOneItem(HTREEITEM htiParent, HTREEITEM htiAfter, TREEITEMID tid) { ASSERT(m_pTreeSrc != NULL);
TVINSERTSTRUCT insert;
insert.hParent = htiParent; insert.hInsertAfter = htiAfter;
insert.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_CHILDREN | TVIF_IMAGE | TVIF_SELECTEDIMAGE; insert.item.lParam = tid; insert.item.iImage = m_pTreeSrc->GetItemImage(tid); insert.item.iSelectedImage = insert.item.iImage; insert.item.cChildren = m_pTreeSrc->GetChildItem(tid) ? 1 : 0;
TCHAR name[MAX_PATH]; m_pTreeSrc->GetItemName(tid, name, countof(name)); insert.item.pszText = name;
return InsertItem(&insert); }
void CTreeObserverTreeImpl::AddChildren(HTREEITEM hti) { ASSERT(m_pTreeSrc != NULL);
TREEITEMID tidChild;
// if adding top level item
if (hti == TVI_ROOT) { if (RootHidden()) { // if root is hidden, add its children
ASSERT(m_tidRoot != 0); tidChild = m_pTreeSrc->GetChildItem(m_tidRoot); } else { // else add root item itself
tidChild = m_pTreeSrc->GetRootItem(); } } else { // convert to TID, then get its child
TREEITEMID tid = static_cast<TREEITEMID>(GetItemData(hti)); ASSERT(tid != 0); tidChild = m_pTreeSrc->GetChildItem(tid); }
while (tidChild) { // Add visible items
if (!ShowFoldersOnly() || m_pTreeSrc->IsFolderItem(tidChild)) AddOneItem(hti, TVI_LAST, tidChild);
tidChild = m_pTreeSrc->GetNextSiblingItem(tidChild); } }
void CTreeObserverTreeImpl::ItemAdded(TREEITEMID tid) { ASSERT(m_pTreeSrc != NULL); ASSERT(tid != 0);
// if only folders visible, skip this item
if (ShowFoldersOnly() && !m_pTreeSrc->IsFolderItem(tid)) return;
// Get parent tree item
TREEITEMID tidParent = m_pTreeSrc->GetParentItem(tid);
// if this is the tree root and the root is not displayed
if (tidParent == NULL && RootHidden()) { // Can only have one hidden root
ASSERT(m_tidRoot == NULL);
// Just save TID as the hidden root and return
m_tidRoot = tid;
// since root is hidden, add its children to the tree
AddChildren(TVI_ROOT);
return; }
// Add new item to tree
HTREEITEM htiParent = FindHTI(tidParent);
// Parent exists and has been expanded
if (WasItemExpanded(htiParent)) { // Determine previous tree item
// Because the source doesn't support GetPrevSibling
// we have to get the next TID then use our own tree to
// back up to the previous item
//
HTREEITEM htiPrev; TREEITEMID tidNext = m_pTreeSrc->GetNextSiblingItem(tid); if (tidNext) { HTREEITEM htiNext = FindChildHTI(htiParent, tidNext); ASSERT(htiNext);
htiPrev = GetPrevSiblingItem(htiNext); if (htiPrev == NULL) htiPrev = TVI_FIRST; } else { htiPrev = TVI_LAST; }
// Insert the new tree item
AddOneItem(htiParent, htiPrev, tid); } else if (htiParent) { // Set child count so parent can expand
TV_ITEM item; item.mask = TVIF_CHILDREN; item.hItem = htiParent; item.cChildren = 1;
SetItem(&item); }
}
void CTreeObserverTreeImpl::ItemRemoved(TREEITEMID tidParent, TREEITEMID tid) { ASSERT(m_pTreeSrc != NULL); ASSERT(tid != 0);
// if deleting hidden root, clear tree and return
if (tid == m_tidRoot) { DeleteAllItems(); m_tidRoot = NULL;
return; }
// Get parent tree item
HTREEITEM htiParent = FindHTI(tidParent);
if (WasItemExpanded(htiParent)) { // Find removed item
HTREEITEM hti = FindChildHTI(htiParent, tid);
// Remove the item
DeleteItem(hti); } }
void CTreeObserverTreeImpl::ItemChanged(TREEITEMID tid, DWORD dwAttrib) { ASSERT(m_pTreeSrc != NULL); ASSERT(tid != 0);
if (dwAttrib & TIA_NAME) { // Get changed tree item
HTREEITEM hti = FindHTI(tid);
// Force item update
if (hti != 0) { TCHAR name[MAX_PATH]; m_pTreeSrc->GetItemName(tid, name, countof(name));
TVITEM item; item.hItem = hti; item.mask = TVIF_TEXT; item.pszText = name; SetItem(&item); } } }
void CTreeObserverTreeImpl::OnItemExpanding(NMHDR* pNMHDR, LRESULT* pResult) { NM_TREEVIEW* pNotify = (NM_TREEVIEW*)pNMHDR; ASSERT(pNotify != NULL);
HTREEITEM hti = pNotify->itemNew.hItem; ASSERT(hti != NULL);
// Enumerate the folders below this item
if (pNotify->action == TVE_EXPAND) { // Only add children on first expansion
if (!(pNotify->itemNew.state & TVIS_EXPANDEDONCE)) AddChildren(hti); }
// Flip state of icon open/closed
ASSERT(m_pTreeSrc != NULL);
TREEITEMID tid = pNotify->itemNew.lParam; ASSERT(m_pTreeSrc->IsFolderItem(tid));
int iImage = (pNotify->action == TVE_EXPAND) ? m_pTreeSrc->GetItemOpenImage(tid) : m_pTreeSrc->GetItemImage(tid); TVITEM item; item.hItem = hti; item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE; item.iImage = item.iSelectedImage = iImage; SetItem(&item);
*pResult = 0; }
void CTreeObserverTreeImpl::OnSingleExpand(NMHDR* pNMHDR, LRESULT* pResult) { *pResult = TVNRET_DEFAULT; }
BEGIN_MESSAGE_MAP(CTreeObserverTreeImpl, CTreeCtrl) ON_NOTIFY_REFLECT(TVN_SINGLEEXPAND, OnSingleExpand) ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemExpanding) END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFavoritesView message handlers
|