VCL框架学习之:从传统WindowsAPI到面向对象的消息分派实现

本文主要是介绍VCL框架学习之:从传统WindowsAPI到面向对象的消息分派实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

/*传统Windows消息机制*/
//创建一个Windows窗口,在其中创建Edit控件:
Function WindowProc(Window:HWnd;AMessage:UINT;Wparam:WPARAM;Lparam:LPARAM):LRESULT;stdcall;export;
Begin
                    //仅有一个窗口回调函数(即当前函数)处理所有消息(窗体消息或Eidt控件消息)
                    //消息回环
                    Case AMessage Of:
                    Case xxx:
                    Case xxx:
                    End ;
                    //无法处置的消息交由默认处理方法处理
                    WindowProc:= DefWindowProc(window,Amessage,Wparam,Lparam);
                    //创建Eidt控件时以包含Eidt控件的Handle作为父窗体参数
                    HWindow := WinCreate;
                    Hedi := EditCreate(HWindow,Hstatus);
                    SetFocus(Hedit);
                    While GetMessage(@AMessage,0,0,0) Do
                    Begin
                      //继续下一轮的消息分发
                    TranslateMessage(AMessage);
                    DispatchMessage(AMessage);
                    End;
End;
Function EditCreate(ParentWindow,Status:HWnd):HWnd;
Begin
                    //绘制一个Eidt
End;
/*面对对象消息机制*/
//继承层次:
TObject
TWinControl.WndProc(var Message:TMessage);Virtual;
TEdit.WndProc(var Message:TMessage);Override;
//分发机制:
Var 
                    aControl:TWinControl;
Begin
                    …
                    GetWindowMessage(Message);
                    aControl : = GetTargetControl(Message);
                    aControl.WndProc(Message);
                    …
End;
/*从窗口回调函数到面向对象的类方法*/
Function WindowProc(…)//开放此函数被Windows操作系统调用
Var
                    …
Begin
                    …
                    Control := FindControl(ControlHandle);
                    Push EAX,Self //将对象地址推入堆栈
                    Control.WndProc(Message);//调用消息处理方法
                     …
End;
/*如何实现消息分派服务*/
TObject = class
                    …
                    Procedure Dispatch(var Message);virtual;//消息分派
                    Procedure DefaultHandler(var Message);virtual;
                    …
End;
/*从Application.Run说起*/
Application.Initialize;①
Application.CreateForm(TForm,Form1);②
Application.Run;③
①应用程序启动时将会调用如下代码:
Application := Application.Create(nil);

//类型声明
TApplication = class(TComponent)
Var 
                    Private
                     …
                    FHandle:HWnd; 
                    ..
                    FObjectInstance:Pointer;
End;
//构造函数
Constructor TApplication.Create(AOwner:TComponet);
Var 
                    If not IsLibrary then CreateHandle;
End ;
Procedure TApplication.CreateHandle;
Var

 Begin
                    …
                    //获得WndProc地址
                    FobjectInstance := Classes.MakeObjectInstance(WndProc);
                    //创建一个大小为0的隐藏窗口
                    FHandle:=CreateWindow(….);
                    …
                    //重新设定窗口回调函数为指定地址
                    SetWindowLong(FHandle,GWL_WNDPROC,Longint(FObjectInstance));
                    …
                    //WndProc成为隐藏窗口的默认回调函数
End ;
Procedure TApplication.WndProc(var Message:TMessage);
Var
Begin
                     …
                     //消息回环
                     With Message do
                     Case Msg of 
                      …
                      WM_CLOSE:
                      //控制主窗体的关闭
                       If MainForm <> nil then MainForm.Close;
                      …
                      CM_ACTIVATE:
                       //与事件响应挂接
                      If Assigned(FOnActiveate) then FOnActivete(Self);
                      …
                     End; 
                     …
End;
③应用程序启动后
Procedure TApplication.Run
                     …
                     Repeat
                      HandleMessage;//完成消息分发
                      … 
                     End;
End;
Procedure TApplication.HandleMessage;
                     …
                     ProcessMessage(Msg)
                     …
End ;
Procedure TApplication.ProcessMessage(var Msg:TMsg):Boolean;
 Var
                     …
 Begin
                      …
                      If Assigned(FOnMessage) then FOnMessage(Msg,Hanled);
                      …
                      Begin
                       //消息分发
                       TranslateMessage(Msg);
                       DispatchMessage(Msg);
                      End ;
                      …
End;
②应用程序创建Form
Procedure TApplication.CreateForm(InstanceClass:TComponentClass;var Reference);
Var
                     Instance:TComponent
Begin
                     Instance := TComponent(InstanceClass.NewInstance);
                     TComponent(Reference) := Instance;
                     ..
                     Instance.Create(Self);
                     //创建新对象,尚未创建实际的窗口控件
                     Instance.Create(Self);④
                     …
                     If (FMainForm = nil) and( Instance is TForm) then
                     Begin
                      //暗示开始调用Window API 创建窗口并取得窗口的Handle值
                      TForm(Instance).HandleNeeded;
                      FMainForm := TForm(Instance);
                     End;
                     …
End;
由④导出的事件
//由TForm到TWincontrol继承链条引发TWinControl.Create调用
Constructor TWinControl.Create(AOwner:TComponent);
Begin
                     Inherited Create(AOwner);//父类构造调用
                     …
                     //获得回调函数MainWndProc入口地址
                     FObjectInstance:=Classes.MakeObjectInstance(MainWndProc); 
                     …
End ;
//继续Procedure TApplication.CreateForm的讨论:
Procedure TWinControl.HandleNeeded;
Begin
                     …
                     CreateHandle;
                     …
End;
Procedure TWinControl.CreateHandle;//virtual
Begin
                     …
                     CreateWnd; 
                     …
End;
Procedure TWincontrol.CreateWnd;//virtual
Begin
                     …
                     //属性设置
                     CreateParams(Params);// virtual,可由继承重写实现窗口属性自定义
                     …
                     WindowClass.lpszClassName := @InitWndProc;//将InitWndProc设置为窗体创建的窗口控件的回调函数
                     …
                     //根据设定的窗口类信息调用API来创建窗体封装的窗口控件
                     CreateWindowHandle(Params);
                     …
End;
Procedure TWinControl.CreateWindowHandle(const Params:TCreateParams)
Begin
                     …
                     With Params do
                     FHandle := CreateWindowEx(……);//调用API创建窗口
End ;
Function InitWndPro(HWindow:Hwnd;….) //让Windows操作系统能够调用到Framework中处理窗口消息的类方法的轴心函数
Begin
                     …
                     CreationControl.FHandle := HWindow;
                     // CreationControl已被自动设置为当前正在创建的控件,也正是窗口消息的目的控件
                     //重新设置MainWndPro为窗体的回调函数
                     SetWindowLong(HWindow,GWL_WNDPROC,Longint(CreationControl.FObjectInstance));
                     …
                     Asm:
                      PUSH LParam
                      PUSH WParam
                      PUSH Message
                      PUSH HWindow
                      MOV EXA,CreationControl //将处理窗口消息的控件推入栈中
                      MOV CreationControl,0
                      CALL [EAX].TWinControl.FObjectInstance //调用该控件的窗口回调函数
                      MOV Result,EAX
                     End ;
End ;
Procedure TWinControl.MainWndProc(var Message:TMessage)
Begin
                     WindowProc(Message);//在TControl.Create中WindowProc被指定成为类成员方法WndProc
                     …
End;
Procedure TWinControl.WndProc(var Message:TMessage)
Begin
                     …
                     Inherited WndProc(Message);
End;
Procedure TControl.WndProc(var Message:TMessage)
Begin
                     …
                     //消息处理
                     …
                     //消息分派
                     Dispatch(Message);
End;
 

这篇关于VCL框架学习之:从传统WindowsAPI到面向对象的消息分派实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/420307

相关文章

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

Python实现微信自动锁定工具

《Python实现微信自动锁定工具》在数字化办公时代,微信已成为职场沟通的重要工具,但临时离开时忘记锁屏可能导致敏感信息泄露,下面我们就来看看如何使用Python打造一个微信自动锁定工具吧... 目录引言:当微信隐私遇到自动化守护效果展示核心功能全景图技术亮点深度解析1. 无操作检测引擎2. 微信路径智能获

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll

Spring Security自定义身份认证的实现方法

《SpringSecurity自定义身份认证的实现方法》:本文主要介绍SpringSecurity自定义身份认证的实现方法,下面对SpringSecurity的这三种自定义身份认证进行详细讲解,... 目录1.内存身份认证(1)创建配置类(2)验证内存身份认证2.JDBC身份认证(1)数据准备 (2)配置依

利用python实现对excel文件进行加密

《利用python实现对excel文件进行加密》由于文件内容的私密性,需要对Excel文件进行加密,保护文件以免给第三方看到,本文将以Python语言为例,和大家讲讲如何对Excel文件进行加密,感兴... 目录前言方法一:使用pywin32库(仅限Windows)方法二:使用msoffcrypto-too