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

📄 shellpidl.cpp

📁 CAN__组建现场总线系统设计技术(光盘)
💻 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 )

⌨️ 快捷键说明

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