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

📄 pidlmgr.cpp

📁 Windows资源浏览器外壳扩展右键菜单功能的实例程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

  Copyright 1997 Microsoft Corporation.  All Rights Reserved.
**************************************************************************/

/**************************************************************************

  File:          PidlMgr.cpp
  
	Description:   Implements CPidlMgr.
	
**************************************************************************/

/**************************************************************************
#include statements
**************************************************************************/
#include "stdafx.h"
#include "PidlMgr.h"
#include "resource.h"

/**************************************************************************

  CPidlMgr::CPidlMgr
  
**************************************************************************/
DWORD GetRootKeyText(HKEY hKeyRoot, LPTSTR lpszOut, DWORD dwOutSize)
{
lstrcpyn(lpszOut, TEXT("服务器根目录"), dwOutSize);
return 10 + 1 ; 
}
BOOL AddBackslash(LPTSTR lpszString)
{
if(*lpszString && *(lpszString + lstrlen(lpszString) - 1) != '\\')
   {
   lstrcat(lpszString, TEXT("\\"));
   return TRUE;
   }
return FALSE;
}

CPidlMgr::CPidlMgr()
{
	//get the shell's IMalloc pointer
	//we'll keep this until we get destroyed
	if(FAILED(SHGetMalloc(&m_pMalloc)))
	{
		delete this;
	}
	
	g_DllRefCount++;
}

/**************************************************************************

  CPidlMgr::~CPidlMgr
  
**************************************************************************/

CPidlMgr::~CPidlMgr()
{
	if(m_pMalloc)
		m_pMalloc->Release();
	
	g_DllRefCount--;
}

/**************************************************************************

  CPidlMgr::Create(DWORD, LPVOID, DWORD)
  
	Creates a new PIDL
	
**************************************************************************/

LPITEMIDLIST CPidlMgr::Create(PIDLTYPE type, LPVOID pIn, USHORT uInSize)
{
	LPITEMIDLIST   pidlOut;
	USHORT         uSize;
	
	pidlOut = NULL;
	
	/*
	Calculate the size. This consists of the ITEMIDLIST, the PIDL structure plus 
	the size of the data. We subtract the size of an HKEY because that is included 
	in uInSize.
	*/
	uSize = sizeof(ITEMIDLIST) + (sizeof(PIDLDATA) - sizeof(HKEY)) + uInSize;
	
	/*
	Allocate the memory, adding an additional ITEMIDLIST for the NULL terminating 
	ID List.
	*/
	pidlOut = (LPITEMIDLIST)m_pMalloc->Alloc(uSize + sizeof(ITEMIDLIST));
	
	if(pidlOut)
	{
		LPITEMIDLIST   pidlTemp = pidlOut;
		LPPIDLDATA     pData;
		
		//set the size of this item
		pidlTemp->mkid.cb = uSize;
		
		//set the data for this item
		pData = GetDataPointer(pidlTemp);
		pData->type = type;
		switch(type)
		{
		case PT_ROOTKEY:
			pData->hRootKey = *(HKEY*)pIn;
			break;
			
		case PT_SUBKEY:
		case PT_VALUE:
			CopyMemory(pData->szText, pIn, uInSize);
			break;
		}
		
		//set the NULL terminator to 0
		pidlTemp = GetNextItem(pidlTemp);
		pidlTemp->mkid.cb = 0;
		pidlTemp->mkid.abID[0] = 0;
	}
	
	return pidlOut;
}

/**************************************************************************

  CPidlMgr::Delete(HKEY)
  
	Deletes a PIDL
	
**************************************************************************/

void CPidlMgr::Delete(LPITEMIDLIST pidl)
{
	m_pMalloc->Free(pidl);
}

/**************************************************************************

  CPidlMgr::CreateRootKey()
  
	Creates a root key PIDL
	
**************************************************************************/

LPITEMIDLIST CPidlMgr::CreateRootKey(HKEY hKeyRoot)
{
	return Create(PT_ROOTKEY, (LPVOID)&hKeyRoot, sizeof(hKeyRoot));
}

/**************************************************************************

  CPidlMgr::CreateSubKey()
  
	Creates a sub key PIDL
	
**************************************************************************/

LPITEMIDLIST CPidlMgr::CreateSubKey(LPCTSTR lpszNew)
{
	return Create(PT_SUBKEY, (LPVOID)lpszNew, (lstrlen(lpszNew) + 1) * sizeof(TCHAR));
}

/**************************************************************************

  CPidlMgr::CreateValue()
  
	Creates a value PIDL
	
**************************************************************************/

LPITEMIDLIST CPidlMgr::CreateValue(LPCTSTR lpszNew)
{
	return Create(PT_VALUE, (LPVOID)lpszNew, (lstrlen(lpszNew) + 1) * sizeof(TCHAR));
}

/**************************************************************************

  CPidlMgr::GetNextItem()
  
**************************************************************************/

LPITEMIDLIST CPidlMgr::GetNextItem(LPCITEMIDLIST pidl)
{
	if(pidl)
		return (LPITEMIDLIST)(LPBYTE)(((LPBYTE)pidl) + pidl->mkid.cb);
	else
		return (NULL);
}

/**************************************************************************

  CPidlMgr::GetSize()
  
**************************************************************************/

UINT CPidlMgr::GetSize(LPCITEMIDLIST pidl)
{
	UINT cbTotal = 0;
	LPITEMIDLIST pidlTemp = (LPITEMIDLIST) pidl;
	
	if(pidlTemp)
	{
		while(pidlTemp->mkid.cb)
		{
			cbTotal += pidlTemp->mkid.cb;
			pidlTemp = GetNextItem(pidlTemp);
		}  
		
		//add the size of the NULL terminating ITEMIDLIST
		cbTotal += sizeof(ITEMIDLIST);
	}
	
	return (cbTotal);
}

/**************************************************************************

  CPidlMgr::GetData(PIDLTYPE, LPCITEMIDLIST, LPVOID, USHORT)
  
**************************************************************************/

DWORD CPidlMgr::GetData(PIDLTYPE type, LPCITEMIDLIST pidl, LPVOID pOut, USHORT uOutSize)
{
	if(!pidl)
		return 0;
	
	LPPIDLDATA  pData = GetDataPointer(pidl);
	DWORD       dwReturn = 0;
	
	//copy the data
	switch(type)
	{
	case PT_ROOTKEY:
		if(uOutSize < sizeof(HKEY))
			return 0;
		
		if(PT_ROOTKEY != pData->type)
			return 0;
		
		*(HKEY*)pOut = pData->hRootKey;
		dwReturn = sizeof(pData->hRootKey);
		break;
		
	case PT_SUBKEY:
	case PT_VALUE:
	case PT_TEXT:
		*(LPTSTR)pOut = 0;
		lstrcpyn((LPTSTR)pOut, pData->szText, uOutSize);
		dwReturn = lstrlen((LPTSTR)pOut);
		break;
	}
	
	return dwReturn;
}

/**************************************************************************

  CPidlMgr::GetRootKey()
  
**************************************************************************/

BOOL CPidlMgr::GetRootKey(LPCITEMIDLIST pidl, HKEY *phKeyRoot)
{
	return (BOOL)GetData(PT_ROOTKEY, pidl, (LPVOID)phKeyRoot, sizeof(HKEY));
}

/**************************************************************************

  CPidlMgr::GetLastItem()
  
	Gets the last item in the list
	
**************************************************************************/

LPITEMIDLIST CPidlMgr::GetLastItem(LPCITEMIDLIST pidl)
{
	LPITEMIDLIST   pidlLast = NULL;
	
	//get the PIDL of the last item in the list
	if(pidl)
	{
		while(pidl->mkid.cb)
		{
			pidlLast = (LPITEMIDLIST)pidl;
			pidl = GetNextItem(pidl);
		}  
	}
	
	return pidlLast;
}

/**************************************************************************

  CPidlMgr::GetItemText()
  
	Gets the text for only this item
	
**************************************************************************/

DWORD CPidlMgr::GetItemText(LPCITEMIDLIST pidl, LPTSTR lpszText, USHORT uSize)
{
	//if this is a root key, it needs to be handled specially
	if(IsRootKey(pidl))
	{
		HKEY  hKey;
		
		if(!GetRootKey(pidl, &hKey))
			return 0;
		return GetRootKeyText(hKey, lpszText, uSize);
	}
	
	return GetData(PT_TEXT, pidl, (LPVOID)lpszText, uSize);
}

/**************************************************************************

  CPidlMgr::GetSubKeyText()
  
	Creates a sub key string from a PIDL, filtering out the root key and 
	value, if either is present.
	
**************************************************************************/

DWORD CPidlMgr::GetSubKeyText(LPCITEMIDLIST pidl, LPTSTR lpszSubKey, DWORD dwSize)
{
	if(!pidl)
		return 0;
	
	LPITEMIDLIST   pidlTemp;
	DWORD          dwCopied = 0;
	
	/*
	This may be a list of items, so if the first item is a key rather than a 
	string, skip the first item because it contains the root key.
	*/
	if(IsRootKey(pidl))
		pidlTemp = GetNextItem(pidl);
	else
		pidlTemp = (LPITEMIDLIST)pidl;
	
	//if this is NULL, return the required size of the buffer
	if(!lpszSubKey)
	{
		while(pidlTemp->mkid.cb)
		{
			LPPIDLDATA  pData = GetDataPointer(pidlTemp);
			
			//add the length of this item plus one for the backslash
			dwCopied += lstrlen(pData->szText) + 1;
			
			pidlTemp = GetNextItem(pidlTemp);
		}
		
		//add one for the NULL terminator
		return dwCopied + 1;
	}
	
	*lpszSubKey = 0;
	
	while(pidlTemp->mkid.cb && (dwCopied < dwSize))
	{
		LPPIDLDATA  pData = GetDataPointer(pidlTemp);
		
		//if this item is a value, then skip it and finish
		if(PT_VALUE == pData->type)
			break;
		
		lstrcat(lpszSubKey, pData->szText);
		lstrcat(lpszSubKey, TEXT("\\"));
		
		dwCopied += lstrlen(pData->szText) + 1;
		
		pidlTemp = GetNextItem(pidlTemp);
	}
	
	//remove the last backslash if necessary
	if(dwCopied)
	{
		if(*(lpszSubKey + lstrlen(lpszSubKey) - 1) == '\\')
		{
			*(lpszSubKey + lstrlen(lpszSubKey) - 1) = 0;
			dwCopied--;
		}
	}
	
	return dwCopied;
}

/**************************************************************************

  CPidlMgr::GetValueText()
  
	Gets the text for the last item in the list
	
**************************************************************************/

DWORD CPidlMgr::GetValueText(LPCITEMIDLIST pidl, LPTSTR lpszValue, DWORD dwSize)
{
	if(!pidl)
		return 0;
	
	LPCITEMIDLIST  pidlTemp = pidl;
	TCHAR          szText[MAX_PATH];
	
	/*
	This may be a list of items, so search through the list looking for an item 
	that is a value. There should be only one, and it should be the last one, but 
	we will assume it can be anywhere and only copy the first one.
	*/
	while(pidlTemp->mkid.cb && !IsValue(pidlTemp))
	{
		pidlTemp = GetNextItem(pidlTemp);
	}
	
	//we didn't find a value pidl
	if(!pidlTemp->mkid.cb)
		return 0;
	
	//get the item's text
	GetItemText(pidlTemp, szText, sizeof(szText));
	
	//if this is NULL, return the required size of the buffer
	if(!lpszValue)
	{
		return lstrlen(szText) + 1;
	}
	
	lstrcpy(lpszValue, szText);
	
	return lstrlen(lpszValue);
}

/**************************************************************************

  CPidlMgr::Copy()
  
**************************************************************************/

LPITEMIDLIST CPidlMgr::Copy(LPCITEMIDLIST pidlSource)
{
	LPITEMIDLIST pidlTarget = NULL;
	UINT cbSource = 0;
	
	if(NULL == pidlSource)
		return (NULL);
	
	// Allocate the new pidl
	cbSource = GetSize(pidlSource);
	pidlTarget = (LPITEMIDLIST)m_pMalloc->Alloc(cbSource);
	if(!pidlTarget)
		return (NULL);
	
	// Copy the source to the target
	CopyMemory(pidlTarget, pidlSource, cbSource);
	
	return pidlTarget;
}

/**************************************************************************

  CPidlMgr::IsRootKey()
  
**************************************************************************/

BOOL CPidlMgr::IsRootKey(LPCITEMIDLIST pidl)
{
	LPPIDLDATA  pData = GetDataPointer(pidl);
	
	return (PT_ROOTKEY == pData->type);
}

/**************************************************************************

  CPidlMgr::IsSubKey()
  

⌨️ 快捷键说明

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