喫茶XRAYトップページ

[スレッド全体
]

[7447] Re6:マウスがコントロールから去った時のイベント返信 削除
2014/4/5 (土) 18:08:03 空色の渚
Taki様

 はじめまして。
 わたしも、新規作成で挑戦してみましたが、やはり反応しませんでした。
 新規作成 → ボタン、メモ、ApplicationEvents1 配置 →
 ApplicationEvents1 の onMessage Wクリック 中身のみペースト → コンパイル
 コンパイル時にエラーは出ません。
 何事もなかったように動き出しますが、反応しませんでした。
 
 当方の環境は、

 Windows7 32bit + Delphi 5 Professional  です。

 残念です。
 ひょっとすると、WM_MOUSELEAVE そのものを Ver.5 では返さないのかもしれないです。
 むかし、他のコンパイラですが、定義はされているけど「意味を持たない」みたいな宣言があったように思います。
 ので、未定義の宣言みたいなエラーがでないのではないでしょうか?


[7448] Re7:マウスがコントロールから去った時のイベント返信 削除
2014/4/5 (土) 18:58:58 taki
▼ 空色の渚さん

>  残念です。
>  ひょっとすると、WM_MOUSELEAVE そのものを Ver.5 では返さないのかもしれないです。
>  むかし、他のコンパイラですが、定義はされているけど「意味を持たない」みたいな宣言があったように思います。
>  ので、未定義の宣言みたいなエラーがでないのではないでしょうか?


う〜ん。ごめんなさい。
私の手には負えません。残念です。


[7449] Re8:マウスがコントロールから去った時のイベント返信 削除
2014/4/5 (土) 22:41:05 Mr.XRAY
▼ takiさん,すみません.スレッドのつながりでここにレスします.

今か帰ってきました.桜はまだきれいでした.

 空色の渚さん,

>言葉に甘えまして、さっそく組み込み前のtest21.pas にコピペしてみました。

テストしていただき,ありがとうございます.
掲示板等でレスした時は,感謝の言葉も嬉しいのですが,本当にうれしいのは
実際に質問された方にテストして頂くこくとです.
このことで,更にサイトの記事も充実していけます.

で,空色の渚 さんの環境でおきている現象ですが,
いま戻ってきたばかりなので,後で調べてみます.


[7451] Delphi 5のMouseLeaveメッセージ返信 削除
2014/4/6 (日) 13:30:00 Mr.XRAY
▼ takiさん,空色の渚さん,

空色の渚さんのテストの結果から判断すると,
Delphi 5 では WM_MOUSELEAVE は実装されているが,実際には検出しないみたいですね.
CM_MOUSELEAVE メッセージを使用するコードを書いてみました.
このメッセージは,Delphi 1 の時からあるので,多分動作するのではと.

例によって,TForm1 のクラス内で処理する場合と,
TButton の継承クラスのコードを書いてみました.
継承クラスを使う方法は,コンポーネントとして使う場合の参考です.
CM_XXXX メッセージについては,以下を参考にしてください.

[10-04_コンポーネントの内部メッセージと通知メッセージ]
http://mrxray.on.coocan.jp/Delphi/plSamples/160_CreateComponent.htm#10-04

参考リンクの VCL Component Messages [RTF] - delphi about.com を
ダウンロードすると,メッセージの説明があります.
ただし,英語です.

動作確認は,Windows 7 U64(SP1) + Delphi XE Pro ですので,あしからず.


[7452] Re:Delphi 5のMouseLeaveメッセージ返信 削除
2014/4/6 (日) 13:33:18 Mr.XRAY
> このメッセージは,Delphi 1 の時からあるので,多分動作するのではと.

実際のコードです,usse 部は省略しています.
uses 部に追加するものはありません.多分.

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
  private
  protected
    { Private 宣言 }
    procedure CMMouseleave(var Message: TMessage); message CM_MOUSELEAVE;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

type
  TCMMouseLeave = record
    Msg    : Cardinal;
    Unused : Integer;
    Sender : TControl;
    Result : LongInt;
  end;

{ TForm1 }

procedure TForm1.CMMouseleave(var Message: TMessage);
begin
  inherited;
  if TCMMouseLeave(Message).Sender = Button1 then begin
    Memo1.Lines.Add('Leave');
  end;
end;

TCMMouseLeave = record の定義は
Inside Delphi (Borland programming series) [単行本]
Ray Lischner 著
満田 秀訳,大野 元久,服部 誠監修の
634 頁にあるものを使用しました.
http://www.amazon.co.jp/dp/4756119514


[7453] Re2:Delphi 5のMouseLeaveメッセージ返信 削除
2014/4/6 (日) 13:35:06 Mr.XRAY
> 実際のコードです,usse 部は省略しています.
> uses 部に追加するものはありません.多分.


続いて,TButton の継承クラスを作成して使用する例です.

type
  TMyButton = class(TButton)
  protected
    procedure CMMouseleave(var Message: TMessage); message CM_MOUSELEAVE;
  public
    procedure Click; override;
  end;

  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure Button1MouseEnter(Sender: TObject);
  private
    MyButton1 : TMyButton;
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1MouseEnter(Sender: TObject);
begin
  Memo1.Lines.Add('AAAA');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  MyButton1 := TMyButton.Create(Self);
  MyButton1.Parent := Self;
  MyButton1.Left   := 20;
  MyButton1.Top    := 5;
end;

{ TMyButton }

procedure TMyButton.Click;
begin
  inherited;
  ShowMessage('クリック');
end;

procedure TMyButton.CMMouseleave(var Message: TMessage);
begin
  inherited;
  Form1.Memo1.Lines.Add('Leave');
end;


[7454] Re2:Delphi 5のMouseLeaveメッセージ返信 削除
2014/4/6 (日) 14:28:49 空色の渚
Mr.XRAYさん

 さっそくのご教示有り難うございました。
 動きました!
 メモに文字が出ました(涙

 引き続き、現在テスト中の環境に実装してみます。
 左にある「閉じる」ボタンが水色になれば完成です。

 


[7455] Re3:Delphi 5のMouseLeaveメッセージ返信 削除
2014/4/6 (日) 14:49:14 空色の渚
Mr.XRAYさん

>  引き続き、現在テスト中の環境に実装してみます。
>  左にある「閉じる」ボタンが水色になれば完成です。


 判定部分をイメージの上に変更し、実行したところ
見事に動作いたしました。
 マウスを下ろせば、元に戻り、乗せれば色が変わる。
 これぞフラットデザインの象徴的なボタンが出来上がりました。

 感謝。
 感謝。
 
 最後まで面倒を見て頂き、有り難うございました。




[7456] Re4:Delphi 5のMouseLeaveメッセージ返信 削除
2014/4/6 (日) 15:59:17 Mr.XRAY
▼ 空色の渚さん

動作してよかったでござんす.
そして,お疲れ様でした.
taki さんも動作確認サンクスです,

更に,掲示板にはレスしなかったけど,実際にコードをテストした方々,
サンクスです.


[7457] Re4:Delphi 5のMouseLeaveメッセージ返信 削除
2014/4/6 (日) 16:18:31 空色の渚
Mr.XRAY 様

 残念な続報です。

 私が作っているプログラムへ移植したところ反応しなくなりました。
 30分ほど四苦八苦して、気づいたのが Timage が、Tpanel の上に
乗っているということでした。
 そこで、先ほどの実験用の form に Tpanel 貼り付け、その上に
Timage を乗せて実験したところ反応しなくなりました(涙
 何が彼等をそうさせてしまうのでしょう?
 対応策はできますでしょうか?

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

 


[7458] Re5:Delphi 5のMouseLeaveメッセージ返信 削除
2014/4/6 (日) 19:16:40 Mr.XRAY
▼ 空色の渚さん

> Timage を乗せて実験したところ反応しなくなりました(涙
>  何が彼等をそうさせてしまうのでしょう?


それはですね.普段の行いが悪いからです.
よ〜く,思い出してください.

>  対応策はできますでしょうか?

上記の理由から,心を改め,普段の行動を改めることです.
こういうのを
「身から出たさび」とか「天網恢恢疎にして漏らさず」
というわけです.
ウソ,ウソです (^^;


他のコントロールに載せているコントロールの場合,
親のコントロールがメッセージを処理します.
このような場合,対象にするコントロールに CM_MOUSELEAVE メッセージを処理する
機能をつけることになります.
その方法は,前に書いたように,継承クラスを作成する.つまりコンポーネントを
作ることです.そのための継承クラスの作成機能があるわけです.
もう1つの方法は,前にも述べた,サブクラス化の方法です,
サブクラス化は,その対象コントロールはあまり使わない,一時的な場合には
便利です.
以下は,サブクラス化のコード例です.
図は,テスト用のフォームの設計時の画面です,
動作確認環境は,またまた Windows 7 U64(SP1) + Delphi XE Pro です.

サブクラスについては,以下を参考にしてください.
[サブクラス化コンポーネント]
http://mrxray.on.coocan.jp/Halbow/Notes/N004.html

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Panel1: TPanel;
    Image1: TImage;
    procedure FormCreate(Sender: TObject);
  private
  protected
    { Private 宣言 }
    OriginalImageProc : TWndMethod;
    procedure SubClassImageProc(var Message:TMessage);
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

{ TForm1 }
//-----------------------------------------------------------------------------
//  アプリ開始時にImage1のWindowProcを自作のWindowProcに置き換える
//  サブクラス関数の名前は何でもいいが,引数はvar Message:TMessage だけ
//-----------------------------------------------------------------------------
procedure TForm1.FormCreate(Sender: TObject);
begin
  OriginalImageProc := Image1.WindowProc;
  Image1.WindowProc := SubClassImageProc;

  //テスト用の画像をImage1に表示
  Image1.Stretch := True;
  Image1.Picture.LoadFromFile('503.bmp');
end;

//-----------------------------------------------------------------------------
//  自作のImage1専用WindowProcのサブクラス化関数
//-----------------------------------------------------------------------------
procedure TForm1.SubClassImageProc(var Message: TMessage);
begin
  //元のWindowProcは必ず実行する
  OriginalImageProc(Message);

  case Message.Msg of
  CM_MOUSELEAVE:
    begin
      Memo1.Lines.Add('Leave');
    end;
  end;
end;


[7459] Re6:Delphi 5のMouseLeaveメッセージ返信 削除
2014/4/6 (日) 19:26:28 Mr.XRAY
> 他のコントロールに載せているコントロールの場合,
> 親のコントロールがメッセージを処理します.


したがって,もし,Image1 の Align が alClient であれば,

procedure TForm1.CMMouseleave(var Message: TMessage);
begin
  inherited;
  if TCMMouseLeave(Message).Sender = Panel1 then begin
    Memo1.Lines.Add('Leave');
  end;
end;

のように,親の TPanel で処理しても構わないと思います.


[7460] Re7:Delphi 5のMouseLeaveメッセージ返信 削除
2014/4/6 (日) 21:50:20 空色の渚
Mr.XRAY様

 今、頂きましたコードを実装致しました。

 結論から書かせていただくと、意図したとおりになりました。

 なぜ意図したとおりに動いたのかわかりませんが、
> したがって,もし,Image1 の Align が alClient であれば,
 と書かれていたので、 alclient にしたところ、「閉じる」ボタンのイメージが
すぅっとパネルに吸い込まれて、下段になくてはならないのに上段へ移動して
しまいました。
 ダメだこりゃ!?とばかりに、ここに書かれているとおりに、panel のname を
そのまま(PL5 というnameにしてある)書き込んでみたら、マウスオンで色が変わり、
マウスアウトで色が元に戻りました。
 理由はよく分からないのですが、とにかく意図したとおり動きました。
 上手く動いているので、いいかな?という気もしますが、理屈に合っていますか?

 このパネルの上に2枚のimage を置いたらどうなるのだろう?とか考えて
しまいますが、偶然なのでしょうか?

 どうもクラスの継承あたりが苦手です(苦笑

 今回も大変お世話になりました。
 ありがとうございました。


追伸

 余談ながら
 私の普段の行いは、秋の青空のように澄んでいるとよく言われます。
 根が爽やかなので、作るソフトのデザインも爽やかです。
 ただ、動作が微妙なのですね。
 よく分からずに書いているコードがあるので(笑)
 「動いたからいいや」みたいな点だけは、高田純次っていわれています。


> > 他のコントロールに載せているコントロールの場合,
> > 親のコントロールがメッセージを処理します.
>
> したがって,もし,Image1 の Align が alClient であれば,
>
> procedure TForm1.CMMouseleave(var Message: TMessage);
> begin
>   inherited;
>   if TCMMouseLeave(Message).Sender = Panel1 then begin
>     Memo1.Lines.Add('Leave');
>   end;
> end;
>
> のように,親の TPanel で処理しても構わないと思います.


[7461] Re8:Delphi 5のMouseLeaveメッセージ返信 削除
2014/4/6 (日) 22:15:58 Mr.XRAY
▼ 空色の渚さん

>  ダメだこりゃ!?とばかりに、ここに書かれているとおりに、panel のname を
> そのまま(PL5 というnameにしてある)書き込んでみたら、マウスオンで色が変わり、
> マウスアウトで色が元に戻りました。


ここ ?
「ここ」がどこかは分かりませんが,プログラムは
「勝てば官軍,動けば正義」です.ハッキリ言って.


[7462] Re8:Delphi 5のMouseLeaveメッセージ返信 削除
2014/4/7 (月) 07:58:47 Mr.XRAY
▼ 空色の渚さん

>  どうもクラスの継承あたりが苦手です(苦笑

そうですか ? 折角意識的に継承クラス,つまりコンポーネント化の参考となる
コードを提示しているのにぃ.
了解しました.今後は,継承クラスやコンポーネント化しないとできない
場合は,「できません」とレスします.

# 昔,データベース関係のレスで SQL 文の使用を勧めたところ,
# 同様の反応が何回か続いたことがありました.
# それ以来データベース関係にはレスしなくなり,記事も書かなくなりました.


[7463] Re9:Delphi 5のMouseLeaveメッセージ返信 削除
2014/4/7 (月) 09:16:58 空色の渚
Mr.XRAY様

 動いたので官軍だったと思います。
 しかし、開発していたマシンでは問題なかったのですが、
家のマシンで動かしたら、やはり元の「戻らない状態」に戻りました。
 動いていた理由がやはりわかりません。
 
 
 プログラムを組んでいて、自分の限界にぶち当たり
一人でへこんでいたところこの掲示板で助けられました。
 そんな中、誰ともわからぬ人に、無償で知識を提供してくださることに
大変な感謝をしております。
 意識的に継承クラス,コンポーネント化の参考となるコードまで提示して
頂いたことには頭が下がるばかりです。

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


> >  どうもクラスの継承あたりが苦手です(苦笑
>
> そうですか ? 折角意識的に継承クラス,つまりコンポーネント化の参考となる
> コードを提示しているのにぃ.
> 了解しました.今後は,継承クラスやコンポーネント化しないとできない
> 場合は,「できません」とレスします.
>
> # 昔,データベース関係のレスで SQL 文の使用を勧めたところ,
> # 同様の反応が何回か続いたことがありました.
> # それ以来データベース関係にはレスしなくなり,記事も書かなくなりました.


[7466] Re10:Delphi 5のMouseLeaveメッセージ返信 削除
2014/4/8 (火) 16:51:03 Mr.XRAY
▼ 空色の渚さん

なんか,お役に立たなかったようで,申し訳ありません.


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