zoukankan      html  css  js  c++  java
  • 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;
  • 相关阅读:
    oracle中Blob和Clob类型的区别
    为什么要分库分表
    Enable file editing in Visual Studio's debug mode
    SQL Server Dead Lock Log
    Debug .NET Framework Source
    SQL Server text field里面有换行符的时候copy到excel数据会散乱
    诊断和修复Web测试记录器(Web Test Recorder)问题
    Can't load Microsoft.ReportViewer.ProcessingObjectModel.dll
    'telnet' is not recognized as an internal or external command
    Linq to XML
  • 原文地址:https://www.cnblogs.com/findumars/p/4102723.html
Copyright © 2011-2022 走看看