-------------------------- 分析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的创建与显示过程的更多相关文章

  1. MFC编程入门之十五(对话框:一般属性页对话框的创建及显示)

    属性页对话框包括向导对话框和一般属性页对话框两类,上一节讲了如何创建并显示向导对话框,本节将继续介绍一般属性页对话框的创建和显示. 实际上,一般属性页对话框的创建和显示过程和向导对话框是很类似的.将上 ...

  2. VS2010/MFC对话框:一般属性页对话框的创建及显示

    一般属性页对话框的创建及显示 本节将介绍一般属性页对话框的创建和显示. 实际上,一般属性页对话框的创建和显示过程和向导对话框是很类似的.鸡啄米将上一节中的向导对话框进行少量修改,使其成为一般属性页对话 ...

  3. VS2010/MFC编程入门之十五(对话框:一般属性页对话框的创建及显示)

    属性页对话框包括向导对话框和一般属性页对话框两类,上一节鸡啄米讲了如何创建并显示向导对话框,本节将继续介绍一般属性页对话框的创建和显示. 实际上,一般属性页对话框的创建和显示过程和向导对话框是很类似的 ...

  4. VS2010-MFC(对话框:一般属性页对话框的创建及显示)

    转自:http://www.jizhuomi.com/software/169.html 属性页对话框包括向导对话框和一般属性页对话框两类,上一节演示了如何创建并显示向导对话框,本节将继续介绍一般属性 ...

  5. ASP.NET Web API 过滤器创建、执行过程(二)

    ASP.NET Web API 过滤器创建.执行过程(二) 前言 前面一篇中讲解了过滤器执行之前的创建,通过实现IFilterProvider注册到当前的HttpConfiguration里的服务容器 ...

  6. java中类的创建及初始化过程

    java中类的创建及初始化过程无外乎两种情况,其一为单类的创建及初始化,其二具有继承关系的父子类创建及初始化过程.     首先说简单的,单类的创建及初始化过程.在java中我们都知道绝大部分对象的创 ...

  7. 【转载】详解CreateProcess调用内核创建进程的过程

    原文:详解CreateProcess调用内核创建进程的过程 昨天同学接到了腾讯的电面,有一题问到了CreateProcess创建进程的具体实现过程,他答得不怎么好吧应该是, 为了以防万一,也为了深入学 ...

  8. MFC编程入门之十二(对话框:非模态对话框的创建及显示)

    上一节讲了模态对话框及其弹出过程,本节接着讲另一种对话框--非模态对话框的创建及显示. 非模态对话框显示后,程序其他窗口仍然能正常运行,可以响应用户输入,还可以相互切换.上一讲中创建的Tip模态对话框 ...

  9. VS2010/MFC对话框:非模态对话框的创建及显示

    非模态对话框的创建及显示 上一节讲了模态对话框及其弹出过程,本节接着讲另一种对话框--非模态对话框的创建及显示. 已经说过,非模态对话框显示后,程序其他窗口仍能正常运行,可以响应用户输入,还可以相互切 ...

随机推荐

  1. How to fix the gray screen bug in VirtualBox

    If you see a gray screen instead of GNOME when entering the system, simply switch to a virtual conso ...

  2. HTML5 移动端头部标签

    <!DOCTYPE html> <!-- 使用 HTML5 doctype,不区分大小写 --> <html lang="zh-cmn-Hans"&g ...

  3. SPOJ 1825 Free tour II (树的点分治)

    题目链接 Free tour II 题意:有$N$个顶点的树,节点间有权值, 节点分为黑点和白点. 找一条最长路径使得 路径上黑点数量不超过K个 这是树的点分治比较基本的题,涉及树上启发式合并……仰望 ...

  4. Careercup | Chapter 4

    二叉查换树,左孩子小于等于根,右孩子大于根. 完全二叉树,除最后一层外,每一层上的节点数均达到最大值:在最后一层上只缺少右边的若干结点. complete binary tree 满二叉树,完美二叉树 ...

  5. Nginx+keepalived双机热备(主主模式)

    IP说明: master机器(master-node):10.0.0.5/172.16.1.5   VIP1:10.0.0.3slave机器(slave-node): 10.0.0.6/172.16. ...

  6. DELPHI跨平台编译开关

    DELPHI跨平台编译开关 DELPHI 现在是跨平台的开发工具,已经不仅仅针对WINDOWS OS. 跨平台的时候,一些WINDOWS特有的API或语法是不能用的,必须使用跨平台的新语法,要用编译开 ...

  7. SharePreferences使用

    获取数据: @SuppressLint("InlinedApi") private String getFromSharePreference(String key) { if ( ...

  8. Android 沉浸式全屏

    Android 4.4 带来了沉浸式全屏体验, 在沉浸式全屏模式下, 状态栏. 虚拟按键动态隐藏, 应用可 以使用完整的屏幕空间, 按照 Google 的说法, 给用户一种 “身临其境” 的体验. A ...

  9. java资源分享、面试题资料、分布式大数据

    马士兵大数据_架构师(1) 链接:http://pan.baidu.com/s/1qYTW1m0 密码:lxjd spring Cloud 链接:http://pan.baidu.com/s/1bzG ...

  10. 第四讲_图像识别之图像分类Image Classification

    第四讲_图像识别之图像分类Image Classification 目录 图片分类 性能指标:top1,top5 ILSVRC:每种任务数据集不一样 imageNet:根据WorldNet组织的图片集 ...