現在、ダイアログによるMFCプログラムをしており、
エクスプローラーのようにデスクトップからのツリー表示を
計画しています。
しかし、肝心のルートとなるデスクトップをどのように
取得すべきかという事がわかりません。
一応、SHGetDesktopFolderというAPI関数を見つけたので
使用してみたのですが、p・・というデータが入っており
なんだかよく分かりません。
OnInitDialogの部分で以下のように書いてみたのですが
あまりよろしくないのでしょうか?
返り値としてはちゃんとNOERRORが帰ってきています。
LPSHLLFOLDER lpShellFolder;
if ( SHGetDesktopFolder(&lpShellFolder) != NOERROR)
{
エラー出力
}
もしかしたら同じような質問があるかもしれませんが
御教授の方を宜しくお願い致します。
開発環境は Windows2000 + VC++6.0 です。
SHGetDesktopFolderのHELPをよく読んでみましたか?
引き渡されるポインターはIShellFolderインターフェイスへのポインタなので
ここからさらに必要なデータを引き出すには関数の呼び出しが必要だと思います。
この辺は、まずはHELPをきちんと読んで内容を確認しましょう。
失礼しました。
どうしたらいいんだろうと考えながら色々な所を
探していた時に見つけたので試すつもりで
何も見ずに使ってしまいました…。
デスクトップフォルダを取得する場合は
SHGetDesktopFolder()でIShellFolderを取得。
そしてGetDisplayNameOfを呼ぶ、
という形で良いのでしょうか…。
以下のように書いてみたのですが合っているのか
間違っているのかという判断がつかない状況です…。
ITEMIDLIST FileIDList;
STRRET stFileName;
lpShellFolder->GetDisplayNameOf( &FileIDList,
SHGDN_NORMAL,
&stFileName );
これで一応コンパイルも通り、ちゃんと実行されるのですが
stFileNameもFileIDListも0xccc…という状況なので
間違っているのだと思うのですが…。
何か事前にすべき事などがあるのでしょうか?
ヘッダにもちゃんとshlobj.hをインクルードしてあります。
私が知っている範囲では、デスクトップの実際のディレクトリを
取得するには、SHGetSpecialFolderLocationという関数を使う方法で行けると
思うのですが、デスクトップに対する情報のうち、何が必要なんでしょう?
よく読むと質問内容の中にその辺の記述が無いような気がします。
あと、SHGetSpecialFolderLocationは、Web上を検索すれば、
詳しい使用方法を説明したページが直ぐ見つかると思いますので
そちらを参照してみてはどうでしょう。
PATIOさん、有難う御座います。
いまいち自分でもどのようにアルゴリズムを考えたら
良いのか、という事がハッキリとしていないため
あやふやな質問をしてしまいました。
すいません。
もう一度、じっくりと色々な事について調べた後に
分からない事があればこちらに寄らせて頂こうかと思います。
有難う御座います。
見てるかどうかわかりませんが…
>ITEMIDLIST FileIDList;
>STRRET stFileName;
>lpShellFolder->GetDisplayNameOf( &FileIDList,
> SHGDN_NORMAL,
> &stFileName );
GetDisplayNameOf はその名の通り、DisplayName、つまり「表示されている名前」を取
得するメソッドです。
具体的には、デスクトップなら「デスクトップ」という文字列を取得します。
FileIDList には、表示名を取得したいオブジェクトのアイテム ID リストへのポインタ
を入れておきます。
stFileName には表示名が格納されますが、これはそのまま文字列ではありません。比較
的新しい環境では StrRetTo ナントカという関数で文字列に変換できます。古い環境で
は自力で変換してやる必要があります。
このへんについては、kab-studio さんが詳しいです。
http://www.kab-studio.biz/
トップから「Codian」→「シェルエクステンション」あたりをご一読ください。
>FileIDList には、表示名を取得したいオブジェクトのアイテム ID リストへのポイン
>タを入れておきます。
訂正。
FileIDList は ITEMIDLIST 型ですので、ポインタではなくアイテム ID リストそのも
のですね。
でもアイテム ID リストは常にポインタで扱うので、
>ITEMIDLIST FileIDList;
>STRRET stFileName;
>lpShellFolder->GetDisplayNameOf( &FileIDList,
> SHGDN_NORMAL,
>
&stFileName );
LPITEMIDLIST lpFileIDList;
STRRET stFileName;
lpShellFolder->GetDisplayNameOf( FileIDList,
SHGDN_NORMAL,
&stFileName );
が正しいかな。
これなら lpFileIDList は「アイテム ID リストへのポインタ」です。
シャノンさん、有難う御座います。
前回チェックを付け忘れてしまったので
申し訳ありませんでした。
現在、シャノンさんに教えて頂いたHPでの
情報を元に勉強中です。
シェルなんて全く使った事が無いので
ちょっと悪戦苦闘中です…。
また、何かあった時には宜しくお願いします。
解決にチェックを入れた後に申し訳ありません。
LPSHLLFOLDER lpShellFolder;
if ( ::SHGetDesktopFolder(&lpShellFolder) != NOERROR)
{
エラー出力
}
を行った後に下記のように
LPITEMIDLIST lpFileIDList;
STRRET stFileName;
lpShellFolder->GetDisplayNameOf( lpFileIDList,
SHGDN_NORMAL,
&stFileName );
書いたのですが、
『ハンドルされていない例外は~.exe(SHELL32.DLL)にあります』
と出てしまいます。
何かこの間にすべき事などがあるのでしょうか…?
lpFileIDListに値が入ってないのでは?
HPをよく読みましょう。
余談ですが…
SHGetDesktopFolder は成功したら NOERROR を返す、と明記されているので
>LPSHLLFOLDER lpShellFolder;
>if ( ::SHGetDesktopFolder(&lpShellFolder) != NOERROR)
>{
> エラー出力
>}
でも決して間違いではありません。
が、私は個人的には、HRESULT 値を返す関数の成否判定には SUCCEEDED、FAILED のマク
ロを使うようにしています。
みんな成功したら NOERROR 返してくれればいいんですが、たまに S_OK とか返す輩がい
るんですよ。
SUCCEEDED、FAILED のマクロを使えば、その関数が成功時に何を返すかを読む必要があ
りません。戻り値の型が HRESULT だというだけで判断できますから。
というわけで、個人的には、HRESULT 値を返す関数の成否判定には SUCCEEDED、FAILED
のマクロを使うのがオススメです、というお話でした。
決して「使うべきです」というわけではありません。
Ⅲさん、有難う御座います。
確かにlpFileIDListに値が入っていませんでした…。
こんな初歩的なミスを犯していました。
またシャノンさん、アドバイス有難う御座います。
今までSUCCEEDED、FAILEDと書く事がちょっと面倒に思い、
一気に判定してしまえと思っていたのでこのような
書き方をしていました。
これからはプログラムの精度を上げることも考えて
書いていきたいと思います。