ありがとうございます。
なんか最初の説明が簡略化されてマズカッタような気がします...(汗 すみません。
エクスプローラのように、左ツリービューと右リストビューがあって、最終的には、
左ツリービュー内のアイテム(フォルダー)をクリックするたびにパス名の切替表示を
したいのです。同様に、右リストビューのアイテム(左ツリービューのアイテムを階層
展開してきたときの下層ファイル)もクリックするたびにパス名の切替表示をしたいの
です。
左ツリービューの最上親はデスクトップとなっています。
このような説明で分かるでしょうか・・・。
メモリを動的に確保する方法については、もう少し勉強してみます。
よろしくご指導お願いします。
エクスプローラとアドレスバーのイメージだったんですか!?
「どういうものを作りたいのか」は質問者しかわからないのですから、
最初に説明して欲しかったですね...
コンボボックスの役割を整理しましょう。
ツリーから選択されているアイテム(フォルダ)のパスを表示するわけですね?
つまり、「今、何フォルダが開かれているか」を示すわけです。
次にリストビューですが、
まさにエクスプローラの動きと同等ということでよろしいですか?
リストビュー内のファイルやフォルダを「クリックしただけ」では、
「今、開かれているフォルダ」は何ら変更がないように思われるのですが、いかがですか?
この時、コンボボックスには何を表示したいと考えていますか?
作りたいものをイメージし、動作をより具体的にしましょう。
そうしないと、やり取りばかりが増えていって、なかなか解決には至れませんよ。
ありがとうございます。お騒がせしてすいません。
> エクスプローラとアドレスバーのイメージだったんですか!?
はい。そうなんですぅ。
>コンボボックスの役割を整理しましょう。
>ツリーから選択されているアイテム(フォルダ)のパスを表示するわけですね?
>つまり、「今、何フォルダが開かれているか」を示すわけです。
はい。全くそのとおりですぅ。
>次にリストビューですが、
>まさにエクスプローラの動きと同等ということでよろしいですか?
>リストビュー内のファイルやフォルダを「クリックしただけ」では、
>「今、開かれているフォルダ」は何ら変更がないように思われるのですが、いかがで
>すか?
>この時、コンボボックスには何を表示したいと考えていますか?
あっ、ここはちょっと工夫したいです。リストビュー内のファイルやフォルダを「クリ
ック」したときは、ツリービューと同様にパス名を表示したいです。実行はダブルクリ
ックにしますから。
このようなイメージなのですが、明確さを欠いで申し訳なかったです。
よろしくご指導お願いします。
ツリービューのアイテムをクリックした時(=選択状態にあるアイテムが変更になった時)に、
コンボボックスにディレクトリを表示するというのは、いいでしょう。
リストビューの動作ですが、
ツリービューで任意のアイテムをクリック(=ディレクトリを特定)して初めて、
リストビューにアイテムが追加される、ということを理解してください。
これをふまえ、
リストビューのアイテムを「クリック」した時というのは、前述の理由により
既にディレクトリが特定されている訳ですから、
改めでコンボボックスにディレクトリ名を表示するという行為をする必要はありませんよね?
次に、リストビューのアイテムを「ダブルクリック」した時ですが、
ダブルクリックしたアイテムが「フォルダ」だった場合、
そのフォルダを開く(=そのディレクトリに移動する)んですよね?
ということは即ち、それに連動してツリービューの表示が更新されるんですよね?
更新されるとは即ち、開いたフォルダのツリーアイテムが選択状態になるわけですよね?
選択状態にあるツリーアイテムが変更になったのなら、冒頭に述べた通り
コンボボックスに新しいパス名が表示されるわけですから、
リストビューでどうこうする必要はなくなりますよね?
これらのことから、ツリービューの選択状態が変わった事をトリガに
コンボボックスの表示を切り替えるようにすれば、事は丸く収まりそうじゃないですか?
ありがとうございます。
全くその通りです。エクスプローラーもそのようになっています。
>ツリービューの選択状態が変わった事をトリガに
>コンボボックスの表示を切り替えるようにすれば、事は丸く収まりそうじゃないです
>か?
はい、そう思います。結局はリストビューのアイテム選択からパス名を表示するので
はなく、ツリービューのアイテム選択からパス名を表示するようにすれば事足ります
ね。
とすると、ツリービュー側のNM_CLICK以下で処理すればいいと思うのですが・・・。
よろしくご指導願います。
ツリービューに代わって、何が問題になりますか?
ディレクトリ構成はツリーがそのものを構成していると思われますので、
今までのリストビューよりかは問題の解決方法は明確かと思うのですが。
(ツリーの親アイテムを辿って行けば...)
> とすると、ツリービュー側のNM_CLICK以下で処理すればいいと思うのですが・・・。
>
キーボード操作を考慮するなら、TVN_SELCHANGEDの方が妥当じゃないでしょうか。
ありがとうございます。
>ツリービューに代わって、何が問題になりますか?
>ディレクトリ構成はツリーがそのものを構成していると思われますので、
>今までのリストビューよりかは問題の解決方法は明確かと思うのですが。
>(ツリーの親アイテムを辿って行けば...)
とくに問題はありません。道すじがはっきりしました。
>キーボード操作を考慮するなら、TVN_SELCHANGEDの方が妥当じゃないでしょうか。
はい。TVN_SELCHANGEDで試行錯誤しています。
只今、奮闘中・・・です。
あっ~、すいません。直前回答↑のハンドルネーム「タルタル」は、「初心者@rumu」
の次に考えた第2ハンドルネームです。まだ初心者ではあるけど・・・。すいません、
なんか独り言みたいで・・・。
中間報告です(半分解決)。
MSDNライブラリで「SHGetPathFromIDList」関数なるものを見つけたので、
int* p;
TCHAR szPath[MAX_PATH];
case TVN_SELCHANGED:
(省略)
//動的メモリの確保 (すいません、GlobalAllocにしました。)
p = (int *)GlobalAlloc(GMEM_FIXED, sizeof(int) * MAX_PATH);
if(SUCCEEDED(SHGetPathFromIDList(lpItemData->lpItemID, szPath)));
{
SetWindowText(hCombo,szPath);
}
//動的メモリの開放
GlobalFree(p);
return 0;
としたところ、OK!でした。また、case NM_CLICK でも、少し手間は要りますがOK!でし
た。
ただ、完璧ではなく不満が残ってます。 8T_T8
「デスクトップ」をクリックしたときは、正常にC:\Documents and Settings\・・・
\デスクトップと表示され、「マイドキュメント」では正常にC:\Documents and
Settings\・・・\My Documents と表示されます。
でも、「マイドキュメント」に格納された「Becky ! ver.2」をクリックする
と、C:\Documents and Settings\・・・\デスクトップ\Becky ! ver.2 と表示さ
れ、・・・\My Documents\Becky ! ver.2とは表示されていません・・・?Windows標準
のエクスプローラでは正確に表示されているのに・・・。
何が原因なのかはわかりません。ご教授お願いできないでしょうか。m(__)M
SHGetPathFromIDList()は使ったことがないのでわかりませんが、
このAPIがバグってることがありえないと考えた場合、
実は単純なミスだったりすることもあるので、もう一度確認してみることです。
例えば引数に与えているlpItemData->lpItemIDは意図したものなのか。
「Becky ! ver.2」は本当にデスクトップにないのか。
フォルダ情報を取得する方法に誤りがないか。
ツリーの構成は本当に間違っていないか。
等々...
ところでGlobalAlloc()で領域確保をしているようですが、
載せられたソースを見る限りでは、何のために確保したのかがわかりません。
sugarさん、ありがとうございます。
>例えば引数に与えているlpItemData->lpItemIDは意図したものなのか。
>Becky ! ver.2」は本当にデスクトップにないのか。
>フォルダ情報を取得する方法に誤りがないか。
>ツリーの構成は本当に間違っていないか。
>等々...
いま、確認しています。ちょっと時間かかりそうです・・・。
>ところでGlobalAlloc()で領域確保をしているようですが、
>載せられたソースを見る限りでは、何のために確保したのかがわかりません。
次のように修正しました。でも、自信のほうは・・・。
/*---------------------------------------------------------------------------*/
TCHAR szPath[MAX_PATH]; //バイト数が最大
int *p; //メモリオブジェクトのハンドルをいれる
LPTSTR lpOut[1024]; //パスを格納するバッファー
case TVN_SELCHANGED:
(省略)
//動的メモリの確保
p = (int *)GlobalAlloc(GMEM_FIXED, sizeof(int) * MAX_PATH);
if(SUCCEEDED(SHGetPathFromIDList(lpFTItemData->lpItemIDL, szPath)));
{
wsprintf(lpOut,szPath, *p);
SetWindowText(hCombo,lpOut);
}
//動的メモリの開放
GlobalFree(p);
return 0;
以上です。よろしくお願いします。
それでもやはり意図が伝わってきません。
GlobalAlloc()で確保したメモリの使い道はなんですか?
wsprintf()の使い方、おかしくないですか?
各引数の意味をMSDNで再チェックするべきです。
実行後、lpOutには何が格納されることを期待してますか?
やったっぁー、出来ましたっ!! |_(^0^)/
sugarさん、色々とご相談にのって頂いてありがとうございました。
PATIOさんも、ありがとうございました。
SHGetPathFromIDList()の第1引数を変えることで正常にフルパス名を表示することが出
来ました。
ただ、この場合に、動的メモリを確保する必要性に疑問があって、単に、
char szPath[MAX_PATH];
/*------------------------------------------------------------------------*/
case TVN_SELCHANGED:
(省略)
if(SUCCEEDED(SHGetPathFromIDList(lpItemData->lpItemIDL2, szPath)));
{
SetWindowText(hCombo,szPath);
}
return 0;
としただけなのですが、やっぱりマズイでしょうか。メモリ関係もよく理解できていま
せん。何か参考になるものがあれば教えてほしいのですが・・・。
よろしくお願いします。
自分自身で何だかよくわからず、利用目的も不明確のままのメモリ確保なら、
ムリにする必要はないんじゃないでしょうか。
確かに私はメモリの確保についてふれる発言をしましたが、
途中で話の筋がガラッと変わってしまいましたからね。
(リストビューの話の時は、必要だと思いましたよ、ホントに。)
まずは、おつかれさまでした。
長きに渡ってがんばった甲斐がありましたね。
sugarさん、ありがとうございました。
一応、解決チェックを付けておきます。