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

📄 bcgpshelllist.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.
//*******************************************************************************
// BCGPShellList.cpp : implementation file
//

#include "stdafx.h"
#include "BCGPShellList.h"
#include "BCGPShellTree.h"
#include ".\bcgpshelllist.h"

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

UINT BCGPM_CHANGE_CURRENT_FOLDER = ::RegisterWindowMessage (_T("BCGPM_CHANGE_CURRENT_FOLDER"));
UINT BCGPM_SELECT_ITEMS_CHANGED	= ::RegisterWindowMessage (_T("BCGPM_SELECT_ITEMS_CHANGED"));

IMPLEMENT_DYNAMIC(CBCGPShellList, CBCGPListCtrl)

IContextMenu2*	CBCGPShellList::m_pContextMenu2 = NULL;

/////////////////////////////////////////////////////////////////////////////
// CBCGPShellList

CBCGPShellList::CBCGPShellList()
{
	m_psfCurFolder = NULL;
	m_pidlCurFQ = NULL;
	m_bContextMenu = TRUE;
	m_hwndRelatedTree = NULL;
	m_bIsDesktop = FALSE;
	m_bNoNotify = FALSE;
	m_nTypes = (SHCONTF) (SHCONTF_FOLDERS | SHCONTF_NONFOLDERS);
}

CBCGPShellList::~CBCGPShellList()
{
}

BEGIN_MESSAGE_MAP(CBCGPShellList, CBCGPListCtrl)
	//{{AFX_MSG_MAP(CBCGPShellList)
	ON_WM_CREATE()
	ON_NOTIFY_REFLECT(LVN_DELETEITEM, OnDeleteitem)
	ON_NOTIFY_REFLECT(LVN_ITEMCHANGED, OnLvnItemchanged)
	ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
	ON_NOTIFY_REFLECT(NM_RETURN, OnReturn)
	ON_WM_CONTEXTMENU()
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBCGPShellList message handlers

void CBCGPShellList::ReleaseCurrFolder ()
{
	ASSERT_VALID (g_pShellManager);

	if (m_psfCurFolder != NULL)
	{
		m_psfCurFolder->Release();
		m_psfCurFolder = NULL;

		g_pShellManager->FreeItem (m_pidlCurFQ);
		m_pidlCurFQ = NULL;
	}
}
//*****************************************************************************************
int CBCGPShellList::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CBCGPListCtrl::OnCreate(lpCreateStruct) == -1)
		return -1;

	if (!InitList ())
	{
		return -1;
	}

	return 0;
}
//***************************************************************************************
HIMAGELIST CBCGPShellList::GetShellImageList (BOOL bLarge)
{
	TCHAR szWinDir [MAX_PATH + 1];
	if (GetWindowsDirectory (szWinDir, MAX_PATH) == 0)
	{
		return NULL;
	}

	SHFILEINFO sfi;
	HIMAGELIST hImageList = (HIMAGELIST) SHGetFileInfo (szWinDir,
						0,
						&sfi, 
						sizeof (SHFILEINFO), 
						SHGFI_SYSICONINDEX | (bLarge ? 0 : SHGFI_SMALLICON));
	return hImageList;
}
//***************************************************************************************
HRESULT CBCGPShellList::LockCurrentFolder (LPBCGCBITEMINFO pItemInfo)
{
	ASSERT_VALID (g_pShellManager);

	HRESULT hr = E_FAIL;
	m_pidlCurFQ = NULL;

	if (pItemInfo != NULL && pItemInfo->pParentFolder != NULL)
	{
		ASSERT (pItemInfo->pidlRel != NULL);
		hr = pItemInfo->pParentFolder->BindToObject(pItemInfo->pidlRel, NULL, IID_IShellFolder, (LPVOID*)&m_psfCurFolder);

		m_bIsDesktop = FALSE;
	}
	else
	{
		hr = SHGetDesktopFolder (&m_psfCurFolder);
		m_bIsDesktop = TRUE;
	}

	if (SUCCEEDED (hr))
	{
		m_pidlCurFQ = g_pShellManager->CopyItem (pItemInfo->pidlFQ);
	}

	return hr;
}
//***************************************************************************************
HRESULT CBCGPShellList::DisplayFolder (LPBCGCBITEMINFO pItemInfo)
{
	HRESULT hr = E_FAIL;

	if (g_pShellManager == NULL)
	{
		ASSERT (FALSE);
		return hr;
	}

	if (pItemInfo != NULL)
	{
		ReleaseCurrFolder();
		hr = LockCurrentFolder(pItemInfo);

		if (FAILED(hr))
		{
			return hr;
		}
	}
	
	DeleteAllItems ();
	
	if (m_psfCurFolder != NULL)
	{
		CWaitCursor wait;
		SetRedraw (FALSE);
		
		hr = EnumObjects (m_psfCurFolder, m_pidlCurFQ);

		if (GetStyle () & LVS_REPORT)
		{
			Sort (BCGPShellList_ColumnName);
		}

		SetRedraw (TRUE);
		RedrawWindow ();
	}

	if (SUCCEEDED (hr) && pItemInfo != NULL)
	{
		CBCGPShellTree* pTree = GetRelatedTree ();
		if (pTree != NULL && !m_bNoNotify)
		{
			ASSERT_VALID (pTree);
			pTree->SelectPath (m_pidlCurFQ);
		}

		if (GetParent () != NULL)
		{
			GetParent ()->SendMessage (BCGPM_CHANGE_CURRENT_FOLDER);
		}
	}

	return hr;
}
//***************************************************************************************
HRESULT CBCGPShellList::DisplayParentFolder ()
{
	ASSERT_VALID (g_pShellManager);

	HRESULT hr = E_FAIL;
	if (m_pidlCurFQ == NULL)
	{
		return hr;
	}

	BCGCBITEMINFO info;
	int nLevel = g_pShellManager->GetParentItem (m_pidlCurFQ, info.pidlFQ);

	if (nLevel < 0)
	{
		return hr;
	}

	if (nLevel == 0)	// Desktop
	{
		hr = DisplayFolder (&info);
	}
	else
	{
		LPSHELLFOLDER pDesktopFolder;
		hr = SHGetDesktopFolder(&pDesktopFolder);

		if (SUCCEEDED (hr))
		{
			info.pParentFolder = pDesktopFolder;
			info.pidlRel = info.pidlFQ;

			hr = DisplayFolder (&info);
			pDesktopFolder->Release();
		}
	}

	g_pShellManager->FreeItem (info.pidlFQ);
	return hr;
}
//***************************************************************************************
HRESULT CBCGPShellList::DisplayFolder (LPCTSTR lpszPath)
{
	if (g_pShellManager == NULL)
	{
		ASSERT (FALSE);
		return E_FAIL;
	}

	ASSERT (lpszPath != NULL);
	ASSERT_VALID (g_pShellManager);

	BCGCBITEMINFO info;
	HRESULT hr = g_pShellManager->ItemFromPath (lpszPath, info.pidlRel);

	if (FAILED (hr))
	{
		return hr;
	}

	LPSHELLFOLDER pDesktopFolder;
	hr = SHGetDesktopFolder(&pDesktopFolder);

	if (SUCCEEDED (hr))
	{
		info.pParentFolder = pDesktopFolder;
		info.pidlFQ = info.pidlRel;

		hr = DisplayFolder (&info);
		pDesktopFolder->Release();
	}

	g_pShellManager->FreeItem (info.pidlFQ);
	return hr;
}
//****************************************************************************************
HRESULT CBCGPShellList::Refresh ()
{
	return DisplayFolder ((LPBCGCBITEMINFO) NULL);
}
//***************************************************************************************
HRESULT CBCGPShellList::EnumObjects (LPSHELLFOLDER pParentFolder,
									LPITEMIDLIST pidlParent)
{
	ASSERT_VALID (this);
	ASSERT_VALID (g_pShellManager);

	LPENUMIDLIST pEnum;
	HRESULT hRes = pParentFolder->EnumObjects (NULL, m_nTypes, &pEnum);

	if (SUCCEEDED (hRes))
	{
		LPITEMIDLIST	pidlTemp;
		DWORD			dwFetched = 1;
		LPBCGCBITEMINFO pItem;
		
		//enumerate the item's PIDLs
		while (pEnum->Next(1, &pidlTemp, &dwFetched) == S_OK && dwFetched)
		{
			LVITEM lvItem;
			ZeroMemory(&lvItem, sizeof(lvItem));
			
			//fill in the TV_ITEM structure for this item
			lvItem.mask = LVIF_PARAM | LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
			
			//AddRef the parent folder so it's pointer stays valid
			pParentFolder->AddRef();
			
			//put the private information in the lParam
			pItem = (LPBCGCBITEMINFO)GlobalAlloc(GPTR, sizeof(BCGCBITEMINFO));
			
			pItem->pidlRel = pidlTemp;
			pItem->pidlFQ = g_pShellManager->ConcatenateItem (pidlParent, pidlTemp);
			
			pItem->pParentFolder = pParentFolder;
			lvItem.lParam = (LPARAM)pItem;
			
			lvItem.pszText = _T("");
			lvItem.iImage = OnGetItemIcon (GetItemCount (), pItem);
			
			//determine if the item is shared
			DWORD dwAttr = SFGAO_DISPLAYATTRMASK;
			pParentFolder->GetAttributesOf (1, (LPCITEMIDLIST*)&pidlTemp, &dwAttr);
			
			if (dwAttr & SFGAO_SHARE)
			{
				lvItem.mask |= LVIF_STATE;
				lvItem.stateMask |= LVIS_OVERLAYMASK;
				lvItem.state |= INDEXTOOVERLAYMASK(1); //1 is the index for the shared overlay image
			}
			
			if (dwAttr & SFGAO_GHOSTED)
			{
				lvItem.mask |= LVIF_STATE;
				lvItem.stateMask |= LVIS_CUT;
				lvItem.state |= LVIS_CUT;
			}
			
			int iItem = InsertItem (&lvItem);
			if (iItem >= 0)
			{
				//-------------
				// Set columns:
				//-------------
				const int nColumns = (GetStyle () & LVS_REPORT) ?
					m_wndHeader.GetItemCount () : 1;

				for (int iColumn = 0; iColumn < nColumns; iColumn++)
				{
					SetItemText (iItem, iColumn, 
								OnGetItemText (iItem, iColumn, pItem));
				}
			}

			dwFetched = 0;
		}
		
		pEnum->Release ();
	}

	return hRes;
}
//***************************************************************************************
void CBCGPShellList::DoDefault (int iItem)
{
	LVITEM lvItem;
	
	ZeroMemory(&lvItem, sizeof(lvItem));
	lvItem.mask = LVIF_PARAM;
	lvItem.iItem = iItem;
	
	if (!GetItem (&lvItem))
	{
		return;
	}

	LPBCGCBITEMINFO	pInfo = (LPBCGCBITEMINFO) lvItem.lParam;
	if (pInfo == NULL || pInfo->pParentFolder == NULL || pInfo->pidlRel == NULL)
	{
		ASSERT (FALSE);
		return;
	}

	IShellFolder *psfFolder = pInfo->pParentFolder;
	if (psfFolder == NULL)
	{
		SHGetDesktopFolder (&psfFolder);
	}
	else
	{
		psfFolder->AddRef ();
	}
	
	if (psfFolder == NULL)
	{
		return;
	}

	//-----------------------------------------------------
	// If specified element is a folder, try to display it:
	//-----------------------------------------------------
	ULONG ulAttrs = SFGAO_FOLDER;
	psfFolder->GetAttributesOf (1, 
		(const struct _ITEMIDLIST **) &pInfo->pidlRel, &ulAttrs);

	if (ulAttrs & SFGAO_FOLDER)
	{
		DisplayFolder (pInfo);
	}
	else
	{
		//-------------------------------
		// Invoke a default menu command:
		//-------------------------------
		IContextMenu *pcm;
		HRESULT hr = psfFolder->GetUIObjectOf (GetSafeHwnd (),
			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_DEFAULTONLY | CMF_EXPLORE);
				
				if (SUCCEEDED (hr))
				{
					UINT idCmd = ::GetMenuDefaultItem (hPopup, FALSE, 0);
					if (idCmd != 0 && idCmd != (UINT)-1)
					{
						CMINVOKECOMMANDINFO cmi;
						cmi.cbSize = sizeof (CMINVOKECOMMANDINFO);
						cmi.fMask = 0;
						cmi.hwnd = GetParent()->GetSafeHwnd ();
						cmi.lpVerb = (LPCSTR)(INT_PTR)(idCmd - 1);
						cmi.lpParameters = NULL;
						cmi.lpDirectory = NULL;
						cmi.nShow = SW_SHOWNORMAL;
						cmi.dwHotKey = 0;
						cmi.hIcon = NULL;

						hr = pcm->InvokeCommand (&cmi);
					}
				}
			}
			
			pcm->Release ();
		}
	}
	
	psfFolder->Release ();
}
//***************************************************************************************
void CBCGPShellList::OnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult) 
{
	ASSERT_VALID (g_pShellManager);

	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	LPBCGCBITEMINFO	pItem = (LPBCGCBITEMINFO)pNMListView->lParam;
	
	//free up the pidls that we allocated
	g_pShellManager->FreeItem (pItem->pidlFQ);
	g_pShellManager->FreeItem (pItem->pidlRel);
	
	//this may be NULL if this is the root item
	if (pItem->pParentFolder != NULL)
	{
		pItem->pParentFolder->Release ();
		pItem->pParentFolder = NULL;
	}

	GlobalFree ((HGLOBAL) pItem);

	*pResult = 0;
}
//*****************************************************************************************
void CBCGPShellList::OnDblclk(NMHDR* /*pNMHDR*/, LRESULT* pResult) 
{
	int nItem = GetNextItem(-1, LVNI_FOCUSED);
	if (nItem != -1)
	{
		DoDefault (nItem);
	}
	
	*pResult = 0;
}
//****************************************************************************************
void CBCGPShellList::OnReturn(NMHDR* /*pNMHDR*/, LRESULT* pResult) 
{
	int nItem = GetNextItem(-1, LVNI_FOCUSED);
	if (nItem != -1)
	{
		DoDefault(nItem);
	}
	
	*pResult = 0;
}
//***************************************************************************************
BOOL CBCGPShellList::GetItemPath (CString& strPath, int iItem) const
{
	ASSERT_VALID (this);

	strPath.Empty ();

	LPBCGCBITEMINFO pItem = (LPBCGCBITEMINFO) GetItemData (iItem);
	if (pItem == NULL || pItem->pidlFQ == NULL)
	{
		return FALSE;
	}

	TCHAR szPath [MAX_PATH];
	if (!SHGetPathFromIDList (pItem->pidlFQ, szPath))
	{
		return FALSE;
	}

	strPath = szPath;
	return TRUE;
}
//***************************************************************************************
BOOL CBCGPShellList::GetCurrentFolder (CString& strPath) const
{
	ASSERT_VALID (this);

	strPath.Empty ();

	if (m_pidlCurFQ == NULL)
	{
		return FALSE;
	}

	TCHAR szPath [MAX_PATH];
	if (!SHGetPathFromIDList (m_pidlCurFQ, szPath))
	{
		return FALSE;
	}

	strPath = szPath;
	return TRUE;
}
//***************************************************************************************
BOOL CBCGPShellList::GetCurrentFolderName (CString& strName) const
{
	ASSERT_VALID (this);

	strName.Empty ();

	if (m_pidlCurFQ == NULL)
	{
		return FALSE;
	}

	SHFILEINFO	sfi;
	if (!SHGetFileInfo((LPCTSTR)m_pidlCurFQ, 0, &sfi, sizeof(sfi), SHGFI_PIDL | SHGFI_DISPLAYNAME))
	{
		return FALSE;
	}

	strName = sfi.szDisplayName;
	return TRUE;
}
//****************************************************************************************
CString CBCGPShellList::OnGetItemText (int /*iItem*/, int iColumn, 
									  LPBCGCBITEMINFO pItem)
{
	ASSERT_VALID (this);
	ASSERT (pItem != NULL);

	SHFILEINFO	sfi;
	TCHAR		szPath [MAX_PATH];

	switch (iColumn)
	{
	case BCGPShellList_ColumnName:
		if (SHGetFileInfo((LPCTSTR)pItem->pidlFQ, 0, &sfi, sizeof(sfi), SHGFI_PIDL | SHGFI_DISPLAYNAME))
		{
			return sfi.szDisplayName;
		}
		break;
		
	case BCGPShellList_ColumnType:
		if (SHGetFileInfo((LPCTSTR)pItem->pidlFQ, 0, &sfi, sizeof(sfi), SHGFI_PIDL | SHGFI_TYPENAME))

⌨️ 快捷键说明

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