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

📄 pidl.cpp

📁 大量windows shell编程例子
💻 CPP
字号:
/*****************************************************************
*
*  Project.....:  That crazy little thing called PIDL
*  Application.:  PIDL.exe
*  Module......:  PIDL.cpp
*  Description.:  Application main module
*  Compiler....:  MS Visual C++ 
*  Written by..:  D. Esposito
*  Environment.:  Windows 9x/NT
*
******************************************************************/

/*---------------------------------------------------------------*/
//                        PRAGMA section
/*---------------------------------------------------------------*/
// Force the linker to add the following libraries.
// In doing so we prevent the use of MFC classes.
#ifdef _MSC_VER

#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "gdi32.lib")
#pragma comment(lib, "shell32.lib")
#pragma comment(lib, "comctl32.lib")

#endif

/*---------------------------------------------------------------*/
//                        INCLUDE section
/*---------------------------------------------------------------*/
#include "Pidl.h"
#include <commctrl.h>
#include <shellapi.h>
#include <shlobj.h>
#include "resource.h"

/*---------------------------------------------------------------*/
//                        GLOBAL section
/*---------------------------------------------------------------*/
// Data
HICON g_hIconLarge;
HICON g_hIconSmall;
HIMAGELIST g_himl;

// Typedefs
typedef BOOL (CALLBACK *FOLDERCONTENTPROC)(LPCSTR, HICON, DWORD);

// Functions
void OnInitDialog(HWND);
void OnOK(HWND);
void DoSearchPath(HWND);
HRESULT SHPathToPidlEx(LPCTSTR, LPITEMIDLIST*, LPSHELLFOLDER);
void ClearUI(HWND);
void StrretToString(LPITEMIDLIST, LPSTRRET, LPSTR);
int SHEnumFolderContent(LPSHELLFOLDER, FOLDERCONTENTPROC, DWORD, LPITEMIDLIST*);
void DoEnumeratePidl(HWND);

// Callbacks
BOOL CALLBACK APP_DlgProc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK SearchText(LPCSTR, HICON, DWORD);
BOOL CALLBACK ShowFolderContent(LPCSTR, HICON, DWORD);


/*---------------------------------------------------------------*/
// Procedure....: WinMain()
// Description..: Entry point in any Windows program
// Input........: HINSTANCE, HINSTANCE, LPSTR, int
// Output.......: INT
/*---------------------------------------------------------------*/
int APIENTRY WinMain(
   HINSTANCE hInstance, HINSTANCE hPrevious, LPTSTR lpsz, int iCmd)
{
   // Save global data
   g_hIconLarge = static_cast<HICON>(LoadImage(hInstance, "APP_ICON", IMAGE_ICON,
      GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CXICON), 0));
   g_hIconSmall = static_cast<HICON>(LoadImage(hInstance, "APP_ICON", IMAGE_ICON,
      GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CXSMICON), 0));
   g_himl = 0;

   // Enable common controls
   INITCOMMONCONTROLSEX iccex;
   iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
   iccex.dwICC = ICC_WIN95_CLASSES;
   InitCommonControlsEx(&iccex);

   // Run main dialog
   BOOL b = DialogBox(hInstance, "DLG_MAIN", NULL, APP_DlgProc);

   // Exit
   DestroyIcon(g_hIconLarge);
   DestroyIcon(g_hIconSmall);
   return b;
}


/*---------------------------------------------------------------*/
// Procedure....: APP_DlgProc()
// Description..: Responds to all messages sent to the dialog
// Input........: HWND, UINT, WPARAM, LPARAM
// Output.......: BOOL
/*---------------------------------------------------------------*/
BOOL CALLBACK APP_DlgProc(HWND hDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
   switch(uiMsg)
   {
   case WM_INITDIALOG:
      OnInitDialog(hDlg);
      break;

   case WM_COMMAND:
      switch(wParam)
      {
      case IDC_SEARCHPATH:
         DoSearchPath(hDlg);
         return FALSE;

      case IDC_PIDLCONTENT:
         DoEnumeratePidl(hDlg);
         return FALSE;

      case IDCANCEL:
         EndDialog(hDlg, FALSE);
         return FALSE;
      }
      break;
   }

   return FALSE;
}


/*****************************************************************
*
*  Internals:
*    - OnOK()
*    - OnInitDialog()
*
******************************************************************/

/*---------------------------------------------------------------*/
// Procedure...: OnOK()
// Description.: Do something
// INPUT.......: HWND
// OUTPUT......: void
/*---------------------------------------------------------------*/
void OnOK(HWND hDlg)
{
   return;
}


/*---------------------------------------------------------------*/
// Procedure...: OnInitDialog()
// Description.: Initialize the dialog
// INPUT.......: HWND
// OUTPUT......: void
/*---------------------------------------------------------------*/
void OnInitDialog(HWND hDlg)
{
   // Set the icons (T/F as to Large/Small icon)
   SendMessage(hDlg, WM_SETICON, FALSE, reinterpret_cast<LPARAM>(g_hIconSmall));
   SendMessage(hDlg, WM_SETICON, TRUE, reinterpret_cast<LPARAM>(g_hIconLarge));

   // Fill the combo box
   HWND hwndCbo = GetDlgItem(hDlg, IDC_SPECIAL);
   int i = ComboBox_AddString(hwndCbo, "Control Panel");
   ComboBox_SetItemData(hwndCbo, i, CSIDL_CONTROLS);
   i = ComboBox_AddString(hwndCbo, "Favorites");
   ComboBox_SetItemData(hwndCbo, i, CSIDL_FAVORITES);
   i = ComboBox_AddString(hwndCbo, "Printers");
   ComboBox_SetItemData(hwndCbo, i, CSIDL_PRINTERS);
   i = ComboBox_AddString(hwndCbo, "Fonts");
   ComboBox_SetItemData(hwndCbo, i, CSIDL_FONTS);
   i = ComboBox_AddString(hwndCbo, "SendTo");
   ComboBox_SetItemData(hwndCbo, i, CSIDL_SENDTO);
   ComboBox_SetCurSel(hwndCbo, 0);
}


void DoSearchPath(HWND hDlg)
{
   LPITEMIDLIST pidl = NULL;
   LPSHELLFOLDER pFolder = NULL;
   LPSHELLFOLDER pSubFolder = NULL;

   // Get the memory allocator
   LPMALLOC pMalloc = NULL;
   SHGetMalloc(&pMalloc);

   // Get the name to search
   TCHAR szName[MAX_PATH] = {0};
   GetDlgItemText(hDlg, IDC_FOLDER, szName, MAX_PATH);

   // Get the IShellFolder interface for the desktop
   SHGetDesktopFolder(&pFolder);

   // Try to find a match under Desktop
   int iNumOfItems = SHEnumFolderContent(pFolder, NULL, 0, NULL);
   int rc = SHEnumFolderContent(
              pFolder, SearchText, reinterpret_cast<DWORD>(szName), &pidl);

   // If not found, try under My Computer
   if(rc == iNumOfItems)
   {
      // Bind to My Computer
      LPITEMIDLIST pidlMyComp;
      SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &pidlMyComp);
      pFolder->BindToObject(pidlMyComp, NULL, IID_IShellFolder,
                                   reinterpret_cast<LPVOID*>(&pSubFolder));

      // Free the pointer to the desktop folder
      pFolder->Release();
      pMalloc->Free(pidlMyComp);
      pFolder = pSubFolder;

      // Scan My Computer
      iNumOfItems = SHEnumFolderContent(pFolder, NULL, 0, NULL);
      rc = SHEnumFolderContent(
              pFolder, SearchText, reinterpret_cast<DWORD>(szName), &pidl);

      if(rc == iNumOfItems)
      {
         // Make the last attempt: is it a path name?
         HRESULT hr = SHPathToPidlEx(szName, &pidl, pFolder);
         if(FAILED(hr))
         {
            Msg("\"%s\" not found under Desktop or My Computer.", szName);
            pMalloc->Free(pidl);
            pFolder->Release();

            // Call a helper function to refresh the UI
            ClearUI(hDlg);
            return;
         }
      }
   }

   // If here, then:
   //   pidl points to the folder we need to bind to enumerate the content
   //   pFolder points to the IShellFolder of the pidl's parent folder

   // Bind to the subfolder we're searching for
   // pFolder can point to Desktop's or My Computer's IShellFolder
   pFolder->BindToObject(pidl, NULL, IID_IShellFolder,
                                   reinterpret_cast<LPVOID*>(&pSubFolder));

   // Refresh UI (empty list view, image list and the like)
   ClearUI(hDlg);

   // Enumerate the content of the folder in the listview
   HWND hwndListView = GetDlgItem(hDlg, IDC_LISTVIEW);
   SHEnumFolderContent(pSubFolder, ShowFolderContent,
                              reinterpret_cast<DWORD>(hwndListView), NULL);

   // Clean up
   pFolder->Release();
   pSubFolder->Release();
   pMalloc->Free(pidl);
   pMalloc->Release();
   return;
}


HRESULT SHPathToPidlEx(LPCTSTR szPath, LPITEMIDLIST* ppidl, LPSHELLFOLDER pFolder)
{
   OLECHAR wszPath[MAX_PATH] = {0};
   ULONG nCharsParsed = 0;
   LPSHELLFOLDER pShellFolder = NULL;
   BOOL bFreeOnExit = FALSE;

   MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szPath, -1, wszPath, MAX_PATH);

   // Use the desktop's IShellFolder by default
   if(pFolder == NULL)
   {
      SHGetDesktopFolder(&pShellFolder);
      bFreeOnExit = TRUE;
   }
   else
      pShellFolder = pFolder;

   HRESULT hr = pShellFolder->ParseDisplayName(NULL, NULL, wszPath, &nCharsParsed, ppidl, NULL);

   if(bFreeOnExit)
      pShellFolder->Release();

   return hr;
}


void ClearUI(HWND hDlg)
{
   HWND hwndListView = GetDlgItem(hDlg, IDC_LISTVIEW);
   ListView_DeleteAllItems(hwndListView);
   ImageList_RemoveAll(g_himl);
   SetDlgItemText(hDlg, IDC_FOUND, __TEXT("0 item(s) found."));
}


void StrretToString(LPITEMIDLIST pidl, LPSTRRET pStr, LPSTR pszBuf)
{
   lstrcpy(pszBuf, "");

   switch(pStr->uType)
   {
   case STRRET_WSTR:              // Unicode string
      WideCharToMultiByte(CP_ACP, 0, pStr->pOleStr, -1, pszBuf, MAX_PATH, NULL, NULL);
      break;

   case STRRET_OFFSET:            // Offset
      lstrcpy(pszBuf, reinterpret_cast<LPSTR>(pidl) + pStr->uOffset);
      break;

   case STRRET_CSTR:              // ANSI string
      lstrcpy(pszBuf, pStr->cStr);
      break;
   }
}


int SHEnumFolderContent(LPSHELLFOLDER pFolder, FOLDERCONTENTPROC pfn, DWORD dwData, LPITEMIDLIST* ppidl)
{
   int iNumOfItems = 0;

   // Enumerates the content
   LPENUMIDLIST pEnumIDList = NULL;
   pFolder->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &pEnumIDList);

   ULONG ulFetched = 0;
   LPITEMIDLIST pItem = NULL;
   while(NOERROR == pEnumIDList->Next(1, &pItem, &ulFetched))
   {
      STRRET sName;
      TCHAR szBuf[MAX_PATH] = {0};
      pFolder->GetDisplayNameOf(pItem, 0, &sName);
      StrretToString(pItem, &sName, szBuf);

      // Invoke callback
      if(pfn)
      {
         // Get the icon
         UINT u = 0;
         int iIconIndex = 0;
         HICON hIcon = NULL;
         HICON hIconSm = NULL;
         TCHAR szIconFile[MAX_PATH] = {0};
         LPEXTRACTICON pExtractIcon = NULL;

         pFolder->GetUIObjectOf(NULL, 1, const_cast<LPCITEMIDLIST*>(&pItem),
         IID_IExtractIcon, NULL, reinterpret_cast<LPVOID*>(&pExtractIcon));
         pExtractIcon->GetIconLocation(0, szIconFile, MAX_PATH, &iIconIndex, &u);
         pExtractIcon->Extract(szIconFile, iIconIndex, &hIcon, &hIconSm, MAKELONG(32, 16));
         pExtractIcon->Release();

         if(hIcon == NULL)
            ExtractIconEx(szIconFile, iIconIndex, &hIcon, NULL, 1);

         if(!pfn(szBuf, hIcon, dwData))
         {
            // Returns the current PIDL
            if(ppidl != NULL)
               *ppidl = pItem;
            break;
         }
      }
      ++iNumOfItems;
   }
   return iNumOfItems;
}


BOOL CALLBACK SearchText(LPCSTR pszItem, HICON hIcon, DWORD dwData)
{
   return static_cast<BOOL>(lstrcmpi(pszItem, reinterpret_cast<LPCSTR>(dwData)));
}


BOOL CALLBACK ShowFolderContent(LPCSTR pszItem, HICON hIcon, DWORD dwData)
{
   // Create the imagelist
   int iIconWidth = GetSystemMetrics(SM_CXICON);
   int iIconHeight = GetSystemMetrics(SM_CYICON);
   if(g_himl == NULL)
      g_himl = ImageList_Create(iIconWidth, iIconHeight, ILC_MASK, 1, 0);
   int iIconPos = ImageList_AddIcon(g_himl, hIcon);

   HWND hwndListView = reinterpret_cast<HWND>(dwData);
   ListView_SetImageList(hwndListView, g_himl, LVSIL_NORMAL);

   LV_ITEM lvi;
   ZeroMemory(&lvi, sizeof(LV_ITEM));
   lvi.mask = LVIF_TEXT | LVIF_IMAGE;
   lvi.pszText = const_cast<LPSTR>(pszItem);
   lvi.cchTextMax = lstrlen(pszItem);
   lvi.iImage = iIconPos;
   ListView_InsertItem(hwndListView, &lvi);

   // Update count
   TCHAR s[MAX_PATH] = {0};
   wsprintf(s, "%d item(s) found.", ListView_GetItemCount(hwndListView));
   SetDlgItemText(GetParent(hwndListView), IDC_FOUND, s);
   return TRUE;
}


void DoEnumeratePidl(HWND hDlg)
{
   LPITEMIDLIST pidl = NULL;

   // Get the special folder and its PIDL
   HWND hwndCbo = GetDlgItem(hDlg, IDC_SPECIAL);
   int i = ComboBox_GetCurSel(hwndCbo);
   int nFolder = ComboBox_GetItemData(hwndCbo, i);
   SHGetSpecialFolderLocation(NULL, nFolder, &pidl);

   // Get the IShellFolder interface
   LPSHELLFOLDER pFolder = NULL;
   SHGetDesktopFolder(&pFolder);

   // Bind to subfolder
   LPSHELLFOLDER pSubFolder = NULL;
   pFolder->BindToObject(pidl, NULL, IID_IShellFolder,
                                   reinterpret_cast<LPVOID*>(&pSubFolder));
   pFolder->Release();
   pFolder = pSubFolder;

   // Clear the program's UI
   ClearUI(hDlg);

   // Enumerate the content
   HWND hwndListView = GetDlgItem(hDlg, IDC_LISTVIEW);
   SHEnumFolderContent(pFolder, ShowFolderContent,
                              reinterpret_cast<DWORD>(hwndListView), NULL);

   // Clean up
   LPMALLOC pMalloc = NULL;
   SHGetMalloc(&pMalloc);
   pMalloc->Free(pidl);
   pMalloc->Release();
   pFolder->Release();
}

/*  End of file: Pidl.c  */

⌨️ 快捷键说明

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