mainwndproc 、 windowproc与wndproc

来源:互联网 发布:新疆广电网络网上登录 编辑:程序博客网 时间:2024/04/29 23:20

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);