.NET2005 VISTA です。
先日、ドキュメントなど特別なフォルダのパスの取得方法をお尋ねして、SHGetFolderPathで、できるようになったのですが、いろいろなサイトを検索して、SHGetKnownFolderPathが気になりました。
MSDNを見ると、
HRESULT SHGetKnownFolderPath(
REFKNOWNFOLDERID rfid,
DWORD dwFlags,
HANDLE hToken,
PWSTR *ppszPath
);
となっています。
この引数のうち、
REFKNOWNFOLDERID rfid,
PWSTR *ppszPath
が分りません。
REFKNOWNFOLDERID rfid,
は、
[in] A reference to the KNOWNFOLDERID that identifies the folder.
となっていますが、よく分かりません。
PWSTR *ppszPathも、なんだか理解できません。
できたら、ドキュメントのバスを取得する具体的なコードをご提示頂けないでしょうか。
> KNOWNFOLDERID
MSDN 見ましょう。ぐぐれば一発で出てきます。
とはいえ、SHGetKnownFolderPath のページからリンクが無いのは不親切ですね。
http://msdn2.microsoft.com/en-us/library/bb762584.aspx
> ppszPath
大抵、文字列を返す関数というのは、呼び出し側でバッファを確保して呼ぶものですが、この関数は、関数側でバッファを確保します。
そのバッファのポインタを受け取る必要があるため、ポインタのポインタを渡します。
確保されたバッファは、呼び出し側で CoTaskMemFree を使って解放します。
> ドキュメントのバスを取得する具体的なコードをご提示頂けないでしょうか。
こんな感じかな?(動作未確認)
PWSTR pBuffer = NULL;
HRESULT hr = SHGetKnownFolderPath( FOLDERID_Documents, 0, NULL, &pBuffer );
if( SUCCEEDED( hr ) )
{
// いろいろ処理する
// メモリを解放
CoTaskMemFree( pBuffer );
}
シャノンさん、ありがとうございます。
KNOWNFOLDERID は、私がウマシカでした。
ご提示のコードで、ビルドすると、
'FOLDERID_Documents' : 定義されていない識別子です。
'SHGetKnownFolderPath': 識別子が見つかりませんでした
というエラーになります。
環境は VISTA MFC ユニコード です。
SP1 はあてています。
検索しても分らなかったのですが、なにかインクルードするなど、追加のコードが必要なのでしょうか。
たぶん、VS2005に同梱されているSDKでは shlobj.h に関数が宣言されていません。
そのままの環境で使うのであれば LoadLibrary を使うことになるでしょう。
>HRESULT hr = SHGetKnownFolderPath( FOLDERID_Documents, 0, NULL, &pBuffer );
の2番目の引数って 0 でOKなのでしょうか?
http://msdn2.microsoft.com/en-us/library/bb762583(VS.85).aspx
すみませんが、私は↑を読んでいる暇はないです。
> とはいえ、SHGetKnownFolderPath のページからリンクが無いのは不親切ですね。
サマリ部分にリンクがあるんですよね。
まぁ,ParametersやSee Alsoにもあってよいと思いますが。
>>HRESULT hr = SHGetKnownFolderPath( FOLDERID_Documents, 0, NULL, &pBuffer );
>の2番目の引数って 0 でOKなのでしょうか?
OKです。
http://msdn2.microsoft.com/en-us/library/bb762188.aspx
> dwFlags
> [in] The KF_FLAG flags that specify special retrieval options. This value can be 0; otherwise, one or more of the KF_FLAG values.
今試してみました。
REFKNOWNFOLDERIDを間違えて解釈していたので 0 じゃだめかもと思ったわけです。
(REFKNOWNFOLDERIDがGUIDだとばかり思っていた。REFってついているからGUID*なのね。)
試したコード
#include <windows.h>
#pragma comment(lib, "User32.lib")
#pragma comment(lib, "ole32.lib")
int main()
{
// FOLDERID_Documents
// GUID {FDD39AD0-238F-46AF-ADB4-6C85480369C7}
//HRESULT SHGetKnownFolderPath(REFKNOWNFOLDERID rfid,
// DWORD dwFlags,
// HANDLE hToken,
// PWSTR *ppszPath
// );
typedef GUID KNOWNFOLDERID;
typedef HRESULT (WINAPI *SHGETKNOWNFOLDERPATH)(KNOWNFOLDERID*, DWORD, HANDLE, PWSTR*);
#define KF_FLAG_CREATE (0x00008000)
#define KF_FLAG_NO_ALIAS (0x00001000)
HMODULE hDll = ::LoadLibrary(TEXT("shell32.dll"));
if (hDll)
{
SHGETKNOWNFOLDERPATH pSHGetKnownFolderPath;
pSHGetKnownFolderPath = (SHGETKNOWNFOLDERPATH)::GetProcAddress(hDll, "SHGetKnownFolderPath");
if (pSHGetKnownFolderPath)
{
KNOWNFOLDERID rfid = {0xFDD39AD0,0x238F,0x46AF,0xAD,0xB4,0x6C,0x85,0x48,0x03,0x69,0xC7};
PWSTR pBuffer = NULL;
HRESULT hr = (*pSHGetKnownFolderPath)(&rfid, 0, NULL, &pBuffer);
if (SUCCEEDED(hr))
{
MessageBoxW(NULL, pBuffer, L"", MB_OK);
::CoTaskMemFree(pBuffer);
}
}
::FreeLibrary(hDll);
}
return 0;
}
間違っていたら指摘してください。
#define は無視しておいてください。
いろいろ試した名残です。
> たぶん、VS2005に同梱されているSDKでは shlobj.h に関数が宣言されていません。
です。
SDK for Vista 入れましょう。
http://www.microsoft.com/downloads/details.aspx?familyid=ff6467e6-5bba-4bf5-b562-9199be864d29&displaylang=en
> サマリ部分にリンクがあるんですよね。
気づきませんでしたorz
> まぁ,ParametersやSee Alsoにもあってよいと思いますが。
ですです。
すみません。
お返事しなければいけないと思ったのですが、初心者の私には理解できない内容になってしまって。。。
とりあえず、SHGetFolderPathでいきます。
2008は、遠からず様子をみて買おうと思っているので、それからまた試してみます。
たいへんありがとうございました。
ツイート | ![]() |