======================================================
注:本文源代码点此下载
======================================================
求助:有谁知道delphi中窗口的创建过程,此“窗口”不仅仅指 tform 类型,
还包括一般的窗口控件,如tbutton,tedit等等,希望有能够十分详细的运作
过程,比如说creatparams,createwindowhandle等等函数的调用情况,可能
调试过 delphi vcl 源代码这个问题才能解决此问题,我很想知道。谢谢!
你的问题只需要从对象的概念来理解也就好了呀!
其实在delphi中,所有的vcl不就是一个个对象么?
它有图形外观也是因为它能够响应消息呀!(wm_pain消息)
基本而言,一个vcl组件创建过程没有什么特殊的,只是将其所有的数据成员
初始化而已(这里的数据成员包括一些消息处理,不过在delphi中消息处理是
由delphi内置的功能完成的,通过message关键字)
至于这个初始化数据成员的顺序,也就是一般意义上的先创建自身的,然后再初始化
子类的(其实应该是每一个子类都是先初始化父类对象成员inherited create,然后
再初始化自己的成员)。
其余操作都是由消息来完成的如一个控件的外观是由wm_paint消息驱动的,此消息
在窗口需要重画时发送出来(如果是windows处理的消息,只有twincontrol才能得到
而在delphi中的tgraphcontrol,类似的消息是由delphi来处理的,当初这样处理
是为了节约资源,当年可用窗口句柄数量不像现在这样没有节制,如果多了,可以促使
windows死掉的)
总之一句话,创建过程中初始化成员数据的过程,我是指在create方法中(所以我在
form的create中一身不作很多事情,而是在formshow中做一些事情),而在释放过程
中释放这些资源,其它事情都是消息驱动的,无论这些消息是来自windows,delphi
更或者是应用程序自身
闲着也是闲着,多写了几句,不好意思,如果哪位用了自动回复,收到的信希望不太
大。
delphi中的窗口分为重叠型窗口,弹出式窗口与子窗口,window系统库中包含着每个应用程序所创建的所有窗口的列表,并赋予每个窗口一个唯一值。创建一个简单的新应用程序并在其中放一个按钮,保存并运行程序。使用delphi的winsight工具可以看到系统窗口的列表。应用程序就是窗口。从winsight信息的分析中,可以看到,应程序具有一个额外的窗口,增加到主窗体系统菜单上的项目并未增加到任务条上。当我们创建一个全新的应用程序时,delphi会为项目文件生成一些代码,包括下列代码:
programe project1;
uses
forms,unit1 in‘unit1。pas’{form1}
{$r*。res}
begin
application.initialize;
application.createform(tform1,form1);
application.run;
end;
当窗体创建时,会接收到oncreat事件,并可以改变或测试初始窗体的属性或元素。但窗体的创建不可改变。与窗体创建相应的语句在项目的源文件中(。dpr)文件中,使用project|viewsource可以看到;
如果不希望窗体自动创建,也可以改动相应代码;或在projectoptions对话框中选择不自动创建,在屏幕后发生了一些事件,当调用creatform时,如果当前没有主窗体,当前窗体会被赋为主窗体。因此对话框mainform编辑框表示的窗体对应着对应程序creatform对象方法的第一次调用,就是说,当启动时可能有多个窗体创建,而mainform是第一个。
delphi中,所有窗体都是重叠型窗口,甚至对话框也是如此。在delphi中,弹出式菜单只出现于隐藏应用程序窗口。在系统中,它们被用作消息框以及弹出式菜单或下拉式菜单。
不知这些是否是你想要的。
//*******************************************************************
to wuwzy:
//*******************************************************************
1、tcustomform.create
在 tcustomform.create 中调用 tcustomform.createnew;
2、tcustomform.createnew;
调用 fcanvas := tcontrolcanvas.create;
触发 tcontrolcanvas.create;
触发 tcontrolcanvas.createhandle;
3、tcontrolcanvas.createhandle;
调用 fcontrol.getdevicecontext(fwindowhandle);
即 twincontrol.getdevicecontext(fwindowhandle);
4、twincontrol.getdevicecontext(fwindowhandle);
调用 twincontrol.getdc(handle);
此处说明一下:
对 twincontrol 的 handle 属性的读取会触发 twincontrol.gethandle;
可以察看 property handle; 的声明。
5、第四步中对 handle 进行读取,触发下述序列:(twincontrol)
handle->gethandle->handleneeded
6、twincontrol.handleneeded 检查 fhandle 的值:
if fhandle = 0 then
begin
if parent twincontrol.createhandle
调用 createwnd;
if fhandle = 0 then // 此时 fhandle 仍然为零
begin
createwnd;
...
end;
8、twincontrol.createwnd
调用 createparams(params);
// 让用户有机会加入新的特征参数
createparams(params);
with params do
begin
...
// 标准的 api 使用,注册窗口类,createwindowex ...
if windows.registerclass(windowclass) = 0 then raiselastwin32error;
...
createwindowhandle(params);
...
end;
9、createwindowhandle(params);
fhandle := createwindowex(exstyle, winclassname, caption, style,
x, y, width, height, wndparent, 0, windowclass.hinstance, param);
完成真正的窗口创建,并赋予 fhandle 窗口句柄。
10、回到第一步
createnew 之后调用 docreate
try
createnew(aowner);
...
if oldcreateorder then docreate;
finally
...
end;
11、docreate
调用用户的 oncreate 事件:
if assigned(foncreate) then
try
foncreate(self); // 调用 oncreate;
except
application.handleexception(self);
end;
if fsvisible in fformstate then visible := true;
// ***************************************************************
the end.
from: bakubaku
// ***************************************************************
补充一点:
其他的控件比如 tedit 等都是 twincontrol 的子孙,构造的顺序都差不多,
关键的一点是:
对 twincontrol.handle 属性的第一次访问会触发对窗口句柄的真正创建。
即:handle->gethandle->handleneeded
关于这一点,可以察看 delphi help->handleallocated 方法的注解。
上文只是剖析了 tform 的构造过程,其它类似控件可能有所差别,其它控件并不
一定是在构造 tcontrolcanvas 时才第一次访问 twincontrol.handle 的,也许
是在其他地方,不过没有必要都写出来。
windows使用createwidnow,createwidnowex函数进行所有窗口的创建工作.
delphi的createparams类似与此,只是一个外壳而已.
每个窗口(指所有大大小小的窗口)都有一个窗口过程winproc,窗口的消息在此
过程中进行处理.当然,消息是链式传递的,windows内建一个缺省的窗口过程,即:
defwidnowproc,程序中某些消息的处理不使用缺省过程,而是自己处理.
c语言中有个winmain函数,这是程序的入口点,
delphi中即程序文件中program中的begin...end过程.
去吧.
======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/