最近気づいたのですが、デルファイってイベントの数少ないですね。
マウスアウトをどうにかして発生させる方法ってあるのですか?よろしくお願いいたします。
CM_MOUSELEAVE
WM_MOUSELEAVE
>最近気づいたのですが、デルファイってイベントの数少ないですね。
とりあえずイベントとは何かを調べましょ。
Delphiは少なくともVB以上にWindowsを学ばなくてはなりません。
WM_MOUSELEAVE
Minimum operating systems Windows 98, Windows NT 4.0
お世話になります。Delphiではどのようにメッセージを受け取るのでしょうか?
> Delphiではどのようにメッセージを受け取るのでしょうか?
いろいろあります。
派生クラスを作れば、メッセージハンドラを追加できますし、WndProc を
overide できますし、派生クラスを作らなければ WindowProc を入れ替える
いわゆるサブクラス化もできます。
具体的なコンポーネントをあげていないので一般論だけ回答しておきます。
あと忘れていましたが、派生クラスでは
DefaultHandler を override する場合もあります。
全く理解できないのですが、どこかサンプルコードかなんか公開している場所ってないですかね?
具体的なコンポーネントがあがってないので回答が具体的にできないのです。
http://www2.big.or.jp/~osamu/Delphi/Tips/new.cgi#0101.txt
例えばです.新規のプロジェクトを作成して(新規が重要!!!)
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.
Formの外にいってもPanel1に'メモに行ってしまった'
と表示されてしまいますが,気にしないで下さい.
みなさんありがとうございます。
チェックリストボックスとイメージ?コンポーネントです。これを参考に作ってみます。
これはコンポーネントがフォームに直接くっついていないとだめなのでしょうか?
自分で試すってことも重要ですよ。
>これはコンポーネントがフォームに直接くっついていないとだめなのでしょうか?
私の提示したコードのことでしょうか.
試してみましたか?
提示したコードは,たまたまCMMouseEnterが他の方のレスにあったので
示したものです.マウスアウトというのが,どのような状態で,それに
よってどんな動作を行いたいかによっても,それを実現する方法は違って
くると考えられます.
みなさんすいません。まだ、勉強途中でして。
>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変数を使っているのですが、なぜ使えるのですか?
初心者で申し訳御座いません。
> これでとにかくTMyMemoが感知できるメッセージが増えたと思っていいので
> しょうか?
良いです。
> コード中でself変数を使っているのですが、なぜ使えるのですか?
self = Form1
> どうもclassの意味がわからないのですが
Seventh Delphi などの入門サイトでじっくり勉強した方が結局近道になりますよ。
各論をたくさん解決したとしても、体系的な理解にはつながりません。
># きっとVBでは簡単なんでしょうね.
はい。確かイベントが用意されていたような気がします。
>(新規が重要!!!)
の意味がわかりました。(多分)
それなんですが、
>AMyMemo : TMyMemo;
で、メッセージを感知できるメモコンポーネントを作成したと思っているのですが、僕の場合、元からあるチェックボックスにメッセージを感知させようと思っているのですが、どうすればいいのでしょうか?
無駄だと思って、
AmyCheckbox(元からあるコンポーネントネーム): TmyCheckBox(クラス定義したチェックボックス)
とやっても駄目でした。多重定義だと言われました。
>体系的な理解にはつながりません。
おっしゃるとおりです。
>self = Form1
ですが、
>Self.Lines.Add('メモに来た');
が使われています。self変数の勉強不足ですが、どうみてもself=memoのような気がします。気のせいですか?
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 の実行時インスタンスです。
追加です。
後者のように、コンポーネントのメソッドで self は自分自身なので一般には
必要ありません。
Lines.Add('メモに来た');
で十分です。
とりあえず、こんな感じでどうでしょう?
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;
返事がラフでごめんなさい。勉強しておりました。
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;
をオーバライドしようと思うのですが、これだとパブリックに宣言しないと行けないですよね?
それはとっても初心者ながらに不安なのです。
というか、どっちも不安なのですが。
何かいい方法ないでしょうか?
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;
ありがとうござあいます.
大変参考になります.
ただ,MouseEnterイベントをプロパティとしても使いたいのです.
そうなるとやはり,typeにOrgPanel(オリジナルパネル)を宣言してプロパティも作ろうと思うのです.
ただ,作り方がわかりません.WinProcで,例えばOrgPanelのMouseEnterを判断するのは難しいような気がして気が進みません.
masayanさんありがとうございます.
上の Mr.XRAY さんの回答そのものだと思います。TMemo 派生のところを TPanel
派生にするだけです。
これまでの回答をちゃんと読むとすでに解決してるはずなんですが。
> MouseEnterイベントをプロパティとしても使いたいのです
これはイベントにしたいということですよね?
普通のプロパティーのつくり方と変わりませんよ。ソースがあるなら
たくさんサンプルがみつかるでしょう。
ツイート | ![]() |