-------------------------- 分析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. 获取cookie中的某个参数值

    因为cookie的值是很多key=value连接起来的字符串,所以如果要取cookie中某个key的值: function getCookie(name) { let cookieValue = nu ...

  2. 51深入理解C指针之---指针与线程

    一.size_t:用于安全表示长度,所有平台和系统都会解析成自己对应的长度 1.定义:size_t类型表示C中任何对象所能表示的最大长度,是个无符号整数:常常定义在stdio.h或stdlib.h中 ...

  3. svg格式矢量图引入方法

    引入方法: span { background: url('1.svg') no-repeat; background-size: 20px 20px; background-position: 0 ...

  4. XSY1659 [HNOI2012]永无乡

    题面 Description 永无乡包含 n 座岛,编号从 1 到 n. 每座岛都有自己的独一无二的重要度,按照重要度可以将这n座岛排名,名次用 1到n来表示.某些岛之间由巨大的桥连接,通过桥可以从一 ...

  5. go 协程与主线程强占运行

    最近在学习了Go 语言 ,  正好学习到了 协程这一块 ,遇到了困惑的地方.这个是go语言官方文档 . 在我的理解当中是,协程只能在主线程释放时间片后才会经过系统调度来运行协程,其实正确的也确实是这样 ...

  6. Go语言_RPC_Go语言的RPC

    一 标准库的RPC RPC(Remote Procedure Call,远程过程调用)是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络细节的应用程序通信协议.简单的说就是要像调用本地函数 ...

  7. 自己封装的CMusic类 【转】

    http://www.cnblogs.com/zhangminaxiang/archive/2013/02/27/2936011.html 缘由: 在改正俄罗斯方块程序的功能的时候,想给这个程序增加一 ...

  8. Python基础语法03-控制流

    Python 条件语句 Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. 可以通过下图来简单了解条件语句的执行过程: Python程序语言指定任何非0和 ...

  9. sdut 面向对象程序设计上机练习九(对象指针)

    面向对象程序设计上机练习九(对象指针) Time Limit: 1000MS Memory limit: 65536K 题目描写叙述 建立对象数组,内放5个学生数据(学号是字符串类型.成绩是整型).设 ...

  10. Phpstorm 放大字体的快捷键是什么?

      这个功能需要设置才能使用: 步骤:control+shift+A功能可以搜索对应功能 输入mouse 设置Change font size(Zoom) ...的按钮打开,然后就可以通过 ctrl+ ...