一个事件如Onclick发生时即向一个窗口发送了一个消息,然后我们可以在事件处理程序中添加代码,但是这个消息怎样被传达到事件处理程序的?这种事件处理程序与消息处理方法有什么不同(带message关键字的对象方法)?
解决方案 »
- 抖动的窗体?
- 来比比谁最晚
- 如何設定StringGrid某单元格可修改?
- 怎样把一个网页的图片用程序保存到本地
- VCLZip V3.03解压缩问题
- 字符操作问题。具体请看内容。
- http://community.csdn.net/Expert/topic/3096/3096870.xml?temp=.2118341欢迎讨论
- 關于fastreport報表
- 串口问题?
- 是mysql的天大的bug,还是我写错了?
- 关于Data: Pointer;的 现在知道pointer 类型,和它的大小SIZE 能用什么办法把它当成memorystream从网路上传输然后在恢复过来呢?
- 关于三层系统的查询和提交记录的疑问!!!!!!!!!!!!!!!!!!!!!!
鼠标移动、键盘按下、时间器触发... ...
可以说,一切操作都离不开消息的处理... ...如下是VCL代码 TControl = class(TComponent)
... ...
private
... ...
procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP;
... ...
protected
procedure Click; dynamic;
... ...
end;... ...procedure TControl.WMLButtonUp(var Message: TWMLButtonUp);
begin
inherited;
if csCaptureMouse in ControlStyle then MouseCapture := False;
if csClicked in ControlState then
begin
Exclude(FControlState, csClicked);
if PtInRect(ClientRect, SmallPointToPoint(Message.Pos)) then Click;
end;
DoMouseUp(Message, mbLeft);
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(Self)
else if Assigned(FOnClick) then
FOnClick(Self);
end;
事件就是一个方法的指针~~
当消息函数触发被执行时~~
就会去检查方法指针是否地址不为空~~
检查通过就将调用方法指针所指向的方法~~
就是说:
procedure TForm1.FormClick(Sender); //它只是一个的方法
begin
//
end;... ...
begin
OnClick := FormClick; //这样就是方法的指针~~
end;要理解这点,最简单的思维就是把处理数据的方法看成数据即可~~
0311-4322146 w/////////////////////////////////////////////////////////////////////////pb学得快说明厉害,聪明。职业生涯才刚开始,不要担心寿命:)不断提高自己,别沉沦在被周围的没有半点生气的环境中!以后只要发展不平衡,毕竟出现差距,难道要阻碍一个人的发展,避免差距?差距何在?能力和见识所在!
如果娟这么认为,我甘愿不去发展,因为我觉得和娟的感情更重要,自己的事业,自己的追求不如这个重要:*疏远//////////////////////////////////////////////////////////////////////////
不才给伴水兄补充:“检查通过就将调用方法指针所指向的方法~~”
--是谁检查?
--application.run如果楼主知道怎样用纯api写windows程序,就会很明白了,建议你看看《windows语言程序设计》--清华出的,告诉你怎样用c写win32程序。//////////////////////你可以看看
application.run的vcl源代码,还有里面的handlemessage,processmessage函数。
注意这个循环:
repeat
try
HandleMessage;
except
HandleException(Self);
end;
until Terminated;
///////////////
procedure TApplication.HandleMessage;
var
Msg: TMsg;
begin
if not ProcessMessage(Msg) then Idle(Msg);
end;
//////////////////////////
function TApplication.ProcessMessage(var Msg: TMsg): Boolean;
var
Handled: Boolean;
begin
Result := False;
if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
begin
Result := True;
if Msg.Message <> WM_QUIT then
begin
Handled := False;
if Assigned(FOnMessage) then FOnMessage(Msg, Handled);
if not IsHintMsg(Msg) and not Handled and not IsMDIMsg(Msg) and
not IsKeyMsg(Msg) and not IsDlgMsg(Msg) then
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end
else
FTerminate := True;
end;
end;
/////////////////////////////
application.run的核心就是这三个api函数:
PeekMessage(Msg, 0, 0, 0, PM_REMOVE);//检测消息队列的消息。
TranslateMessage(Msg);//翻译消息。
DispatchMessage(Msg);//分发消息。/////////////////////////////--DispatchMessage(Msg)分发消息给谁呢?
--根据msg.hwnd决定是那个窗口的消息确定应该调用哪个窗口实例注册过的wndproc。ATOM RegisterClass( CONST WNDCLASS *lpWndClass // address of structure with class data
);
typedef struct _WNDCLASS { // wc
UINT style;
WNDPROC lpfnWndProc; //注册窗口类的时候应该负值相应窗体的wndproc。
int cbClsExtra;
int cbWndExtra;
HANDLE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCTSTR lpszMenuName;
LPCTSTR lpszClassName;
} WNDCLASS;/////////////////
见:TWinControl.CreateParams,TWinControl.CreateWnd,这2个应该是设置注册窗口类用的。tapplication.wndproc,
tcontrol.wndproc,twincontrol.wndproc,TCustomForm.wndproc.application是forms单元的一个变量,是tapplication类的一个实例。
但是看看:
procedure TApplication.Initialize;
begin
if InitProc <> nil then TProcedure(InitProc);
end;
但是不知道application实例是什么时候创建的,估计是在某个单元的initialization部分创建的application应该是个窗体,而且应该是应用程序实际的主窗体。////////////////////////////////
水有限,只能灌到这里,楼下继续~~