void CDlgTestDlg::OnBnClickedOk()
{
LPITEMIDLIST pidl;
TCHAR szPath [MAX_PATH];
if(SUCCEEDED( SHGetSpecialFolderLocation ( NULL, CSIDL_FAVORITES, &pidl )))
{
if ( SHGetPathFromIDList ( pidl, szPath ))
{
CString sDisplayName;
SHFILEINFO sfi;
ZeroMemory(&sfi,sizeof(sfi));
UINT uFlags = SHGFI_PIDL | SHGFI_DISPLAYNAME;
SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(SHFILEINFO), uFlags);
sDisplayName = sfi.szDisplayName;
CString szDisplay;
szDisplay.Format(_T(" %s /n /n %s"),szPath, sDisplayName);
GetDlgItem(IDC_STATIC)->SetWindowText(szDisplay);
CoTaskMemFree(pidl); //free the resource
}
}
}
很多时候“我的文档”位置经常被人移到D盘,如下是获取“我的文档”路径:
#include <windows.h>
#include <shlobj.h>
#pragma comment( lib, "shell32.lib")
#include <iostream>
int main(int argc, char* argv[])
{
char m_lpszDefaultDir[MAX_PATH];
char szDocument[MAX_PATH]={0};
memset(m_lpszDefaultDir,0,_MAX_PATH);
LPITEMIDLIST pidl=NULL;
SHGetSpecialFolderLocation(NULL, CSIDL_PERSONAL, &pidl);
if (pidl && SHGetPathFromIDList(pidl, szDocument))
{
GetShortPathName(szDocument,m_lpszDefaultDir,_MAX_PATH);
}
std::cout<<m_lpszDefaultDir<<std::endl;
printf("Hello World!/n");
return 0;
}
可以使用SHGetSpecialFolderLocation函数获得“我的电脑”所对应的虚拟文件夹的id。然后使用ShellExecuteEx打开这个虚拟文件夹。
使用API函数SHGetSpecialFolderLocation。shlobj.h里有SHGetSpecialFolderLocation的原型声明。这个函数可以帮我们找到Windows的桌面目录、启动目录、我的文档目录等。
SHGetSpecialFolder需要三个参数。 第一个参数是HWND,它指定了"所有者窗口":在调用这个函数时可能出现的对话框或消息框。第二个参数是一个整数id,决定哪个目录是待查找目录,它的取值可能是:
CSIDL_BITBUCKET | 回收站 |
CSIDL_CONTROLS | 控制面板 |
CSIDL_DESKTOP | Windows 桌面Desktop |
CSIDL_DESKTOPDIRECTORY | Desktop的目录 |
CSIDL_DRIVES | 我的电脑 |
CSIDL_FONTS | 字体目录 |
CSIDL_NETHOOD | 网上邻居 |
CSIDL_NETWORK | 网上邻居虚拟目录 |
CSIDL_PERSONAL | 我的文档 |
CSIDL_PRINTERS | 打印机 |
CSIDL_PROGRAMS | 程序组 |
CSIDL_RECENT | 最近打开的文档 |
CSIDL_SENDTO | “发送到”菜单项 |
CSIDL_STARTMENU | 任务条启动菜单项 |
CSIDL_STARTUP | 启动目录 |
CSIDL_TEMPLATES | 文档模板 |
这里只是最常用的部分。完整的请参考http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/enums/csidl.asp。
最后一个参数是pidl地址。SHGetSpecialFolderLocation把地址写到pidl。
下面是一个例子:
LPITEMIDLIST pidl;
TCHAR szPath [MAX_PATH];
LPMALLOC pMalloc;
if ( SUCCEEDED( SHGetSpecialFolderLocation ( NULL, CSIDL_DRIVES, &pidl )))
{
SHELLEXECUTEINFO sei;
ZeroMemory(&sei, sizeof(sei));
sei.cbSize = sizeof(sei);
sei.fMask = SEE_MASK_IDLIST;
sei.lpIDList = pidl;
sei.lpVerb = "open";
sei.hwnd = AfxGetMainWnd()->GetSafeHwnd();
sei.nShow = SW_SHOWNORMAL;
ShellExecuteEx(&sei);
if ( SUCCEEDED( SHGetMalloc ( &pMalloc )))
{
pMalloc->Free ( pidl );
pMalloc->Release();
}
}
由于“我的电脑”是虚拟文件夹,所以必须使用ShellExecuteEx函数,如果是普通文件夹,则可以使用SHGetPathFromIDList获得文件名,然后利用ShellExecute函数打开。例如要打开“发送到”文件夹,可以这样:
if ( SUCCEEDED( SHGetSpecialFolderLocation ( NULL, CSIDL_SENDTO, &pidl )))
{
if ( SHGetPathFromIDList ( pidl, szPath ))
{
ShellExecute(AfxGetMainWnd()->GetSafeHwnd(),
"open", szPath, NULL, NULL,
SW_SHOWNORMAL);
}
if ( SUCCEEDED( SHGetMalloc ( &pMalloc )))
{
pMalloc->Free ( pidl );
pMalloc->Release();
}
}
如果是虚拟文件夹,SHGetPathFromIDList函数会失败。
对于普通文件夹也可以使用SHGetSpecialFolderPath函数,而不使用SHGetSpecialFolderLocation函数,这样更简单些,但运行环境必须是Windows 2000以后的操作系统或安装了IE 4.0以上版本。
如果要获取系统History文件夹路径:可以调用另外一个参数:
CSIDL_HISTORY
详细说明如下:
WINSHELLAPI HRESULT WINAPI SHGetSpecialFolderLocation(
HWND hwndOwner,
int nFolder,
LPITEMIDLIST *ppidl
);
CSIDL_ALTSTARTUP | File system directory that corresponds to the user's nonlocalized Startup program group. |
CSIDL_APPDATA | File system directory that serves as a common repository for application-specific data. |
CSIDL_BITBUCKET | File system directory containing file objects in the user's Recycle Bin. The location of this directory is not in the registry; it is marked with the hidden and system attributes to prevent the user from moving or deleting it. |
CSIDL_COMMON_ALTSTARTUP | File system directory that corresponds to the nonlocalized Startup program group for all users. |
CSIDL_COMMON_DESKTOPDIRECTORY | File system directory that contains files and folders that appear on the desktop for all users. |
CSIDL_COMMON_FAVORITES | File system directory that serves as a common repository for all users' favorite items. |
CSIDL_COMMON_PROGRAMS | File system directory that contains the directories for the common program groups that appear on the Start menu for all users. |
CSIDL_COMMON_STARTMENU | File system directory that contains the programs and folders that appear on the Start menu for all users. |
CSIDL_COMMON_STARTUP | File system directory that contains the programs that appear in the Startup folder for all users. |
CSIDL_CONTROLS | Virtual folder containing icons for the Control Panel applications. |
CSIDL_COOKIES | File system directory that serves as a common repository for Internet cookies. |
CSIDL_DESKTOP | Windows Desktop—virtual folder at the root of the namespace. |
CSIDL_DESKTOPDIRECTORY | File system directory used to physically store file objects on the desktop (not to be confused with the desktop folder itself). |
CSIDL_DRIVES | My Computer—virtual folder containing everything on the local computer: storage devices, printers, and Control Panel. The folder may also contain mapped network drives. |
CSIDL_FAVORITES | File system directory that serves as a common repository for the user's favorite items. |
CSIDL_FONTS | Virtual folder containing fonts. |
CSIDL_HISTORY | File system directory that serves as a common repository for Internet history items. |
CSIDL_INTERNET | Virtual folder representing the Internet. |
CSIDL_INTERNET_CACHE | File system directory that serves as a common repository for temporary Internet files. |
CSIDL_NETHOOD | File system directory containing objects that appear in the network neighborhood. |
CSIDL_NETWORK | Network Neighborhood Folder—virtual folder representing the top level of the network hierarchy. |
CSIDL_PERSONAL | File system directory that serves as a common repository for documents. |
CSIDL_PRINTERS | Virtual folder containing installed printers. |
CSIDL_PRINTHOOD | File system directory that serves as a common repository for printer links. |
CSIDL_PROGRAMS | File system directory that contains the user's program groups (which are also file system directories). |
CSIDL_RECENT | File system directory that contains the user's most recently used documents. |
CSIDL_SENDTO | File system directory that contains Send To menu items. |
CSIDL_STARTMENU | File system directory containing Start menu items. |
CSIDL_STARTUP | File system directory that corresponds to the user's Startup program group. The system starts these programs whenever any user logs onto Windows NT or starts Windows 95. |
CSIDL_TEMPLATES | File system directory that serves as a common repository for document templates. |