当我们创建一个窗体的时候,简单的调用一下Create,窗口就出来了1,书上都说Create的背后,包含了: 
注册窗口类,注册窗口函数, 创建窗口等一系列API调用。
那么有以下问题:
  这么API调用是在什么时候执行的,我在VCL代码里怎么看不到?
  每一个窗口及控件都有一个Handle,这个Handle是什么时候怎么、由谁分配的?
2,在消息循环中,Aplication在获取消息后,派遣(Dispatch)了这个消息,由于我现在还看不到WndProc在VCL代码的哪个地方,以及是否也有Case  Msg of:...之类的消息处理代码。但我看到了此类过程声明:
  procedure WMxx(var Message: xx); message WMxx;是否可以这样回答,编译经过特殊处理,把这些过程整合到了一起以达到WinProc的功能?
要真是这样的话,它又是怎么实现的呢?总共四个问题,积压心口已久。希望高手不吝赐教,先谢了。

解决方案 »

  1.   

    看看WINDOWS程式的结构吧,看纯C的
      

  2.   

    呵呵,惭愧惭愧,这个问题大概知道,但是也只知道个大概,没有真正去研究求证过。在这里乱讲几句,说错了别打我哦。InsideVCL里应该说的比较清楚吧。
    1,在Form的继承路线里找,我估计是在WinControl里,因为这是所有窗口控件的根。基本的窗口创建和消息处理应该都有了。
    2,Case肯定没有了,那样多不美观。面向对象是用多态来实现分派的。用message修饰的方法类似于虚方法。这样在调用的时候就会多态绑定到实际子类的方法中。不过Message方法比虚方法更加灵活,虚方法要在父类中声明才可以重载。而Message方法可以直接在子类中声明,向使用父类接口的对象发对应的消息就可以调用子类中的方法。这两种方法的动态绑定方式也不同虚方法是查找子类的虚方法表获得函数地址的,而Message方法会沿着继承树回溯查找。具体的区别可以查查书。整体而言这个体系中,除了message方法是通过编译器提供支持的。其他的机制都是用代码来实现的,没有什么神秘的,应该都可以找到出处。
      

  3.   

    谢谢 asj().请高手继续
      

  4.   

    仔细查一下,原来在TControl的定义中有:
        procedure WndProc(var Message: TMessage); virtual;在接下来的TWinControl,TCustomerForm....中都有重写这方法,并且都是
    Case  Msg of...
    的结构。又在 system单元中找到这个方法:
    procedure TObject.Dispatch(var Message);
    asm
        PUSH    ESI
        MOV     SI,[EDX]
        OR      SI,SI
        JE      @@default
        CMP     SI,0C000H
        JAE     @@default
        PUSH    EAX
        MOV     EAX,[EAX]
        CALL    GetDynaMethod
        POP     EAX
        JE      @@default
        MOV     ECX,ESI
        POP     ESI
        JMP     ECX@@default:
        POP     ESI
        MOV     ECX,[EAX]
        JMP     DWORD PTR [ECX] + VMTOFFSET TObject.DefaultHandler
    end;
    不太懂汇编, 估计 Message 形式的过程是在这个方法中被调用的的吧。那么Handle也应该是在创建窗体由Windows分配的吧。小弟一味的在想当然。看了许多书,还是不太明白,希望有高手能给我一个清晰的说明
      

  5.   

    VCL封装了API了
    Handle由操作系统分配的编译器的功能和机制很复杂,没多去研究
    VCL内部结构相关有兴趣自己去研究了
      

  6.   

    这个我看过一些,很比较复杂(是在TWinControl中实现的)。我也说不太清楚,要自己去的看的,如果没有信心的话,可以看看TTimer,先熟悉一下用API作窗体,及拦截消息