• 虚函数的特点就是执行的时候会下降到子类去执行同名覆盖函数 good


    var
    t: TBitBtn;
    begin
    t:=TBitBtn.Create(nil);
    t.Name:='BitBtn100';
    t.parent :=Self; // 这里下断点
    end;

    一路跟踪就会发现到TWinControl.UpdateShowing函数,它发现当前控件尚未有句柄,因此会调用CreateHandle,然后就有了这些虚函数的系列旅程,会执行子类覆盖函数:

    TBitBtn.CreateHandle; // 在TWinControl.UpdateShowing里调用CreateHandle的时候,会下降到这里来
    TButton.CreateWnd;    // 在TWinControl.CreateHandle里调用CreateWnd的时候,会下降到这里来
    TBitBtn.CreateParams  // 在TWinControl.CreateWnd里调用CreateParams的时候,会下降到这里来

    但是子类通常不会放弃父类已经提供的功能,全都是在父类函数执行前或者执行后的结果上增加一小部分特性,形成三明治风格。

    干脆,我们看看TBitBtn增加些什么东西:

    procedure TBitBtn.CreateHandle; var
    State: TButtonState;
    begin
    if Enabled then // 增加按钮的状态
    State := bsUp
    else
    State := bsDisabled;
    inherited CreateHandle; // 三明治风格
    TButtonGlyph(FGlyph).CreateButtonGlyph(State); // 增加按钮的图像
    end;
    
    procedure TButton.CreateWnd;
    begin
    inherited CreateWnd;
    FActive := FDefault; // 增加判断是否处于激活状态
    end;
    
    procedure TBitBtn.CreateParams(var Params: TCreateParams);
    begin
    inherited CreateParams(Params);
    with Params do Style := Style or BS_OWNERDRAW; // 增加自绘状态
    end;

    可以手动执行跟踪一遍,加深印象~

  • 相关阅读:
    c++11 static_assert
    UVA
    析构函数与运行错误
    UVA
    2017 ACM-ICPC 亚洲区(乌鲁木齐赛区) C. Coconut
    2017 ACM-ICPC 亚洲区(乌鲁木齐赛区) A. Banana
    DOCTYPE的作用?
    数组去重的方法
    闭包的分析?
    SVN(集中式管理)分析
  • 原文地址:https://www.cnblogs.com/findumars/p/3970630.html
Copyright © 2020-2023  润新知