喫茶XRAYトップページ

[スレッド全体
]

[6351] Re:Mouseメッセージの捕獲返信 削除
2012/9/14 (金) 01:03:56 Mr.XRARY
▼ snail3さん,どうもです.

>     procedure DoMouseDown(var Message: TWMMouse; Button: TMouseButton;
>       Shift: TShiftState); override;
>
> と適当にコード書いてみましたが「基本クラスで見つかりません」
> と怒られてしまいました。


イヒヒヒッ(いやみな笑い)
実は,DoMouseXXX はないのでございますよ.
MouseXXX ならあるでござんす.
とりあえず,お休みなさい.

継承コンボで,内部で使用するメソッド類を作成する時は,
以下のように,タイピングすると,あるかどうか確認しやすいです.

http://mrxray.on.coocan.jp/Delphi/Others/A_IDETechnique.htm#07

[6352] Re2:Mouseメッセージの捕獲返信 削除
2012/9/14 (金) 08:40:37 snail3
▼ Mr.XRARYさん

ありがとうございました。無事 MouseDown でコーディングできました。

最初 [Ctrl]+[Space] でゴニョゴニョしてみましたが変化なし。

その後アプリソースの OnMouseDown の定義をゴニョゴニョして作成。
無事コンパイルが通りました。今試していますが問題なさそうです。


本当にありがとうございました。


[6354] Re3:Mouseメッセージの捕獲返信 削除
2012/9/14 (金) 18:11:55 Mr.XRARY
▼ snail3さん

> 最初 [Ctrl]+[Space] でゴニョゴニョしてみましたが変化なし。

あらっ!? そのDelphi 値切って購入したとか (^^;

[6355] Re4:Mouseメッセージの捕獲返信 削除
2012/9/14 (金) 22:19:40 snail3
▼ Mr.XRARYさん

DelphiというかPASCALは安全な言語だと思って始めたけど、
しょせん夢物語。

今日も2時間ばかり例外エラーの原因探し。
なんと SaveDialog を実行しただけで
「外部例外 C000071C」が発生します。

もっとも EurekaLog という例外関知ソフトを使わないと例外は
発生しません。

あれ何が言いたいのか、、ただいま愚痴モードに入っています。


[6356] Re5:Mouseメッセージの捕獲返信 削除
2012/9/14 (金) 23:27:46 Mr.XRARY
▼ snail3さん

> なんと SaveDialog を実行しただけで
> 「外部例外 C000071C」が発生します。


あれっ,これと同じようなのをどこかで見たような.
どこだっけなぁ.

> もっとも EurekaLog という例外関知ソフトを使わないと例外は
> 発生しません。


う〜ん.どういうことになっているんでしょうね.
「人の不幸は蜜の味」....  (^^;

[6358] Re6:Mouseメッセージの捕獲返信 削除
2012/9/15 (土) 17:49:51 snail3
▼ Mr.XRARYさん

> > なんと SaveDialog を実行しただけで
> > 「外部例外 C000071C」が発生します。


もし見つけたら教えて下さい。
 


[6360] Re7:Mouseメッセージの捕獲返信 削除
2012/9/15 (土) 18:06:41 Mr.XRARY
▼ snail3さん

> もし見つけたら教えて下さい。

ありました.が.... しかし,スレッドがズタズタです.
で,様子がよくわかりません.
これが一番新しいのかな?

http://www.freeml.com/delphi-users/2688/latest

http://www.freeml.com/delphi-users/topics

[6362] Re8:Mouseメッセージの捕獲返信 削除
2012/9/16 (日) 08:20:30 snail3
▼ Mr.XRARYさん

> http://www.freeml.com/delphi-users/2688/latest

ありがとうございました。
「 OpenDialogやSaveDialogを実行するとコケる件」
このメール読んでいました。 (;_;)

私の場合キャパシティの問題があるようで、ズハリのタイトルなのに
前々覚えていませんでした。
DEKOさんの方法で無事エラー発生なくなりました。

ありがとうございました。


procedure TForm9.SpeedButton1Click(Sender: TObject);
begin
  SaveDialog1.Execute;  // この後Closeで例外エラー発生
end;
      ↓修正版
procedure TForm9.SpeedButton1Click(Sender: TObject);
begin
  UseLatestCommonDialogs := False;  // ←DEKOさん解決策
  SaveDialog1.Execute;
end;


[6363] OpenDialogやSaveDialogを実行するとコケる件返信 削除
2012/9/16 (日) 14:08:39 Mr.XRARY
▼ snail3さん

> 私の場合キャパシティの問題があるようで、ズハリのタイトルなのに
> 前々覚えていませんでした。


私も偶然です.うろ覚えです.

> DEKOさんの方法で無事エラー発生なくなりました。

あらっ.そうですか.よかったです.
こんなやり取りができるのも雑談系の利点ですね.

# DEKOさんの助言に基づき,タイトル変更しました(笑)

[6366] Re3:Mouseメッセージの捕獲返信 削除
2012/9/17 (月) 16:06:51 snail3
▼ snail3さん

またまた大ぼけをかましていました。

マウスイベントですが、コンポーネント本体でクリックした時は
反応しますが、このコンポーネントに載せた子コンポーネントで
クリックすると補足することができませんでした。子供でクリック
した場合も横取りする方法はないでしょうか。


[6367] Re4:Mouseメッセージの捕獲返信 削除
2012/9/17 (月) 16:37:03 Mr.XRAY
▼ snail3さん.どうもです.

> マウスイベントですが、コンポーネント本体でクリックした時は
> 反応しますが、このコンポーネントに載せた子コンポーネントで
> クリックすると補足することができませんでした。子供でクリック
> した場合も横取りする方法はないでしょうか。


たしか,TScrollBoxを継承したコンポでしたよね.
載せるコンポというのは,動的に,つまり,実行時に生成して載せる
ということですよね.

とすると,動的に生成して載せたコンポにマウスイベントを
定義するしかないのかな ?

複数生成するのであれば,管理が必要だと思います.
以下のように,配列とか,ジェネリックが便利ですが,Delphi 2007
以降ですね.確か.
http://mrxray.on.coocan.jp/Delphi/plSamples/160_CreateComponent.htm#02

> クリックすると補足することができませんでした。子供でクリック
> した場合も横取りする方法はないでしょうか。


「横取り」と言えば,マウスフックなんてのも考えられますが.
う〜ん.少し考えてみないと... 何とも言えマシェーン.

[6368] Re5:Mouseメッセージの捕獲返信 削除
2012/9/17 (月) 17:46:59 snail3
▼ Mr.XRAYさん
> たしか,TScrollBoxを継承したコンポでしたよね.
はい

> 載せるコンポというのは,動的に,つまり,実行時に生成して載せる
> ということですよね.

伝票形式の入力で利用するコンポーネントです。1行分は設計時に
置いてあります。実行時にプロパティで指定した行数分、最初に
置いたコンポーネントをコピーして使っています。

 
> とすると,動的に生成して載せたコンポにマウスイベントを
> 定義するしかないのかな ?


できれば避けて通りたいと考えています。

> 「横取り」と言えば,マウスフックなんてのも考えられますが.
> う〜ん.少し考えてみないと... 何とも言えマシェーン.


ボタンクリックしたときにだけ反応できればいいんですが、

よろしくお願いします。

私も無い頭をもう少し使ってみます。

[6369] Re6:Mouseメッセージの捕獲返信 削除
2012/9/17 (月) 20:41:58 Mr.XRAY
考えてみたのですが(本当か?)
やっぱり,生成した子コンポにイベントを割り当てのが一番のような
気がします.どうせ生成コードを書かなければならないのですから.

こんな感じですね.
動作確認環境は,Windows XP(SP3) + Delphi XE

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
    APanel : TPanel;
    procedure OnPanelChildChick(Sender: TObject);
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  APanel := nil;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if APanel = nil then begin
    APanel                  := TPanel.Create(Self);
    APanel.Parent           := Self;
    APanel.ParentBackground := False;
    APanel.Color            := clSkyBlue;
    APanel.SetBounds(30, 50, 200, 200);

    with TButton.Create(Self) do begin
      Parent  := APanel;
      Name    := 'AAA';
      OnClick := OnPanelChildChick;
      SetBounds(50, 50, 100, 40);
    end;

    with TButton.Create(Self) do begin
      Parent  := APanel;
      Name    := 'BBB';
      OnClick := OnPanelChildChick;
      SetBounds(50, 100, 100, 40);
    end;
  end;
end;

procedure TForm1.OnPanelChildChick(Sender: TObject);
begin
  Application.MessageBox(PChar(TControl(Sender).Name), '情報');
end;


[6370] Re7:Mouseメッセージの捕獲返信 削除
2012/9/17 (月) 21:32:13 snail3
▼ Mr.XRAYさん

独自に色々と実験しているんですが、教えて下さい。

    procedure WndProc(var Message: TMessage); override;

を定義してみました。
最初

  if Message.Msg = WM_LBUTTONDOWN then   // マウス左ボタンクリック

としてメッセージを拾っていましたが、子コンポーネントのマウスクリック
は補足できませんでした。 でもメッセージ自体は発生している様です。


    if ( Message.Msg = WM_LBUTTONDOWN )   // マウス左ボタンクリック
      or( Message.Msg = $B034 ) then   // マウス左ボタンクリック

実際に子コンポーネントでクリックすると B034 が発生するようです。

改めて TMessage とは何か?ヘルプには WMメッセージが入っている
と書かれているのですが、当然 $B034 なんてありません。

↓こちらのサンプルでは
http://delfusa.main.jp/delfusafloor/archive/www.nifty.ne.jp_forum_fdelphi/samples/00214.html

 if Msg.Msg= MSWHEEL_ROLLMSG then

などとしているのですが「MSWHEEL_ROLLMSG」って「Winapi.Windows」
で文字列定義されています。

頭から湯気が出そうです。

>やっぱり,生成した子コンポにイベントを割り当てのが一番のような
>気がします.どうせ生成コードを書かなければならないのですから.


元のコンポーネントの OnClick 処理を保存するのがちょっと嫌だな
などと思っています。怠け者ですみません。




[6371] Re8:Mouseメッセージの捕獲返信 削除
2012/9/17 (月) 23:10:21 Mr.XRAY
▼ snail3さん

>     procedure WndProc(var Message: TMessage); override;

WndProc では,子ウィンドウ,子コントロールの WM_LBUTTONDOWN などは
検出できないと思います.残念ですが.
「お前の子だろう.面倒見ろよ!!」
と言いたいところですが(笑)

[6372] Re9:Mouseメッセージの捕獲返信 削除
2012/9/18 (火) 01:17:39 snail3
▼ Mr.XRAYさん

> WndProc では,子ウィンドウ,子コントロールの WM_LBUTTONDOWN などは
> 検出できないと思います.残念ですが.


げげ Message.Msg = $B034 で今補足しているのはお化けなんでしょうか

昼間になると消えてしまうのか ^^;




[6373] Re10:Mouseメッセージの捕獲返信 削除
2012/9/18 (火) 08:44:32 Mr.XRAY
▼ snail3さん

> げげ Message.Msg = $B034 で今補足しているのはお化けなんでしょうか

そうです.ハハハッ.そんなことはないですけど.
こういうことだと思います.

1. WndProc では,子コントロールのWM_LBUTTONDOWN メッセージは直接こない
2. 子コントロールからは何らかのメッセージが飛んでくる
3. メッセージの内容は,子コントロールの種類による

WndProc からのWM_NOTIFY メッセージを受けて,その LParam から
NMHDR 構造体の値を使用して処理することはあります.

子コントロールからの
WM_LBUTTONDOWN メッセージを処理する方法として考えられるのは,
現在の私の知識範囲では,以下の3 つが考えられます.

1. 生成した子コントロールにイベントを割り当てる
2. ローカルマウスフックを使用する
3. TApplicationのOnMessage で処理する

Message.Msg = $B034
で処理できているのであれば問題ないと思います.
なんと言っても
「勝てば官軍,動けば正義」ですから (^^;

[6374] Re8:Mouseメッセージの捕獲返信 削除
2012/9/18 (火) 08:54:06 SO
▼ snail3さん

> 改めて TMessage とは何か?ヘルプには WMメッセージが入っている
> と書かれているのですが、当然 $B034 なんてありません。


良く分かっていませんが(^^;a

http://chokuto.ifdef.jp/urawaza/message/index.html

[6375] Re9:Mouseメッセージの捕獲返信 削除
2012/9/18 (火) 10:07:55 Mr.XRAY
▼ SOさん,どうもです.

そっか.TMessage のこと忘れていました.

> http://chokuto.ifdef.jp/urawaza/message/index.html

TMessage 型には,
PostMessage(Handle, WM_XXXX, WParam, LParam)
SendMessage(Handle, WM_XXXX, WParam, LParam)

で送られてくる WM_XXXX, WParam, LParam が取り出せるということですね.
WM_XXXX だけとは限りませんが.
$B034 は分かりません.通知メッセージなのかな?

http://msdn.microsoft.com/en-us/library/ms644927#system_defined
ここの Notifications ですね.
Windows の Windows SDK 7.0 にも定数定義がないものもあるようです.
最新のにはあるかも知れません.

[6377] Re10:Mouseメッセージの捕獲返信 削除
2012/9/18 (火) 20:37:31 snail3
▼ Mr.XRAYさん
> ▼ SOさん,どうもです.

$B034 いうのは何かのメッセージが重なっているような気がしますが、、
あくまで気だけです。根拠はありません。

こういった未定義の値が出てくるプログラムミスのような気がして
心配ですが、最後は「Windowだから」で終わってしまう。いい加減な私。



[6376] Re8:Mouseメッセージの捕獲返信 削除
2012/9/18 (火) 10:28:14 Mr.XRAY
> 元のコンポーネントの OnClick 処理を保存するのがちょっと嫌だな
> などと思っています。怠け者ですみません。


子コントロールの情報を保存しておいて,次回自動生成するという
ことですよね.
でしたら,イベントの情報は保存しないで,次回子コントロールを
生成したら,イベントだけ定義しなおす,というのはどうですか.

う〜ん.面倒かな?

[6378] Re9:Mouseメッセージの捕獲返信 削除
2012/9/18 (火) 20:46:03 snail3
▼ Mr.XRAYさん

> う〜ん.面倒かな?

今日から客先テスト開始でして、とりあえず納品してしまいました。 :-)
で、1台だけこれが原因かわかりませんが変な動作してしまいました。
他のマシンは正しく動作しているようにみえました。

先ほど、食事の後にアイスクリームをぺろり。あと数分が寝てしまうと
思います。

なぜかアイスクリーム食べると睡魔に襲われるおじいです。




[6379] Re10:Mouseメッセージの捕獲返信 削除
2012/9/18 (火) 21:10:15 Mr.XRAY
▼ snail3さん

> なぜかアイスクリーム食べると睡魔に襲われるおじいです。

お疲れ様でした.お休みなさいませ.
サーティワンのおいしいです.でも,ちょっと量がありすぎ.

[6380] Re8:Mouseメッセージの捕獲返信 削除
2012/9/18 (火) 22:58:17 おかぽん
▼ snail3さん
> 実際に子コンポーネントでクリックすると B034 が発生するようです。

Delphi5 で恐縮ですが、Controls.pas で宣言されている
"CM_INVALIDATE" だったりしません?
52=$34

  CM_BASE                   = $B000;
  CM_INVALIDATE             = CM_BASE + 52;



[6381] Re9:Mouseメッセージの捕獲返信 削除
2012/9/18 (火) 23:08:42 Mr.XRAY
▼ おかぽんさん

> Delphi5 で恐縮ですが、Controls.pas で宣言されている
> "CM_INVALIDATE" だったりしません?
> 52=$34
>
>   CM_BASE                   = $B000;
>   CM_INVALIDATE             = CM_BASE + 52;


おおっ!! 何という.いや〜,勉強になります.
Delphi が送っているメッセージなんですね.
再勉強しないと.

[第2章 コントロールのメッセージ処理(その1)]
http://mrxray.on.coocan.jp/Halbow/VCL02.html
[2−5 どのコントロールがどんな通知メッセージを送るのか]
http://mrxray.on.coocan.jp/Halbow/VCL02.html#VChap2-5


[6391] Re9:Mouseメッセージの捕獲返信 削除
2012/9/20 (木) 22:42:19 snail3
▼ おかぽんさん
> ▼ snail3さん
> > 実際に子コンポーネントでクリックすると B034 が発生するようです。
>
> Delphi5 で恐縮ですが、Controls.pas で宣言されている
> "CM_INVALIDATE" だったりしません?


そうです。これみたいです。最初よく理解できていませんでしたが(現在も)
やっと少しわかったような気持ちになっています。


> 52=$34
>
>   CM_BASE                   = $B000;
>   CM_INVALIDATE             = CM_BASE + 52;
>


最終的に WndProc に戻ってきました。

↓こんな感じでコーディングしています。ごく短時間のテストですが
よさそうな感じです。

  if ( Message.Msg = WM_LBUTTONDOWN )   // マウス左ボタンクリック
    or( Message.Msg = CM_FOCUSCHANGED ) then   // CM_FOCUSCHANGED  = CM_BASE + 7;

なんだか難しそうでよく読んでいなかったこの↓ページを
我慢して勉強しておけば皆さんに迷惑をかけなくてすんだようです。

第2章 コントロールのメッセージ処理(その1)
http://mrxray.on.coocan.jp/Halbow/VCL02.html



[6392] Re10:Mouseメッセージの捕獲返信 削除
2012/9/20 (木) 22:51:29 snail3
 
> なんだか難しそうでよく読んでいなかったこの↓ページを
> 我慢して勉強しておけば皆さんに迷惑をかけなくてすんだようです。
>
> 第2章 コントロールのメッセージ処理(その1)
> http://mrxray.on.coocan.jp/Halbow/VCL02.htm


誤解を生みそうなので捕捉しますが、文書自体の話ではなくて、
あくまで根気がなく頭の悪い私が事です。
 

[6393] Re11:Mouseメッセージの捕獲返信 削除
2012/9/20 (木) 23:13:07 Mr.XRAY
▼ snail3さん,どうもです.

> > なんだか難しそうでよく読んでいなかったこの↓ページを

何を隠そう.私もあまりまじめに読んでいませんです.

> > 我慢して勉強しておけば皆さんに迷惑をかけなくてすんだようです。

そういうのは,この店ではないんじゃないでしょうか?
snail3 さんの発言と,おかぽんさんのおかげで勉強になりましたし.
そして,もしかしたら,このスレッドを読んでいる方々にも参考に
なったんじゃないかと,密かに思っています.(^^

[6394] 謝ってもらいたいのは,迷惑をかけた人返信 削除
2012/9/20 (木) 23:31:16 Mr.XRAY
しつこい性格なので,

> > > 我慢して勉強しておけば皆さんに迷惑をかけなくてすんだようです。

「迷惑」と言えば,過去にステハンで発言した方に,
「ご迷惑をおかけしました」と
一言あやまってもらいたいですね.ハッキリ言って.

他人に迷惑をかけて謝らないのは,人として情けないです.ハッキリ言って.
そういう人は,政治家にも,今回の中国に対しても,原発の事故に関しても,
大津の中学校の事件に関しても,
何も発言する資格はありません!! ハッキリ言って.

『邪魔なMr.XRAYのサイトを消すのに刃物はいらぬ,
喫茶XRAYでステハンで発言すればいい』
ってね.

[6395] Re:謝ってもらいたいのは,迷惑をかけた人返信 削除
2012/9/21 (金) 08:37:50 snail3
▼ Mr.XRAYさん

私物忘れが良い方でして ^^;

過去のことを繰り返し思い出しているとだんだんと腹が立ってきてしまいますよ。

(私の場合は反応する気力が無くなったのかもしれませんが)

「嫌なことは聞かなかったふりをする。」

ことが時々できるようになりました。

[6382] Re4:Mouseメッセージの捕獲返信 削除
2012/9/19 (水) 18:12:06 おかぽん
▼ snail3さん
> マウスイベントですが、コンポーネント本体でクリックした時は
> 反応しますが、このコンポーネントに載せた子コンポーネントで
> クリックすると補足することができませんでした。子供でクリック
> した場合も横取りする方法はないでしょうか。


WM_PARENTNOTIFYをとっつかまえると、子コントロールのマウスダウンだけなら
補足できるようです。

手抜きかつDelphi5での記述ですが・・・
とりあえずTScrollBoxと位置を表示するためのTLabelを1個を配置。
それ以外は、TPanelとかTEdit,TConboBox,TListBox等を、TScrollBox上に適当に配置。

type
  TScrollBox=class(Forms.TScrollBox)
  private
    procedure WMParentNotify(var Message: TWMParentNotify); message WM_PARENTNOTIFY;
  public
    HintLabel        :TLabel;
  end;

  TForm1 = class(TForm)
    ScrollBox1: TScrollBox;
    Label1: TLabel;
    //コンポーネントいろいろ
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  end;

procedure TScrollBox.WMParentNotify(var Message: TWMParentNotify);
begin
  if HintLabel <> nil then begin
    case Message.Event of
      WM_LBUTTONDOWN: HintLabel.Caption := 'L: X=' + IntToStr(Message.XPos) + ' Y=' + IntToStr(Message.YPos);
      WM_MBUTTONDOWN: HintLabel.Caption := 'M: X=' + IntToStr(Message.XPos) + ' Y=' + IntToStr(Message.YPos);
      WM_RBUTTONDOWN: HintLabel.Caption := 'R: X=' + IntToStr(Message.XPos) + ' Y=' + IntToStr(Message.YPos);
    end;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ScrollBox1.HintLabel := Label1;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  ScrollBox1.HintLabel := nil;
end;

[6383] Re5:Mouseメッセージの捕獲返信 削除
2012/9/19 (水) 20:17:44 snail3
▼ おかぽんさん

ありがとうございました。色々とためになります。

これから試してみます。



[6384] Re5:Mouseメッセージの捕獲返信 削除
2012/9/19 (水) 20:33:14 Mr.XRAY
▼ おかぽんさん

すげぇ !! (みち子さんに『はしたなない』と言われてしまいそう)

WM_PARENTNOTIFY メッセージですか,
早速ググッてみました.なるほどです.
XPos と YPos から TWinControl はコントロールを判定できまからね.
これは使えますね.ありがとうごさいます.

>Delphi5での記述ですが・・・

でも基本は同じですからね.(^^;

[6385] Re6:Mouseメッセージの捕獲返信 削除
2012/9/19 (水) 20:53:36 Mr.XRAY
> WM_PARENTNOTIFY メッセージですか,

考えてみたら,サンプルプログラム集の中で,サブクラス化でやっている
ものの,いくつかは,このメッセージで済みますね.

サブクラスのサンプルだと思えばいいか... ?

[6386] Re6:Mouseメッセージの捕獲返信 削除
2012/9/19 (水) 23:42:26 snail3
▼ Mr.XRAYさん

> XPos と YPos から TWinControl はコントロールを判定できまからね.


これって簡単に取り出す関数無いですよね。
知っていたら教えて下さい。



[6387] Re7:Mouseメッセージの捕獲返信 削除
2012/9/20 (木) 09:56:56 Mr.XRAY
> > XPos と YPos から TWinControl はコントロールを判定できまからね.

ウィンドウハンドルを持つコントロール(TWinControl)だけですと,
こんな関数でしょうか.

 FindVCLWindow
http://docwiki.embarcadero.com/Libraries/ja/Vcl.Controls.FindVCLWindow

WindowFromPoin と FindControl の組み合わせ
http://msdn.microsoft.com/ja-jp/library/cc364874.aspx
http://docwiki.embarcadero.com/Libraries/ja/Vcl.Controls.FindControl

TGraphicControl だと,
フォーム(Self)に直接乗っているTControlの場合

  GetCursorPos(CurPos);
  Windows.ScreenToClient(Handle, CurPos);

  for i := 0 to Self.ControlCount - 1 do begin
    AControl := Controls[i];
    ARect    := AControl.BoundsRect;
    if PtInRect(ARect, CurPos) then begin
      //
      break;
    end;
  end;

な感じで検索するしかないような気がします.
更に高級な技 (^^;
[06_マウスカーソル下のオブジェクトの情報]
http://mrxray.on.coocan.jp/Delphi/plSamples/678_IAccessibleInterface.htm#06



[6388] Re7:Mouseメッセージの捕獲返信 削除
2012/9/20 (木) 11:47:48 おかぽん
▼ snail3さん
> これって簡単に取り出す関数無いですよね。
> 知っていたら教えて下さい。

すでにマスターからレスがありますが、FindVCLWindowは、ウインドウハンドルを
持っているコンポーネントしか拾うことができないようなので、
直接の子コントロールしか返してくれないけど、ウインドウハンドルなしでもOKな
ControlAtPosを使ってみると、こんな感じですかね。

上記のWMParentNotify内で行うなら
var
  ctrlPos: TPoint;
  control1, control2: TControl;

    ctrlPos := Point(Message.XPos, Message.YPos);
    control1 := ControlAtPos(ctrlPos, True, True);
    while control1 <> nil do begin
      control2 := control1;
      if control2 is TwinControl then begin
        //子コントロールの座標に変更
        ctrlPos := Point(ctrlPos.X - TwinControl(control2).Left,
                         ctrlPos.Y - TwinControl(control2).Top);
        //子コントロール内のコントロールを検索
        control1 := TwinControl(control2).ControlAtPos(ctrlPos, True, True);
      end
      else begin
        control1 := nil;
      end;
    end;
  {ここで control2 がマウス下のコンポーネント
  今更ながら、WMParentNotifyは ウィンドウハンドルのないコントロールからは
  届かないので、TScrollBoxに直接貼ったTLabelとかだと、ここではつかまえることが
  できないですね。}

[6389] Re8:Mouseメッセージの捕獲返信 削除
2012/9/20 (木) 13:10:52 Mr.XRAY
▼ おかぽんさん

これで出揃った感じですね.
ControlAtPos がありました.
これ便利ですよね.無効化したのも,子コントロールも検出しますから.

[6390] Re8:Mouseメッセージの捕獲返信 削除
2012/9/20 (木) 20:22:35 snail3
▼ おかぽんさん

最初 GetCursorPos 使ったいたんですが、キャレットが残ってしまって
うまくいきませんでした。

  control1 := ControlAtPos(ctrlPos, True, True);

今試していますが ControlAtPos を使うと、再度

WM_LBUTTONDOWN イベントが発生してしまいます。


>   今更ながら、WMParentNotifyは ウィンドウハンドルのないコントロールからは
>   届かないので、TScrollBoxに直接貼ったTLabelとかだと、ここではつかまえることが
>   できないですね。}


ユーザーは普通 Tedit なんかをクリックするので
これはあまり問題にならないと思います。


[6401] Re9:Mouseメッセージの捕獲返信 削除
2012/9/22 (土) 22:50:09 おかぽん
▼ snail3さん
> 今試していますが ControlAtPos を使うと、再度
>
> WM_LBUTTONDOWN イベントが発生してしまいます。


残念ながら、うちのDelphi5では発生しないです。
先に示したサンプル内の話ですけど。

使いどころによっては発生するんですかね?


[6402] Re10:Mouseメッセージの捕獲返信 削除
2012/9/23 (日) 12:50:26 snail3
▼ おかぽんさん
> ▼ snail3さん
> > 今試していますが ControlAtPos を使うと、再度
> >
> > WM_LBUTTONDOWN イベントが発生してしまいます。
>
> 残念ながら、うちのDelphi5では発生しないです。
> 先に示したサンプル内の話ですけど。
>
> 使いどころによっては発生するんですかね?


試しに おかぽんさん 提供のソースでそのまま実行したところ
確かに発生しませんね。

もう少し調べてみます。

[6403] Re11:Mouseメッセージの捕獲返信 削除
2012/9/23 (日) 13:49:34 snail3
▼ snail3さん

原因がわかりました。
色々と触っているときに

Application.ProcessMessages;

これを入れちゃていました。

余計なお手間をおかけしてすみませんでした。


[6404] Re12:Mouseメッセージの捕獲返信 削除
2012/9/23 (日) 14:19:10 Mr.XRAY
▼ snail3さん

> Application.ProcessMessages;
>
> これを入れちゃていました。


Application.ProcessMessages の使い方って,結構難しいですよね.
これを入れないと,処理が飛ぶこともありますが.
一方で,挙動がおかしくなることがあります.
具体的な処理の内容によりますね.

今回の場合は,キューにたまっているのを処理してくれた,
ということでしょう.Windows さんがまじめにやった,というこで...
お許しください.

[6407] Re13:Mouseメッセージの捕獲返信 削除
2012/9/24 (月) 00:27:20 snail3
▼ Mr.XRAYさん
 
> Application.ProcessMessages の使い方って,結構難しいですよね.
> これを入れないと,処理が飛ぶこともありますが.
> 一方で,挙動がおかしくなることがあります.
> 具体的な処理の内容によりますね.
>
> 今回の場合は,キューにたまっているのを処理してくれた,
> ということでしょう.Windows さんがまじめにやった,というこで...
> お許しください.


一件落着と思ったら、複雑怪奇。ゾンビのごとく復活してきます。
メインルーチンの ProcessMessages で WMParentNotify
が呼び出されてしまいます。(;_;)

[6408] Re14:Mouseメッセージの捕獲返信 削除
2012/9/24 (月) 01:06:03 snail3
▼ snail3さん

BlockInput 関数で囲んだらいい感じ。


http://mrxray.on.coocan.jp/Delphi/plSamples/840_CancellLockDisable.htm

ためになります。


[6410] Re15:Mouseメッセージの捕獲返信 削除
2012/9/24 (月) 07:41:00 Mr.XRAY
▼ snail3さん

「勝てば官軍,動けば正義」ということにしますか.

TApplication.ProcessMessages は,例えば,キーやフックで,処理コード
内でループしで処理すると,おかしな動作をしてしまうことがあります.
また,ファイルの一覧を取得する時に使用する,findfirst, findNext
のループで使用しても同様に,シェルの項目識別子を使用したファイル
情報取得のループ内でも同じですね.

TApplication.ProcessMessages はあくまでも,I/O 処理待ち用です.
Sleep(1) とか Sleep(10) なんてのもよく使用しますが,

あっ,思い出した.Sleep で,TApplication.ProcessMessagesとは違いますが
最近こんのながありました.
これは,Label の文字描画が終了しない内に,Sleep の処理に入って
しまうために,文字が描画更新されない,というものです.

http://www.freeml.com/delphi-users/2732/latest




[6438] Re16:Mouseメッセージの捕獲返信 削除
2012/10/4 (木) 20:03:22 snail3
▼ Mr.XRAYさん
▼ おかぽんさん

あれからもメインルーチンにある

 Application.ProcessMessages

で時々ゾンビが発生していまして、困っていました。

意味は全然わかっていないのですが

    Message.Value :=  0;  // ←これでイベントのループが消える?

を入れることで解決したようです。


[6439] Re17:Mouseメッセージの捕獲返信 削除
2012/10/5 (金) 10:23:52 Mr.XRAY
▼ snail3さん

苦労していますね.お疲れ様です.

>    Message.Value :=  0;  // ←これでイベントのループが消える?

これはメッセージなしにすることですね.なるほど,その手がありましたか.
これで何とか落ち着くといいですね.
無事を祈っています (^^;


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