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

📄 bcgpshelltree.cpp

📁 远程网络监视程序的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//*******************************************************************************
// COPYRIGHT NOTES
// ---------------
// This is a part of the BCGControlBar Library
// Copyright (C) 1998-2000 BCGSoft Ltd.
// All rights reserved.
//
// This source code can be used, distributed or modified
// only under terms and conditions 
// of the accompanying license agreement.
//*******************************************************************************
// BCGShellTree.cpp : implementation file
//

#include "stdafx.h"
#include "BCGPShellTree.h"
#include "BCGPShellList.h"
#include "BCGPShellManager.h"

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

/////////////////////////////////////////////////////////////////////////////
// CBCGPShellTree

IMPLEMENT_DYNAMIC(CBCGPShellTree, CTreeCtrl)

IContextMenu2* CBCGPShellTree::m_pContextMenu2 = NULL;

CBCGPShellTree::CBCGPShellTree()
{
	m_bContextMenu = TRUE;
	m_hwndRelatedList = NULL;
	m_bNoNotify = FALSE;
	m_dwFlags = SHCONTF_FOLDERS;
}

CBCGPShellTree::~CBCGPShellTree()
{
}

BEGIN_MESSAGE_MAP(CBCGPShellTree, CTreeCtrl)
	//{{AFX_MSG_MAP(CBCGPShellTree)
	ON_WM_CREATE()
	ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding)
	ON_NOTIFY_REFLECT(TVN_DELETEITEM, OnDeleteitem)
	ON_WM_CONTEXTMENU()
	ON_WM_RBUTTONDOWN()
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBCGPShellTree message handlers

int CBCGPShellTree::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CTreeCtrl::OnCreate(lpCreateStruct) == -1)
		return -1;

	if (g_pShellManager == NULL)
	{
		TRACE0("You need to initialize CBCGPShellManager first\n");
		return -1;
	}
	
	InitTree ();
	return 0;
}
//***************************************************************************************
void CBCGPShellTree::SetRelatedList (CBCGPShellList* pShellList)
{
	ASSERT_VALID (this);

	m_hwndRelatedList = (pShellList == NULL) ? NULL : pShellList->GetSafeHwnd ();
	if (pShellList != NULL)
	{
		pShellList->m_hwndRelatedTree = GetSafeHwnd ();
	}
}
//***************************************************************************************
CBCGPShellList* CBCGPShellTree::GetRelatedList () const
{
	ASSERT_VALID (this);

	if (m_hwndRelatedList == NULL || !::IsWindow (m_hwndRelatedList))
	{
		return NULL;
	}

	CBCGPShellList* pList = DYNAMIC_DOWNCAST (CBCGPShellList,
		CWnd::FromHandlePermanent (m_hwndRelatedList));

	return pList;
}
//****************************************************************************************
void CBCGPShellTree::Refresh ()
{
	ASSERT_VALID (this);

	DeleteAllItems ();

	GetRootItems ();
	TreeView_SetScrollTime (GetSafeHwnd (), 100);
}
//***************************************************************************************
BOOL CBCGPShellTree::GetRootItems ()
{
	ASSERT_VALID (this);
	ASSERT_VALID (g_pShellManager);

	LPITEMIDLIST pidl;

	if (FAILED (SHGetSpecialFolderLocation (NULL, CSIDL_DESKTOP, &pidl)))
	{
		return FALSE;
	}

	//--------------------------------
	// Get the desktop's IShellFolder:
	//--------------------------------
	LPSHELLFOLDER pDesktop;
	if (FAILED (SHGetDesktopFolder (&pDesktop)))
	{
		return FALSE;
	}
	
	//--------------------------------------------
	// Fill in the TVITEM structure for this item:
	//--------------------------------------------
	TV_ITEM	tvItem;
	tvItem.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN;
	
	//-------------------------------------------
	// Put the private information in the lParam:
	//-------------------------------------------
	LPBCGCBITEMINFO pItem = (LPBCGCBITEMINFO) GlobalAlloc (GPTR, sizeof(BCGCBITEMINFO));
	ASSERT (pItem != NULL);

	pItem->pidlRel = pidl;
	pItem->pidlFQ = g_pShellManager->CopyItem (pidl);
	
	//-------------------------------------------------------------
	// The desktop doesn't have a parent folder, so make this NULL:
	//-------------------------------------------------------------
	pItem->pParentFolder = NULL;
	tvItem.lParam = (LPARAM)pItem;
	
	CString strItem = OnGetItemText (pItem);
	tvItem.pszText = strItem.GetBuffer (strItem.GetLength ());
	tvItem.iImage = OnGetItemIcon (pItem, FALSE);
	tvItem.iSelectedImage = OnGetItemIcon (pItem, TRUE);
	
	//---------------------------------
	// Assume the desktop has children:
	//---------------------------------
	tvItem.cChildren = TRUE;
	
	//-----------------------------------------------------
	// Fill in the TV_INSERTSTRUCT structure for this item:
	//-----------------------------------------------------
	TV_INSERTSTRUCT tvInsert;

	tvInsert.item = tvItem;
	tvInsert.hInsertAfter = TVI_LAST;
	tvInsert.hParent = TVI_ROOT;
	
	//--------------
	// Add the item:
	//--------------
	HTREEITEM hParentItem = InsertItem (&tvInsert);
	
	//-------------------------------
	// Go ahead and expand this item:
	//-------------------------------
	Expand (hParentItem, TVE_EXPAND);
	
	pDesktop->Release();
	return TRUE;
}
//***************************************************************************************
BOOL CBCGPShellTree::GetChildItems (HTREEITEM hParentItem)
{
	ASSERT_VALID (this);

	CWaitCursor wait;

	//----------------------------
	// Get the parent item's pidl:
	//----------------------------
	TVITEM tvItem;
	ZeroMemory (&tvItem, sizeof(tvItem));

	tvItem.mask = TVIF_PARAM;
	tvItem.hItem = hParentItem;

	if (!GetItem (&tvItem))
	{
		return FALSE;
	}
	
	SetRedraw (FALSE);
	
	LPBCGCBITEMINFO pItem = (LPBCGCBITEMINFO) tvItem.lParam;
	ASSERT (pItem != NULL);
	
	LPSHELLFOLDER pParentFolder = NULL;
	HRESULT	hr;

	//--------------------------------------------------------------------
	// If the parent folder is NULL, then we are at the root 
	// of the namespace, so the parent of this item is the desktop folder
	//--------------------------------------------------------------------
	if (pItem->pParentFolder == NULL)
	{
		hr = SHGetDesktopFolder (&pParentFolder);
	}
	else
	{
		//---------------------------------------------------------
		// Otherwise we need to get the IShellFolder for this item:
		//---------------------------------------------------------
		hr = pItem->pParentFolder->BindToObject (pItem->pidlRel, 
					NULL, IID_IShellFolder, (LPVOID*) &pParentFolder);
	}
	
	if (FAILED (hr))
	{
		SetRedraw ();
		return FALSE;
	}
	
	EnumObjects (hParentItem, pParentFolder, pItem->pidlFQ);
	
	//--------------------
	// Sort the new items:
	//--------------------
	TV_SORTCB tvSort;

	tvSort.hParent = hParentItem;
	tvSort.lpfnCompare = CompareProc;
	tvSort.lParam = 0;

	SortChildrenCB (&tvSort);
	
	SetRedraw ();
	RedrawWindow ();
	
	pParentFolder->Release ();
	return TRUE;
}
//***************************************************************************************
HRESULT CBCGPShellTree::EnumObjects (HTREEITEM		hParentItem,
									LPSHELLFOLDER	pParentFolder,
									LPITEMIDLIST	pidlParent)
{
	ASSERT_VALID (this);
	ASSERT_VALID (g_pShellManager);

	LPENUMIDLIST pEnum;
	
	HRESULT hr = pParentFolder->EnumObjects (NULL, m_dwFlags, &pEnum);
	if (FAILED (hr))
	{
		return hr;
	}

	LPITEMIDLIST		pidlTemp;
	DWORD				dwFetched = 1;
	
	//----------------------------
	// Enumerate the item's PIDLs:
	//----------------------------
	while (SUCCEEDED (pEnum->Next(1, &pidlTemp, &dwFetched)) && dwFetched)
	{
		TVITEM tvItem;
		ZeroMemory (&tvItem, sizeof (tvItem));
		
		//---------------------------------------------
		// Fill in the TV_ITEM structure for this item:
		//---------------------------------------------
		tvItem.mask =	TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | 
						TVIF_SELECTEDIMAGE | TVIF_CHILDREN;
		
		//------------------------------------------------------
		// AddRef the parent folder so it's pointer stays valid:
		//------------------------------------------------------
		pParentFolder->AddRef ();
		
		//-------------------------------------------
		// Put the private information in the lParam:
		//-------------------------------------------
		LPBCGCBITEMINFO pItem = (LPBCGCBITEMINFO)GlobalAlloc (GPTR, sizeof (BCGCBITEMINFO));
		ASSERT (pItem != NULL);
		
		pItem->pidlRel = pidlTemp;
		pItem->pidlFQ = g_pShellManager->ConcatenateItem (pidlParent, pidlTemp);
		
		pItem->pParentFolder = pParentFolder;
		tvItem.lParam = (LPARAM)pItem;
		
		CString strItem = OnGetItemText (pItem);
		tvItem.pszText = strItem.GetBuffer (strItem.GetLength ());
		tvItem.iImage = OnGetItemIcon (pItem, FALSE);
		tvItem.iSelectedImage = OnGetItemIcon (pItem, TRUE);
		
		//------------------------------------
		// Determine if the item has children:
		//------------------------------------
		DWORD dwAttribs =	SFGAO_HASSUBFOLDER | SFGAO_FOLDER | 
							SFGAO_DISPLAYATTRMASK | SFGAO_CANRENAME;

		pParentFolder->GetAttributesOf (1, (LPCITEMIDLIST*) &pidlTemp, &dwAttribs);
		tvItem.cChildren = (dwAttribs & SFGAO_HASSUBFOLDER);
		
		//---------------------------------
		// Determine if the item is shared:
		//---------------------------------
		if (dwAttribs & SFGAO_SHARE)
		{
			tvItem.mask |= TVIF_STATE;
			tvItem.stateMask |= TVIS_OVERLAYMASK;
			tvItem.state |= INDEXTOOVERLAYMASK(1); //1 is the index for the shared overlay image
		}
		
		//-----------------------------------------------------
		// Fill in the TV_INSERTSTRUCT structure for this item:
		//-----------------------------------------------------
		TVINSERTSTRUCT tvInsert;

		tvInsert.item = tvItem;
		tvInsert.hInsertAfter = TVI_LAST;
		tvInsert.hParent = hParentItem;
		
		InsertItem (&tvInsert);
		dwFetched = 0;
	}
	
	pEnum->Release ();
	return S_OK;
}
//***************************************************************************************
int CALLBACK CBCGPShellTree::CompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
	UNREFERENCED_PARAMETER(lParamSort);
	
	LPBCGCBITEMINFO pItem1 = (LPBCGCBITEMINFO)lParam1;
	LPBCGCBITEMINFO pItem2 = (LPBCGCBITEMINFO)lParam2;
	
	HRESULT hr = pItem1->pParentFolder->CompareIDs (0,
		pItem1->pidlRel,
		pItem2->pidlRel);
	
	if (FAILED (hr))
	{
		return 0;
	}
	
	return (short)SCODE_CODE(GetScode(hr));
}
//****************************************************************************************
void CBCGPShellTree::OnShowContextMenu (CPoint point)
{
	if (m_pContextMenu2 != NULL)
	{
		return;
	}

	if (!m_bContextMenu)
	{
		Default ();
		return;
	}

	HTREEITEM hItem = NULL;
	if (point.x == -1 && point.y == -1)
	{
		hItem = GetSelectedItem ();
	}
	else
	{
		CPoint ptClient = point;
		ScreenToClient (&ptClient);

		hItem = HitTest (ptClient);
	}

	if (hItem == NULL)
	{
		return;
	}
	
	TVITEM tvItem;
	
	ZeroMemory (&tvItem, sizeof (tvItem));
	tvItem.mask = TVIF_PARAM;
	tvItem.hItem = hItem;
	
	if (!GetItem (&tvItem))
	{
		return;
	}

	LPBCGCBITEMINFO pInfo = (LPBCGCBITEMINFO)tvItem.lParam;
	if (pInfo == NULL)
	{
		ASSERT (FALSE);
		return;
	}

	IShellFolder* psfFolder = pInfo->pParentFolder;
	
	if (psfFolder == NULL)
	{
		SHGetDesktopFolder (&psfFolder);
	}
	else
	{
		psfFolder->AddRef();
	}
	
	if (psfFolder != NULL)
	{
		HWND hwndParent = GetParent()->GetSafeHwnd ();
		IContextMenu* pcm = NULL;

		HRESULT hr = psfFolder->GetUIObjectOf (hwndParent,
			1, 
			(LPCITEMIDLIST*)&pInfo->pidlRel, 
			IID_IContextMenu, 
			NULL, 
			(LPVOID*)&pcm);
		
		if (SUCCEEDED (hr))
		{
			HMENU hPopup = CreatePopupMenu ();
			if (hPopup != NULL)
			{
				hr = pcm->QueryContextMenu(hPopup, 0, 1, 0x7fff, CMF_NORMAL | CMF_EXPLORE);
				
				if (SUCCEEDED (hr))
				{
					pcm->QueryInterface(IID_IContextMenu2, (LPVOID*)&m_pContextMenu2);
					
					HWND hwndThis = GetSafeHwnd ();
					UINT idCmd = TrackPopupMenu (hPopup,
									TPM_LEFTALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON, 
									point.x, 
									point.y,
									0,
									GetSafeHwnd (),

⌨️ 快捷键说明

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