喫茶XRAYトップページ

[スレッド全体
]

[4082] plExplorerFolderTreeにて返信 削除
2010/12/26 (日) 23:53:42 Sara
Mr.XRAYさん こんばんは。

また、やってきました(^^;

plExplorerFolderTreeでグローバルフックを使わずにOnMouseEnterを
起こすことに成功しました。(って言うほどのものでもないですが)

どのようにしたかといいますと・・・

以下のように、MessageLoop内で強引にイベントを発生させたのです。

procedure TplExplorerFolderTreeThread.MessageLoop;
var
  Amsg : Msg;
  APos : TPoint;
  cmpFind : TWinControl;
begin
  while True do begin
    if GetMessage(AMsg, 0, 0, 0) = False then begin
      PostQuitMessage(0);
      break;
    end;
    case AMsg.message of
      WM_MOUSEMOVE:begin
        GetCursorPos(APos);
        cmpFind := FindVCLWindow(APos);
        if (cmpFind = FWinControl) then begin
          if not FWinControl.FMouseEnterFlg then begin
             FWinControl.FMouseEnterFlg := True;
             FWinControl.DoMouseEnter;
          end
        end
        else begin
          if FWinControl.FMouseEnterFlg then begin
             FWinControl.FMouseEnterFlg := False;
             FWinControl.DoMouseLeave;
          end;
        end;
      end;
    end;
    TranslateMessage(Amsg);
    DispatchMessage(Amsg);
  end;
end;

そこで、実際のMouseEnterイベント内で、plExplorerFolderTreeにSetFocusを
実行すると、何も起きない・・・で調べると、実際のFolderTreeはFEXPLとなって
いるので、こちらにもSetFocusを追加したのは良いのですが、
  IUnknown_GetWindow(m_pNameSpaceTreeControl, FHandle);
  Windows.SetFocus(FHandle);
とするしかなく、実際にフォーカスはわたるのですが、MouseLeave時に
他のコンポーネントで例えば ListView1.SetFocus としても、フォーカスが
わたらないんです・・・(^^;

かといって、全コンポーネントでWindows.SetFocusを利用すると、Zオーダーが
狂うのですよね・・・(^^;

なにかよい方法ありませんでしょうか?m(_ _)m

[4084] Re:plExplorerFolderTreeにて返信 削除
2010/12/27 (月) 13:06:41 Mr.XRAY
▼ Saraさんち,どうも

> 実際のFolderTreeはFEXPLとなっているので、

FEXPLを使用しないコードにしてみました.
前にも書いたのですが,Delphiではインタフェースの大部分を面倒みて
くれます.参考にしたサイトのC++のコードを,ほとんどそのままので移植
したわけですが,これは,ちょうどHalbow資料館の

http://mrxray.on.coocan.jp/Halbow/Chap01.html

のようになっているわけです.そこで,

 TplExplorerFolderTree = class(TCustomPanel,
                               INameSpaceTreeControlCustomDraw)

ように変更しました.つまり,インターフェイス部分を
 TplExplorerFolderTreeの直接のメンバーにしたわけです.
これで,少しはメッセージ処理がしやすくなるのではないかと思います.

今,別の解決方法も考えています.
しばらくお待ちくださいませ.
published部と,Create部の重要な変更はないので,再構築,ビルドは
必要ありません.単に置き換えてください.

■添付ファイル plexplorerfolder.zip

[4085] Re2:plExplorerFolderTreeにて返信 削除
2010/12/27 (月) 15:14:45 Mr.XRAY
▼ Saraさん,どうも

> 今,別の解決方法も考えています.

エクスプローラのツリーのハンドルで操作することを考えました.
このハンドル不思議です.このハンドルでウィンドウプロシージャーでの
操作を考えたのですが,確かに設定はできました.
しかし,メッセージを補足することができません.

ところが,このハンドルで,位置とサイズは取得,更新できます.
(実際にコンポ内で,位置とサイズはWndProcで再設定しています)

前にエクスプローラのサンプル([945])での記憶があったので,
メッセージ処理は,フックしかないと思っていたのですが,
考えてみれば,このエクスプローラのオブジェクト,同じプロセス内で
動作しているんですよね.

そこで,このハンドルをプロパティにして,以下の手順で検出すると
いうのはどうでしょう.

(1)このコンポを配置しているフォームに TApplicationEventsを配置
    TApplicationEventsは[Addtioanl]タブにある

(2) TApplicationEventsのOnMessageイベントを作成

(3) このイベントを以下のようなコードにする

procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);
var
  APos  : TPoint;
  ARect : TRect;
begin
  if Msg.message = WM_MOUSEMOVE then begin
    GetCursorPos(APos);
    GetWindowRect(plExplorerFolderTree1.hwndTree, ARect);
    if PtInRect(ARect, APos) then begin
      //ここに処理を書く
    end;
  end;
end;

動作確認は,Windows 7 U64 + Delphi 2010(UP5) + IE8

hwndTreeをpublicなプロパティにしたコード
■添付ファイル 4085_plexplorerfolder.zip

[4092] Re3:plExplorerFolderTreeにて返信 削除
2010/12/27 (月) 20:16:37 Sara
▼ Mr.XRAYさん

> hwndTreeをpublicなプロパティにしたコード

これから、検証してみます。(^^) 御苦労様です。

[4093] Re4:plExplorerFolderTreeにて返信 削除
2010/12/27 (月) 20:23:19 Mr.XRAY
▼ Saraさん,どうも

> これから、検証してみます。(^^) 御苦労様です。

個人的には,同じプロセス内でのメッセージ処理なので,例の
スレッドのコードではなく,OnMessage等を使用する方がいいと思っています.
コンポ内で処理する場合もです.

http://mrxray.on.coocan.jp/Halbow/VCL07.html
こなんところも参考になるかと思います.


[4094] Re5:plExplorerFolderTreeにて返信 削除
2010/12/27 (月) 22:26:08 Sara
▼ Mr.XRAYさん こんばんは

> 個人的には,同じプロセス内でのメッセージ処理なので,例の
> スレッドのコードではなく,OnMessage等を使用する方がいいと思っています.
> コンポ内で処理する場合もです.


procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;

すみません。これにメッセージが返ってきませんが・・・

どこか、記述漏れがありますかね・・・(^^;
こちらで修正したものにソースを見ながら追記したので・・・

それ以外は、正常動作をしています。


[4096] Re6:plExplorerFolderTreeにて返信 削除
2010/12/27 (月) 22:48:34 Sara
▼ Mr.XRAYさん こんばんは

> procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
>
> すみません。これにメッセージが返ってきませんが・・・


ちなみに、
procedure TplExplorerFolderTreeThread.MessageLoop;

    DispatchMessage(Amsg);
    Application.ProcessMessages;
とすると、メッセージが返ってきます・・・終了できなくなりますが・・・(^^;

あと、面白いことに、WM_MOUSEMOVEだけ検出してみると、plExplorerFolderTree
のアイテム上でしか、WM_MOUSEMOVEが検出されないようです。
(背景の白い部分や、他のコンポーネント上は未検出)



[4097] Re7:plExplorerFolderTreeにて返信 削除
2010/12/27 (月) 22:54:05 Mr.XRAY
▼ Saraさん

> > procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
> >
> > すみません。これにメッセージが返ってきませんが・・・


今ちょっとやってみました.
はは〜ん,おそらく,こういうことではないかと思います.
このApplicationのOnMessageはコードでも作成できますが,
TApplicationコンポーネントというのがあります.これを使用してください.
この方が簡単です.[4085]参照

とりあえず,ここの部分だけ


[4098] Re8:plExplorerFolderTreeにて返信 削除
2010/12/27 (月) 23:01:02 Mr.XRAY
ちょっと待ってください.
今,やったら,フォルダツリーからのメッセージが来ません.
表示前なら来るのですが.


[4099] Re9:plExplorerFolderTreeにて返信 削除
2010/12/27 (月) 23:12:17 Sara
▼ Mr.XRAYさん
> ちょっと待ってください.
> 今,やったら,フォルダツリーからのメッセージが来ません.
> 表示前なら来るのですが.


そうなんですよね・・・

で、ちょっと試しに

//  if FThread = nil then begin
//    FThread := TplExplorerFolderTreeThread.Create;
//  end;

としてみたんです・・・すると・・・メッセージきますね・・・
処理も正常に動いているっぽいんですが・・・
(フォルダ追加、削除にちゃんと追従しますし)
このスレッドっていったい・・・(^^;

[4100] Re10:plExplorerFolderTreeにて返信 削除
2010/12/27 (月) 23:16:35 Mr.XRAY
▼ Saraさん

> (フォルダ追加、削除にちゃんと追従しますし)
> このスレッドっていったい・・・(^^;


ファイルかフォルダの名前を変更してみてください.
[F2]でも,マウスを静かにクリックでも.


[4103] Re11:plExplorerFolderTreeにて返信 削除
2010/12/27 (月) 23:33:11 Sara
▼ Mr.XRAYさん
> ▼ Saraさん
>
> > (フォルダ追加、削除にちゃんと追従しますし)
> > このスレッドっていったい・・・(^^;
>
> ファイルかフォルダの名前を変更してみてください.
> [F2]でも,マウスを静かにクリックでも.


なるほど・・・F2だと、フォーカスに関係なく別な処理が割り当てられていると
そちらにいってしまいますね・・・クリックならなんとか変更可能ですが、
矢印キーが使えないですね・・・マウスと併用なら何とか変更可ですが・・・
使いづらい・・・(^^;

しかし、このスレッドがあると、F2がフォーカスに関係なくplExplorerFolderTreeに
持って行かれますね・・・
っていうか キーボードー系のイベントが全て持って行かれる?・・・(^^;

これは、困った・・・

[4104] Re12:plExplorerFolderTreeにて返信 削除
2010/12/27 (月) 23:43:12 Mr.XRAY
▼ Saraさん

> しかし、このスレッドがあると、F2がフォーカスに関係なくplExplorerFolderTreeに
> 持って行かれますね・・・
> っていうか キーボードー系のイベントが全て持って行かれる?・・・(^^;
>
> これは、困った・・・


「弊社としてましては,この現象を認識しています.
これは,エクスプローラーのオブジェクトを正常に動作させるための仕様
と認識しています.
お客様は,仕様の範囲内でのご利用をお勧めいたします」

という感じの文章を,とあるサイトでよく見かけます.
フォルダビュー(ファイルリスト)だと,TranslateAcceleratorという関数が
あり,この現象をある程度回避できるんですけどね.


[4105] Re13:plExplorerFolderTreeにて返信 削除
2010/12/28 (火) 00:34:37 Sara
▼ Mr.XRAYさん

> という感じの文章を,とあるサイトでよく見かけます.
> フォルダビュー(ファイルリスト)だと,TranslateAcceleratorという関数が
> あり,この現象をある程度回避できるんですけどね.


なるほど、参考になります・・・

なにかできないか、調べてみますm(_ _)m

[4109] Re14:plExplorerFolderTreeにて返信 削除
2010/12/28 (火) 20:24:50 Sara
▼ Mr.XRAYさん
 
> > フォルダビュー(ファイルリスト)だと,TranslateAcceleratorという関数が
> > あり,この現象をある程度回避できるんですけどね.

 
> なにかできないか、調べてみますm(_ _)m

というわけで、強引な方法で解決策を作ってみました・・・(^^;
この方法で問題ないかどうかは、まだ何とも言えませんが、
今のところ、問題なく動いているようです。(^^;

で、具体的に何をしたかですが・・・(あまり言いたくないかも・・・)

plExplorerFolderTreeにマウスカーソルが入った時に、FThreadをCreateして
マウスが出た時に、FThreadをTerminateしましたとさ・・・

問題がでなければ、この方法で進んでみます。(^^;;

[4110] Re15:plExplorerFolderTreeにて返信 削除
2010/12/28 (火) 23:59:30 Mr.XRAY
▼ Saraさん

> plExplorerFolderTreeにマウスカーソルが入った時に、FThreadをCreateして
> マウスが出た時に、FThreadをTerminateしましたとさ・・・


なるほど....
 
> 問題がでなければ、この方法で進んでみます。(^^;;

了解しました.
では,がんばってくたさい (^^)


[▼次のスレッド]
INCM/CMT
Cyclamen v3.82