很多時候“我的文檔”位置經常被人移到D盤,如下是獲取“我的文檔”路徑:
#include "stdafx.h"
#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以上版本。
posted on 2009-05-22 11:45
漂漂 閱讀(7988)
評論(1) 編輯 收藏 引用 所屬分類:
c++經典文章轉載