■ SHGetKnownFolderPathの引数

[Visual C++ Q & A 掲示板] [過去ログの一覧]


にゃおん 2008/01/31(木) 06:06:12 <初心者>
.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も、なんだか理解できません。

できたら、ドキュメントのバスを取得する具体的なコードをご提示頂けないでしょうか。

シャノン 2008/01/31(木) 10:12:07 <常連>
> 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 );
}

にゃおん 2008/02/01(金) 04:42:33
シャノンさん、ありがとうございます。
KNOWNFOLDERID は、私がウマシカでした。

ご提示のコードで、ビルドすると、

'FOLDERID_Documents' : 定義されていない識別子です。
'SHGetKnownFolderPath': 識別子が見つかりませんでした

というエラーになります。

環境は VISTA MFC ユニコード です。
SP1 はあてています。

検索しても分らなかったのですが、なにかインクルードするなど、追加のコードが必要なのでしょうか。

Blue 2008/02/01(金) 09:32:26
たぶん、VS2005に同梱されているSDKでは shlobj.h に関数が宣言されていません。
そのままの環境で使うのであれば LoadLibrary を使うことになるでしょう。

Blue 2008/02/01(金) 13:51:43
>HRESULT hr = SHGetKnownFolderPath( FOLDERID_Documents, 0, NULL, &pBuffer );
の2番目の引数って 0 でOKなのでしょうか?
http://msdn2.microsoft.com/en-us/library/bb762583(VS.85).aspx
すみませんが、私は↑を読んでいる暇はないです。

YuO [E-Mail] 2008/02/01(金) 15:08:23
> とはいえ、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.

Blue 2008/02/01(金) 15:11:59
今試してみました。

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;
}

間違っていたら指摘してください。

Blue 2008/02/01(金) 15:12:53
#define は無視しておいてください。
いろいろ試した名残です。

シャノン 2008/02/01(金) 15:57:54 <常連>
> たぶん、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にもあってよいと思いますが。

ですです。

にゃおん 2008/02/03(日) 10:19:26
すみません。
お返事しなければいけないと思ったのですが、初心者の私には理解できない内容になってしまって。。。

とりあえず、SHGetFolderPathでいきます。
2008は、遠からず様子をみて買おうと思っているので、それからまた試してみます。

たいへんありがとうございました。

毎週金曜日はポイント最大3倍!さらに4倍のチャンスも!

Programming Library