喫茶XRAYトップページ

[スレッド全体
]

[4033] 教えてください。返信 削除
2010/12/20 (月) 18:33:53 たてぐや
 多分初歩的な無知だと思うのですが、たとえばこの掲示板やOutlookのように
マウスのホイールを回すとマウスポインタがある方のコントロールがスクロー
ルします。これはどういうコーディングをしたらこうなるのでしょうか?
メインフォームにTListviewとTMemomがTSplitterで分けられておかれています。
マウスポインタがTListviewにあればこれを、TMemoにあればこちらをスクロー
ルさせたいのですが… こんなこと知らないのはもしかして私だけ?

[4040] Re:教えてください。返信 削除
2010/12/21 (火) 23:44:23 Mr.XRAY
▼ たてぐやさん

> マウスポインタがTListviewにあればこれを、TMemoにあればこちらをスクロー
> ルさせたいのですが… こんなこと知らないのはもしかして私だけ?


いや,そんなことはないと思いますけど.
普通は,クリックする等して,フォーカスを移動しないとなりませんから.
最近必要がないのでやってないけど.えっと,
どうやるんでしたっけ?
ちょっと待ってください.
MouseEnterを捕捉すればいいわけなんですが,TMemoとかTListViewなら
WndProcをオーバーライドしなくてもメッセージがあったような...


[4041] Re2:教えてください。返信 削除
2010/12/21 (火) 23:50:08 Mr.XRAY
> MouseEnterを捕捉すればいいわけなんですが,TMemoとかTListViewなら
> WndProcをオーバーライドしなくてもメッセージがあったような...


Delphi 2010なら,そのものズバリ.
OnMouseEnter, OnMouseLeaveというのがあります.ということは,Delphi 6
でもProtetedに... と,探してみます.


[4042] Re3:教えてください。返信 削除
2010/12/22 (水) 00:22:09 Mr.XRAY
> OnMouseEnter, OnMouseLeaveというのがあります.ということは,Delphi 6
> でもProtetedに... と,探してみます.


あっと,そんな面倒なことをしなくても,OnMouseWheelか
MouseWheelHandlerで実装できそうです.
OnMouseWheelはワード操作フォームでも使っていました.


[4047] スクロールバーの制御返信 削除
2010/12/22 (水) 11:56:09 Mr.XRAY
> あっと,そんな面倒なことをしなくても,OnMouseWheelか
> MouseWheelHandlerで実装できそうです.


というか,OnEnterとかは,直接関係ないですね.ハハハッ.
これ結構ややこしそうです.
WM_MOUSEWHEELイベントは,アクティブなコントロールに対してだけしか
発生,動作しませんから,

>マウスのホイールを回すとマウスポインタがある方のコントロールがスクロー
>ルします。


の機能は,ホイールの作業量分たけ,スクロールバーにメッセージを
送って処理しているのではないかと思います.
とすると,こんな手順になるかと思います.

1. マウス,つまりカーソルがある位置を検出.
   MouseWheelHandlerか,OnMouseWheelイベント
2. マウスホイールの作業量,奥へか,手前かと,その移動量分を検出
3. スクロールバーが表示されていれば,その分だけスクロールするメッセージ
   を送る

だそくですが,1.は,コントロールのプロパティやイベントの引数で取得でき
ますが,個人的にはAPIを使った方が,直接スクリーン座標値が取得できるので
好きです.

var
  APos : TPoint;
  RectMemo1 : TRect;
  RectMemo2 : TRect;
begin
  GetCursorPos(APos);
  GetWindowRect(Memo1.Handle, RectMemo1);
  GetWindowRect(Memo2.Handle, RectMemo2);

  //カーソルがMemo1内にある場合
  if PtInRect(RectMemo1, APos) then begin

てな感じです.ということは,

> こんなこと知らないのはもしかして私だけ?

「とんでもはっぷん,歩いてじゅっぷん」ですね.


[4053] Re:スクロールバーの制御返信 削除
2010/12/22 (水) 18:59:40 たてぐや
▼ Mr.XRAYさん

> WM_MOUSEWHEELイベントは,アクティブなコントロールに対してだけしか
> 発生,動作しませんから,


 そこで悩んだのでした。
 
> 1. マウス,つまりカーソルがある位置を検出.
>    MouseWheelHandlerか,OnMouseWheelイベント
> 2. マウスホイールの作業量,奥へか,手前かと,その移動量分を検出
> 3. スクロールバーが表示されていれば,その分だけスクロールするメッセージ
>    を送る


 なるほど、マウスポインターの位置さえ解れば、あとメッセージを送る
やりかたはどこぞの本に載っていたような記憶があります。調べてみます
ね。ありがとうございます。

[4059] Re2:スクロールバーの制御返信 削除
2010/12/23 (木) 18:10:47 Mr.XRAY
▼ たてぐやさん

というわけで(どういわけだ!?),こんな感じでしょうか.
スクロールメッセージ関係は,Halbow資料館の以下にあります.
http://mrxray.on.coocan.jp/Halbow/VCL03.html

//=============================================================================
//  マウスカーソルがあるコントロール上でのみスクロールさせるテスト
//  ここでは,対象コントロールであるMemoがあるForm1のOnMouseWheelイベントで処理
//
//  Form上にMemo1とMemo2がある場合
//  スクロールメッセージの詳しい内容は以下を参照
//  http://mrxray.on.coocan.jp/Halbow/VCL03.html
//=============================================================================
procedure TForm1.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
var
  APos : TPoint;
  RectMemo1 : TRect;
  RectMemo2 : TRect;
begin
   GetCursorPos(APos);
   GetWindowRect(Memo1.Handle, RectMemo1);
   GetWindowRect(Memo2.Handle, RectMemo2);

   if PtInRect(RectMemo1, APos) then begin
     if WheelDelta > 0 then begin
       Memo1.Perform(EM_SCROLL,SB_LINEDOWN,0);
     end else begin
       Memo1.Perform(EM_SCROLL,SB_LINEUP,0);
     end;
   end;

   if PtInRect(RectMemo2, APos) then begin
     if WheelDelta > 0 then begin
       Memo2.Perform(EM_SCROLL,SB_LINEDOWN,0);
     end else begin
       Memo2.Perform(EM_SCROLL,SB_LINEUP,0);
     end;
   end;

   //元のスクロールメッセージは処理しない
   Handled := True;
end;


[4060] Re3:スクロールバーの制御返信 削除
2010/12/23 (木) 18:12:19 Mr.XRAY
ハハハッ.間違えました.
SB_LINEDOWNとSB_LINEUPが逆でした.


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