?? shellpidl.cpp
字號:
#include "stdafx.h"
#include "..\\resource.h"
#include "shellpidl.h"
#include "wm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#pragma warning ( disable : 4711 )
////////////////////////////////////////////////////////////////////////////////
//
// This source is part of CShellTree - Selom Ofori
//
//
// FUNCTIONS THAT DEAL WITH PIDLs
//
/****************************************************************************
*
* FUNCTION: Next(LPCITEMIDLIST pidl)
*
* PURPOSE: Gets the next PIDL in the list
*
****************************************************************************/
LPITEMIDLIST CShellPidl::
Next (LPCITEMIDLIST pidl)
{
LPTSTR lpMem = (LPTSTR) pidl;
lpMem += pidl->mkid.cb;
return (LPITEMIDLIST) lpMem;
}
/****************************************************************************
*
* FUNCTION: GetSize(LPCITEMIDLIST pidl)
*
* PURPOSE: Gets the size of the PIDL
*
****************************************************************************/
UINT CShellPidl::
GetSize (LPCITEMIDLIST pidl)
{
UINT cbTotal = 0;
if (pidl)
{
cbTotal += sizeof (pidl->mkid.cb); // Null terminator
while (pidl->mkid.cb)
{
cbTotal += pidl->mkid.cb;
pidl = Next (pidl);
}
}
return cbTotal;
}
/****************************************************************************
*
* FUNCTION: CreatePidl(UINT cbSize)
*
* PURPOSE: Allocates a PIDL
*
****************************************************************************/
LPITEMIDLIST CShellPidl::
CreatePidl (UINT cbSize)
{
LPMALLOC lpMalloc;
HRESULT hr;
LPITEMIDLIST pidl = NULL;
hr = SHGetMalloc (&lpMalloc);
if (FAILED (hr))
return 0;
pidl = (LPITEMIDLIST) lpMalloc->Alloc (cbSize);
if (pidl)
memset (pidl, 0, cbSize); // zero-init for external task alloc
if (lpMalloc)
lpMalloc->Release ();
return pidl;
}
/****************************************************************************
*
* FUNCTION: ConcatPidls(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
*
* PURPOSE: Concatenates two PIDLs
*
****************************************************************************/
LPITEMIDLIST CShellPidl::
ConcatPidls (LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
{
LPITEMIDLIST pidlNew;
UINT cb1;
UINT cb2;
if (pidl1) //May be NULL
cb1 = GetSize (pidl1) - sizeof (pidl1->mkid.cb);
else
cb1 = 0;
cb2 = GetSize (pidl2);
pidlNew = CreatePidl (cb1 + cb2);
if (pidlNew)
{
if (pidl1)
memcpy (pidlNew, pidl1, cb1);
memcpy (((LPTSTR) pidlNew) + cb1, pidl2, cb2);
}
return pidlNew;
}
/****************************************************************************
*
* FUNCTION: CopyITEMID(LPMALLOC lpMalloc, LPITEMIDLIST lpi)
*
* PURPOSE: Copies the ITEMID
*
****************************************************************************/
LPITEMIDLIST CShellPidl::
CopyITEMID (LPMALLOC lpMalloc, LPITEMIDLIST lpi)
{
LPITEMIDLIST lpiTemp;
lpiTemp = (LPITEMIDLIST) lpMalloc->Alloc (lpi->mkid.cb + sizeof (lpi->mkid.cb));
CopyMemory ((PVOID) lpiTemp, (CONST VOID *) lpi, lpi->mkid.cb + sizeof (lpi->mkid.cb));
return lpiTemp;
}
/****************************************************************************
*
* FUNCTION: GetName(LPSHELLFOLDER lpsf,LPITEMIDLIST lpi,DWORD dwFlags,
* LPTSTR lpFriendlyName)
*
* PURPOSE: Gets the friendly name for the folder
*
****************************************************************************/
BOOL CShellPidl::
GetName (LPSHELLFOLDER lpsf,
LPITEMIDLIST lpi,
DWORD dwFlags,
LPTSTR lpFriendlyName)
{
BOOL bSuccess = TRUE;
STRRET str;
if (NOERROR == lpsf->GetDisplayNameOf (lpi, dwFlags, &str))
{
switch (str.uType)
{
case STRRET_WSTR:
#ifdef _UNICODE
_tcscpy (lpFriendlyName, (LPTSTR) str.cStr);
#else // _UNICODE
WideCharToMultiByte (CP_ACP, // CodePage
0, // dwFlags
str.pOleStr, // lpWideCharStr
-1, // cchWideChar
lpFriendlyName, // lpMultiByteStr
MAX_PATH,
//sizeof(lpFriendlyName), // cchMultiByte, wrong. sizeof on a pointer, psk, psk
NULL, // lpDefaultChar,
NULL); // lpUsedDefaultChar
#endif // _UNICODE
break;
case STRRET_OFFSET:
_tcscpy (lpFriendlyName, (LPTSTR) lpi + str.uOffset);
break;
case STRRET_CSTR:
_tcscpy (lpFriendlyName, (LPTSTR) str.cStr);
break;
default:
bSuccess = FALSE;
break;
}
}
else
bSuccess = FALSE;
return bSuccess;
}
/****************************************************************************
*
* FUNCTION: GetFullyQualPidl(LPSHELLFOLDER lpsf, LPITEMIDLIST lpi)
*
* PURPOSE: Gets the Fully qualified Pidls for the folder
*
****************************************************************************/
LPITEMIDLIST CShellPidl::
GetFullyQualPidl (LPSHELLFOLDER lpsf, LPITEMIDLIST lpi)
{
TCHAR szBuff[MAX_PATH];
OLECHAR szOleChar[MAX_PATH];
LPSHELLFOLDER lpsfDeskTop;
LPITEMIDLIST lpifq;
ULONG ulEaten, ulAttribs;
HRESULT hr;
if (!GetName (lpsf, lpi, SHGDN_FORPARSING, szBuff))
return NULL;
hr = SHGetDesktopFolder (&lpsfDeskTop);
if (FAILED (hr))
return NULL;
#ifdef _UNICODE
_tcscpy (szOleChar, szBuff);
#else // _UNICODE
MultiByteToWideChar (CP_ACP,
MB_PRECOMPOSED,
szBuff,
-1,
(USHORT *) szOleChar,
sizeof (szOleChar));
#endif // _UNICODE
hr = lpsfDeskTop->ParseDisplayName (NULL,
NULL,
szOleChar,
&ulEaten,
&lpifq,
&ulAttribs);
lpsfDeskTop->Release ();
if (FAILED (hr))
return NULL;
return lpifq;
}
/****************************************************************************
*
* FUNCTION: DoTheMenuThing(HWND hwnd,
* LPSHELLFOLDER lpsfParent,
* LPITEMIDLIST lpi,
* LPPOINT lppt)
*
* PURPOSE: Displays a popup context menu, given a parent shell folder,
* relative item id and screen location.
*
* PARAMETERS:
* hwnd - Parent window handle
* lpsfParent - Pointer to parent shell folder.
* lpi - Pointer to item id that is relative to lpsfParent
* lppt - Screen location of where to popup the menu.
*
* RETURN VALUE:
* Returns TRUE on success, FALSE on failure
*
****************************************************************************/
BOOL CShellPidl::DoTheMenuThing (HWND hwnd, LPSHELLFOLDER lpsfParent,
LPITEMIDLIST lpi, LPPOINT lppt)
{
LPCONTEXTMENU lpcm;
HRESULT hr;
TCHAR szTemp[64];
CMINVOKECOMMANDINFO cmi;
DWORD dwAttribs = 0;
int idCmd;
HMENU hMenu;
BOOL bSuccess = TRUE;
hr = lpsfParent->GetUIObjectOf (hwnd,
1, //Number of objects to get attributes of
(const struct _ITEMIDLIST **) &lpi,
IID_IContextMenu,
0,
(LPVOID *) & lpcm);
if (SUCCEEDED (hr)){
hMenu = CreatePopupMenu ();
if (hMenu){
hr = lpcm->QueryContextMenu (hMenu, 0, 1, 0x7fff, CMF_EXPLORE);
if (SUCCEEDED (hr)){
ULONG ulAttrs = SFGAO_HASSUBFOLDER|SFGAO_FOLDER;
// Determine what type of object we have.
lpsfParent->GetAttributesOf(1,(const struct _ITEMIDLIST **)&lpi,&ulAttrs);
if (!(ulAttrs & SFGAO_FOLDER )){
MENUITEMINFO minfo;
minfo.cbSize = sizeof (minfo);
minfo.fMask = MIIM_TYPE;
minfo.fType = MFT_SEPARATOR;
::InsertMenuItem (hMenu, 0, MF_BYPOSITION, &minfo);
minfo.fMask = MIIM_TYPE|MIIM_ID;
minfo.wID = ID_OPEN_HERE;
minfo.fType = MFT_STRING;
minfo.dwTypeData = _T ("&Open here");
minfo.cch = 17;
::InsertMenuItem (hMenu, 0, MF_BYPOSITION, &minfo);
}
idCmd = TrackPopupMenu (hMenu,
TPM_LEFTALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON,
lppt->x, lppt->y, 0, hwnd, NULL);
if (idCmd == ID_OPEN_HERE){
TCHAR szPath[_MAX_PATH];
if (GetName (lpsfParent, lpi, SHGDN_NORMAL|SHGDN_FORPARSING, szPath))
AfxGetMainWnd ()->SendMessage (WM_OPEN_HERE, 0, (LPARAM) szPath);
}
else if (idCmd){
USES_CONVERSION;
cmi.cbSize = sizeof (CMINVOKECOMMANDINFO);
cmi.fMask = 0;
cmi.hwnd = hwnd;
cmi.lpVerb = T2A (MAKEINTRESOURCE (idCmd - 1));
cmi.lpParameters = NULL;
cmi.lpDirectory = NULL;
cmi.nShow = SW_SHOWNORMAL;
cmi.dwHotKey = 0;
cmi.hIcon = NULL;
hr = lpcm->InvokeCommand (&cmi);
if (!SUCCEEDED (hr)){
_stprintf (szTemp, _T ("InvokeCommand failed. hr=%lx"), hr);
AfxMessageBox (szTemp);
}
}
}
else{
bSuccess = FALSE;
}
DestroyMenu (hMenu);
}
else{
bSuccess = FALSE;
}
lpcm->Release ();
}
else{
_stprintf (szTemp, _T ("GetUIObjectOf failed! hr=%lx"), hr);
AfxMessageBox (szTemp);
bSuccess = FALSE;
}
return bSuccess;
}
/****************************************************************************
*
* FUNCTION: GetIcon(LPITEMIDLIST lpi, UINT uFlags)
*
* PURPOSE: Gets the index for the current icon. Index is index into system
* image list.
*
* PARAMETERS:
* lpi - Fully qualified item id list for current item.
* uFlags - Flags for SHGetFileInfo()
*
* RETURN VALUE:
* Icon index for current item.
****************************************************************************/
int CShellPidl::GetItemIcon (LPITEMIDLIST lpi, UINT uFlags)
{
SHFILEINFO sfi;
SHGetFileInfo ((LPCTSTR) lpi,
0,
&sfi,
sizeof (SHFILEINFO),
uFlags);
return sfi.iIcon;
}
////////////////////////////////////////////////////////////////////////////////
#pragma warning ( default : 4711 )
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -