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

📄 shfolder.cpp

📁 This software performs code conversion of Chinese characters, including GB2312/GBK and BIG5. It a
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// shfolder.cpp

#include <windows.h>
#include <shlobj.h>
#include <stdlib.h>
#include <string.h>
#include "msc.h"
#include "shfolder.h"


#ifdef _WIN64
#define ua  __unaligned
#else
#define ua
#endif


static ITEMIDLIST *WINAPI ShOpenItemIdListInternal ( wchar_t *szPath ) ;
static HRESULT ShGetAttributesInternal ( const ITEMIDLIST *pItemIdList, SFGAOF *pSfGaof ) ;
static HRESULT ShBindToParent ( const ITEMIDLIST *pItemIdList, REFIID RefIid, void **ppObject, const ITEMIDLIST ua **pItemIdListLast ) ;
static ITEMIDLIST *ShILCombine ( const ITEMIDLIST *pBase, const ITEMIDLIST *pAdd ) ;
static const ITEMIDLIST ua *ShILFindLastID ( const ITEMIDLIST *pItemIdList ) ;
static size_t ShILGetSize ( const ITEMIDLIST *pItemIdList ) ;
static HRESULT StrretToBufA ( STRRET *pStrret, const ITEMIDLIST *pItemIdList, char *szBuffer, int nBufferSize ) ;
static HRESULT StrretToBufW ( STRRET *pStrret, const ITEMIDLIST *pItemIdList, wchar_t *szBuffer, int nBufferSize ) ;


// IMalloc
#define ShAlloc   CoTaskMemAlloc
#define ShFree    CoTaskMemFree


// This function is not supported in Win95
#ifndef NTFUNC_IMPORT_IMPLICITLY
#define SHGetPathFromIDListW SHGetPathFromIDListW_
#define ShellExecuteExW ShellExecuteExW_
typedef BOOL ( WINAPI *SHGETPATHFROMIDLISTW ) ( const ITEMIDLIST *pidl, LPWSTR pszPath ) ;
typedef BOOL ( WINAPI *SHELLEXECUTEEXW ) ( LPSHELLEXECUTEINFOW lpExecInfo ) ;
static HINSTANCE hShell32 ;
static SHGETPATHFROMIDLISTW SHGetPathFromIDListW ;
static SHELLEXECUTEEXW ShellExecuteExW ;
static int FreeLibraryOnDetach ( void ) ;
#endif



///////////////////////////////////
//    ITEMIDLIST 偺庢摼偲夝曻    //
///////////////////////////////////



// 僷僗柤偐傜 ITEMIDLIST 傪庢摼偡傞乮ANSI斉乯
// szPath 偵偼僼儖僷僗柤丄傑偨偼 GUID 柤 "::{GUID}" 傪巜掕
// 惉岟偟偨傜 ITEMIDLIST 偺億僀儞僞傪丄幐攕偟偨傜 NULL 傪曉偡
ITEMIDLIST *WINAPI ShOpenItemIdListA ( const char *szPath ) {

   wchar_t szPathTmp [ MAX_PATH ] ;
   if ( ! MultiByteToWideChar ( CP_ACP, 0, szPath, -1, szPathTmp, MAX_PATH ) ) return NULL ;

   return ShOpenItemIdListInternal ( szPathTmp ) ;
}



// 僷僗柤偐傜 ITEMIDLIST 傪庢摼偡傞乮UNICODE斉乯
// szPath 偵偼僼儖僷僗柤丄傑偨偼 GUID 柤 "::{GUID}" 傪巜掕
// 惉岟偟偨傜 ITEMIDLIST 偺億僀儞僞傪丄幐攕偟偨傜 NULL 傪曉偡
ITEMIDLIST *WINAPI ShOpenItemIdListW ( const wchar_t *szPath ) {

   wchar_t *szPathTmp = wcsdup_max ( szPath, MAX_LONG_PATH ) ;
   if ( ! szPathTmp ) return NULL ;

   ITEMIDLIST *pItemIdList = ShOpenItemIdListInternal ( szPathTmp ) ;

   free ( szPathTmp ) ;
   return pItemIdList ;
}



// ShOpenItemIdList 偺壓惪偗娭悢
// 惉岟偟偨傜 ITEMIDLIST 偺億僀儞僞傪丄幐攕偟偨傜 NULL 傪曉偡
static ITEMIDLIST *WINAPI ShOpenItemIdListInternal ( wchar_t *szPath ) {

   ITEMIDLIST *pItemIdList = NULL ;

   IShellFolder *pIShellFolder ;
   if ( SUCCEEDED ( SHGetDesktopFolder ( & pIShellFolder ) ) ) {
      pIShellFolder->ParseDisplayName ( NULL, NULL, szPath, NULL, & pItemIdList, NULL ) ;
      pIShellFolder->Release () ;
   }

   return pItemIdList ;
}



// 摿庩側僼僅儖僟乕偺 ITEMIDLIST 傪庢摼偡傞
// 惉岟偟偨傜 ITEMIDLIST 偺億僀儞僞傪丄幐攕偟偨傜 NULL 傪曉偡
ITEMIDLIST *WINAPI ShOpenSpecialItemIdList ( int nCsidl ) {

   ITEMIDLIST *pItemIdList ;

   if ( ! SUCCEEDED ( SHGetSpecialFolderLocation ( NULL, nCsidl, & pItemIdList ) ) ) pItemIdList = NULL ;

   return pItemIdList ;
}



// ITEMIDLIST 傪暵偠傞
// 惉岟偟偨傜 0 傪, 幐攕偟偨傜 0 埲奜傪曉偡
int WINAPI ShCloseItemIdList ( ITEMIDLIST *pItemIdList ) {

   ShFree ( pItemIdList ) ;

   return 0 ;
}



///////////////////////////////////
//       ITEMIDLIST 偺夝愅       //
///////////////////////////////////



// ITEMIDLIST 偐傜僷僗柤傪庢摼偡傞乮ANSI斉乯
// 惉岟偟偨傜 0 傪, 幐攕偟偨傜 0 埲奜傪曉偡
int WINAPI ShGetPathA ( const ITEMIDLIST *pItemIdList, char *szPath ) {

   *szPath = 0 ;
   int nRetValue = 1 ;

   if ( SHGetPathFromIDListA ( pItemIdList, szPath ) ) nRetValue = 0 ;

   return nRetValue ;
}



// ITEMIDLIST 偐傜僷僗柤傪庢摼偡傞乮UNICODE斉乯
// 惉岟偟偨傜 0 傪, 幐攕偟偨傜 0 埲奜傪曉偡
int WINAPI ShGetPathW ( const ITEMIDLIST *pItemIdList, wchar_t *szPath ) {

   *szPath = 0 ;
   int nRetValue = 1 ;

#ifndef NTFUNC_IMPORT_IMPLICITLY
   if ( ! hShell32 && ( hShell32 = LoadLibraryW ( L"SHELL32.DLL" ) ) ) FreeLibraryOnDetach () ;
   if ( GETPROCADDRESS ( hShell32, SHGETPATHFROMIDLISTW, SHGetPathFromIDListW ) ) return 1 ;
#endif

   if ( SHGetPathFromIDListW ( pItemIdList, szPath ) ) nRetValue = 0 ;

   return nRetValue ;
}



// ITEMIDLIST 偐傜昞帵柤傪庢摼偡傞乮ANSI斉乯
// 惉岟偟偨傜 0 傪, 幐攕偟偨傜 0 埲奜傪曉偡
int WINAPI ShGetDisplayNameA ( const ITEMIDLIST *pItemIdList, char *szName ) {

   *szName = 0 ;
   int nRetValue = 1 ;

   IShellFolder *pIShellFolder ;
   if ( SUCCEEDED ( ShBindToParent ( pItemIdList, IID_IShellFolder, (void**) & pIShellFolder, & pItemIdList ) ) ) {
      STRRET Strret ;
      if ( SUCCEEDED ( pIShellFolder->GetDisplayNameOf ( pItemIdList, SHGDN_INFOLDER, & Strret ) ) ) {
         if ( SUCCEEDED ( StrretToBufA ( & Strret, pItemIdList, szName, MAX_PATH ) ) ) nRetValue = 0 ;
      }
      pIShellFolder->Release () ;
   }

   return nRetValue ;
}



// ITEMIDLIST 偐傜昞帵柤傪庢摼偡傞乮UNICODE斉乯
// 惉岟偟偨傜 0 傪, 幐攕偟偨傜 0 埲奜傪曉偡
int WINAPI ShGetDisplayNameW ( const ITEMIDLIST *pItemIdList, wchar_t *szName ) {

   *szName = 0 ;
   int nRetValue = 1 ;

   IShellFolder *pIShellFolder ;
   if ( SUCCEEDED ( ShBindToParent ( pItemIdList, IID_IShellFolder, (void**) & pIShellFolder, & pItemIdList ) ) ) {
      STRRET Strret ;
      if ( SUCCEEDED ( pIShellFolder->GetDisplayNameOf ( pItemIdList, SHGDN_INFOLDER, & Strret ) ) ) {
         if ( SUCCEEDED ( StrretToBufW ( & Strret, pItemIdList, szName, MAX_PATH ) ) ) nRetValue = 0 ;
      }
      pIShellFolder->Release () ;
   }

   return nRetValue ;
}



// ITEMIDLIST 偐傜僷僗柤傑偨偼 GUID 柤傪庢摼偡傞乮ANSI斉乯
// 惉岟偟偨傜 0 傪, 幐攕偟偨傜 0 埲奜傪曉偡
int WINAPI ShGetNameForParsingA ( const ITEMIDLIST *pItemIdList, char *szName ) {

   *szName = 0 ;
   int nRetValue = 1 ;

   IShellFolder *pIShellFolder ;
   if ( SUCCEEDED ( ShBindToParent ( pItemIdList, IID_IShellFolder, (void**) & pIShellFolder, & pItemIdList ) ) ) {
      STRRET Strret ;
      if ( SUCCEEDED ( pIShellFolder->GetDisplayNameOf ( pItemIdList, SHGDN_FORPARSING, & Strret ) ) ) {
         if ( SUCCEEDED ( StrretToBufA ( & Strret, pItemIdList, szName, MAX_PATH ) ) ) nRetValue = 0 ;
      }
      pIShellFolder->Release () ;
   }

   return nRetValue ;
}



// ITEMIDLIST 偐傜僷僗柤傑偨偼 GUID 柤傪庢摼偡傞乮UNICODE斉乯
// 惉岟偟偨傜 0 傪, 幐攕偟偨傜 0 埲奜傪曉偡
int WINAPI ShGetNameForParsingW ( const ITEMIDLIST *pItemIdList, wchar_t *szName ) {

   *szName = 0 ;
   int nRetValue = 1 ;

   IShellFolder *pIShellFolder ;
   if ( SUCCEEDED ( ShBindToParent ( pItemIdList, IID_IShellFolder, (void**) & pIShellFolder, & pItemIdList ) ) ) {
      STRRET Strret ;
      if ( SUCCEEDED ( pIShellFolder->GetDisplayNameOf ( pItemIdList, SHGDN_FORPARSING, & Strret ) ) ) {
         if ( SUCCEEDED ( StrretToBufW ( & Strret, pItemIdList, szName, MAX_PATH ) ) ) nRetValue = 0 ;
      }
      pIShellFolder->Release () ;
   }

   return nRetValue ;
}



// ITEMIDLIST 偐傜懏惈傪庢摼偡傞
// 惉岟偟偨傜 懏惈乮SFGAOF乯傪, 幐攕偟偨傜 (unsigned long) -1 傪曉偡
SFGAOF WINAPI ShGetAttributes ( const ITEMIDLIST *pItemIdList ) {

   SFGAOF SfGaof ;

   if ( ! SUCCEEDED ( ShGetAttributesInternal ( pItemIdList, & SfGaof ) ) ) SfGaof = (SFGAOF) -1 ;

   return SfGaof ;
}



// ITEMIDLIST 偐傜 CSIDL 傪庢摼偡傞
// 惉岟偟偨傜 CSIDL 傪丄幐攕偟偨傜晧悢傪曉偡
int WINAPI ShGetCsidl ( const ITEMIDLIST *pItemIdList ) {

   int nRetValue = -1 ;

   IShellFolder *pIShellFolder ;
   if ( SUCCEEDED ( SHGetDesktopFolder ( & pIShellFolder ) ) ) {

      for ( int nCsidl = CSIDL_DESKTOP ; nCsidl <= CSIDL_MAX ; nCsidl ++ ) {
         ITEMIDLIST *pItemIdListTmp = ShOpenSpecialItemIdList ( nCsidl ) ;
         if ( pItemIdListTmp ) {
            HRESULT hResult = pIShellFolder->CompareIDs ( 0, pItemIdList, pItemIdListTmp ) ;
            if ( SUCCEEDED ( hResult ) && ! (short) HRESULT_CODE ( hResult ) ) {
               nRetValue = nCsidl ;
               break ;
            }
            ShCloseItemIdList ( pItemIdListTmp ) ;
         }
      }

      pIShellFolder->Release () ;
   }

   return nRetValue ;
}



// 擇偮偺 ITEMIDLIST 傪斾妑
// pIsError 偼 NULL 偱傕壜
// 惉岟偟偨傜 pIsError 偵 0 傪僙僢僩偟丄斾妑寢壥傪曉偡
// 幐攕偟偨傜 pIsError 偵 0 埲奜傪僙僢僩偡傞
int WINAPI ShCompareItemIdList ( const ITEMIDLIST *pItemIdList1, const ITEMIDLIST *pItemIdList2, int *pIsError ) {

   HRESULT hResult = E_FAIL ;

   IShellFolder *pIShellFolder ;
   if ( SUCCEEDED ( SHGetDesktopFolder ( & pIShellFolder ) ) ) {
      hResult = pIShellFolder->CompareIDs ( 0, pItemIdList1, pItemIdList2 ) ;
      pIShellFolder->Release () ;
   }

   if ( pIsError ) *pIsError = ! SUCCEEDED ( hResult ) ;

   return (short) HRESULT_CODE ( hResult ) ;
}



///////////////////////////////////
//       ITEMIDLIST 偺楍嫇       //
///////////////////////////////////



// 僼僅儖僟偺 ITEMIDLIST 偐傜 巕 ITEMIDLIST 傪楍嫇
// 僐乕儖僶僢僋娭悢偑 0 傪曉偟偨傜丄楍嫇傪掆巭
//                    0 埲奜傪曉偟偨傜丄楍嫇傪宲懕
// 惉岟偟偨傜 0 傪, 幐攕偟偨傜 0 埲奜傪曉偡
int WINAPI ShEnumItemIdList ( const ITEMIDLIST *pItemIdList, int ( CALLBACK *CallbackProc ) ( ITEMIDLIST *pItemIdList, LPARAM lParam ), unsigned long dwFlags, LPARAM lParam ) {

   int nRetValue = 1 ;

   IShellFolder *pIShellFolder ;
   const ITEMIDLIST ua *pItemIdListLast ;

   if ( SUCCEEDED ( ShBindToParent ( pItemIdList, IID_IShellFolder, (void**) & pIShellFolder, & pItemIdListLast ) ) ) {

      IShellFolder *pIShellFolderSub ;
      if ( IsDesktopItemIdList ( pItemIdListLast ) ) pIShellFolderSub = pIShellFolder ;
      else if ( ! SUCCEEDED ( pIShellFolder->BindToObject ( pItemIdListLast, NULL, IID_IShellFolder, (void**) & pIShellFolderSub ) ) ) pIShellFolderSub = NULL ;

      if ( pIShellFolderSub ) {

         unsigned long dwEnumFlags = ( SHCONTF_FOLDERS | SHCONTF_NONFOLDERS ) ;
         if ( dwFlags & ENUMITEMIDLIST_FOLDER_ONLY ) dwEnumFlags &= ~ SHCONTF_NONFOLDERS ;
         if ( dwFlags & ENUMITEMIDLIST_FILE_ONLY ) dwEnumFlags &= ~ SHCONTF_FOLDERS ;
         if ( dwFlags & ENUMITEMIDLIST_HIDDEN ) dwEnumFlags |= SHCONTF_INCLUDEHIDDEN ;

         IEnumIDList *pIEnumIdList ;
         if ( SUCCEEDED ( pIShellFolderSub->EnumObjects ( NULL, dwEnumFlags, & pIEnumIdList ) ) ) {

            nRetValue = 0 ;

            ITEMIDLIST *pItemIdListSub ;
            unsigned long dwNumber ;
            while ( ! pIEnumIdList->Next ( 1, & pItemIdListSub, & dwNumber ) ) {

               ITEMIDLIST *pItemIdListSubFul = ShILCombine ( pItemIdList, pItemIdListSub ) ;
               ShCloseItemIdList ( pItemIdListSub ) ;
               if ( ! pItemIdListSubFul ) continue ;

               int nResut = CallbackProc ( pItemIdListSubFul, lParam ) ;

               if ( ! ( dwFlags & ENUMITEMIDLIST_CLOSE_BY_USER ) ) ShCloseItemIdList ( pItemIdListSubFul ) ;
               if ( ! nResut ) break ;
            }

            pIEnumIdList->Release () ;
         }

         if ( pIShellFolderSub != pIShellFolder ) pIShellFolderSub->Release () ;
      }

      pIShellFolder->Release () ;
   }

   return nRetValue ;
}



///////////////////////////////////
//       ITEMIDLIST 偺憖嶌       //
///////////////////////////////////



// 摿暿側僼僅儖僟柤傪奐偔乮ANSI斉乯
// 惉岟偟偨傜 0 傪, 幐攕偟偨傜 0 埲奜傪曉偡
int WINAPI ShExecuteA ( HWND hWnd, const char *szVerb, const ITEMIDLIST *pItemIdList, const char *szArguments, const char *szDirectory, int nShowCmd ) {

   size_t nLength = ShILGetSize ( pItemIdList ) ;
   ITEMIDLIST *pItemIdListTmp = (ITEMIDLIST*) malloc ( nLength ) ;
   if ( ! pItemIdListTmp ) return 1 ;
   memmove ( pItemIdListTmp, pItemIdList, nLength ) ;

   SHELLEXECUTEINFOA ShellExecuteInfo = { 0 } ;
   ShellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFOA) ;
   ShellExecuteInfo.hwnd = hWnd ;
   ShellExecuteInfo.lpVerb = szVerb ;
   ShellExecuteInfo.lpParameters = szArguments ;
   ShellExecuteInfo.lpDirectory = szDirectory ;
   ShellExecuteInfo.nShow = nShowCmd ;
   ShellExecuteInfo.fMask = SEE_MASK_INVOKEIDLIST | SEE_MASK_FLAG_NO_UI ;
   ShellExecuteInfo.lpIDList = pItemIdListTmp ;

   int nResult = ! ShellExecuteExA ( & ShellExecuteInfo ) ;

   free ( pItemIdListTmp ) ;
   return nResult ;
}



// 摿暿側僼僅儖僟柤傪奐偔乮UNICODE斉乯
// 惉岟偟偨傜 0 傪, 幐攕偟偨傜 0 埲奜傪曉偡
int WINAPI ShExecuteW ( HWND hWnd, const wchar_t *szVerb, const ITEMIDLIST *pItemIdList, const wchar_t *szArguments, const wchar_t *szDirectory, int nShowCmd ) {

#ifndef NTFUNC_IMPORT_IMPLICITLY
   if ( ! hShell32 && ( hShell32 = LoadLibraryW ( L"SHELL32.DLL" ) ) ) FreeLibraryOnDetach () ;
   if ( GETPROCADDRESS ( hShell32, SHELLEXECUTEEXW, ShellExecuteExW ) ) return 1 ;
#endif

   size_t nLength = ShILGetSize ( pItemIdList ) ;
   ITEMIDLIST *pItemIdListTmp = (ITEMIDLIST*) malloc ( nLength ) ;
   if ( ! pItemIdListTmp ) return 1 ;
   memmove ( pItemIdListTmp, pItemIdList, nLength ) ;

   SHELLEXECUTEINFOW ShellExecuteInfo = { 0 } ;
   ShellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFOW) ;
   ShellExecuteInfo.hwnd = hWnd ;
   ShellExecuteInfo.lpVerb = szVerb ;
   ShellExecuteInfo.lpParameters = szArguments ;
   ShellExecuteInfo.lpDirectory = szDirectory ;
   ShellExecuteInfo.nShow = nShowCmd ;
   ShellExecuteInfo.fMask = SEE_MASK_INVOKEIDLIST | SEE_MASK_FLAG_NO_UI ;
   ShellExecuteInfo.lpIDList = pItemIdListTmp ;

   int nResult = ! ShellExecuteExW ( & ShellExecuteInfo ) ;

   free ( pItemIdListTmp ) ;
   return nResult ;
}



///////////////////////////////////
//     ITEMIDLIST 峏怴偺捠抦     //
///////////////////////////////////



⌨️ 快捷键说明

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