有谁知道Delphi中"窗口"的创建过程?


======================================================
注:本文源代码点此下载
======================================================

求助:有谁知道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^)/
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页