【读书笔记】【delphi高手突破】TCanvas与Windows GDI
2015-01-06 14:07
288 查看
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,则直接返回该句柄。
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,则直接返回该句柄。
相关文章推荐
- 【读书笔记】【Delphi高手突破】TCanvas
- 【读书笔记】【Delphi高手突破】TGraphicControl/TcustomControl 与画布(Canvas)
- delphi VCL研究之消息分发机制-delphi高手突破读书笔记
- 【读书笔记】【Delphi高手突破】TControl与Windows消息的封装
- Delphi高手突破学习笔记三
- Delphi高手突破第二章(3),封装,继承,多态
- delphi高手突破学习笔记之面向对象类和对象的本质(有汇编解释 good)
- Delphi高手突破第二章(4),VMT与DMT
- delphi高手突破之异常及错误处理
- delphi高手突破学习笔记之面向对象类和对象的本质
- delphi高手突破之异常及错误处理
- 鼓励,很多的,Delphi高手突破,外加冷水一瓢
- delphi高手突破学习笔记之面向对象类和对象的本质
- Delphi高手突破学习笔记一
- Delphi高手突破第二章(1),堆与栈,构造与析构函数
- Delphi高手突破第二章(2),对象大小,类方法与类引用,错误的面向对象设计
- (读书笔记)《玩着玩着就能成为PPT高手》——如何制作一个简单易懂的PPT
- Delphi 快捷键 让你更像高手!! (form DFW)
- 读书笔记:Delphi5开发人员指南 第二章(1)
- delphi 精要-读书笔记(内存分配释放)