紧急求助:关于在控件中自定义消息以及在应用程序中向对象发送消息和响应消息(100分)

  • 主题发起人 主题发起人 bells
  • 开始时间 开始时间
B

bells

Unregistered / Unconfirmed
GUEST, unregistred user!
问题是这样的:我要继承F1Book做一个控件,在其中自定义一个消息,
当应用程序(用户)向对象实例发送此消息时(例如点击button按钮时)
此对象实例执行的动作是将book中的数据存盘.我该在控件中如何写代码,在应用程序中又该如何发送消息?请指教.
interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
OleCtrls, vcf1, Db, DBTables;
const
WM_Mymessage=WM_USER+200;
type
TSaveEvent=procedure(Sender:TObject;bc:string) of Object;
TMyBook = class(TF1Book)
private
{ Private declarations }
FOnSave:TSaveEvent;
FWindowHandle:HWND;
procedure WndProc(var msg : TMessage);
protected
{ Protected declarations }
procedure dosave;dynamic;
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
{ Published declarations }
property OnSave:TSaveEvent read FOnSave write FOnSave;
end;

procedure Register;

implementation
procedure TMyBook.WndProc(var msg:tmessage);
begin
with msg do
if msg=WM_Mymessage then
dosave
else
result:=defwindowproc(fwindowhandle,msg,wparam,lparam);
end;

procedure TMyBook.dosave;
begin
//数据存盘
end;
end.
 
无需如此, 只需如此:

...
protected
procedure WMMyMessage(var Msg: TMessage); WM_Mymessage;
...

procedure TMyBook.WMMyMessage(var Msg: TMessage);
begin
dosave;
end;

在程序中:
procedure TForm1.Button1Click(Sender);
begin
SendMessage(MyBook1, WM_Mymessage, 0, 0);
end;
 
谢谢xWolf如此迅速的解答,您的见解离解决问题不远了.
再问:如何响应控件中自定义的事件?例如
TSaveEvent=procedure(Sender:TObject;bc:string) of Object;
private
FOnSave:TSaveEvent;
published
property OnSave:TSaveEvent read FOnSave write FOnSave;
就像点击控件就触发onclick事件一样.
 
TForm1=class(TForm)
private
YouClass:TYouClass;
procedure MyProc(Sender:TObject;bc:string);
public
{...}
end;

constructor TForm1.Create(Onwer:TComponent);
begin
inherited;

YouClass:=TYouClass.Create;
YouClass.OnSave:=MyProc;
end;
 
沈前卫的理解与我的意图有所不同:
如何通过发送消息和接受消息来触发onsave事件呢?
 
TSaveEvent=procedure(Sender:TObject;bc:string) of Object;
private
FOnSave:TSaveEvent;
procedure WMMyMessage(var Msg: TMessage); WM_Mymessage;
...
published
property OnSave:TSaveEvent read FOnSave write FOnSave;
...

procedure TMyBook.WMMyMessage(var Msg: TMessage);
begin
dosave;
if Assigned(FOnSave) then
FOnSave(Self, YourString)
end

在程序中:
procedure TForm1.Button1Click(Sender);
begin
SendMessage(MyBook1, WM_Mymessage, 0, 0);
end;
 
谢谢!我不懂消息触发的机制,比如说,点击VCL控件触发点击事件,双击
触发双击事件,并没有向控件sendmessage呀.烦请专家不吝赐教.
 
点击VCL控件, 会发送WM_LBUTOONUP等消息
procedure TControl.WMLButtonUp(var Message: TWMLButtonUp);
begin
... Click;
end;

procedure TControl.Click;
begin
{ Call OnClick if assigned and not equal to associated action's OnExecute.
If associated action's OnExecute assigned then call it, otherwise, call
OnClick. }
if Assigned(FOnClick) and (Action <> nil) and (@FOnClick <> @Action.OnExecute) then
FOnClick(Self)
else if not (csDesigning in ComponentState) and (ActionLink <> nil) then
ActionLink.Execute
else if Assigned(FOnClick) then
FOnClick(Self);
end;
 
问题已解决,金子给定.但仍有问题不清楚:
1 当点击出发点击事件时,谁是消息的发送者,谁是消息的接收者,消息的处理过程又是怎样的?
2 只能给有句柄的类(可视和非可视)发送消息吗?
3 sendmessage与perform有何区别?
 
不一定全对:
1 消息由Windows发出, 被点击的控件是接收者,
2 不是的, 没有句柄的可以用方法: Perform
3 Call Perform to bypass the Windows message queue and send a message
directly to the control's window procedure.

Perform fills a message record (of type TMessage) with the message ID
passed in the Msg parameter, the message parameters passed in WParam
and LParam, and a result field of zero. Perform then passes the
message record to the WindowProc method for processing.
 
1 当点击出发点击事件时,windows 是消息的发送者,控件是消息的接收者,消息的处理过程就是你编写的和消息相连的过程
procedure form1。wndmsg(var msg:message);message wm_lbuttondown;
2 只能给有句柄的类(可视和非可视)发送消息吗,和句柄无关。
应该说基本上控件都是由消息处理的,即使自己不处理也要交给自己上一级处理。
3 sendmessage与perform有何区别?
我只知道 seenmessage 可以向控件或窗体消息
例如:
s:string;
sendmessage(edit。handle,wm_gettext,0,s);
 
TControl.peform()

Tcontrol自己搞定自己,假装给自己来点消息...
 
多人接受答案了。
 
后退
顶部