【读书笔记】【delphi高手突破】TCanvas与Windows GDI

来源:互联网 发布:mac wifi 未安装硬件 编辑:程序博客网 时间:2024/05/21 15:08

TCanvas: 一条为图形组件(基类:TGraphicControl) , 一条为窗口组件(基类:TWinControl)。

1,TGraphicControl讲解(Tpen和Tbrush原理基本一致,TCanvas)

Windows使用pen绘图过程

     1,获取窗口的“设备上下文句柄”(HDC)。

     2,调用API函数CreatePen()创建一个宽度为2像素、颜色为红色(RGB(255, 0, 0))的笔对象

     3,调用API函数SelectObject()将所创建的笔对象选择为当前对象。(需要注意的是,此时必须将SelectObject()函数所返回的原先的GDI对象保存起来,在使用完创建的新的GDI对象后,要将它还原回去,否则就会发生GDI资源泄漏。)

     4,调用API函数LineTo()画出一条直线

     5,收尾工作:。首先选择还原GDI对象,并调用API函数DeleteObject()删除所创建的笔对象。最后不要忘记调用API函数ReleaseDC以释放窗口的HDC

      那么VCL将Windows GDI的Pen对象抽象为TPen类

工作原理:

     TPen = class(TGraphicsObject)
private
FMode: TPenMode;
procedure GetData(var PenData: TPenData);
procedure SetData(const PenData: TPenData);
protected
function GetColor: TColor;
procedure SetColor(Value: TColor);
function GetHandle: HPen;
procedure SetHandle(Value: HPen);
procedure SetMode(Value: TPenMode);
function GetStyle: TPenStyle;
procedure SetStyle(Value: TPenStyle);
function GetWidth: Integer;
procedure SetWidth(Value: Integer);
public
constructor Create;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
property Handle: HPen read GetHandle write SetHandle;
published
property Color: TColor read GetColor write SetColor default clBlack;
property Mode: TPenMode read FMode write SetMode default pmCopy;
property Style: TPenStyle read GetStyle write SetStyle default psSolid;
property Width: Integer read GetWidth write SetWidth default 1;
end;

步骤:

    1,TPen.create构建函数的工作

            constructor TPen.Create;
            begin
               FResource := PenManager.AllocResource(DefPenData);
               FMode := pmCopy;
            end;

          其中PenManager正是TResourceManager类,

          AllocResource()的任务是:

           a,寻找是否已经分配了同类型的Pen
           b,如果有,则增加该类型的Pen的引用计数;
           c,如果没有,则分配一个新的类型的Pen

        (其中:TPen的构造函数其实就是为其实例申请一块内存以存放该Pen的一些属性                 TPenData = record
                      Handle: HPen;
                      Color: TColor;
                      Width: Integer;
                      Style: TPenStyle;
                       end;)

          注意:默认(Handle)句柄=0,当真正需要使用Pen时,就需要将向Windows申请而获得的Pen对象的句柄赋给VCL的Pen对象。这就是通过其Handle属性进行的。

         那么Handle 如何获取的呢?

         答案:property Handle: HPen read GetHandle write SetHandle;

         a:

            SetHandle()方法将句柄传递给TPen实例的那个TPenData记录:
                 procedure TPen.SetHandle(Value: HPen);
                 var
                    PenData: TPenData;
                 begin
                     PenData := DefPenData;
                     PenData.Handle := Value;

                     SetData(PenData);
                 end;

         b:

           GetHandle()方法中,将判断其句柄是否为0。

      如果为0,则说明还没有真正向Windows申请创建过Pen对象,此时会真正地调用API函数CreatePenIndirect()来创建(该函数与CreatePen()差不多,区别只在于通过一个结构参数来指定该Pen的属性)一个GDI的Pen对象,并返回其句柄;如果不为0,则直接返回该句柄。





0 0