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

📄 shellpidl.cpp

📁 一个完整的编辑器的代码(很值得参考
💻 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 in EditPad");
                  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 + -