mainwndproc 、 windowproc与wndproc

vcl在窗体建立时就做了手脚,把mainwndproc()方法做为消息处理的入口,使消息的处理与分发进入了自己的

特有的体系。作为刚入道delphi的新手来说,要真正理解还不是一件轻松的事。

 

 

 

vcl通过InitWndProc和MainWndProc函数兼容了windows的消息。

1、vcl窗体建立(执行creat过程)时运行TWinControl.Create过程
(Controls中)。该函数把MainWndProc函数指向FObjectInstance指针
该完成此功能的代码为:FObjectInstance := Classes.MakeObjectInstance
(MainWndProc)
2、执行TWinControl.CreateWnd过程(Controls中)。该过程中的几行代码如下:
WindowClass.lpfnWndProc := @InitWndProc;
WindowClass.lpszClassName := WinClassName;
if Windows.RegisterClass(WindowClass) = 0 then RaiseLastOSError;
代码解释如下:
第一行:InitWndProc作为标准的windows窗口函数赋给
WindowClass.lpfnWndProc。该InitWndProc函
数的入口参数是标准的windows消息参数但
InitWndProc函数中的函数SetWindowLong(HWindow,
GWL_WNDPROC, Longint(CreationControl.FObjectInstance));
把消息处理的过程交给FObjectInstance指向的函数
来处理也就是MainWndProc处理
第三行:把InitWndProc函数注册为windows标准窗口函数
3、经过第1和2步骤工作后(初始化定义)。Windows接受到消息后工作如下:
1) windows把消息发送给windows的标准函数InitWndProc(该函
数是所有vcl消息函数的最底层函数)
2) InitWndProc函数接到消息后转交给MainWndProc(var Message:
TMessage)过程处理。
比较两个函数:
function InitWndProc(HWindow: HWnd; Message, WParam,LParam:
Longint): Longint;
procedure TDragObject.MainWndProc(var Message: TMessage);
可以看出InitWndProc带的是windows的标准消息参数,但
是MainWndProc的参数是vcl的特有参数,因此,delphi把windows
参数在这两个过程中兼容了。
3) 执行vcl格式的过程。后面的函数自动带delphi vcl的隐含参数Self

 

 

建立一个application,写下以上三个"过程":WndProc、WindowProc、MainWndProc,于按下Ctrl+光标,看看他们的定义:
procedure TCustomForm.WndProc(var Message: TMessage);
procedure TWinControl.MainWndProc(var Message: TMessage);
 property WindowProc: TWndMethod read FWindowProc write FWindowProc;//Tcontrol类下的一个属性。
我们再看看MainWndProc的具体定义:


procedure TWinControl.MainWndProc(var Message: TMessage);
begin
  try
    try
      WindowProc(Message);
    finally
      FreeDeviceContexts;
      FreeMemoryContexts;
    
end;
  except
    Application.HandleException(Self);
  
end;
end;

MainWndProc没有对Message作特别处理,就交由WindowProc属性去处理了。
再看看在Tcontrol中WindowProc的处理:


constructor TControl.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FWindowProc :
= WndProc;

WindowProc本身也没做什么处理也交给WndProc去处理了。
在Form上调用WndProc是调用TCustomForm上的WndProc,其处理“WM_ACTIVATE, WM_SETFOCUS, WM_KILLFOCUS”等之类的消息后,继承了TWinControl.WndProc方法,而TWinControl.WndProc处理了“WM_SETFOCUS,WM_NCHITTEST”之类消息后继承TControl.WndProc方法。在这些子类处理其类的消息后,需要
inherited WndProc(Message);
而Tcontrol.WndProc最终让无意义的消息作必要的处理后抛弃,其余消息被传入Dispatch实现消息派遣。
 Tcontrol.WndProc定义的最后一句为 Dispatch(Message);



 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值