|
Shell.h¶ó´Â ÇϳªÀÇ ÆÄÀϸ¸ »ç¿ëÇÏ¸é µË´Ï´Ù. ÇØ´ç ÆÄÀÏÀº ÷ºÎµÈ ÆÄÀÏ¿¡ Æ÷ÇԵǾî
ÀÖ½À´Ï´Ù.
SHBrowseForFolder¸¦ °£´ÜÇÏ°Ô È£ÃâÇØ¼ »ç¿ëÇϵµ·Ï µÇ¾î ÀÖ½À´Ï´Ù.
°£´ÜÇÑ »ç¿ë ¹æ¹ýÀº ´ÙÀ½°ú °°½À´Ï´Ù.
CString sPath = "c:\\temp"; //Ãʱ⠰æ·Î
if (CShell::BrowseForFolder(sPath, "Æú´õ ¼±ÅÃ:") != IDOK) return;
Ãʱ⠰æ·Î´Â ÁÖ¾îÁöÁö ¾Ê¾Æµµ µË´Ï´Ù. ¼±ÅÃµÈ °æ·Î´Â sPath¿¡ ´Ù½Ã ´ã°ÜÁ® ¿É´Ï´Ù.
³ª¸ÓÁö ±âº» ¿É¼Ç¿¡ ´ëÇØ¼´Â Çì´õ ÆÄÀÏÀ» Âü°íÇϽñ⠹ٶø´Ï´Ù.
÷ºÎµÈ ¿¹Á¦´Â Professional Visual C++ Windows Shell Programming¿¡µµ ³ª¿ÍÀÖ´Â
¿¹Á¦¿Í µ¿ÀÏÇÒ °ÍÀÔ´Ï´Ù. ´Ù¸£´Ù¸é MFC ÇüÅ·ΠµÇ¾î ÀÖÀ»»ÓÀÔ´Ï´Ù. ÀÌ ¿¹Á¦´Â
CShell Ŭ·¡½º¸¦ »ç¿ëÇϰí ÀÖ½À´Ï´Ù.
ÀÌ Çì´õ¿¡´Â ±× ¿Ü¿¡µµ ½©°ú °ü·ÃµÈ ¸î°¡Áö ÇÔ¼öµéÀÌ ´õ Æ÷ÇԵǾî ÀÖ½À´Ï´Ù. ±×¿¡
´ëÇÑ ¿¹Á¦´Â ¿À·¡Àü¿¡ ½áº»°Å¶ó ãÀ» ¼ö°¡ ¾ø³×¿ä..
´ÙÀ½Àº Çì´õÀÇ ³»¿ëÀÔ´Ï´Ù.
//#ifndef __SHELLBROWSE_H__20020531
//#define __SHELLBROWSE_H__20020531
#pragma once
#include "Shlobj.h"
typedef BOOL (CALLBACK *FOLDERCONTENTPROC)(LPCSTR, LPITEMIDLIST, DWORD);
class CShell {
public:
CShell() {}
//////////////////////////////////////////////////////////////////////////////////
// Function Name : BrowseForFolder
// Description : Æú´õ Ž»öÀ» Áö¿øÇÑ´Ù.
// Return type : static int (IDOK or IDCANCEL)
// Arguments :
// CString& sPath : Ãʱ⠰æ·Î & ¼±Åà °æ·Î
// CString sTitle : "Choose a folder:"¸¦ ´ëüÇÒ Á¦¸ñ
// HWND hParent : ºÎ¸ð ÇÚµé
// UINT uiFlag : ¼³Á¤ Ç÷¡±×
// LPITEMIDLIST pidlRoot:ÁöÁ¤ °æ·Î¸¦ ·çÆ®·Î »ï´Â´Ù.
// UINT uiSpecial : Ư¼ö Æú´õ¸¦ ·çÆ®·Î »ï´Â´Ù.pidlRootº¸´Ù ¿ì¼±ÇÑ´Ù.
//--------------------------------------------------------------------------------
// uiFlag Á¾·ù
// BIF_RETURNONLYSDIRS : ÆÄÀÏ ½Ã½ºÅÛ µð·ºÅ丮¸¦ ¼±ÅÃÇÒ °æ¿ì¿¡¸¸
// OK ¹öư Ȱ¼ºÈ
// BIF_DONTGOBELOWDOMAIN : ³×Æ®¿öÅ© Æú´õ´Â º¸¿©ÁÖÁö ¾Ê´Â´Ù.
// BIF_STATUSTEXT : ¶óº§À» Ȱ¼ºÈ ½ÃŲ´Ù.(¿©±â¼´Â Àüü °æ·Î Ãâ·Â)
// BIF_EDITBOX : Æú´õ¸¦ ¼öµ¿À¸·Î ¼±ÅÃÇÏ´Â ¿¡µðÅÍ ¹Ú½º »ç¿ë
// (½© ¹öÁ¯ 4.71ÀÌ»ó)
// BIF_VALIDATE : BIF_EDITBOXÀÇ º¸Ãæ ¿ªÇÒ.
// À߸øµÈ ÆÄÀÏÀ̳ª Æú´õ À̸§À» ¿¡µðÅ͹ڽº¿¡ ÀÔ·ÂÇÒ
// °æ¿ì ÅëÁö¸¦ ¹ÞÀ»¼ö ÀÖ´Ù.(½© ¹öÁ¯ 4.71ÀÌ»ó)
// BIF_BROWSEFORCOMPUTER : »ç¿ëÀÚ°¡ ÄÄÇ»ÅÍ À̸§¸¸ ¼±ÅÃÇÏ°Ô ÇÑ´Ù.
// BIF_BROWSEFORPRINTER : ÇÁ¸°ÅÍ À̸§¸¸ ¼±ÅÃÇÏ°Ô ÇÑ´Ù.
// BIF_BROWSEINCLUDEFILES : Æ®¸® ºä¿¡ ÆÄÀϱîÁö ³ªÅ¸³´Ù.
// ±× ¿Ü¿¡µµ ´ÙÀ½°ú °°Àº Ç÷¡±×°¡ Á¸ÀçÇÑ´Ù.(µµ¿ò¸» ÂüÁ¶)
// BIF_RETURNFSANCESTORS,
// BIF_NEWDIALOGSTYLE, BIF_USENEWUI, BIF_SHAREABLE, BIF_BROWSEINCLUDEURLS
// uiSpecial Á¾·ù
// CSIDL_FLAG_CREATE
// CSIDL_ADMINTOOLS
// CSIDL_ALTSTARTUP
// CSIDL_APPDATA
// CSIDL_BITBUCKET
// CSIDL_COMMON_ADMINTOOLS
// CSIDL_COMMON_ALTSTARTUP
// CSIDL_COMMON_APPDATA
// CSIDL_COMMON_DESKTOPDIRECTORY
// CSIDL_COMMON_DOCUMENTS
// CSIDL_COMMON_FAVORITES
// CSIDL_COMMON_PROGRAMS
// CSIDL_COMMON_STARTMENU
// CSIDL_COMMON_STARTUP
// CSIDL_COMMON_TEMPLATES
// CSIDL_CONTROLS
// CSIDL_COOKIES
// CSIDL_DESKTOP
// CSIDL_DESKTOPDIRECTORY
// CSIDL_DRIVES
// CSIDL_FAVORITES
// CSIDL_FONTS
// CSIDL_HISTORY
// CSIDL_INTERNET
// CSIDL_INTERNET_CACHE
// CSIDL_LOCAL_APPDATA
// CSIDL_MYMUSIC
// CSIDL_MYPICTURES
// CSIDL_NETHOOD
// CSIDL_NETWORK
// CSIDL_PERSONAL
// CSIDL_PRINTERS
// CSIDL_PRINTHOOD
// CSIDL_PROFILE
// CSIDL_PROGRAM_FILES
// CSIDL_PROGRAM_FILES_COMMON
// CSIDL_PROGRAMS
// CSIDL_RECENT
// CSIDL_SENDTO
// CSIDL_STARTMENU
// CSIDL_STARTUP
// CSIDL_SYSTEM
// CSIDL_TEMPLATES
// CSIDL_WINDOWS
static int BrowseForFolder(CString& sPath, CString sTitle, HWND hParent=NULL,
UINT uiFlag=0, UINT uiSpecial=0, LPITEMIDLIST pidlRoot=NULL)
{
BROWSEINFO bi;
ZeroMemory(&bi, sizeof(BROWSEINFO));
bi.hwndOwner = (hParent == NULL) ? AfxGetMainWnd()->GetSafeHwnd() : hParent;
bi.pidlRoot = pidlRoot;
char pszDisplayName[_MAX_PATH];
bi.pszDisplayName = pszDisplayName;
bi.lpszTitle = sTitle;
bi.ulFlags = uiFlag;
bi.lParam = (LPARAM)(LPCTSTR)sPath; // set lParam to point to path
bi.lpfn = BrowseCallbackProc; // set the callback procedure
LPITEMIDLIST pidl=NULL;
if (uiSpecial)
{
SHGetSpecialFolderLocation(NULL, uiSpecial, &pidl);
bi.pidlRoot = pidl;
}
else
bi.pidlRoot = pidlRoot;
LPITEMIDLIST pidlFolder = SHBrowseForFolder(&bi);
char szPath[_MAX_PATH]="";
int nRet = IDCANCEL;
if (pidlFolder && SHGetPathFromIDList (pidlFolder, szPath))
{
sPath.Format("%s", szPath);
nRet = IDOK;
}
LPMALLOC pMalloc = NULL;
SHGetMalloc(&pMalloc);
pMalloc->Free(pidl);
pMalloc->Free(pidlFolder);
pMalloc->Release();
return nRet;
}
//////////////////////////////////////////////////////////
// PathToPidl
// Function Name : SHPathToPidl
// Description : °æ·Î¸íÀ» ITEMIDLIST·Î º¯È¯ÇÑ´Ù.
// Return type : static HRESULT
// Arguments :
// LPCTSTR szPath : °æ·Î¸í
// LPITEMIDLIST* ppidl : ã¾Æ³½ ITEMIDLIST
// LPSHELLFOLDER pFolder : ·çÆ® Æú´õ Á¤º¸.. NULLÀÌ¸é µ¥½ºÅ© žÀ» µÚÁø´Ù.
static HRESULT PathToPidl(LPCTSTR szPath, LPITEMIDLIST* ppidl,
LPSHELLFOLDER pFolder=NULL)
{
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;
}
// Function Name : PathToShellFolder
// Description : ¹®ÀÚ¿À» SHELLFOLDER ÇüÀ¸·Î º¯È¯ÇÑ´Ù.
// Return type : static void
// Arguments :
// LPCTSTR szPath : ÁÖ¾îÁø °æ·Î¸í
// LPSHELLFOLDER& pSubFolder : º¯È¯µÈ SHELLFOLDER
static void PathToShellFolder(LPCTSTR szPath, LPSHELLFOLDER& pSubFolder)
{
LPITEMIDLIST pidl = NULL;
LPSHELLFOLDER pFolder = NULL;
// Get the memory allocator
LPMALLOC pMalloc = NULL;
SHGetMalloc(&pMalloc);
// Get the IShellFolder interface for the desktop
SHGetDesktopFolder(&pFolder);
// µ¥½ºÅ© ž Æú´õÀÇ ¾ÆÀÌÅÛ °¹¼ö¸¦ ȹµæÇÑ´Ù.
int iNumOfItems = EnumFolderContent(pFolder, NULL, 0, NULL);
// Try to find a match under Desktop
int rc = EnumFolderContent(pFolder,
SearchText, //CallBack Function
reinterpret_cast<DWORD>(szPath), &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 = EnumFolderContent(pFolder, NULL, 0, NULL);
rc = EnumFolderContent(pFolder,
SearchText, //CallBack Function
reinterpret_cast<DWORD>(szPath), &pidl);
if(rc == iNumOfItems)
{
// Make the last attempt: is it a path name?
HRESULT hr = PathToPidl(szPath, &pidl, pFolder); //Local Function
if(FAILED(hr)) {
pMalloc->Free(pidl);
pFolder->Release();
pSubFolder = NULL;
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));
// Clean up
pFolder->Release();
pMalloc->Free(pidl);
pMalloc->Release();
}
// Function Name : EnumFolderContent
// Description : Æú´õ ³»ºÎ¿¡ Á¸ÀçÇÏ´Â ¾ÆÀÌÅÛ °¹¼ö ȤÀº ãÀº ´ë»ó±îÁöÀÇ °¹¼ö¸¦ ±¸ÇÑ´Ù.
// Return type : static int
// Arguments :
// LPSHELLFOLDER pFolder : °Ë»ö ´ë»ó ·çÆ® Æú´õ
// FOLDERCONTENTPROC pfn : User Defined CallBack Function
// DWORD dwData : ¿ÜºÎ¿¡¼ ³Ñ¾î¿À´Â ´ë»ó ÀÎÀÚ - CallBack ÇÔ¼ö¿¡¼ »ç¿ëÇÏ´Â ÀÎÀÚ
// LPITEMIDLIST* ppidl : ã¾Æ³½ LPITEMIDLIST
static int EnumFolderContent(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)
{
if(!pfn(szBuf, pItem, dwData))
{
// Returns the current PIDL
if(ppidl != NULL)
*ppidl = pItem;
break;
}
}
++iNumOfItems;
}
return iNumOfItems;
}
// Function Name : StrretToString
// Description : STRRETÇüÀ» ¹®ÀÚ¿·Î º¯È¯ÇÑ´Ù.
// Return type : static void
// Arguments :
// LPITEMIDLIST pidl : ÇöÀç ¾ÆÀÌÅÛ¿¡ ´ëÇÑ ItemIDList °ª
// LPSTRRET pStr : IShellFolder::GetDisplayNameOf() ÇÔ¼ö¸¦ ÅëÇØ¼ ȹµæÇÑ STRRET °ª
// LPSTR pszBuf : º¯È¯µÈ ¹®ÀÚ¿ÀÌ ´ã°ÜÁú ¹öÆÛ
static 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;
}
}
private:
// This is the default callback procedure for the SHBrowseForFolder function.
// It will set the current selection to the directory specified in the edit control
static int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM dwData)
{
switch (uMsg)
{
case BFFM_INITIALIZED:
{
//ĸ¼Ç¿¡¼ Help »èÁ¦
DWORD dwStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
SetWindowLong(hWnd, GWL_EXSTYLE, dwStyle & ~WS_EX_CONTEXTHELP);
//ÁöÁ¤µÈ Æú´õ°¡ ¼±Åõǵµ·Ï ÇÑ´Ù.
SendMessage(hWnd, BFFM_SETSELECTION, TRUE, dwData);
//´ëÈ»óÀÚ°¡ Áß¾Ó¿¡ ¿Àµµ·Ï ÇÑ´Ù.
RECT rc;
GetClientRect(hWnd, &rc);
SetWindowPos(hWnd, NULL,
(GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
(GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
0, 0, SWP_NOZORDER | SWP_NOSIZE);
//Status text¿¡ 3D Å׵θ® ÷°¡
HWND hwndLabel = GetDlgItem(hWnd, 0x3743);
if (IsWindow(hwndLabel))
{
TCHAR szClass[MAX_PATH] = {0};
GetClassName(hwndLabel, szClass, MAX_PATH);
if (lstrcmpi(szClass, __TEXT("static")))
break;
}
else
break;
dwStyle = GetWindowLong(hwndLabel, GWL_EXSTYLE);
SetWindowLong(hwndLabel, GWL_EXSTYLE, dwStyle | WS_EX_STATICEDGE);
SetWindowPos(hwndLabel, NULL, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_DRAWFRAME);
}
break;
case BFFM_SELCHANGED:
{
TCHAR szText[MAX_PATH] = {0};
SHGetPathFromIDList(reinterpret_cast<LPITEMIDLIST>(lParam), szText);
SendMessage(hWnd, BFFM_SETSTATUSTEXT, 0, reinterpret_cast<LPARAM>(szText));
}
break;
case BFFM_VALIDATEFAILED:
break;
}
return 0;
}
//ÀÎÀÚ·Î ³Ñ¾î¿Â dwData¿Í ÇöÀç °Ë»öµÈ pszItemÀÌ µ¿ÀÏÇÑ ¾ÆÀÌÅÛÀÎÁö ºñ±³ÇÑ °á°ú
//pIdlÀº CallBack ÇÔ¼ö¸¦ °øÅëÀûÀ¸·Î »ç¿ëÇϱâ À§Çؼ ³ÖÀº ¹«È¿ÀÎÀÚÀÌ´Ù.
static BOOL CALLBACK SearchText(LPCSTR pszItem, LPITEMIDLIST pIdl, DWORD dwData)
{
return static_cast<BOOL>(lstrcmpi(pszItem, reinterpret_cast<LPCSTR>(dwData)));
}
//ÀÎÀÚ·Î ³Ñ¾î¿Â dwData¿Í ÇöÀç °Ë»öµÈ pszItemÀÌ µ¿ÀÏÇÑ ¾ÆÀÌÅÛÀÎÁö ºñ±³ÇÑ °á°ú
//pIdlÀº CallBack ÇÔ¼ö¸¦ °øÅëÀûÀ¸·Î »ç¿ëÇϱâ À§Çؼ ³ÖÀº ¹«È¿ÀÎÀÚÀÌ´Ù.
BOOL CALLBACK SearchPidl(LPCSTR pszItem, LPITEMIDLIST pIdl, DWORD dwData)
{
LPITEMIDLIST PIDL = reinterpret_cast<LPITEMIDLIST>(dwData);
return (pIdl == PIDL) ? 0:1;
}
};
//#endif //__SHELLBROWSE_H__20020531
|