研读深入浅出VCL一书的时候,有不少地方被网友提出疑问,而且似乎是网友们正确。但这丝毫不动摇李维在大中华Delphi界的江湖地位,因为高手应该是对整个系统理解的高手,而不是对某一个疑问的高手。能花巨量心思与精力写出如此巨著已经很不可思议,更不用说他还写了许多其它书籍、做了许多其它事情。

我自己也算仔细研读了一遍VCL,对照李维的巨著学习之外,仍有自己的不少心得,我也会慢慢写在这里,一个世界级的Windows平台编程基础库,实在是太难太庞大了,以至于李维也无法面面俱到。但是有一点对Delphi的哲学思想必须领会:工程师就是用最简便的方法解决问题、达到目的,并且还要解决工程中所遇到的每一个问题的细节,而且还经常得是不偏不倚的解决方案,而不能是太过于私有的技巧。闲话少说:

1. TControl的Parent必须是TWinControl

《深入BCB理解VCL的消息机制》一文里提到:鼠标消息是由IsControlMouseMsg方法来处理的。只有再跟到IsControlMouseMsg去看看啦。源码如下:

function TWinControl.IsControlMouseMsg(var Message: TWMMouse): Boolean;
var
//TControl出现啦
Control: TControl;
P: TPoint;
begin
if GetCapture = Handle then
begin
Control := nil;
if (CaptureControl <> nil) and (CaptureControl.Parent = Self) then
Control := CaptureControl;
end else
Control := ControlAtPos(SmallPointToPoint(Message.Pos), False);
Result := False;
if Control <> nil then
begin
P.X := Message.XPos - Control.Left;
P.Y := Message.YPos - Control.Top;
file://TControl的Perform方法将消息交由WndProc 处理。
Message.Result := Control.Perform(Message.Msg, Message.Keys,
Longint(PointToSmallPoint(P)));
Result := True;
end;
end;

由于这个原因,BCB和Delphi中的TControl类及其所有的派生类都有一个先天的而且是必须的限制。那就是所有的TControl类及其派生类的Owner 必须是TWinControl类或者TWinControl的派生类。Owner属性最早可以在TComponent中找到,一个组件或者控件是由它的Owner 拥有并负责释放其内存的。这就是说,当Owner从内存中释放的时候,它所拥有的所有控件占用的内存也都被释放了。Owner最好的例子就是Form。Owner同时也负责消息的分派,当Owner接收到消息的时候,它负责将应该传递给其所拥有的控件的消息传递给它们。这样这些控件就能够取得处理消息的能力。TImage 就是个例子:你可以发现Borland并没有让TImage重载TControl的WndProc方法,所以TImage也只有处理鼠标消息的能力,而这种能力正是来自TControl的。

李维对VCL理解的几个错误的更多相关文章

  1. 李维作答 《insideVCL》——李维实在很勤奋,而且勇于突破,从不以旧的内容充数

    (编者按)<Inside VCL(VCL核心架构剖析)>一书出版以来,众多热心读者给李维先生.博文视点公司.CSDN写来信件,有更多朋友在各个论坛上发表关于该书的言论.读者们不但盛赞该书, ...

  2. 2018.9.28 典型for循环特殊理解及其二维数组的理解

    如果for里面换成了函数结果会是怎么样呢?下面就来介绍一下 package praDemo; public class Test { public static boolean foo(char c) ...

  3. c语言中指针和多维数组的理解

    1.复习指针和数组之间的特殊关系:不带方括号的数组名是一个指针,指向该数组的第一个元素. 2.多维数组: ][];//声明一个二维数组作为举例 a.理解方式1:可以将数组看成行和列构成,即理解成2行4 ...

  4. 从运维的角度理解Iaas、Paas、Saas云计算

    平时我们的运维工作,大致就是了解需求.申请服务器.配置网络.服务器软件安装.应用部署.数据存储.系统调优.平台维护等 按照Iaas.Paas.Saas的三层来分工我们平时的任务: 最底层的Iaas层提 ...

  5. Boost_1_33_1沒有想像中的恐怖 (李维)

    2006/11/16 下午 02:14:16原則上要先使用build.bat, 產生bjam.exe, 再編繹出library. 由於各編譯器不同, lib並無法共用! 編譯完成後:*.lib在 C: ...

  6. DataSnap控件TDSServerClass属性LifeCycle生命周期管理(From李维)

    DelphiXE2中的DataSnap中提供了三种不同的生命周期,开发人员可以在TDSServerClass控件的LifeCycle特性中设定,下面分别说明每一种生命周期的意义 1. Server:在 ...

  7. 改变TLabel字型和颜色(Styled特性高于自身特性,李维的博客)

    最近收到几位使用者的来信都是和如何改变FireMonkey TLabel组件的字型和颜色, 这几位使用者都是直接改变TextSettings特性中的Font子特性但却无法改变字型和颜色, 因此来信询问 ...

  8. 运维LVS-NAT模式理解

    一.LVS-NAT模式的工作原理这个是通过网络地址转换的方法来实现调度的.首先调度器(LB)接收到客户的请求数据包时(请求的目的IP为VIP),根据调度算法决定将请求发送给哪个 后端的真实服务器(RS ...

  9. 李洪强iOS开发之OC常见错误汇总

    // //  main.m //  16 - 常见错误汇总 // //  Created by vic fan on 16/7/13. //  Copyright © 2016年 李洪强. All r ...

随机推荐

  1. gulp 前缀

    var gulp = require('gulp'), autoprefixer = require('gulp-autoprefixer'); gulp.task('testAutoFx', fun ...

  2. 懒癌晚期学图论的时候自己用C语言写了个求可达性矩阵的算法~

    可达性矩阵算法~ 直接上代码 #include <iostream> #include <cstring> using namespace std; #define n 5 v ...

  3. 笔试算法题(43):布隆过滤器(Bloom Filter)

    议题:布隆过滤器(Bloom Filter) 分析: BF由一个很长的二进制向量和一系列随机映射的函数组成,通过多个Hash函数将一个元素映射到一个Bit Array中的多个点,查询的时候仅当所有的映 ...

  4. LIBSVM使用方法及参数设置

    LIBSVM 数据格式需要---------------------- 决策属性 条件属性a 条件属性b ... 2 1:7 2:5 ... 1 1:4 2:2 ... 数据格式转换--------- ...

  5. AspNetPager控件的简单使用

    1.首先引用这个控件. 在前台页面上修改一些属性. <webdiyer:AspNetPager ID=" AlwaysShow="true" FirstPageTe ...

  6. HDU 4473

    题目大意: 给定一个long long 型的数 n,找到一共有多少对a,b,使比n小的某一个数的是a*b的倍数 这样我们可以理解为 存在a*b*c <= n,令 a <= b <= ...

  7. codeforces 359A

    #include<stdio.h> #define N 60 int map[N][N]; int main() {  int n,m,i,j,flag;  while(scanf(&qu ...

  8. 【NOIP2017练习】怎样学习哲学(计数,DP)

    题意:OI大师抖儿在夺得银牌之后,顺利保送pku.这一天,抖儿问长者:“虽然我已经保送了,但是我还要参加学考.马上就要考政治了,请问应该怎样学习哲学,通过政治考试?”  长者回答:“你啊,Too Yo ...

  9. msp430入门学习21

    msp430的USART的SPI模式 msp430入门学习

  10. UVa 12563_Jin Ge Jin Qu hao

    [题意]在KTV唱歌,假设每首歌最长180s,时间结束时如果还有歌正在唱,则将此歌唱完.为使唱歌时间最长,规定最后唱长达678s的<劲歌金曲>[介是个嘛?] 假设你正在唱KTV,在剩余的t ...