喫茶XRAYトップページ


[4003] 947_ExplorerBrowser の plExplorerFolderTreeにて返信 削除
2010/12/12 (日) 00:08:50 Sara
いつもお世話になっております。Saraです。

さて、plExplorerFolderTreeを利用させていただこうとテストしておりますが、
SelectFolderにフォルダーパスを入れてもSelectFolderに反映されません。

ソースを見る限り、SetFSelectFolderでもSetFpidlSelectFolderでも
FSelectFolderに値を入れていないためとおもわれますが、
SetFpidlSelectFolderの最後に

    SHGetPathFromIDList(FpidlSelectFolder, pFullPath);
    FSelectFolder := pFullPath;

を追加しておけば、大丈夫でしょうか?(一応これで動いてますが)

あと、隠し属性を持つフォルダーを表示するには、どのようにしたら
よいでしょうか?

度々で申し訳ございませんが、ご教示いただけたら、幸いです。

[4006] Re:947_ExplorerBrowser の plExplorerFolderTreeにて返信 削除
2010/12/12 (日) 15:01:24 Mr.XRAY
▼ Saraさん,おっ,いろいろやっていますね.

>FSelectFolderに値を入れていないためとおもわれますが、

ありゃ,失礼しました.m(_ _)m

> を追加しておけば、大丈夫でしょうか?(一応これで動いてますが)

すみませんね.UPしたサンプルも後で修正しておきます.

>あと、隠し属性を持つフォルダーを表示するには、どのようにしたら
>よいでしょうか?


plExplorerFolderTreeですよね.するとリスト6ですね.いや,7ですね.
えっと,属性を指定しているところだから,
function TplCNameSpaceTreeControlHost.SetRootFolder(pid....
のことろですね.ここの

  if Failed(m_pNameSpaceTreeControl.AppendRoot(
                              pShellItem,
                              SHCONTF_FOLDERS, //ここに属性追加
                              NSTCRS_VISIBLE or NSTCRS_EXPANDED,
                              nil)) then exit;

隠し属性は,確かHIDDENだから,
SHCONTF_FOLDERS or SHCONTF_INCLUDEHIDDEN,
でいいような.スミマセン,今Windows 7起動していないので,未確認です.
定数の一覧は以下にあります.
SUPERHIDDEN ってのもありますね.何だろう?

http://msdn.microsoft.com/en-us/library/bb762539%28v=vs.85%29.aspx


[4007] Re2:947_ExplorerBrowser の plExplorerFolderTreeにて返信 削除
2010/12/12 (日) 16:30:49 Mr.XRAY
この一連のエクスプローラのコードなんですが,
参考にしたサイトの記事がC++なんです.

Delphiでは,_AddRefと,_Releaseはいらないようです.
Delphiでは,参照カウンタを自動で管理してくれるようです.
もちろん,これらのコードの,この部分を単に削除するたけではエラーに
なってしまいますが.

後,エクスプローラとそれを表示するインターフェイスを別のクラスに
していますが,インターフェイス部分を,TPanelのメンバーにしてしまう
のもいいかも知れません.


[4012] Re2:947_ExplorerBrowser の plExplorerFolderTreeにて返信 削除
2010/12/13 (月) 00:50:51 Sara
▼ Mr.XRAYさん こんばんは

> ▼ Saraさん,おっ,いろいろやっていますね.
はい(^^; やってます。

>   if Failed(m_pNameSpaceTreeControl.AppendRoot(
>                               pShellItem,
>                               SHCONTF_FOLDERS, //ここに属性追加
>                               NSTCRS_VISIBLE or NSTCRS_EXPANDED,
>                               nil)) then exit;

おぉ なるほど・・・ぢゃあプロパティーを作って・・・
おぉ、できました。(^^)

Delphi付属のShellTreeViewを使うより、数段いい感じです。(^^)V

が、Windows2000でうまく動かない・・・(^^;
いろいろ試してみているんですが・・・
どうも、IUnknown_GetWindowの取得がうまくいっていないらしく・・・

もう少しがんばってみます・・・(^^)V

[4013] Re3:947_ExplorerBrowser の plExplorerFolderTreeにて返信 削除
2010/12/13 (月) 08:31:05 Mr.XRAY
▼ Saraさん

> が、Windows2000でうまく動かない・・・(^^;

ヘヘヘッ,
「そいつぁ〜,無理だぜ,女将さん」だと思いますよ.
このサンプルで使用しているインターフェイスINameSpaceTreeControlCustomDraw
は,Vista以降で使えるようになっています.

http://msdn.microsoft.com/en-us/library/bb761614%28VS.85%29.aspx
(このページの下のMinimum supported client参照)

もちろん,非公開なんとかであれば,ということは多分ないでしょう (^^)


[4014] Re4:947_ExplorerBrowser の plExplorerFolderTreeにて返信 削除
2010/12/13 (月) 09:57:17 Sara
▼ Mr.XRAYさん こんにちは

> ヘヘヘッ,
> 「そいつぁ〜,無理だぜ,女将さん」だと思いますよ.
> このサンプルで使用しているインターフェイスINameSpaceTreeControlCustomDraw
> は,Vista以降で使えるようになっています.

な、なに? と・と言うことは、XPでもだめなの? まぢで?

げげっ、また、別の方法を考えないとだわね・・・(^^;

Windows2000上で、全くエラーは出ないで動くんだけど、ツリー表示が
全くされないんで、困っていたんですが、真相はそこにありましたが・・・(--;

情報、ありがとうございます。m(_ _)mペコリ

(VISTA,7専用バージョンとXP以前でアプリ自体を分けるのも手かな・・・)

[4015] Re5:947_ExplorerBrowser の plExplorerFolderTreeにて返信 削除
2010/12/13 (月) 10:11:30 Mr.XRAY
▼ Saraさん,どうも

> な、なに? と・と言うことは、XPでもだめなの? まぢで?

まぢで.ヒヒヒッ(嫌味な笑い)
(PCの画面見て,本当に笑っています)


[4019] Re6:947_ExplorerBrowser の plExplorerFolderTreeにて返信 削除
2010/12/15 (水) 00:02:01 Sara
▼ Mr.XRAYさん こんばんは

結局、ShellTreeViewとplExplorerFolderTreeをOSバージョンによって
動的に作成して使うという手間とバグが増える方法を選んでしまいました。(^^;


概ね動くようになりましたが、plExplorerFolderTreeにいくつかイベントを
追加したいので、改変しようと思っています。

行き詰ったら、また来ます・・・(。_°☆\(- - ) バシっ!


[4020] Re7:947_ExplorerBrowser の plExplorerFolderTreeにて返信 削除
2010/12/15 (水) 07:13:09 Mr.XRAY
▼ Saraさん,おはようこざいます.

> 結局、ShellTreeViewとplExplorerFolderTreeをOSバージョンによって
> 動的に作成して使うという手間とバグが増える方法を選んでしまいました。(^^;


そうですね.Windows 2000をターゲットにすると,結構面倒になりますよね.
お疲れ様です.

> 行き詰ったら、また来ます・・・(。_°☆\(- - ) バシっ!

いつでもどうぞ.解決の保証はありませんが. (^^;


[4023] Re8:947_ExplorerBrowser の plExplorerFolderTreeにて返信 削除
2010/12/16 (木) 20:36:08 Sara
▼ Mr.XRAYさん こんばんは

> いつでもどうぞ.解決の保証はありませんが. (^^;

との優しい言葉を真に受けて、やってまいりました。(^^;

plExplorerFolderTreeにOnMouseEnterイベントを発生させるには、
どうすればよいでしょうか?

よろしくお願いいたします。m(_ _)m

[4024] Re9:947_ExplorerBrowser の plExplorerFolderTreeにて返信 削除
2010/12/16 (木) 23:23:15 Mr.XRAY
▼ Saraさん,どうも

> plExplorerFolderTreeにOnMouseEnterイベントを発生させるには、
> どうすればよいでしょうか?


http://mrxray.on.coocan.jp/Delphi/plSamples/947_ExplorerBrowsert.htm#03
ですよね.
これは,
http://msdn.microsoft.com/en-us/library/bb774328%28v=VS.85%29.aspx
のリストの,INameSpaceTreeControlCustomDrawインターフェイスを
使用しています.

インターフェイスのリストから,使えそうなのを調べて,そのインターフェイス
を実装することになります.
ただし,インターフェイスの組合せによっては,正常に機能しない場合があります.

今,ちょっとみたところでは,
INameSpaceTreeControlEvents:
http://msdn.microsoft.com/en-us/library/bb761567%28v=VS.85%29.aspx

が使えそうですね.ここの
OnItemClick MethodのnsctsFlags [in]に
Indicates which button was clicked and the kind of click.
One of the following values:
という説明があります.

サンプルでは,

  TplCNameSpaceTreeControlHost = class(TInterfacedObject,
                                       INameSpaceTreeControlCustomDraw)

となっていますから,

  TplCNameSpaceTreeControlHost = class(TInterfacedObject,
                                       INameSpaceTreeControlCustomDraw,
                                       INameSpaceTreeControlEvents)
として,このINameSpaceTreeControlEventsの定義のところを開いて,
([Ctrl]+クリックでShlObj.pasの定義のところを開く)
メソッド(関数類)を全て実装します.インターフェイスでは,必要な関数だけを
実装するということはできません.全てです.
戻り値は,とりあえず,Result := S_OK などとしておいて,
MSDNの英語の記事を解読しながら,作成していくことになります.


[4025] Re10:947_ExplorerBrowser の plExplorerFolderTreeにて返信 削除
2010/12/16 (木) 23:29:23 Mr.XRAY
> 戻り値は,とりあえず,Result := S_OK などとしておいて,

イベントの検出だけですから,MSDNの該当関数の説明を全て読んだわけでは
ないですが,何もすることはないようなきがします.
(Result := S_OKでいいという意味です)

Result := E_NOTIMPL;
という,何もしないというのもあります.


[4026] Re10:947_ExplorerBrowser の plExplorerFolderTreeにて返信 削除
2010/12/16 (木) 23:37:25 Mr.XRAY
> として,このINameSpaceTreeControlEventsの定義のところを開いて,
> ([Ctrl]+クリックでShlObj.pasの定義のところを開く)
> メソッド(関数類)を全て実装します.


釈迦に説法になってしまうと思いますが,定義してある関数のコードを,
全てコピーして,自分のプロジェクトのところに貼り付け,後は,
[Ctrl]+ [Shift] + [C]
で一揆に実装部を作ってしまうと便利です.


[4027] すみません.勘違いでした返信 削除
2010/12/16 (木) 23:50:42 Mr.XRAY
▼ Saraさん

> plExplorerFolderTreeにOnMouseEnterイベントを発生させるには、
> どうすればよいでしょうか?


あっ,ゴメンなさい.OnMouseEnterですか.
マウスクリックと勘違いしていました.


[4028] Re:すみません.勘違いでした返信 削除
2010/12/18 (土) 06:32:55 Mr.XRAY
▼ Saraさん

> あっ,ゴメンなさい.OnMouseEnterですか.

う〜む.OnMouseEnterね.どうしたらいいんだろう.
フック,それとも何かのメッセージ処理でできるのかな.
ちょっと考えます.


[4029] Re2:すみません.勘違いでした返信 削除
2010/12/18 (土) 10:35:20 Sara
▼ Mr.XRAYさん

> う〜む.OnMouseEnterね.どうしたらいいんだろう.
> フック,それとも何かのメッセージ処理でできるのかな.
> ちょっと考えます.


お手数をおかけしております。m(_ _)m

WndProcにはそれらしきメッセージは返ってきません。
CM_MOUSEENTERもだめですね・・・コンポーネント上だけでなく、
メインフォーム上で受けてもplExplorerFolderTreeは反応しません。
(他のコンポーネントは反応しますが・・・)
ので、やっぱりフックですかね・・・(やったことない・・・orz)


[4030] Re3:すみません.勘違いでした返信 削除
2010/12/18 (土) 19:12:19 Mr.XRAY
▼ Saraさん

スミマセン.レスがちょっ間が空いて.

> ので、やっぱりフックですかね・・・(やったことない・・・orz)

じゃぁ,やってみますか.
その前に,もう少し調べてみます.


[4031] グローバルマウスフックしかないようです返信 削除
2010/12/19 (日) 20:15:05 Mr.XRAY
> その前に,もう少し調べてみます.

今のところ,マウス操作のフックしか思いつきません.
DLLにしたくないのであれば,
http://mrxray.on.coocan.jp/Delphi/plSamples/260_HookKeyMouseEvent.htm#03

ですね.


[4034] Re:グローバルマウスフックしかないようです返信 削除
2010/12/20 (月) 20:30:36 Sara
▼ Mr.XRAYさん こんばんは

> 今のところ,マウス操作のフックしか思いつきません.
> DLLにしたくないのであれば,
> http://mrxray.on.coocan.jp/Delphi/plSamples/260_HookKeyMouseEvent.htm#03

なろほど、参考になります。
現在、パソコンを置いてある部屋が利用できないため、
検証ができません。(別室でミニノートを使用中)
明日には多分使えますので、検証しだい、ご報告いたします。

よろしくお願いいたします。

[4036] Re2:グローバルマウスフックしかないようです返信 削除
2010/12/21 (火) 20:29:48 Sara
▼ Mr.XRAYさん こんばんは

> > 今のところ,マウス操作のフックしか思いつきません.
> 明日には多分使えますので、検証しだい、ご報告いたします。


検証しました。問題なく動作しているようです。

が、さすがに、この方法だと、コンポーネントに組み込むわけには
いかないですよね・・・(^^;

でもまぁ 動いてるし良いか(^^;

大変ありがとうございました。m(_ _)m

[4039] Re3:グローバルマウスフックしかないようです返信 削除
2010/12/21 (火) 23:39:35 Mr.XRAY
▼ Saraさん

> が、さすがに、この方法だと、コンポーネントに組み込むわけには
> いかないですよね・・・(^^;


むむっ,う〜ん.そうですね.結構ややこしいコードになる感じがします.
できなくはないでしょうが,
Saraさんも,現在いろいろテストしている段階のようですので,
もうしばらく様子を見てみてはいかがでしょうか.


[4044] Re4:グローバルマウスフックしかないようです返信 削除
2010/12/22 (水) 00:46:27 Sara
▼ Mr.XRAYさん

> むむっ,う〜ん.そうですね.結構ややこしいコードになる感じがします.
> できなくはないでしょうが,
> Saraさんも,現在いろいろテストしている段階のようですので,
> もうしばらく様子を見てみてはいかがでしょうか.


そうですね。そうします。(^^)

しかし、グローバルフックを使っているとデバッガでブレークしてもマウス制御が
戻ってくるまで少し時間がかかるんですね・・・(^^;



[4045] Re5:グローバルマウスフックしかないようです返信 削除
2010/12/22 (水) 11:18:15 Mr.XRAY
▼ Saraさん

> しかし、グローバルフックを使っているとデバッガでブレークしてもマウス制御が
> 戻ってくるまで少し時間がかかるんですね・・・(^^;


ハハハッ.固まったかと思うでしょう.
フックのデバックは,ものにもよるのかも知れませんが,面倒なようです.
DLLのデバッグなんかも.
Delphiのデバッガーも使いやすくなってきたようですが,あまり使ってないです.
CPUウィンドウもあまり,読めないので使いません.

最近使っているのは,HalbowさんのDebugWndUnitと,
テスト用のフォームに,TMemoを配置して,そこに出力するようにしています.
この時,コンポのPublicに
  FMemo : TMemo
としておいて,テスト用フォームのユニットで,Compo.FMemo := Memo1;
そして,コンポ内で追跡する値を,FMemo1.Lines.Add();
等としています.広い画面を有効に使っています.

フック関係のプログラムは,個人的には難しい方ではないかと思っています.


[4056] Re6:グローバルマウスフックしかないようです返信 削除
2010/12/22 (水) 21:10:08 Sara
▼ Mr.XRAYさん こんばんは

> 最近使っているのは,HalbowさんのDebugWndUnitと,
> テスト用のフォームに,TMemoを配置して,そこに出力するようにしています.
> この時,コンポのPublicに
>   FMemo : TMemo
> としておいて,テスト用フォームのユニットで,Compo.FMemo := Memo1;
> そして,コンポ内で追跡する値を,FMemo1.Lines.Add();
> 等としています.広い画面を有効に使っています.


なるほど、それはいいですねぇ。
さっそく、真似します。(^^;V

[4032] Re:947_ExplorerBrowser の plExplorerFolderTreeにて返信 削除
2010/12/19 (日) 20:19:20 Mr.XRAY
▼ Saraさん

> SetFpidlSelectFolderの最後に
>
>     SHGetPathFromIDList(FpidlSelectFolder, pFullPath);
>     FSelectFolder := pFullPath;


http://mrxray.on.coocan.jp/Delphi/plSamples/947_ExplorerBrowsert.htm#03
のプログラムにボタンを追加してテストしてみました.
う〜ん.SelectFolderが取得できいるみたいなんですが...
引き続き調べてみます.

procedure TForm1.Button4Click(Sender: TObject);
begin
  plExplorerFolderTree1.RootFolder   := '';
  plExplorerFolderTree1.SelectFolder := 'D:\000\947_ExplorerBrowser';
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
  ShowMessage(plExplorerFolderTree1.SelectFolder);
end;


[4035] Re2:947_ExplorerBrowser の plExplorerFolderTreeにて返信 削除
2010/12/20 (月) 20:37:40 Sara
▼ Mr.XRAYさん こんばんは

> のプログラムにボタンを追加してテストしてみました.
> う〜ん.SelectFolderが取得できいるみたいなんですが...
> 引き続き調べてみます.

あれ? そうなんですか? 変だな・・・
ちなみに、FormCreate時に設定していたはず(ソース見れないのでうろ覚え)
なんですが、関係あります?(前回見ていたフォルダーを表示するため)

いずれにしても、明日以降に検証してみます。

よろしくお願いいたします。

[4037] Re3:947_ExplorerBrowser の plExplorerFolderTreeにて返信 削除
2010/12/21 (火) 20:37:09 Sara
▼ Mr.XRAYさん こんばんは

> > う〜ん.SelectFolderが取得できいるみたいなんですが...
> いずれにしても、明日以降に検証してみます。


検証しました。

procedure TForm2.FormCreate(Sender: TObject);
begin
   flg := True;
end;

procedure TForm2.FormShow(Sender: TObject);
begin
   if flg then begin
     flg := False;
     plExplorerFolderTree1.RootFolder := '';
     plExplorerFolderTree1.SelectFolder := 'D:\';
     caption := plExplorerFolderTree1.SelectFolder;
   end;
end;

この状態だと、設定がされません・・・ソースをよくよく見ると、
ItemPrePaint内でFSelectFolderの設定をしているんですね。
ということは、初期表示前の状態では設定されないんですね・・・(^^;

と、いうわけで、私のような使い方をしたい場合は、
    SHGetPathFromIDList(FpidlSelectFolder, pFullPath);
    FSelectFolder := pFullPath;
の2行が必要そうです・・・(^^;

よろしくお願いいたします。

[4038] Re4:947_ExplorerBrowser の plExplorerFolderTreeにて返信 削除
2010/12/21 (火) 23:37:09 Mr.XRAY
▼ Saraさん

> と、いうわけで、私のような使い方をしたい場合は、
>     SHGetPathFromIDList(FpidlSelectFolder, pFullPath);
>     FSelectFolder := pFullPath;
> の2行が必要そうです・・・(^^;


なるほど,了解しました.そういうことでしたか.
やっぱり自分だけで,固定したコードでテストしているだけじゃダメ
ですね.後で見直しておきます.


[4043] Re5:947_ExplorerBrowser の plExplorerFolderTreeにて返信 削除
2010/12/22 (水) 00:43:19 Sara
▼ Mr.XRAYさん

> なるほど,了解しました.そういうことでしたか.
> やっぱり自分だけで,固定したコードでテストしているだけじゃダメ
> ですね.後で見直しておきます.


すいません、抜けがありました・・・(^^;
あの2行を追加すると、OnSelctFolderChangedが発生しないような・・・
検証がしきれてないですが、そんな気がします。(^^;

また、明日再度検証してみます。

[4046] コンポのプロパティ返信 削除
2010/12/22 (水) 11:43:59 Mr.XRAY
▼ Saraさん,いいとこついてきますねぇ.

> あの2行を追加すると、OnSelctFolderChangedが発生しないような・・・
> 検証がしきれてないですが、そんな気がします。(^^;


このあたりは,話だすと長くなりそうなんですが,
コンポの動作仕様をどのようにするかとも関係してくるんです.
今回のは,ビジュアルなコンポです,つまり,コントロールを,TPanelと
フォルダーツリーのインターフェイスオブジェクトです.

ビジュアルなコンポの場合,コンポのCreate,それを配置したフォームの
Createでは,まだ表示,生成されていません.
もちろん,フォーム自体もですが,

多くのコンポのプロパティは,既に設定してある値と同じ値を設定しようと
すると,再設定しないようにしています.
つまり,まだ表示されていないCreateで設定すると,プロパティは設定済み
です.表示してからプロパティを設定すると,同じ値だと設定作業はしない,
ということになります.したがって,その関係のイベントも発生しません.

そこで,ビジュアルなコンポでは,プロパティの設定のタイミングは,
表示に関係しないプロパティは,Create等,表示に影響を与えるプロパティは
OnLoad,SetParent等で行っています.

実は,プロパティの設定のタイミングは変更することも可能です.
それは,
ComponentStateを使うことです.
http://docwiki.embarcadero.com/VCL/ja/Classes.TComponent.ComponentState
(しかし,ホントに重たいサイトです)

    if csReading in ComponentState then exit;
    if csLoading in ComponentState then exit;
こんな感じで使用します.
この2行は,コンポが,ストリームから読出し中と,ロード中の時は設定
しないようにする例です.

別のページを作成しているコンポの場合,このことをある程度考慮して
コーディングしていますが,サンプルの方は,あまり考えないコードと
なっています.
そうでなくても,「Mr.XRAYさんのサンプルは難解すぎます」なんて
言われちゃうので (^^;

コンポが,プロパティを設定を試みるのは,完全に表示されるまで,難解,
いや,何回かあります.


[4055] Re:コンポのプロパティ返信 削除
2010/12/22 (水) 20:57:26 Sara
▼ Mr.XRAYさん こんばんは

>     if csReading in ComponentState then exit;
>     if csLoading in ComponentState then exit;
> こんな感じで使用します.

なるほど、参考になります。
ちなみに、この情報を見る前に、例の2行の下に

    if Assigned(FOnSelctFolderChanged) then begin
       if DirectoryExists(FSelectFolder) then begin
          FOnSelctFolderChanged(Self,FpidlSelectFolder,FSelectFolder);
       end;
    end;

を追加してみました。(^^; とりあえず、動いていますが、だめ?(^^;


あと、例の2行が問題だったのではなく、plExplorerFolderTreeが非表示の状態
(といっても、PageControlで別ページにある)状態で設定していたため、
またしても、ItemPrePaintが行われずOnSelctFolderChangedが発生しない状況に
あったというのが、真相でした。 ので、問題なければ、この方法で・・・(^^;


> そうでなくても,「Mr.XRAYさんのサンプルは難解すぎます」なんて
> 言われちゃうので (^^;

そうですね。私にも難解なサンプルが結構・・・(^^;
でも、まぁ私の場合、なんとなくいじっている内に理解できるので、
まずはいじり倒す・・・(^^;

[4057] Re2:コンポのプロパティ返信 削除
2010/12/22 (水) 23:31:46 Mr.XRAY
▼ Saraさん

> を追加してみました。(^^; とりあえず、動いていますが、だめ?(^^;

そんな感じでいろいろやってくださいませ.
で,ファイルリストと併用する場合は,その点に矛盾がないか確認を.

ご存知だとは思いますが,コンポーネント内のコードでプロパティを
操作する場合は,必ず,proctected部のプロパティの定義名,
ほとんど,習慣的に,先頭がFになっていますが,このFXXXXを操作します.
そうしないと,内部で循環してえらいことになることがあります.
Fなんとかがなく,Set... Getで操作しいる場合は別ですが.

> まずはいじり倒す・・・(^^;

ですよね.
「百聞は一見にしかず,百見るは,一触にしかず」
いじっているうちに見えてきたりすることもありまよね.


[4058] Re3:コンポのプロパティ返信 削除
2010/12/23 (木) 17:49:15 Mr.XRAY
> > を追加してみました。(^^; とりあえず、動いていますが、だめ?(^^;
>
> そんな感じでいろいろやってくださいませ.


ということで,いろいろいじれますので,記事のサンプルコードは
そのままにしておきます.


INCM/CMT
Cyclamen v3.82