MFC GDI 绘图模式、映射模式、画笔、笔、字体

  GDI 绘图模式(RoP2 Mode)       

        在使用·VC++ MFC进行图形程序编程时,常会用到GDI绘图指令,而要做到绘图时有橡皮筋动态效果,就需设置GDI绘图模式。GDI绘图模式有多种,如下:

常用R2_NOT模式来实现橡皮筋效果,当使用了R2_NOT模式后,一般需要使用R2_COPYPENQ切换回常规的绘图效果。设置绘图模式需用到SetROP2函数,例如实现绘制直线的橡皮筋效果,会用到类似下面的代码:

pDC->SetROP2(R2_NOT);
pDC->MoveTo(mcpoint[0]);
pDC->LineTo(mcpoint[1]);
pDC->SetROP2(R2_NOT);
pDC->MoveTo(mcpoint[0]);
pDC->LineTo(point);
mcpoint[1] = point;

实现移动鼠标时的动态效果后,最后要绘出直线则会用到类似下面的指令代码:

pDC->SetROP2(R2_NOT);
pDC->MoveTo(mcpoint[0]);
pDC->LineTo(mcpoint[1]);
pDC->SetROP2(R2_COPYPEN);
pDC->MoveTo(mcpoint[0]);
pDC->LineTo(mcpoint[1]);

         二 映射模式

        通常情况下,GDI绘图·使用的是逻辑单位,输入的x,y坐标通常是逻辑数值,是整数类型(对于窗口是逻辑值,对视口来讲是像素)。要将逻辑单位与长度单位联系起来,就需用到映射模式。下面是映射模式的列表:

后面两种为可编程映射模式,即通过对窗口与视口的合理设置,可以使前面6种模式无法全部显示的图形得以完整显示。常用于根据窗口尺寸按比例自动调节图画的输出大小的场合。当设置为MM_ISOTROPIC模式时,应先调用SetWindowEX函数函数,再绘图。如下面代码:

CRect rec;
GetClientRect(rec);
dc.SetMapMode(MM_ISOTROPIC);
dc.SetWindowExt(500,500);
dc.SetViewportExt(rec.Width(),rec.Height());
dc.Lin(CPoint(0,0), CPoint(800,300));

        MM_ANISOTROPIC模式对先设置窗口还是视口没有特别要求。        

        要获取显示设备显示区域的大小(即我们常说的屏幕分辨率)可以使用GetDeviceCaps函数,如下面代码:

CClientDC dc(this);
int x = dc.GetDeviceCaps(HORZRES);
int x = dc.GetDeviceCaps(VERTRES);

通过在GetDeviceCaps函数输入其它参数,还可获得更多的有用信息,GetDeviceCaps函数可以设置以下参数:

在图形程序设计时还会遇到坐标原点移动即逻辑坐标与屏幕坐标间的转换。这时可以使用SetWindowOrg、DPtoLP、LPtoDP等函数。下面是一端示例代码:

CRect rec;
GetClientRect(&rec);
dc.SetMapMode(MM_LONGENGLISH);
CPoint pt(rec.Width() / 2. rec.Height() / 2);
dc.DPtoLP(&pt);
dc.SEtWindowOrg(-pt.x,-pt.y);

        画笔(刷)(CBrush)

        MFC 封装一个 Windows 图形设备接口 (GDI) 类CBrush,这就是我们常说的画笔,叫画刷的时候跟多。CBrush类比较简单其构造函数、公有方法·及·运算法如下:

   构造函数 CBrush有四个重载构造函数。 没有参数的构造函数构造未初始化的  CBrush 对象,必
须先对其进行初始化,然后才能使用。其构造函数的原型如下:

构造函数参数:

CBrush::CreateBrushIndirect 使用 LOGBRUSH 结构中指定的样式、颜色和图案初始化画笔。其原型如下:BOOL CreateBrushIndirect(const LOGBRUSH* lpLogBrush); 参数lpLogBrush指向包含画笔信息的 LOGBRUSH 结构。返回值:如果该函数成功,则为非 0;否则为 0。

LOGBRUSH 结构体的定义如下:

typedef struct tag LOGBRUSH { /* lb */ UINT lbStyle; COLORREF lbColor; LONG lbHatch; 
} LOGBRUSH;
  • lbStyle:这个成员指定了画刷的样式。它可以取以下值之一:
    • BS_DIBPATTERN:使用设备无关位图(DIB)定义的模板画刷。
    • BS_DIBPATTERNPT:与BS_DIBPATTERN类似,但使用指向已打包DIB的指针。
    • BS_HATCHED:阴影画刷。
    • BS_HOLLOW:空画刷,实际上不绘制任何内容。
    • BS_NULL:与BS_HOLLOW相同。
    • BS_PATTERN:使用内存位图定义的模板画刷。
    • BS_SOLID:实心画刷。
  • bColor:这个成员指定了画出画刷的颜色。
  • lbHatch:这个成员的含义依赖于lbStyle所定义的画刷样式。例如,如果lbStyleBS_HATCHED,则lbHatch指定了创建阴影时使用的线条的方向。如果lbStyleBS_PATTERN,则lbHatch为定义了模板的位图句柄。

示例:

// Initialize a LOGBRUSH structure.
LOGBRUSH logBrush;
logBrush.lbStyle = BS_HATCHED;
logBrush.lbColor = RGB(0, 192, 192);
logBrush.lbHatch = HS_CROSS;
// Declare an uninitialized CBrush ...
CBrush brush;
// ... and initialize it with the LOGBRUSH.
brush.CreateBrushIndirect(&logBrush);

CBrush::CreateDIBPatternBrush 使用与设备无关的位图 (DIB) 指定的模式初始化画笔。其原型如下:

BOOL CreateDIBPatternBrush(
HGLOBAL hPackedDIB,
UINT nUsage);
BOOL CreateDIBPatternBrush(
const void* lpPackedDIB,
UINT nUsage);

参数hPackedDIB标识包含打包的设备无关位图 (DIB) 的全局内存对象。nUsage指定 BITMAPINFO 数据结构(“打包 DIB”的一部分)的  bmiColors[] 字段是否包含显式RGB 值或当前所实现逻辑调色板的索引。 该参数必须是以下值之一:DIB_PAL_COLORS 颜色表包含一组 16 位索引。DIB_RGB_COLORS 颜色表包含文字 RGB 值。lpPackedDIB 指向由  BITMAPINFO 结构组成的压缩 DIB,其后紧跟定义位图像素的字节数组。返回值 如果成功,非0;否则为 0。

示例:

// Resource handle to bitmap.
HRSRC hRes;
// Global handles to bitmap resource.
HGLOBAL hData;
void *hLockedData;
CBrush brush;
// Find the resource handle.
hRes = ::FindResource(AfxGetResourceHandle(),
MAKEINTRESOURCE(IDB_BRUSH), RT_BITMAP);
if (hRes != NULL)
{
// Lock and Load (or Load and Lock).
if (((hData = ::LoadResource(AfxGetResourceHandle(),
hRes)) != NULL) &&((hLockedData = ::LockResource(hData)) != NULL))
{
// Initialize the brush.
brush.CreateDIBPatternBrush((const void *)hLockedData,
DIB_RGB_COLORS);
// Select the brush into the device context.
CBrush *pOldBrush = pDC->SelectObject(&brush);
// Draw.
pDC->Rectangle(50, 50, 200, 200);
// Restore the original device context.
pDC->SelectObject(pOldBrush);
// Free the resource.
::FreeResource(hLockedData);
}
}

CBrush::CreateHatchBrush 使用指定的阴影图案和颜色初始化画笔。其原型如下:

BOOL CreateHatchBrush(int nIndex,COLORREF crColor);

参数 nIndex指定画笔的阴影样式。 可以是以下任一值:HS_BDIAGONAL 45 度向下的阴影(从左到右),HS_CROSS 横向缩放与纵向阴影线,HS_DIAGCROSS 45 度阴影线,HS_FDIAGONAL 45 度向上的阴影(从左到右),HS_HORIZONTAL 水平阴影,HS_VERTICAL 垂直阴影。crColor 将画笔的前景色指定为 RGB 颜色(阴影的颜色)。 有关详细信息,请参阅 Windows
SDK 中的 COLORREF。返回值: 如果成功,非 0;否则为 0。

CBrush::CreatePatternBrush 使用位图指定的模式初始化画笔。其原型如下:

BOOL CreatePatternBrush(CBitmap* pBitmap);

参数 pBitmap 标识位图。返回值 如果成功,则不为 0;否则为 0

CBrush::CreateSolidBrush 用指定的纯色初始化画笔。其原型如下:

BOOL CreateSolidBrush(COLORREF crColor);
参数 crColor 指定画笔颜色的 COLORREF 结构。 颜色指定一个 RGB 值,并可以使用  WINDOWS.H 中的RGB 宏进行构造。返回值 如果成功,则不为 0;否则为 0。

CBrush::CreateSysColorBrush 初始化画笔颜色。其原型如下:

BOOL CreateSysColorBrush(int nIndex);

参数  nIndex 指定颜色索引。 

COLOR_3DDKSHADOW       21  三维显示元素的深色阴影。

COLOR_3DFACE                   15  三维显示元素和对话框背景的人脸颜色。

COLOR_3DHIGHLIGHT         20 三维显示元素的突出显示颜色 (面向光源的边缘。)

COLOR_3DLIGHT                 22 三维显示元素的浅色 (面向光源的边缘。)

COLOR_3DSHADOW           16 三维显示元素的阴影颜色 (面向远离光源的边缘) 。

COLOR_ACTIVEBORDER   10 活动窗口边框。

COLOR_ACTIVECAPTION   2 活动窗口标题栏。 关联的前景色为 COLOR_CAPTIONTEXT。

COLOR_APPWORKSPACE 12 多个文档界面 (MDI) 应用程序的背景色。

COLOR_BACKGROUND     1 桌面设备。

COLOR_BTNFACE              15 三维显示元素和对话框背景的人脸颜色。 关联的前景色。 

OLOR_BTNHIGHLIGHT       20 三维显示元素的突出显示颜色 (面向光源的边缘。)

COLOR_BTNSHADOW       16 三维显示元素的阴影颜色 (面向远离光源的边缘) 。

COLOR_BTNTEXT              18 按下按钮上的文本。 关联的背景色为COLOR_BTNFACE。

COLOR_CAPTIONTEXT      9  描述文字、大小框和滚动条箭头框中的文本。

COLOR_DESKTOP             1   桌面设备。

COLOR_GRADIENTACTIVECAPTION  27 活动窗口标题栏颜色渐变中的右侧颜色。

COLOR_GRADIENTINACTIVECAPTION 28 非活动窗口标题栏颜色渐变中的右侧颜色。

COLOR_GRAYTEXT          17 已禁用 文本的灰色 。 如果当前显示驱动程序不支持纯灰色,则此颜色设置为 0。

COLOR_HIGHLIGHT         13 在 控件中选择的项 () 。

COLOR_HIGHLIGHTTEXT 14 在 控件中选择的项 () 的文本。

COLOR_HOTLIGHT            26 超链接或热跟踪项的颜色。

OLOR_INACTIVEBORDER 11 非活动窗口边框。

COLOR_INACTIVECAPTION 3 非活动窗口描述文字。

COLOR_INACTIVECAPTIONTEXT 19 工具提示控件的背景色。

COLOR_INFOBK                  24 工具提示控件的背景色。

COLOR_INFOTEXT             23 工具提示控件的文本颜色。

COLOR_MENU                    4    菜单背景。

COLOR_MENUHILIGHT     29 当菜单显示为平面菜单时用于突出显示菜单项的颜色

COLOR_MENUBAR          30 菜单显示为平面菜单时菜单栏的背景色

COLOR_MENUTEXT        7 菜单中的文本。

COLOR_SCROLLBAR       0 滚动条灰色区域。

COLOR_WINDOW            5 窗口背景。

返回值   如果成功,则不为 0;否则为 0。

CBrush::FromHandle 当给定 Windows HBRUSH 对象的句柄时,返回指向  CBrush 对象的指针。其原型如下:

static CBrush* PASCAL FromHandle(HBRUSH hBrush);

参数 hBrush Windows GDI 画刷的 HANDLE。返回值 如果成功,则为指向  CBrush 对象的指针;否则为  NULL 。

CBrush::GetLogBrush 调用此成员函数以检索  LOGBRUSH 结构。其原型如下:

int GetLogBrush(LOGBRUSH* pLogBrush);

参数 pLogBrush 指向包含画笔信息的 LOGBRUSH 结构。返回值 如果函数成功,并且  pLogBrush 是有效指针,则返回值是存储在缓冲区中的字节数。如果函数成功,并且  pLogBrush 是  NULL ,则返回值是保存函数将存储到缓冲区中的信息所需的字节数。如果函数失败,返回值为 0。

CBrush::operator HBRUSH 使用此运算符获取  CBrush 对象的附加 Windows GDI 句柄。其原型如下:

operator HBRUSH() const;

返回值 如果成功,则由  CBrush 对象表示的 Windows GDI 对象的句柄;否则  NULL 。

示例:

RECT rc = {50, 50, 200, 200};
Rectangle(pDC->GetSafeHdc(), rc.left, rc.top, rc.right, rc.bottom);
// The Win32 call to FillRect requires an HBRUSH.
// The HBRUSH operator casts the CBrush object
// to the required type.
CBrush brush;
brush.CreateSysColorBrush(COLOR_BTNFACE);
FillRect(pDC->GetSafeHdc(), &rc, (HBRUSH)brush);

可给通过LOGBRUSH 对象赋值,设置画笔样式,并用CreateBrushIndirect生成该样式的画笔。

在用MFC设计图形程序,常用画笔(刷),来填充背景或在封闭区域,如果希望画出的圆、矩形等不被填充则需选择空画笔。

        四 笔(CPen)

        CPen 是MFC封装的一个 Windows 图形设备接口 (GDI) 类。其构造函数、公共方法、操作符如下:

        构造函数

        构造函数函数用于构造  CPen 对象。其原型如下:

CPen();
CPen(
int nPenStyle,
int nWidth,
COLORREF crColor);
CPen(
int nPenStyle,
int nWidth,
const LOGBRUSH* pLogBrush,
int nStyleCount = 0,
const DWORD* lpStyle = NULL);

 参数  nPenStyle 指定笔样式。 此参数在构造函数的第一个版本中可以是以下值之一:

        PS_SOLID 创建实心笔。

        PS_DASH 创建短划线式虚线笔。 仅当笔宽为 1 或更小(以设备单位为单位)时有
效。
        PS_DOT 创建点式虚线笔。 仅当笔宽为 1 或更小(以设备单位为单位)时有效。
        PS_DASHDOT 创建短划线和点交替的笔。 仅当笔宽为 1 或更小(以设备单位为单
位)时有效。
        PS_DASHDOTDOT 创建短划线和双点交替的笔。 仅当笔宽为 1 或更小(以设备单位为
单位)时有效。
        PS_NULL 创建 null 笔。
        PS_INSIDEFRAME 创建可在指定边界矩形的 Windows GDI 输出函数(例如
        Ellipse 、 Rectangle 、 RoundRect 、 Pie 和  Chord 成员函数)生成的封闭形状框架
内绘制线条的笔。 如果此样式与不指定边界矩形的 Windows GDI 输出函数(例如
LineTo 成员函数)一起使用,则笔的绘图区域不受框架限制。

        CPen 构造函数的第二个版本指定类型、样式、末端和联接特性的组合。 应使用按位“或”
( | ) 运算符组合每个类别中的值。 笔类型可以是下列值之一:
        PS_GEOMETRIC 创建几何笔。
        PS_COSMETIC 创建整容笔。
        CPen 构造函数的第二个版本为  nPenStyle 添加了以下笔样式:
        PS_ALTERNATE 创建设置所有其他像素的笔。 (此样式仅适用于整容笔。)
        PS_USERSTYLE 创建使用用户提供的样式数组的笔。
  末端可以是以下值之一:
        PS_ENDCAP_ROUND 末端是圆的。
        PS_ENDCAP_SQUARE 末端是正的。
        PS_ENDCAP_FLAT 末端是平的.                                                                                              联接可以是以下值之一:
        PS_JOIN_BEVEL 联接是斜切的。
        PS_JOIN_MITER 当联接位于 SetMiterLimit 函数设置的当前限制内时,联接是斜接
   的。 如果联接超出此限制,则是斜切的。                                                                            PS_JOIN_ROUND 联接是圆的。

        nWidth 指定笔的宽度。对于构造函数的第一个版本,值 0 的处理方式与值 1 类似,但宽度不会受到对笔用于图形对象的缩放转换操作的影响:宽度始终为 1 像素。对于构造函数的第二个版本,如果  nPenStyle 是  PS_GEOMETRIC ,则宽度以逻辑单位提供。 如果  nPenStyle 是  PS_COSMETIC ,则宽度必须设置为 1。

        crColor 包含笔的 RGB 颜色。

        pLogBrush 指向  LOGBRUSH 结构。 如果  nPenStyle 是  PS_COSMETIC ,则  LOGBRUSH 结构的  lbColor 成员指定笔的颜色,并且  LOGBRUSH 的  lbStyle 成员必须设置为  BS_SOLID 。 如果nPenStyle 是  PS_GEOMETRIC ,则必须使用所有成员来指定笔的画笔性。

        lpStyle 指向双字值的数组。 第一个值指定用户定义的样式中第一条短划线的长度,第二个值指定第一个空格的长度,依此类推。 如果  nPenStyle 不是  PS_USERSTYLE ,则此指针必须为
NULL 。

        如果使用没有自变量的构造函数,则必须使用  CPen 、 CreatePen 或  CreatePenIndirect
成员函数初始化生成的  CreateStockObject 对象。如果使用采用自变量的构造函数,则无需进一步初始化。 如果遇到错误,具有自变量的构造函数可能会引发异常,而没有自变量的构造函数将始终成功。示例:

// Create a solid red pen of width 2.
CPen myPen1(PS_SOLID, 2, RGB(255, 0, 0));
/ Create a geometric pen.
LOGBRUSH logBrush;
logBrush.lbStyle = BS_SOLID;
logBrush.lbColor = RGB(0, 255, 0);
CPen myPen2(PS_DOT | PS_GEOMETRIC | PS_ENDCAP_ROUND, 2, &logBrush);

        CreatePen 创建具有指定样式、宽度和画笔特性的逻辑整容笔或几何笔,并将其附加到  CPen 对象。其原型如下:

BOOL CreatePen(
int nPenStyle,
int nWidth,
COLORREF crColor);
BOOL CreatePen(
int nPenStyle,
int nWidth,
const LOGBRUSH* pLogBrush,
int nStyleCount = 0,
const DWORD* lpStyle = NULL);

        参数 :nPenStyle 指定笔的样式。 有关可能值的列表,请参阅 CPen 构造函数中的  nPenStyle 参数。nPenStyle 指定笔的宽度。对于  CreatePen 的第一个版本,值 0 的处理方式与值 1 类似,但宽度不会受到对笔用于图形对象的缩放转换操作的影响:宽度始终为 1 像素。对于  CreatePen 的第二个版本,如果  nPenStyle 是  PS_GEOMETRIC ,则宽度以逻辑单位提供。 如果  nPenStyle 是  PS_COSMETIC ,则宽度必须设置为 1。crColor 包含笔的 RGB 颜色。pLogBrush指向 LOGBRUSH 结构。 如果  nPenStyle 是  PS_COSMETIC ,则  LOGBRUSH 结构的  lbColor成员指定笔的颜色,并且  LOGBRUSH 的  lbStyle 成员必须设置为  BS_SOLID 。 如果nPenStyle 是  PS_GEOMETRIC ,则必须使用所有成员来指定笔的画笔特性。nStyleCount
指定  lpStyle 数组的长度(以双字单位为单位)。 如果  nPenStyle 不是  PS_USERSTYLE ,
则此值必须为零。lpStyle 指向双字值的数组。 第一个值指定用户定义的样式中第一条短划线的长度,第二个值指定第一个空格的长度,依此类推。 如果  nPenStyle 不是  PS_USERSTYLE ,则此指针必须为NULL 。

        返回值 如果成功,则为非零;如果方法失败,则为零。

        CreatePen 的第一个版本使用指定的样式、宽度和颜色初始化笔。 随后可以选择该笔作
为任何设备上下文的当前笔。宽度大于 1 像素的笔应始终具有  PS_NULL 、 PS_SOLID 或  PS_INSIDEFRAME 样式。如果笔的  PS_INSIDEFRAME 样式和颜色与逻辑颜色表中的颜色不匹配,则笔将以抖色进行绘制。 笔  PS_SOLID 样式不能用于创建具有任一颜色的笔。 如果笔宽小于或等于 1,则样式  PS_INSIDEFRAME 与  PS_SOLID 相同。
        CreatePen 的第二个版本初始化具有指定样式、宽度和画笔特性的逻辑整容笔或几何笔。
整容笔的宽度始终为 1;几何笔的宽度始终以世界单位指定。 应用程序在创建逻辑笔后,可以通过调用 CDC::SelectObject 函数将该笔选入设备上下文。 将笔选入设备上下文后,可用于绘制线条和曲线。如果  nPenStyle 是  PS_COSMETIC 和  PS_USERSTYLE ,则  lpStyle 数组中的条目以样式单位指定短划线和空格的长度。 样式单位由用于绘制线条的设备定义。如果  nPenStyle 是  PS_GEOMETRIC 和  PS_USERSTYLE ,则  lpStyle 数组中的条目以逻辑单位指定短划线和空格的长度。如果  nPenStyle 是  PS_ALTERNATE ,则忽略样式单位,并设置所有其他像素。
        当应用程序不再需要给定笔时,它应调用 CGdiObject::DeleteObject 成员函数或销毁CPen 对象,以便不再使用资源。 如果设备上下文中选择了某个笔,则应用程序不应删除笔。示例:

CPen myPen1, myPen2;
// Create a solid red pen of width 2.
myPen1.CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
// Create a geometric pen.
LOGBRUSH logBrush;
logBrush.lbStyle = BS_SOLID;
logBrush.lbColor = RGB(0, 255, 0);
myPen2.CreatePen(PS_DOT | PS_GEOMETRIC | PS_ENDCAP_ROUND, 2, &logBrush);

         CreatePenIndirect 初始化一个笔,该笔的样式、宽度和颜色在  lpLogPen 所指向的结构中给出。其原型如下:

BOOL CreatePenIndirect(LPLOGPEN lpLogPen);

参数 lpLogPen 指向包含有关笔的信息的 Windows LOGPEN 结构。

返回值 如果该函数成功,则为非 0;否则为 0。

        宽度大于 1 像素的笔应始终具有  PS_NULL 、 PS_SOLID 或  PS_INSIDEFRAME 样式。如果笔的  PS_INSIDEFRAME 样式和颜色与逻辑颜色表中的颜色不匹配,则笔将以抖色进行绘制。 如果笔宽小于或等于 1,则  PS_INSIDEFRAME 样式与  PS_SOLID 相同。示例:

LOGPEN logpen;
CPen cMyPen;
// Get the LOGPEN of an existing pen.
penExisting.GetLogPen(&logpen);
// Change the color to red and the width to 2.
logpen.lopnWidth.x = 2;
logpen.lopnColor = RGB(255, 0, 0);
// Create my pen using the new settings.
cMyPen.CreatePenIndirect(&logpen);

        FromHandle 在提供了 Windows GDI 笔对象句柄的情况下,返回指向  CPen 对象的指针。其原型如下:

static CPen* PASCAL FromHandle(HPEN hPen);

         参数 hPen Windows GDI 笔的  HPEN 句柄。

        返回值 如果成功,则为指向  CPen 对象的指针;否则为  NULL 。

        GetExtLogPen 获取  EXTLOGPEN 基础结构。其原型如下:

int GetExtLogPen(EXTLOGPEN* pLogPen);

        参数 pLogPen 指向包含有关笔的信息的 EXTLOGPEN 结构。

        返回值 如果成功,则不为 0;否则为 0。 示例:

EXTLOGPEN extlogpen;
penExisting.GetExtLogPen(&extlogpen);
CPen penOther;
LOGBRUSH LogBrush = { extlogpen.elpBrushStyle, extlogpen.elpColor,
extlogpen.elpHatch };
penOther.CreatePen(PS_COSMETIC, 1, &LogBrush);

        GetLogPen 获取  LOGPEN 基础结构。其原型如下:

int GetLogPen(LOGPEN* pLogPen);

        参数 pLogPen 指向包含有关笔的信息的 LOGPEN 结构。

        返回值 如果成功,则不为 0;否则为 0。

        operator HPEN 获取  CPen 对象的附加 Windows GDI 句柄。其原型如下:

operator HPEN() const;

示例:

// Create a solid red pen of width 2.
CPen myPen(PS_SOLID, 2, RGB(255, 0, 0));
// Get the handle of the pen object.
HPEN hPen = (HPEN)myPen;

五 字体(CFont)

CFont是MFC中一个 Windows 图形设备接口 (GDI) 字体并提供用于操作字体的成员函数的类。其构造函数、公共方法、公共·运算符如下:

        构造函数 CFont 构造  CFont 对象。其原型如下:

CFont();

生成的对象必须用  CreateFont 、 CreateFontIndirect 、 CreatePointFont 或CreatePointFontIndirect 初始化后才能使用。        示例:

CFont font;

        CreateFont 使用指定的特征初始化  CFont 对象。其原型如下:

BOOL CreateFont(
int nHeight,
int nWidth,
int nEscapement,
int nOrientation,
int nWeight,
BYTE bItalic,
BYTE bUnderline,
BYTE cStrikeOut,
BYTE nCharSet,
BYTE nOutPrecision,
BYTE nClipPrecision,
BYTE nQuality,
BYTE nPitchAndFamily,
LPCTSTR lpszFacename);

        参数

          nHeight 指定字体的所需高度(以逻辑单元表示)。 有关说明,请参阅 Windows SDK 中LOGFONT 结构的  lfHeight 成员。 转换后, nHeight 的绝对值不得超过 16,384 个设备单元。 对于所有高度比较,字体映射器查找不超过请求大小的最大字体,或者查找所有字体超过请求大小时的最小字体。

        nWidth 指定字体中字符的平均宽度(以逻辑单元表示)。 如果  nWidth 为 0,则设备的纵横比将与可用字体的数字化纵横比匹配,以查找最接近的匹配项,这由差值的绝对值决定。

        nEscapement 指定转义矢量与显示图面 x 轴之间的角度(以 0.1 度单元表示)。 转义矢量是通过直线上第一个字符和最后一个字符的原点的直线。 角度是从 x 轴逆时针方向测量的。 有关详细信息,请参阅 Windows SDK 中  LOGFONT 结构的  lfEscapement 成员。

        nOrientation 指定字符基线与 x 轴之间的角度(以 0.1 度单元表示)。 在 y 方向向下的坐标系统中,该角度是从 x 轴逆时针测量的;而在 y 方向向上的坐标系统中,角度是从 x 轴顺时针测
量的。

        nWeight 指定字体粗细(以每 1000 个墨迹像素表示)。 有关详细信息,请参阅 Windows SDK 中LOGFONT 结构的  lfWeight 成员。 描述的值是近似值;实际外观取决于字样。 某些字体
只有  FW_NORMAL 、 FW_REGULAR 和  FW_BOLD 粗细。 如果指定  FW_DONTCARE ,则使用默认粗细。

        bItalic 指定字体是否为斜体。

        cStrikeOut 指定字体中的字符是否被删除。如果设置为非零值,则指定删除线字体。

        nCharSet 指定字体的字符集。有关值列表,请参阅 Windows SDK 中  LOGFONT 结构的  lfCharSet 成员。OEM 字符集依赖于系统。系统中可能存在具有其他字符集的字体。 使用具有未知字符集的字体的应用程序不得尝试翻译或解释要使用该字体呈现的字符串。 相反,应将字符串直接传递给输出设备驱动程序。字体映射器不使用  DEFAULT_CHARSET 值。 应用程序可以使用该值来允许字体的名称和大小完全描述逻辑字体。 如果具有指定名称的字体不存在,则任何字符集中的字体都可以替换指定的字体。 为了避免意外结果,应用程序应谨慎使DEFAULT_CHARSET 值。

        nOutPrecision 指定所需的输出精度。 输出精度定义输出与所请求字体的高度、宽度、字符方向、转义和间距的必需匹配程度。 有关值列表和详细信息,请参阅 Windows SDK 中LOGFONT 结构的  lfOutPrecision 成员。

        nClipPrecision 指定所需的剪裁精度。 剪裁精度定义如何剪裁部分超出剪裁区域的字符。 有关值列表,请参阅 Windows SDK 中  LOGFONT 结构的  lfClipPrecision 成员。若要使用嵌入的只读字体,应用程序必须指定  CLIP_ENCAPSULATE 。若要实现设备、TrueType 和矢量字体的一致旋转,应用程序可以使用按位“或”运算符 ( | )将  CLIP_LH_ANGLES 值与其他任何  nClipPrecision 值组合在一起。 如果设置了CLIP_LH_ANGLES 位,则所有字体的旋转取决于坐标系统的方向是左侧还是右侧。 (有关坐标系统方向的详细信息,请参阅  nOrientation 参数说明。)如果未设置CLIP_LH_ANGLES ,则设备字体始终逆时针旋转,但其他字体的旋转取决于坐标系统的方向。

        nQuality 指定字体的输出质量,它定义 GDI 必须尝试将逻辑字体属性与实际物理字体的属性进行匹配时的谨慎程度。 有关值列表,请参阅 Windows SDK 中  LOGFONT 结构的  lfQuality
成员。

        lpszFacename CString 或以 null 结尾的字符串指定字体的字样名称。 此字符串的长度不得超过 30 个字符。 Windows EnumFontFamilies 函数可用于枚举所有当前可用的字体。 如果
lpszFacename 为  NULL ,则 GDI 使用独立于设备的字样。

        返回值 如果成功,则不为 0;否则为 0。 示例:

CFont font;
VERIFY(font.CreateFont(
12, // nHeight
0, // nWidth
0, // nEscapement
0, // nOrientation
FW_NORMAL, // nWeight
FALSE, // bItalic
FALSE, // bUnderline
0, // cStrikeOut
ANSI_CHARSET, // nCharSet
OUT_DEFAULT_PRECIS, // nOutPrecision
CLIP_DEFAULT_PRECIS, // nClipPrecision
DEFAULT_QUALITY, // nQuality
DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
_T("Arial"))); // lpszFacename
// Do something with the font just created...
CClientDC dc(this);
CFont *def_font = dc.SelectObject(&font);
dc.TextOut(5, 5, _T("Hello"), 5);
dc.SelectObject(def_font);
// Done with the font. Delete the font object.
font.DeleteObject();

        CreateFontIndirect 使用 LOGFONT 结构中给定的特征初始化  CFont 对象。其原型如下:

BOOL CreateFontIndirect(const LOGFONT* lpLogFont);

        参数  lpLogFont 指向定义逻辑字体特征的  LOGFONT 结构。

        返回值 如果成功,则不为 0;否则为 0。示例:

CFont font;
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT)); // zero out structure
lf.lfHeight = 12; // request a 12-pixel-height font
_tcsncpy_s(lf.lfFaceName, LF_FACESIZE,
_T("Arial"), 7); // request a face name "Arial"
VERIFY(font.CreateFontIndirect(&lf)); // create the font
// Do something with the font just created...
CClientDC dc(this);
CFont *def_font = dc.SelectObject(&font);
dc.TextOut(5, 5, _T("Hello"), 5);
dc.SelectObject(def_font);
// Done with the font. Delete the font object.
font.DeleteObject();

        CreatePointFont  提供了一种创建指定字样和磅值的字体的简单方法。其原型如下:

BOOL CreatePointFont(
int nPointSize,
LPCTSTR lpszFaceName,
CDC* pDC = NULL);

 参数:

         nPointSize 请求的字体高度(以十分之一磅表示)。 (例如,传递 120 以请求 12 磅字体。)

        lpszFaceName CString 或以 null 结尾的字符串指定字体的字样名称。 此字符串的长度不得超过 30 个字符。 Windows  EnumFontFamilies 函数可用于枚举所有当前可用的字体。 如果
lpszFaceName 为  NULL ,则 GDI 使用独立于设备的字样。

        pDC 指向要用于将以  nPointSize 表示的高度转换为逻辑单元的 CDC 对象的指针。 如果为
NULL ,则使用屏幕设备上下文进行转换。

        返回值 如果成功,则为非零值;否则为 0。示例:

CClientDC dc(this);
CFont font;
VERIFY(font.CreatePointFont(120, _T("Arial"), &dc));
// Do something with the font just created...
CFont *def_font = dc.SelectObject(&font);
dc.TextOut(5, 5, _T("Hello"), 5);
dc.SelectObject(def_font);
// Done with the font. Delete the font object.
font.DeleteObject();

        CreatePointFontIndirect 此函数与 CreateFontIndirect 相同,只是  LOGFONT 的  lfHeight 成员以十分之一磅(而不是设备单元)说明。其原型如下:

BOOL CreatePointFontIndirect(
const LOGFONT* lpLogFont,
CDC* pDC = NULL);

参数:

        lpLogFont 指向定义逻辑字体特征的 LOGFONT 结构。 结构  lfHeight 的成员  LOGFONT 以十分之一磅(而不是逻辑单元)进行度量。 (例如,将  lfHeight 设置为 120,以请求 12 磅字
体。)

        pDC 指向要用于将以  lfHeight 表示的高度转换为逻辑单元的 CDC 对象的指针。 如果为
NULL ,则使用屏幕设备上下文进行转换。

        返回值 如果成功,则为非零值;否则为 0。

        在将  LOGFONT 结构传递到 Windows 之前,此函数使用  pDC 指向的  CDC 对象自动将以
lfHeight 表示的高度转换为逻辑单元。完成通过  CreatePointFontIndirect 函数创建的  CFont 对象后,首先选择设备上下文中的字体,然后删除  CFont 对象。示例:

LOGFONT lf;
// clear out structure.
memset(&lf, 0, sizeof(LOGFONT));
// request a 12-pixel-height font
lf.lfHeight = 120;
// request a face name "Arial".
_tcsncpy_s(lf.lfFaceName, LF_FACESIZE, _T("Arial"), 7);
CClientDC dc(this);
CFont font;
VERIFY(font.CreatePointFontIndirect(&lf, &dc));
// Do something with the font just created...
CFont *def_font = dc.SelectObject(&font);
dc.TextOut(5, 5, _T("Hello"), 5);
dc.SelectObject(def_font);
// Done with the font. Delete the font object.
font.DeleteObject();

        FromHandle 在给定 Windows GDI 字体对象的  HFONT 句柄时返回指向  CFont 对象的指针。其原型如下:

static CFont* PASCAL FromHandle(HFONT hFont);

        参数 hFont Windows 字体的  HFONT 句柄。

        返回值 如果成功,则为指向  CFont 对象的指针;否则为  NULL 。示例:

LOGFONT lf;
// clear out structure
memset(&lf, 0, sizeof(LOGFONT));
// request a 12-pixel-height font
lf.lfHeight = 12;
// request a face name "Arial"
_tcsncpy_s(lf.lfFaceName, LF_FACESIZE, _T("Arial"), 7);
// create the font
HFONT hfont = ::CreateFontIndirect(&lf);
// Convert the HFONT to CFont*.
CFont *pfont = CFont::FromHandle(hfont);
// Do something with the font just created...
CClientDC dc(this);
CFont *def_font = dc.SelectObject(pfont);
dc.TextOut(5, 5, _T("Hello"), 5);
dc.SelectObject(def_font);
// Done with the font. Delete the font object.
::DeleteObject(hfont);

        GetLogFont 调用此函数可检索  CFont 的  LOGFONT 结构的副本。其原型如下:

int GetLogFont(LOGFONT* pLogFont);

        参数 pLogFont 指向用于接收字体信息的 LOGFONT 结构的指针。

        返回值 如果函数成功,则返回非零值;否则返回 0。示例:

CFont *pFont = pWnd->GetFont();
if (NULL != pFont)
{
LOGFONT lf;
pFont->GetLogFont(&lf);
TRACE(_T("Typeface name of font = %s\n"), lf.lfFaceName);
}

        operator HFONT 使用此运算符获取附加到  CFont 对象的字体的 Windows GDI 句柄。其原型如下:

operator HFONT() const;

        返回值 如果成功,则返回附加到  CFont 的 Windows GDI 字体对象的句柄;否则返回  NULL。示例:

LOGFONT lf;
// clear out structure
memset(&lf, 0, sizeof(LOGFONT));
// request a 12-pixel-height font
lf.lfHeight = 12;
// request a face name "Arial"
_tcsncpy_s(lf.lfFaceName, LF_FACESIZE, _T("Arial"), 7);
CFont font1;
font1.CreateFontIndirect(&lf); // create the font
// CFont::operator HFONT automatically converts font1 from
// CFont* to HFONT.
CFont *font2 = CFont::FromHandle(font1);
// Do something with the font just created...
CClientDC dc(this);
CFont *def_font = dc.SelectObject(font2);
dc.TextOut(5, 5, _T("Hello"), 5);
dc.SelectObject(def_font);
// Done with the font. Delete the font object.
font1.DeleteObject();

CBrush,CPen,CFont皆为GDI接口类,当要使用时一般需要先创建的对象,当不用时需调用DeleteObject()函数删除对象。Window预定义了一些CBrush、CFont、CPen等对象,使用它们时不需要显示创建,使用SelectStockObject将其选入设备描述表即可。常用的Windows预定义GDi对象如下:

·

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/15957.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux|操作系统|如何下载各个版本的centos操作系统

前言: centos做为一个现在比较常用的Linux社区版本,还是比较受欢迎的,那么,如何下载centos的安装包,也就是centos的操作系统呢? 首先,我们应该知道硬件底层有aarch64,ppc64&#x…

【限免】短时傅里叶变换时频分析【附MATLAB代码】

来源:微信公众号:EW Frontier 简介 一种能够同时对信号时域和频域分析的方法——短时傅里叶变换(STFT),可以在时频二维角度准确地描述信号 的时间、频域的局部特性,与其他算法不同,通过该算法可…

【Elasticsearch】Centos7安装Elasticsearch、kibana、IK分词

目录 本文安装包下载地址注意安装elasticsearch1.上传文件2.解压elasticsearch-6.3.1.tar.gz3.开启远程连接权限4.修改其他配置[root用户操作]5.重启虚拟机6.启动es7.外部访问 安装kibana-61.解压2.配置3.启动kibana4.访问5.在开发工具中做数据的增删改查操作 安装IK分词1.wind…

软件安全复习

文章目录 第一章 软件安全概述1.1 信息定义1.2 信息的属性1.3 信息安全1.4 软件安全1.5 软件安全威胁及其来源1.5.1 软件缺陷与漏洞1.5.1.1 软件缺陷1.5.1.2 漏洞1.5.1.3 软件漏洞1.5.1.4 软件缺陷和漏洞的威胁 1.5.2 恶意软件1.5.2.1 恶意软件的定义1.5.2.2 恶意软件的威胁 1.…

携手AI,如何共赢未来?

5/25日参加了一个培训分享会,由博奥研究院、武汉博奕咨询和华工科技联合举办,主题是“携手Ai,共赢未来”。 抱着跟书友线下交流的心态我参与了,参与前我对博奥做了基础了解,他们跟工信部考试和教育中心有合作&#x…

【C语言】指针作为参数(传值调用vs传址调用)

前言 在前面讲了那些指针相关的内容后,是时候探讨一下指针有什么作用了。 在C语言中,指针有多种各不相同的应用,在本篇文章中,我们探讨一下指针作为函数参数的作用(对比传值与传址两种不同函数调用方式)。…

【QGIS入门实战精品教程】10.7: 基于DEM的地形因子分析(坡度、坡向、粗糙度、山体阴影、耐用指数)

文章目录 一、加载dem二、山体阴影三、坡度四、坡向五、地形耐用指数六、地形位置指数七、地表粗糙度一、加载dem 二、山体阴影 方法一:符号系统 利用符号系统中的山体阴影,渲染出阴影效果。 方法二:山体阴影工具 该算法计算输入中的数字化地形模型的山体阴影。根据太阳的位…

2024 年 5 个 GO REST API 框架

什么是API? API是一个软件解决方案,作为中介,使两个应用程序能够相互交互。以下一些特征让API变得更加有用和有价值: 遵守REST和HTTP等易于访问、广泛理解和开发人员友好的标准。API不仅仅是几行代码;这些是为移动开…

kali下载zsteg和stegpy

1.kali下载zsteg 从 GitHub 上克隆zsteg到kali git clone https://github.com/zed-0xff/zsteg 切换目录 cd zsteg 用于安装名为 zsteg 的 Ruby Gem 包 gem install zsteg 2.kali下载stegpy 下载网站内的stegpy-master压缩包GitCode - 开发者的代码家园 并拉到kali中 切换到s…

python数据分析——数据可视化(图形绘制)

数据可视化(图形绘制基础) 前言一、图形绘制基础Matplotlib简介使用过程sin函数示例 二、常用图形绘制折线图的绘制plot示例 散点图的绘制scatter()示例 柱状图的绘制bar示例 箱型图绘制plot.box示例 饼状图的绘制pie示例 三、图形绘制的组合情况多个折线…

Sql Sever删除数据库时提示数据库正在被使用,解决办法

报错解释: 当您尝试删除SQL Server中的某个对象(如数据库、表等)时,如果有程序或进程正在使用该对象,您可能会收到一个错误信息,提示该对象正被使用。这通常是因为还有一个或多个数据库连接仍然保持着对该…

易备数据备份软件: 快速备份 MySQL\SQL Server\Oracle\泛微 OA 数据库

易备数据备份软件支持对 SQL Server、Oracle、MySQL、PostgreSQL、MariaDB、泛微 OA 等数据库进行快速备份,备份过程不会对任何服务造成中断。 使用一份授权,可以备份无限量的数据库,不管数据库服务器是否在本机、本地网络、或是远程网络。可…

Vitis HLS 学习笔记--控制驱动TLP-处理deadlock

目录 1. 简介 2. 代码解析 2.1 HLS kernel代码 2.2 查看接口报告 2.3 TestBench 2.4 Dataflow 报告 3. Takeaways 4. 总结 1. 简介 本文是对《Hardware Acceleration Tutorials: FIFO Sizing for Performance and Avoiding Deadlocks》实验内容的详细解释。 首先需要…

自动驾驶场景中的长尾问题怎么解决?

自动驾驶长尾问题是指自动驾驶汽车中的边缘情况,即发生概率较低的可能场景。感知的长尾问题是当前限制单车智能自动驾驶车辆运行设计域的主要原因之一。自动驾驶的底层架构和大部分技术问题已经被解决,剩下的5%的长尾问题,逐渐成了制约自动驾…

huggingface 笔记:查看GPU占用情况

0 准备部分 0.1 创建虚拟数据 import numpy as npfrom datasets import Datasetseq_len, dataset_size 512, 512 dummy_data {"input_ids": np.random.randint(100, 30000, (dataset_size, seq_len)),"labels": np.random.randint(0, 1, (dataset_size…

【代码随想录训练营】【Day 29】【回溯-3】| Leetcode 39, 41, 131

【代码随想录训练营】【Day 29】【回溯-3】| Leetcode 39, 41, 131 需强化知识点 startInex作用:一是处理是否可以有重复值,二是实现纵向遍历(不能没有)去重要在数组有序的前提下进行分割问题 题目 39.…

工业控制2D组态界面,丑是丑了点,但非常实用。

工业控制的2D组态界面是用于监控和控制工业过程的界面。它通常具有以下特征: 实时数据显示:2D组态界面能够实时显示传感器和设备的数据,如温度、压力、流量等。这些数据以图表、仪表盘、数字显示等形式呈现,使操作人员能够实时了解…

Android:使用Kotlin搭建MVVM架构模式

一、简介Android MVVM架构模式 MVVM全称:Model、View、ViewModel; Model:负责数据的请求、解析、过滤等数据层操作,其中Repository: 提供数据的 API(从本地或者网络)。View:负责视图部分展示Vie…

快速幂求逆元与逆元

我上一篇博客链接写的是多个数求乘法逆元而快速幂求逆元用于单个数求乘法逆元 逆元是对分数取模用的 对于除法取模不成立,即(a/b)%p≠(a%p/b%p)%p。求逆元的思路:(一般ACM的题目都是对1e97这种素数取模,所以gcd(a,p)1)a*b1(mod p) > b1/a…

[Algorithm][动态规划][简单多状态DP问题][按摩师][打家劫舍Ⅱ][删除并获得点数][粉刷房子]详细讲解

目录 1.按摩师1.题目链接2.算法思路详解3.代码实现 2.打家劫舍 II1.题目链接2.算法思路详解3.代码实现 3.删除并获得点数1.题目链接2.算法思路详解3.代码实现 4.粉刷房子1.题目链接2.算法思路详解3.代码实现 1.按摩师 1.题目链接 按摩师 2.算法思路详解 思路: 确…