TEdit的创建与显示过程
-------------------------- 分析TEdit的创建与显示过程 --------------------------
TCustomEdit = class(TWinControl) 分析TEdit的创建与显示过程(注意,它不是由TCustomControl派生而来):
TCustomEdit.Create 虽然执行inherited Create(AOwner);但除此之外只是初始化,什么都看不出来。只能研究它的父类调用了哪些虚函数,比如它覆盖了这些函数:
procedure CreateParams(var Params: TCreateParams); override;
procedure CreateWindowHandle(const Params: TCreateParams); override;
procedure CreateWnd; override;
分析:
TWinControl.CreateParams 调用 Parent.GetHandle(但是这是条件语句,不一定执行,而且创建的也是父控件的句柄,不是创建当前控件的句柄,一般情况下不是创建当前窗口的入口)
TWinControl.GetHandle 调用 HandleNeeded;
TWinControl.HandleNeeded; 调用 Parent.HandleNeeded; 和 CreateHandle; (如有还没有创建的话,所以这么多函数之间不会形成一个悖论)
TWinControl.CreateHandle; 调用 CreateWnd,并记录 SetProp,并 SetWindowPos (VCL创建窗口的真正入口,但程序员经常以CreateParams作为入口创建窗口)
TWinControl.CreateWnd(它有一个局部变量Params); 调用CreateParams,管注册,指定lpfnWndProc后调用API RegisterClass 最后调用 CreateWindowHandle(Params)和SetWindowLong
TWinControl.CreateWindowHandle 管创建,简单调用API CreateWindowEx
TWinControl.RecreateWnd; 简单调用 Perform(CM_RECREATEWND, 0, 0);
测试语句:
procedure TForm1.Button1Click(Sender: TObject);
var
t: TEdit;
begin
t:=TEdit.Create(self); // 第一个断点
t.Name:='myedit';
t.Top:=50;
t.Left:=100;
t.Parent:=self; // 第二个断点
//t.Visible:=True;
end;
并且在上面给上面一堆TWinControls的函数下断点
发现1:执行到第一个断点后,再点击执行到下一个断点,居然会跳到第二个断点,而不是TWinControls那些函数的断点,这说明在t.parent:=self之前,根本就没有创建实际句柄(只创建了TEdit实例,内部WindowHandle依然为空,Delphi只在它真正需要的时候才创建相关Windows内核对象,这一点可以通过调试的时候观察t.WindowHandle得到结论),更谈不上显示。
发现2:在一堆TWinControl.CreateXXX函数里,发现第二个断点会首先执行TWinControl.CreateHandle; 这说明这个函数才是真正的入口。
那么TWinControl.CreateHandle;是如何被执行到的呢?整个过程依次执行:
procedure TWinControl.SetParent(AParent: TWinControl); 调用 TControl.SetParent
procedure TWinControl.InsertControl(AControl: TControl);
procedure TWinControl.UpdateControlState;
procedure TWinControl.UpdateShowing; 这个函数很特殊,内有递归:
TWinControl(FWinControls[I]).UpdateShowing; // 递归
TWinControl.UpdateShowing; 在这里终于发现 if WindowHandle = 0 then CreateHandle; 而且经过若干次递归(排除已经被创建和显示的,比如界面上还有一个Button1和Label1,其中Label1不是TWinControl,这里不会管它)后会执行CreateHandle;。
CreateHandle会调用CreateWnd,但却是TCustomEdit.CreateWnd; 后者调用inherited CreateWnd; 后面还有若干次调用虚拟函数,但总的来说问题不大。以后再补充。
-------------------------- 分析TEdit的创建与显示过程 --------------------------
TCustomEdit = class(TWinControl) 分析TEdit的创建与显示过程(注意,它不是由TCustomControl派生而来):
TCustomEdit.Create 只是初始化,什么都看不出来。只能研究它的父类调用了哪些虚函数。最后发现是myEdit.parent:=Self;的时候才真正创建并显示
procedure CreateParams(var Params: TCreateParams); override;
procedure CreateWindowHandle(const Params: TCreateParams); override;
procedure CreateWnd; override;
TWinControl.CreateParams 调用 Parent.GetHandle
TWinControl.GetHandle 调用 HandleNeeded;
TWinControl.HandleNeeded; 调用 Parent.HandleNeeded; 和 CreateHandle;
TWinControl.CreateHandle; 调用 CreateWnd,并记录 SetProp,并 SetWindowPos
TWinControl.CreateWindowHandle 管创建,简单调用API CreateWindowEx
TWinControl.CreateWnd; 调用CreateParams,管注册,指定lpfnWndProc后调用API RegisterClass 比较复杂
TWinControl.RecreateWnd; 简单调用 Perform(CM_RECREATEWND, 0, 0);
TEdit的创建与显示过程的更多相关文章
- MFC编程入门之十五(对话框:一般属性页对话框的创建及显示)
属性页对话框包括向导对话框和一般属性页对话框两类,上一节讲了如何创建并显示向导对话框,本节将继续介绍一般属性页对话框的创建和显示. 实际上,一般属性页对话框的创建和显示过程和向导对话框是很类似的.将上 ...
- VS2010/MFC对话框:一般属性页对话框的创建及显示
一般属性页对话框的创建及显示 本节将介绍一般属性页对话框的创建和显示. 实际上,一般属性页对话框的创建和显示过程和向导对话框是很类似的.鸡啄米将上一节中的向导对话框进行少量修改,使其成为一般属性页对话 ...
- VS2010/MFC编程入门之十五(对话框:一般属性页对话框的创建及显示)
属性页对话框包括向导对话框和一般属性页对话框两类,上一节鸡啄米讲了如何创建并显示向导对话框,本节将继续介绍一般属性页对话框的创建和显示. 实际上,一般属性页对话框的创建和显示过程和向导对话框是很类似的 ...
- VS2010-MFC(对话框:一般属性页对话框的创建及显示)
转自:http://www.jizhuomi.com/software/169.html 属性页对话框包括向导对话框和一般属性页对话框两类,上一节演示了如何创建并显示向导对话框,本节将继续介绍一般属性 ...
- ASP.NET Web API 过滤器创建、执行过程(二)
ASP.NET Web API 过滤器创建.执行过程(二) 前言 前面一篇中讲解了过滤器执行之前的创建,通过实现IFilterProvider注册到当前的HttpConfiguration里的服务容器 ...
- java中类的创建及初始化过程
java中类的创建及初始化过程无外乎两种情况,其一为单类的创建及初始化,其二具有继承关系的父子类创建及初始化过程. 首先说简单的,单类的创建及初始化过程.在java中我们都知道绝大部分对象的创 ...
- 【转载】详解CreateProcess调用内核创建进程的过程
原文:详解CreateProcess调用内核创建进程的过程 昨天同学接到了腾讯的电面,有一题问到了CreateProcess创建进程的具体实现过程,他答得不怎么好吧应该是, 为了以防万一,也为了深入学 ...
- MFC编程入门之十二(对话框:非模态对话框的创建及显示)
上一节讲了模态对话框及其弹出过程,本节接着讲另一种对话框--非模态对话框的创建及显示. 非模态对话框显示后,程序其他窗口仍然能正常运行,可以响应用户输入,还可以相互切换.上一讲中创建的Tip模态对话框 ...
- VS2010/MFC对话框:非模态对话框的创建及显示
非模态对话框的创建及显示 上一节讲了模态对话框及其弹出过程,本节接着讲另一种对话框--非模态对话框的创建及显示. 已经说过,非模态对话框显示后,程序其他窗口仍能正常运行,可以响应用户输入,还可以相互切 ...
随机推荐
- Nginx没有启动文件、nginx服务不支持chkconfig、nginx无法自启
Nginx没有启动文件.nginx服务不支持chkconfig.nginx无法自启 问题描述: Nginx安装后,当想要设置Ngixn为开机启动时, 就需要把nginx的启动命令路径放到/etc/rc ...
- LeetCode OJ-- Simplify Path **
https://oj.leetcode.com/problems/simplify-path/ 对linux路径的规范化,属于字符串处理的题目.细节很多. #include <iostream& ...
- osstatus -9801 workerman websocket 小程序不带端口
帮事业部的同事,解决问题,坑总结 小程序出现,osstatus -9801 情况好多,说一下配置环境可解决的方法和问题 tls 1.2, php 5.6+, nginx, workerman 做的 w ...
- 使用KNN对iris数据集进行分类——python
filename='g:\data\iris.csv' lines=fr.readlines()Mat=zeros((len(lines),4))irisLabels=[]index=0for lin ...
- 微信小程序提交 webapi FormDataCollection
/// <returns></returns> [HttpPost] public ShoppingCartModel UpdateCart(FormDataCollectio ...
- [simple-orm-mybaits]基于Mybatis的ORM封装介绍
目录 前言 ORM框架现状 Mybatis优缺点 simple-orm-mybatis设计思路介绍 simple-orm-mybatis使用说明 simple-orm-mybatis实际使用 推荐最佳 ...
- Android NDK 环境配置
1. 下载NDK 官方链接地址: http://developer.android.com/tools/sdk/ndk/index.html 下载下来的应该是这个东西(以后可能会有更新,但步骤变动不会 ...
- 【sublime text3】破解 最近破解码 /激活成功,但是过一会就提示激活码失效的 Build3143
—– BEGIN LICENSE —– TwitterInc User License EA7E- 1D77F72E 390CDD93 4DCBA022 FAF60790 61AA12C0 A3708 ...
- module has no attribute 'seq2seq'
tensorflow 中tf.nn.seq2seq.sequence_loss_by_example to tf.contrib.legacy_seq2seq.sequence_loss_by_exa ...
- ThinkPHP学习(五)图片验证码
今天用到图片验证码的功能,在网上找到ThinkPHP的下面代码: Public function verify(){ import('think.Image'); Image::buildImageV ...