• VCL里为什么要用类函数代替API,为什么要用CM_消息代替虚函数


    之所以要用类函数代替API,是因为VCL对它做了一些包装,好在API起作用之前和之后做一些额外的事情:通知和判断等等。
    之所以类函数要包装一个CM_消息,是因为这样方便程序员(在调用类函数的基础上)截断和改写这个处理过程

    举例:

    procedure TWinControl.Invalidate;
    begin
      // 注意,是简单执行函数,把消息当作参数,不是发送消息
      Perform(CM_INVALIDATE, 0, 0); // 注意,第二个参数即WParam是0,即要求API使自己失效,而不是仅仅做一个通知作用。
    end;
    
    procedure TWinControl.CMInvalidate(var Message: TMessage);
    var
      I: Integer;
    begin
      // 这个函数被所有Windows子控件所继承,只要没有被程序员(或者控件程序员)覆盖,那么就会使用API将整个客户区全部都声明为无效区域,其实过程很简单
    // 其实最后就是简单调用API,但是就是被VCL库框架包装了一遍
    
    if HandleAllocated then
      begin
        // 相当于子控件要重画,必须通知一下父控件,而且是挨个通知,父控件想处理就处理,不处理就算了(大部分情况下不会处理)。
        if Parent <> nil then
          Parent.Perform(CM_INVALIDATE, 1, 0); // 递归,先通知父类。
          
        // 父控件通知完了,就该重画自己了。
    if Message.WParam = 0 then
        begin
          InvalidateRect(FHandle, nil, not (csOpaque in ControlStyle)); // API,第二个参数为NULL的话,则重画整个客户区;第三个参数TRUE则背景重绘。
          { Invalidate child windows which use the parentbackground when themed }
    if ThemeServices.ThemesEnabled then
            for I := 0 to ControlCount - 1 do
    if csParentBackground in Controls[I].ControlStyle then // important
                Controls[I].Invalidate;
        end;
      end;
    end;
  • 相关阅读:
    服务详解网址
    WCF、WebAPI、WCFREST、WebService之间的区别
    ql常见面试题 受用了
    用VSCode写python的正确姿势
    C#集合类型大盘点
    ASP.NET Web API 创建帮助页
    C#中IEnumerable、ICollection、IList、List之间的区别
    [WCF REST] 一个简单的REST服务实例
    sql存储过程算法
    oracle 存储过程
  • 原文地址:https://www.cnblogs.com/findumars/p/4102723.html
Copyright © 2020-2023  润新知