本章涵盖了VCL的图形编程的基本知识 .vcl封装了Windows图形设备接口,或GDI。 GDI 的方案可能是一个微妙而危险的进程。 塔梅斯这项技术并使其非常容易使用。
在下面的页面中,您将了解到:
重要的是要理解基本图形功能这里是从你在第28章,“游戏编程见过的DirectX程序查找先进的工具相距甚远。” 这只是基本的功能需要本标准的Windows程序.然而,在这一章所提供的材料是有用的大多数程序标准的Windows,它的核心是知识,所有的VCL的程序员应该具备的一部分。特别是,它显示了如何VCL的封装和简化的Windows GDI编程。
在VCL的图形支持的核心是发现Graphics.Hpp。 下列对象中可以找到这个文件:
Object 对象 | Description 描述 |
TCanvas 画布 | 这是基本的图形对象用于绘制窗体上或其他表面形状。这是周围的GDI的主要包装。 |
TBrush 画刷 | 这是用来指定颜色或图案,在中心的填充的形状,如矩形或椭圆形的对象。 |
TPen 画笔 | 这是画线所使用的对象,作为矩形或椭圆形的轮廓。 |
TPicture | 这是广义的,高层次的VCL包装围绕“如位图,图元文件,图片或图标”。 |
TMetaFileCanvas | 这是图元文件绘图表面。 |
TMetaFile | 这是围绕一个Windows图元文件的VCL包装。 |
TBitmap | 这是围绕位图的VCL包装。 |
TIcon TIcon | 这是围绕图标的VCL包装。 |
TGraphicsObject | Thi这是画刷,TFont基类,和画笔 。 |
TGraphic | 这是TMetaFile,TBitmap基类,Ticon。 |
这些对象的许多探索,在未来几页。特别是,我演示如何使用位图和笔,并显示如何绘制基本几何形状在屏幕上。你也可以看到如何使用位图和图元文件。 了解TFont对象后,下一个最重要的图形VCL的对象是画布 。这是周围的Windows GDI或图形设备接口的包装。在GDI是子系统Windows程序员使用油漆图片和实物,其他图形。对Graphics.Hpp中的大部分内容,目的是设法简化的GDI,使其相对容易使用。
另外两个重要的图形,并非源于Graphics.Hpp找到的对象是TImage和TPaintBox。 这两个组件包括在本章。
几乎所有的图形对象使用简单TColor类型。 这是建设该系统的整体图形奠定基石之一。
对于大多数实际目的,类型TColor,就是变量内置的Windows类型COLORREF。然而,TColor实际声明如下:
enum TColor {clMin=-0x7fffffff-1, clMax=0x7fffffff};
如果您知道COLORREF类型,你可以看到类似TColor类型。 在某种意义上说,TColor类型,不过是一组
预定COLORREF
调色板的Windows系统使您可以定义三种不同的颜色,红色,绿色和蓝色,其中每种颜色有255个不同的色调。 这些颜色指定在过去的3个字节字节长的值用来表示一个变量的类型TColor。
这里是什么三原色如下所示:
Canvas->Brush->Color = 0x000000FF; // Red 油画,“刷”颜色= 0x000000FF; / /红色
Canvas->Brush->Color = 0x0000FF00; // Green油画,“刷”颜色= 0x0000FF00; / /绿
Canvas->Brush->Color = 0x00FF0000; // Blue油画,“刷”颜色= 0x00FF0000; / /蓝
"你用这些色彩和这些颜色组合,在从第2章RGBShape计划“,基本事实的C + + Builder的。”
当然,这不是方便要写出这些数字的16进制直接。 相反,你可以使用RGB宏:
Canvas->Brush->Color = RGB(255, 0, 0); // Red 油画,“刷”的RGB颜色=(255,0,0); / /红色
Canvas->Brush->Color = RGB(0, 255, 0); // Green油画,“刷”的RGB颜色=(0,255,0); / /绿
Canvas->Brush->Color = RGB(0, 0, 255); // Blue油画,“刷”的RGB颜色=(0,0,255); / /蓝
你当然可以,结合红,绿,蓝,生产各种色调:
RGB(255, 0, 255); // Purple 的RGB(255,0,255); / /紫
RGB(255, 255, 0); // Yellow的RGB(255,255,0); / /黄色
RGB(127, 127, 127); // Gray的RGB(127,127,127); / /灰色
VCL中还提供了可以使用常量来指定常见的颜色系列。clBlack,例如,具有相同的内部编号你会从下面的代码:
COLORREF clBlack = RGB(0, 0, 0); COLORREF clBlack =的RGB(0,0,0);
下面是一些来自GRAPHICS.HPP声明:
#define clBlack TColor(0)
#define clMaroon TColor(128)
#define clGreen TColor(32768)
#define clOlive TColor(32896)
如果您想与这个系统进行试验,可以在BCB创建一个新的项目,拖放到主窗体的按钮和运行的方法有所改变,看起来像这样:
void __fastcall TForm1::Button1Click(TObject *Sender)
{ (
Canvas->Brush->Color = 0x0000FFFF;
Canvas->Rectangle(0, 0, 200, 200);//画布
} )
此代码将绘制在主窗体右上角明亮的黄色矩形。 尝试改变的刷颜色值0x00FF0000,到RGB(255,0,255),以clBlue,等等。 如果你绘制矩形厌了,您可以切换到椭圆形,而不是:
Canvas->Ellipse(0, 0, 200, 200);
我谈到与绘图画布后面的章节中形状多。
在大多数情况下你会选择从颜色属性编辑器提供的大多数组件的颜色。 例如,您可以双击一个TForm对象的颜色属性造就TColorDialog。然而,有些时候你需要与TColor类型直接,这就是为什么我有详细解释的主题。
一切形式的许多组成部分,有一个画布。你能想到的一个帆布被表面上的图形对象可以油漆。 总之,这里的开发人员使用的比喻是一个画家的画布。
这画布对象纳入层次结构的核心组件,通过聚合,在许多情况下意味着你可以通过一个对象的领域,例如TForm或TImage.
例如,您可以编写如下:
Form1->Canvas->TextOut(1, 1, "Hello from the canvas");
.本声明中写道从帆布改为“你好”,窗体的左上角。 请注意,您没有访问或引用一个设备上下文进行直接使用此方法。
当然,很多时候,你是从Form1 的内部访问Form1的大部分,因此,你可以写
Canvas->TextOut(1, 1, "Hello from the canvas");
但是,你不能写
Form1->TextOut(1, 1, "Hello from the canvas");
这是因为Canvas对象是到 Form1。 画布是通过多重继承带来的汇总。 此外,聚合并没有试图对包内的TForm方法画布的每一种方法。 "聚集在讨论19章更详细,“继承”和20,“封装。”
在 Canvas对象有几个关键的方法,所有的VCL的程序员应该知道:
Arc 弧 | 画弧线 |
Chord 和弦 | 一个封闭的数字显示1线和椭圆相交 |
CopyRect | 复制一个到另一个地区帆布 |
Draw 绘制 | 绘制位图或其他图形画布上 |
Ellipse 椭圆 | 绘制椭圆 |
FillRect | 填充矩形 |
FloodFill | 填写一个封闭的区域 |
FrameRect | Draw a border around a rectangle周围绘制一个矩形边框 |
LineTo | 画线 |
MoveTo | 画线 |
Pie | 画一个饼形对象 |
Polygon | 绘制多面对象 |
PolyLine | 连接一组点的画布 |
Rectangle | 绘制一个矩形 |
RoundRect | Draw a rectangle with rounded corners绘制一个圆角矩形 |
StretchDraw | 绘制相同,但该对象延伸,以填补区 |
TextHeight | 一个在当前字体弦高 |
TextOut | 输出文本 |
TextRect | 输出文本在某个特定地区的 |
TextWidth | 一个在当前字体字符串的宽度 |
在画布以下属性的对象很重要:
Font 字体
Brush刷
Pen笔
Pixels像素
以下事件可能对一些非常重要的技术程序:
OnChange
OnChanging
如果您知道在Windows API,这些方法中的许多人都会熟悉。从用帆布大可以获得对象而不是原始的Windows GDI调用是使用的资源会为你自动管理。特别是,你永远必须有一个设备上下文,也不必为选择到一个设备上下文对象。
在某些情况下,您将得到更好的性能,如果你直接写入到Windows GDI的。 然而,这是一个错误的假设,你将总是得到这样更好。 例如,VCL的图形子系统将缓存在一个复杂的方式共享资源,将很难复制在自己的代码。 我个人的看法是,你应该使用VCL的图形程序只要有可能,只有转向原始的Windows API当你碰到一个没有被覆盖的VCL图形区域。
该DrawShapes程序演示是多么容易使用的画布在程序中的对象。 此应用程序勾划出一个简单的画图程序的有能力来画线,矩形和椭圆轮廓。 该程序的屏幕截图见图7.1,以及该程序的源表7.1和7.2出现。
清单7.1为DrawShapes程序头文件中声明了一个枚举类型和几个简单的领域。
/// ///
// Main.cpp / /主程序
// DrawShapes Example / / DrawShapes范例
// Copyright (c) 1997 by Charlie Calvert / /版权所有(c)1997年由查理卡尔弗特
// / /
#ifndef MainH
#define MainH
#include
#include
#include
#include
#include
#include
#include
#include
enum TCurrentShape {csLine, csRectangle, csEllipse};
class TForm1 : public TForm
{ (
__published:
TMainMenu *MainMenu1; ;
TMenuItem *File1;
TMenuItem *Open1; ;
TMenuItem *Save1;
TMenuItem *N1;
TMenuItem *Rectangle1;
TMenuItem *Shapes1;
TMenuItem *Rectangle2;
TMenuItem *Ellipse1;
TMenuItem *Colors1;
TMenuItem *Brush1;
TMenuItem *Pen1;
TPanel *Panel1;
TSpeedButton *SpeedButton1;
TSpeedButton *SpeedButton2;
TSpeedButton *SpeedButton3;
TSpeedButton *SpeedButton4;
TMenuItem *Lines1;
TColorDialog *ColorDialog1;
TSpeedButton *SpeedButton5;
void __fastcall FormMouseDown(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y);
void __fastcall FormMouseUp(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y);
void __fastcall FormMouseMove(TObject *Sender, TShiftState Shift, int X,
int Y);
void __fastcall SpeedButton1Click(TObject *Sender);
void __fastcall Brush1Click(TObject *Sender);
void __fastcall Pen1Click(TObject *Sender);
void __fastcall SpeedButton5Click(TObject *Sender);
private:
TRect FShapeRect;
TColor FPenColor;
TColor FBrushColor;
bool FDrawing;
TCurrentShape FCurrentShape;
int FPenThickness;
void __fastcall DrawShape();
public:
virtual __fastcall TForm1(TComponent* Owner);
}; );
extern TForm1 *Form1;
#endif
清单7.2 为DrawShapes计划的主要形式展示了如何在画布上绘制形状。
/// ///
// Main.cpp / /主程序
// DrawShapes Example / / DrawShapes范例
// Copyright (c) 1997 by Charlie Calvert / /版权所有(c)1997年 查理卡尔弗特
// / /
#include
#pragma hdrstop
#include "Main.h"
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
FDrawing= False;
FCurrentShape = csRectangle;
FBrushColor = clBlue;
FPenColor = clYellow;
FPenThickness = 1;
}
void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
FShapeRect.Left = X;
FShapeRect.Top = Y;
FShapeRect.Right = - 32000;
FDrawing = True;
}
void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
FDrawing = False;
FShapeRect.Right = X;
FShapeRect.Bottom = Y;
Canvas->Pen->Mode = pmCopy;
DrawShape();
}
void __fastcall TForm1::DrawShape()
{
Canvas->Brush->Color = FBrushColor;
Canvas->Pen->Color = FPenColor;
Canvas->Pen->Width = FPenThickness;
switch (FCurrentShape)
{
case csLine:
Canvas->MoveTo(FShapeRect.Left, FShapeRect.Top);
Canvas->LineTo(FShapeRect.Right, FShapeRect.Bottom);
break;
case csRectangle:
Canvas->Rectangle(FShapeRect.Left, FShapeRect.Top,
FShapeRect.Right, FShapeRect.Bottom);
break;;
case csEllipse:
Canvas->Ellipse(FShapeRect.Left, FShapeRect.Top,
FShapeRect.Right, FShapeRect.Bottom);
break;
default:
;
}
}
void __fastcall TForm1::FormMouseMove(TObject *Sender,
TShiftState Shift, int X, int Y)
{
if (FDrawing)
{
Canvas->Pen->Mode = pmNotXor;
if (FShapeRect.Right != -32000)
DrawShape();
FShapeRect.Right = X;
FShapeRect.Bottom = Y;
DrawShape();
}
}
void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
{
FCurrentShape = TCurrentShape(dynamic_cast
}
void __fastcall TForm1::Brush1Click(TObject *Sender)
{
ColorDialog1->Color = FBrushColor;
if (ColorDialog1->Execute())
FBrushColor = ColorDialog1->Color;
}
void __fastcall TForm1::Pen1Click(TObject *Sender)
{
ColorDialog1->Color = FPenColor;
if (ColorDialog1->Execute())
FPenColor = ColorDialog1->Color; ;
}
void __fastcall TForm1::SpeedButton5Click(TObject *Sender)
{
FPenThickness = dynamic_cast
}
该程序使您能够画线,矩形,并在应用程序的主要形式椭圆形。您可以选择的形状类型您要通过菜单或以速度按钮即可。该计划还允许您设置的形状要绘制并指定宽度和形状周围边框的颜色。
当设置形状的颜色,你需要知道,在一个区域获得形状填充设置为画布当前刷颜色。该行构成了形状的边界是受当前的笔 。
以下是如何设置当前的颜色和笔的宽度:
Canvas->Pen->Color = clBlue;
Canvas->Pen->Width = 5;
如果你想改变刷颜色,您可以编写下面的代码:
Canvas->Brush->Color = clYellow;
我不工作正是在这一程序,但您可以分配不同风格的刷子 ,如以下定义的枚举类型:
TBrushStyle { bsSolid, bsClear, bsHorizontal, bsVertical,
bsFDiagonal, bsBDiagonal, bsCross, bsDiagCross };
默认情况下, 刷子有bsSolid类型。
若要设置一刷子风格,你会编写的代码如下:
Canvas->Brush->Style = bsSolid;
上课也有刷颜色和位图属性。 位图属性可以被设置为一个小的外部位图图像定义为画笔模式。
只有一个的画刷对象,你很可能会使用的方法。这种方法被称为分配 ,这是当你要复制的一刷到另一个特点刷。
所有笔已全部刷类作为相同的属性,但它们添加宽度和模式的财产。属性定义的宽度以像素为单位的笔宽,Mode属性定义的类型 .操作时要使用油漆笔在屏幕上。这些逻辑业务将进一步讨论在短短的几分钟。
在阅读本节,加快DrawShapes程序和惯例制定椭圆和矩形屏幕上的灭火器,你可以看到如何橡皮技术工程。 如果由于某种原因,你不能运行DrawShapes程序,打开Windows画图和借鉴一下,首先从工具菜单中选择相应的图标一些正方形或圆形。观察这些程序的方式创造一个弹性方形或圆形,您可以拖动桌面。这些形状播放你决定什么尺寸和位置为您的几何图形想要的。
这些工具似乎难以程序员创建,但到Windows的API,代码是比较小.以下是主要涉及的步骤,每个解释深入本节后面:
虽然这种描述显然省略了一些重要细节,纲要应在你的脑海中只有几个相对简单,逻辑抚摸形状的算法。 事情变得有点复杂的细节时,超过1一个心理转折实在不足,但基本步骤应该是比较清楚的。
(NOTE)注意: 在前面的编号列表,我给的消息的名称,生成的VCL事件。 例如,WM_LBUTTONDOWN消息生成一个OnMouseDown事件的WM_MOUSEMOVE消息产生一个onMouseMove事件,等等。 我指的是基本的信息,因为这是一个好主意记住之间的VCL事件及其相关的Windows消息的连接。
放大的细节,这里有一个在一个WM_LBUTTONDOWN消息的响应看看:
void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
FShapeRect.Left = X;
FShapeRect.Top = Y;
FShapeRect.Right = - 32000;
FDrawing = True;
}
FormMouseDown保存的位置上鼠标是在首两个月的TRect结构字段点击称为FShapeRect。FShapeRect是作为一个TForm1领域的申报。 本人设置TRect结构的权利方面有很大的负数,所以我知道这是第一次,我需要开始跟踪用户的鼠标移动。这是非常必要的,因为第一个形状我提请作为一种特例来处理的需要。
最后一件事,在FormMouseDown方法所做的是建立一个TForm1私有变量FDrawing为 True。这让程序知道用户已经开始绘图操作。
鼠标左键被按下后,该程序拿起一切开始DrawShape飞行一条WM_MOUSEMOVE消息的消息:
void __fastcall TForm1::FormMouseMove(TObject *Sender,
TShiftState Shift, int X, int Y)
{
if (FDrawing)
{
Canvas->Pen->Mode = pmNotXor;
if (FShapeRect.Right != -32000)
DrawShape();
FShapeRect.Right = X;
FShapeRect.Bottom = Y;
DrawShape();
}
}
该函数的第一行使用的检查,看看几个可能的方法之一,如果鼠标左键下降。如果该按钮不下来,函数忽略此消息。如果它已关闭,该函数获取设备上下文,设置笔氏绘图模式pmNotXor,背的数字目前尺寸,绘制它,并释放设备上下文。
一个画笔对象的模式属性设置方式类似于在BitBLT等方式最后一个参数设置当前绘画模式当前绘图模式。您可以实现通过直接调用Windows API函数调用SetROP2同样的效果。在这种情况下,DrawShape使用逻辑异或和 NOT行动blit的弹性图像的屏幕。这是合乎逻辑的行动选择,因为它描绘的原始图像的顶部的老形状直接,从而有效地清除每个形状:
这就是在图形模式下简单的逻辑运算的优点。
(NOTE)注意: Aficionados 的图形芯片将注意到,合乎逻辑的行动DrawShapes就业是一个关于异或 (XOR)变异操作。这种变化确保在形状的中心填写要绘制不会抹杀它下面是什么的。 微软文档解释了这样的区别:
R2_XOR: final pixel = pen ^ screen pixel
R2_NOTXORPEN : final pixel = ~(pen ^ screen pixel)
此代码测试,看看是否像素是异署属于一支笔。不要浪费太多的逻辑运算令人担忧,它们是如何工作。 如果您感兴趣的罚款;如果他们不这样做,没关系。 这本书的主题是编程,而不是逻辑。
如果你是工作在Windows API直接,你会与一个常数,而不是所谓的pmNotXor RT_NOTXORPEN。我必须承认,VCL的倾向重新命名的Windows API使用的常量是不是一个很成功的特征。当然,在微软的人谁带着这些标识多了一些值得可怕的,无名的命运,但一旦损害已经造成,可能有简单的坚持使用原来的常量。这样人们就不会记住,是Windows API的使用两套标识符与VCL的使用1,和其他。您不能使用VCL的常量将Windows常数,因为各标识符没有映射到相同的值。
尽管有这些反对意见,我仍然认为这是明智的使用VCL的,而不是直接写入到Windows的API。 VCL的是更安全和更容易使用。 从大多数的VCL对象的性能是伟大的,也将是比大多数程序员可以直接写入Windows API中取得更好的许多案件。
请注意,FormMouseMove 调用 DrawShape两次。第一次,它通过在旧的数字,需要擦除的尺寸。这意味着它的S 异或相同的图像直接对原始图像的顶部,从而抹去了。 然后FormMouseMove记录了最新的WM_MOUSEMOVE消息的位置并通过这项新的信息DrawShape,其中涂料的新形象在屏幕上。这整个过程重复一遍又一遍(以难以置信的速度),直到用户解除了鼠标左键。
在DrawImage功能, 隐喻首先检查的形状用户选择,然后继续塑造绘制到屏幕上使用当前的笔和填充颜色:
void __fastcall TForm1::DrawShape()
{
Canvas->Brush->Color = FBrushColor;
Canvas->Brush->Style = bsSolid;
Canvas->Pen->Color = FPenColor;
Canvas->Pen->Width = FPenThickness;
switch (FCurrentShape)
{
case csLine:
Canvas->MoveTo(FShapeRect.Left, FShapeRect.Top);
Canvas->LineTo(FShapeRect.Right, FShapeRect.Bottom);
break;
case csRectangle:
Canvas->Rectangle(FShapeRect.Left, FShapeRect.Top,
FShapeRect.Right, FShapeRect.Bottom);
break;
case csEllipse:
Canvas->Ellipse(FShapeRect.Left, FShapeRect.Top,
FShapeRect.Right, FShapeRect.Bottom);
break;
default:
; ;
}
}
此代码设置当前的笔和刷子由用户选择的值。 然后,使用switch语句来选择适当类型的形状绘制到屏幕上。 如FPenColor这些私有变量大多设置允许用户从菜单中作出选择。要清楚地看到它的工作原理,你可以研究在应用程序代码。
请注意,当这些形状绘图,没有必要跟踪当前画布 HDC。对画布对象的主要目标之一是完全隐藏在用户的HDC。"本人更深入地讨论这一问题在本章下一节,“为了GDI或不GDI的。”
在整个行动的最后一步发生时,用户抬起关闭鼠标手指:
在整个行动的最后一步发生时,用户抬起关闭鼠标手指:
void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
FDrawing = False;
FShapeRect.Right = X;
FShapeRect.Bottom = Y;
Canvas->Pen->Mode = pmCopy;
DrawShape();
}
此代码执行下列操作:
油漆的代码,最后形成考虑到颜色和厚度的笔,用户选择的菜单。 那么,你有它。 .这就是你画的形状在屏幕上用橡皮筋技术。 总的来说,如果你在一件事,但这个过程并不是太复杂。 正是这样您可以使这些步骤清醒的头脑,在这里他们再次:
这就是这么简单。
如果你想获得一个窗口的HDC,你可以在它通过画布的Handle属性:
MyOldPenHandle = SelectObject(Canvas->Handle, MyPen->Handle);
In this case you are copying the Handle of a Pen object into the HDC of the TCanvas object.
Having free access to the Handle of the TCanvas object can be useful at times, but the longer I use the VCL, the less inclined I am to use it. The simple truth of the matter is that I now believe that it is best to let an object of some sort handle all chores that require serious housekeeping. This course of action allows me to rely on the object's internal logic to correctly track the resources involved.
If you are not using the VCL, whenever you select something into an HDC, you need to keep track of the resources pumped out of the HDC by the selection. When you are done, you should then copy the old Handle back into the HDC. If you accidentally lose track of a resource, you can upset the balance of the entire operating system. Clearly, this type of process is error-prone and best managed by an object that can be debugged once and reused many times. My options, therefore, are to either write the object myself or use the existing code found in the VCL. In most cases, I simply take the simplest course and use the excellent TCanvas object provided by the VCL.
When I do decide to manage an interaction with the GDI myself, I often prefer to get hold of my own HDC and ignore the TCanvas object altogether. The reason I take this course is simply that the TCanvas object will sometimes maintain the Canvas 's HDC on its own, and I therefore can't have complete control over what is happening to it.
这里有一个如何使用程序内的VCL了GDI直接简单的例子:
HDC DC = GetDC(Form1->Handle); HDC直流= GetDC(Form1上,“柄);
HFONT OldFont = SelectObject(DC, Canvas->Font->Handle); HFONT OldFont = SelectObject(区,帆布,“字体”柄);
TextOut(DC, 1, 100, "Text", 4);
SelectObject(DC, OldFont);
ReleaseDC(Form1->Handle, DC);
如果您在此处显示的代码,你会看到我通过调用Windows API函数GetDC我自己的直流。 然后我将选择一个DC新字体。 请注意,我使用的VCL TFont对象。 我通常会更容易地管理字体秒, 笔秒,并比原始的Windows API代码的VCL对象刷上课。 不过,如果你想创建原始的Windows API编写自己的字体,您可以自由地这样做。
下面是一个创建的VCL 字体从头对象的例子:
TFont *Font = new TFont();
Font->Name = "Time New Roman";
Font->Size = 25;
Font->Style = TFontStyles() << fsItalic << fsBold;
HDC DC = GetDC(Form1->Handle);
HFONT OldFont = SelectObject(DC, Font->Handle);
TextOut(DC, 1, 100, "Text", 4);
SelectObject(DC, OldFont);
ReleaseDC(Form1->Handle, DC);
delete Font;
此代码分配了一个字体对象的内存,分配一些值其主要属性,然后复制的句柄Font对象到当前DC。请注意,我仍然要保存旧的字体处理和复制到当我与它所做的直流回来。这是我喜欢的运作有一个对象处理的类型。当我与此处显示的示例代码一样,我删除我创建Font对象。
摘要:
在这一章中你有一个图形编程与VCL的概述。我并没有试图掩盖这一问题的所有方面,但希望你现在有足够的资料,以满足您的需求最大。
本章涉及的关键议题包括画布对象,绘制在窗体或部件的表面形状或使用的措词。你也看到了TFont,画刷和画笔对象,定义的形状特征或在组件上绘制的信件。在TMetaFile和TBitmap对象们介绍,虽然我从来没做的简单和容易使用的TIcon对象的任何东西。该章的最后一节有一点乐趣华丽的图像绘制到屏幕上。
一个有关的问题,这不是本章所覆盖的TImageList对象。如果您对这个问题感兴趣,你可能想看看KdAddExplore程序上找到的CD - ROM伴随着这本书。该计划应在Chap14目录。该TImageList组件提供了一个图像存储在内存列表意味着同时采取了最低的系统资源的数量。这是更昂贵的存储图像列表5张图像比将是在程序中使用五个不同的位图。