VBでいうとこのマウスアウトイベントを実現するためには?


VB出身  2005-10-08 20:36:47  No: 17967

最近気づいたのですが、デルファイってイベントの数少ないですね。
マウスアウトをどうにかして発生させる方法ってあるのですか?よろしくお願いいたします。


ママん  2005-10-08 21:47:52  No: 17968

CM_MOUSELEAVE
WM_MOUSELEAVE
>最近気づいたのですが、デルファイってイベントの数少ないですね。
とりあえずイベントとは何かを調べましょ。
Delphiは少なくともVB以上にWindowsを学ばなくてはなりません。


3.  2005-10-09 09:22:53  No: 17969

WM_MOUSELEAVE
Minimum operating systems Windows 98, Windows NT 4.0


VB出身  2005-10-13 03:01:03  No: 17970

お世話になります。Delphiではどのようにメッセージを受け取るのでしょうか?


えーと  2005-10-13 03:06:31  No: 17971

> Delphiではどのようにメッセージを受け取るのでしょうか?

いろいろあります。

派生クラスを作れば、メッセージハンドラを追加できますし、WndProc を
overide できますし、派生クラスを作らなければ WindowProc を入れ替える
いわゆるサブクラス化もできます。

具体的なコンポーネントをあげていないので一般論だけ回答しておきます。


えーと  2005-10-13 03:08:48  No: 17972

あと忘れていましたが、派生クラスでは
DefaultHandler を override する場合もあります。


VB出身  2005-10-18 03:20:57  No: 17973

全く理解できないのですが、どこかサンプルコードかなんか公開している場所ってないですかね?


ママん  2005-10-18 04:24:20  No: 17974

具体的なコンポーネントがあがってないので回答が具体的にできないのです。
http://www2.big.or.jp/~osamu/Delphi/Tips/new.cgi#0101.txt


Mr.XRAY  URL  2005-10-18 09:15:55  No: 17975

例えばです.新規のプロジェクトを作成して(新規が重要!!!)
Panelを一つ配置して(なるべく上の方)以下のコードを実行してみて下さい.
FormのOnCreateはオブジェクトインスペクタで作成,他は,private部に
コードを書いて,[Shift]+[Ctrl]+[C]で実現部作成後,コードをコピペ.
(まるっきりコピペも可)

# きっとVBでは簡単なんでしょうね.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls;

type
  TMyMemo = class(TMemo)
  private
    procedure CMMouseEnter(var Msg: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Msg: TMessage); message CM_MOUSELEAVE;
  end;

  TForm1 = class(TForm)
    Panel1: TPanel;
    procedure FormCreate(Sender: TObject);
  private
    { Private 宣言 }
    AMyMemo : TMyMemo;
    procedure CMMouseEnter(var Msg: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Msg: TMessage); message CM_MOUSELEAVE;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses DebugWndUnit;

{$R *.DFM}

{ TForm1 }

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
     AMyMemo:=TMyMemo.Create(Self);
     AMyMemo.Parent:=Self;
     AMyMemo.Left:=100;
     AMyMemo.Top :=100;
end;

procedure TForm1.CMMouseEnter(var Msg: TMessage);
begin
     Panel1.Caption:='フォームに来た';
end;

procedure TForm1.CMMouseLeave(var Msg: TMessage);
begin
     Panel1.Caption:='メモに行ってしまった';
end;

{ TMyMemo }

procedure TMyMemo.CMMouseEnter(var Msg: TMessage);
begin
     Self.Lines.Add('メモに来た');
end;

procedure TMyMemo.CMMouseLeave(var Msg: TMessage);
begin
     Self.Lines.Add('メモから逃げた');
end;

end.


Mr.XRAY  URL  2005-10-18 09:21:34  No: 17976

Formの外にいってもPanel1に'メモに行ってしまった'
と表示されてしまいますが,気にしないで下さい.


VB出身  2005-10-22 06:06:38  No: 17977

みなさんありがとうございます。
チェックリストボックスとイメージ?コンポーネントです。これを参考に作ってみます。


VB出身  2005-10-23 19:45:47  No: 17978

これはコンポーネントがフォームに直接くっついていないとだめなのでしょうか?


えーと  2005-10-23 20:29:34  No: 17979

自分で試すってことも重要ですよ。


Mr.XRAY  URL  2005-10-23 22:07:12  No: 17980

>これはコンポーネントがフォームに直接くっついていないとだめなのでしょうか?

私の提示したコードのことでしょうか.
試してみましたか? 

提示したコードは,たまたまCMMouseEnterが他の方のレスにあったので
示したものです.マウスアウトというのが,どのような状態で,それに
よってどんな動作を行いたいかによっても,それを実現する方法は違って
くると考えられます.


VB出身  2005-10-24 04:27:43  No: 17981

みなさんすいません。まだ、勉強途中でして。

>type
>  TMyMemo = class(TMemo)
>  private
>    procedure CMMouseEnter(var Msg: TMessage); message CM_MOUSEENTER;
>    procedure CMMouseLeave(var Msg: TMessage); message CM_MOUSELEAVE;
>  end;

の部分が

>派生クラスを作れば、メッセージハンドラを追加できますし、WndProc を
overide できますし

と、いうことなのでしょうか?どうもclassの意味がわからないのですが、これでとにかくTMyMemoが感知できるメッセージが増えたと思っていいのでしょうか?
それと、コード中でself変数を使っているのですが、なぜ使えるのですか?
初心者で申し訳御座いません。


ママん  2005-10-24 05:28:18  No: 17982

> これでとにかくTMyMemoが感知できるメッセージが増えたと思っていいので
> しょうか?
良いです。

> コード中でself変数を使っているのですが、なぜ使えるのですか?
self = Form1


えーと  2005-10-24 15:34:58  No: 17983

> どうもclassの意味がわからないのですが

Seventh Delphi などの入門サイトでじっくり勉強した方が結局近道になりますよ。
各論をたくさん解決したとしても、体系的な理解にはつながりません。


VB出身  2005-10-25 20:06:36  No: 17984

># きっとVBでは簡単なんでしょうね.
はい。確かイベントが用意されていたような気がします。

>(新規が重要!!!)
の意味がわかりました。(多分)
それなんですが、
>AMyMemo : TMyMemo;
で、メッセージを感知できるメモコンポーネントを作成したと思っているのですが、僕の場合、元からあるチェックボックスにメッセージを感知させようと思っているのですが、どうすればいいのでしょうか?

無駄だと思って、
AmyCheckbox(元からあるコンポーネントネーム): TmyCheckBox(クラス定義したチェックボックス)
とやっても駄目でした。多重定義だと言われました。

>体系的な理解にはつながりません。
おっしゃるとおりです。

>self = Form1
ですが、
>Self.Lines.Add('メモに来た');
が使われています。self変数の勉強不足ですが、どうみてもself=memoのような気がします。気のせいですか?


えーと  2005-10-25 20:13:50  No: 17985

self はそのコードが書かれているメソッドのクラスの実行時にインスタンスそのものです。あいまいさはゼロです。

procedure TForm1.FormCreate(Sender: TObject);
begin
     AMyMemo:=TMyMemo.Create(Self);
     AMyMemo.Parent:=Self;
     AMyMemo.Left:=100;
     AMyMemo.Top :=100;
end;

の場合は self は Form1 であり、

procedure TMyMemo.CMMouseEnter(var Msg: TMessage);
begin
     Self.Lines.Add('メモに来た');
end;

の場合の self は、 TMyMemo の実行時インスタンスです。


えーと  2005-10-25 20:17:28  No: 17986

追加です。

後者のように、コンポーネントのメソッドで self は自分自身なので一般には
必要ありません。

Lines.Add('メモに来た');

で十分です。


masayan  2005-10-27 02:21:07  No: 17987

とりあえず、こんな感じでどうでしょう?

type
  TForm1 = class(TForm)
    CheckBox1: TCheckBox;
  private
    { Private 宣言 }
  protected
    procedure WndProc(var Message : TMessage); override;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.WndProc(var Message : TMessage);
var
  Sender : TObject;
begin
  case Message.Msg of
  CM_MOUSEENTER:
    begin
      Sender := TObject(Message.LParam);
      if Sender = CheckBox1 then
      begin
        // マウスカーソルがCheckBox1に入ったときの処理
        // ↓とりあえず、フォントを太字に...
        if not (fsBold in CheckBox1.Font.Style) then
          CheckBox1.Font.Style := [fsBold];
      end;
    end;
  CM_MOUSELEAVE:
    begin
      Sender := TObject(Message.LParam);
      if Sender = CheckBox1 then
      begin
        // マウスカーソルがCheckBox1から出たときの処理
        // ↓とりあえず、フォントを標準に...
        if fsBold in CheckBox1.Font.Style then
          CheckBox1.Font.Style := [];
      end;
    end
  end;

  // 標準のWndProcを呼び出す。
  inherited WndProc(Message);
end;


VB出身  2005-11-08 05:00:49  No: 17988

返事がラフでごめんなさい。勉強しておりました。
masayanさんのコードですが、
>type
>  TForm1 = class(TForm)
>    CheckBox1: TCheckBox;
>  private
>    { Private 宣言 }
>  protected
>    procedure WndProc(var Message : TMessage); override;
>  public
>    { Public 宣言 }
>  end;
ですが、これだとフォームに直接のったコンポーネントしか検知できません。
できれば、Tpanelの上にのったコンポーネントの検知したいのですが、

フォームの定義型変数(?:type)がある下に
type
  OrgnPanel = class(TPanel)
  CheckBox1: TCheckBox;
とやるか、
今までユニット一個でプログラムを組んでいたのですが、
別のユニットに
オリジナルのTpanelを組んで
procedure WndProc(var Message : TMessage); override;
をオーバライドしようと思うのですが、これだとパブリックに宣言しないと行けないですよね?
それはとっても初心者ながらに不安なのです。
というか、どっちも不安なのですが。
何かいい方法ないでしょうか?


masayan  2005-11-08 21:06:02  No: 17989

Panel上のコンポーネントに対するCM_MOUSEENTER,CM_MOUSELEAVE
メッセージは、PanelのWndProcで処理する必要があるみたいですね。
オリジナルのPanelコンポーネントを作る以外に、次のような方法
もあります。

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    CheckBox1: TCheckBox; // <= Panel1上に配置
    procedure FormCreate(Sender: TObject);
  private
    { Private 宣言 }
    FOrgPanelWndProc : TWndMethod;
    procedure PanelWndProc(var Message : TMessage);
  public
    { Public 宣言 }

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  // Panel1標準のWindowProc(=WndProc)を保存する
  FOrgPanelWndProc := Panel1.WindowProc;
  // Panel1標準のWindowProc(=WndProc)をPanelWndProcに置き換える
  Panel1.WindowProc := PanelWndProc;
end;

procedure TForm1.PanelWndProc(var Message : TMessage);
var
  Sender : TObject;
begin
  case Message.Msg of
  CM_MOUSEENTER:
    begin
      Sender := TObject(Message.LParam);
      if Sender = CheckBox1 then
      begin
        // マウスカーソルがCheckBox1に入ったときの処理
        // ↓とりあえず、フォントを太字に...
        if not (fsBold in CheckBox1.Font.Style) then
          CheckBox1.Font.Style := [fsBold];
      end;
    end;
  CM_MOUSELEAVE:
    begin
      Sender := TObject(Message.LParam);
      if Sender = CheckBox1 then
      begin
        // マウスカーソルがCheckBox1から出たときの処理
        // ↓とりあえず、フォントを標準に...
        if fsBold in CheckBox1.Font.Style then
          CheckBox1.Font.Style := [];
      end;
    end
  end;

  // 保存しておいた標準のWndProcを呼び出す。
  FOrgPanelWndProc(Message);
end;


VB出身  2005-11-09 20:09:41  No: 17990

ありがとうござあいます.
大変参考になります.
ただ,MouseEnterイベントをプロパティとしても使いたいのです.
そうなるとやはり,typeにOrgPanel(オリジナルパネル)を宣言してプロパティも作ろうと思うのです.
ただ,作り方がわかりません.WinProcで,例えばOrgPanelのMouseEnterを判断するのは難しいような気がして気が進みません.
masayanさんありがとうございます.


りおりお  2005-11-09 22:55:37  No: 17991

上の Mr.XRAY さんの回答そのものだと思います。TMemo 派生のところを TPanel
派生にするだけです。

これまでの回答をちゃんと読むとすでに解決してるはずなんですが。

> MouseEnterイベントをプロパティとしても使いたいのです

これはイベントにしたいということですよね?
普通のプロパティーのつくり方と変わりませんよ。ソースがあるなら
たくさんサンプルがみつかるでしょう。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加