VC++技术内幕(五_1)

GDI:Graphics Device Interface,图形设备接口,是Windows操作系统提供的一组函数。

DC:Device Context,设备上下文,常称为画布。应用程序中每个窗口都关联一个设备上下文,所有绘制操作都在设备上下文上完成。

GetDC方法用于获得设备上下文,返回一CDC类型指针。CDC是封装Windows设备上下文的类,该类提供各种绘制方法。

CDC:设备环境类,CDC作为基类包含绘图所需所有成员函数,派生类中只有构造函数和析构函数的差别(CMetaFileDC除外)。

显示器常用派生类:CClientDC/CWindowDC。对于其他设备则可以构造一CDC基类。

通常窗口客户区不包括边框、标题栏和菜单栏。

视图窗口没有非客户区,因此CwindowDC更适合于框架窗口,非视图窗口。

CDC对象的构造和析构:

创建一CDC对象后在适当时候要删除它。

最好的办法是在堆栈中构造对象,

eg1:

void CMyView::OnLButtonDown(UINT nFlags,CPoint point)
{
CRect rect;
CClientDC dc(this);//在堆栈中构造设备环境对象,用一个窗口指针this作参数。
dc.GetClipBox(rect); //GetClipBox函数是一个虚函数,作用是可以获得选定区域的尺寸
}

eg2:

void CMyView::OnLButtonDown(UINT nFlags,CPoint point)
{
CRect rect;
CDC * pDC=GetDC(); //通过调用CWnd的GetDC()函数获得设备环境指针
pDC->GetClipBox(rect); //可以获得选定区域的尺寸
ReleaseDC(pDC); //一定不能忘记,释放设备环境。

}

GDI对象

GDI对象即为CGdiObject派生类的对象:例如,CBrush是一个GDI的派生类,它在MFC中的层次结构是这样的:CObject派生CGdiObject派生CBrush。CGdiObject是所有GDI对象的抽象基类。

Windows操作系统提供6个GDI对象:

CBitmap:位图是一种位矩阵,每一个显示象素都对应于其中的一个或多个位,可以用来表示图象,也可以用来创建刷子

CBrush:刷子定义了一种位图形式的象素,可以用来对区域内部填充颜色。

CFont:字体是一种具有某种风格和尺寸的所有字符的完整集合,常常被作为资源,其中一些依赖某种设备。

CPalette:调色板是一种颜色映射接口,它允许应用程序在不影响其他应用程序的前提下,可以充分利用输出设备的颜色描绘能力。

CPen:笔是一种用来画线及绘制有形边框的工具,可以指定它的颜色及宽度,并可以指定画虚线、点线还是实线。

CRgn:区域是由多边形、椭圆二者组合形成的一种范围,可以用来进行填充、裁剪、鼠标点中测试等等。对象的使用:SelectObject方法选中GDI对象(会返回原GDI对象)。调用设备上下文绘图,使用完后调用SelectObject选中之前GDI对象。

GDI对象的构造和析构:

有些GDI对象(如CPen和CBrush)可一步即完成创建,如:

CPen newPen(PS_DASHDOTDOT,2,(COLORREF) 0); //黑色的笔宽度为2

有些(如CFont和CRgn)需两步才能完成。首先调用默认构造函数,然后调用相应创建函数,如CreateFont和CreatePolygonRgn等。

例:

定义成员变量:

CFont m_Font;

在OnInitDialog()中对字体进行创建:

m_Font.CreateFont(12, 12, 0, 0, FW_NORMAL, 0, 0, 0,

               DEFAULT_CHARSET,

OUT_DEFAULT_PRECIS,

               CLIP_DEFAULT_PRECIS,

DEFAULT_QUALITY,

DEFAULT_PITCH|FF_ROMAN, "黑体");

在OnPaint()中调用:

CDC* pDC = GetDC();                           //获取窗口设备上下文

pDC->SetTextColor(RGB(255, 0, 0));            //设置红色的文本颜色

CFont *pOleFont = pDC->SelectObject(&m_Font); //选中字体对象并保存旧

pDC->TextOut(20, 50, "No man is wise at all times.");   //输出文本

pDC->TextOut(20, 70, "智者千虑,必有一失.");       //输出文本

pDC->SelectObject(pOleFont);      

库存GDI对象:

不需要删除,可以通过SelectStockObject()选中库存GDI对象,将非库存的GDI对象分离出来,以便删除。

eg:

CPen newPen(PS_DASHDOTDOT,2,(COLORREF) 0); //黑色的笔宽度为2

pDC->SelectObject(&newPen);

pDC->MoveTo(10,10);

pDC->LineTo(110,10);

pDC->SelectStockObject(BLACK_PEN);//newPen is deselected

//newPen will be destroyed on exit

GDI选择的有效期:

由于SelectObject函数返回的GDI C++对象指针具有临时性,当程序的空闲处理阶段或者控制函数返回时应用程序框架会将临时的C++对象删除,我们不能简单的把这一指针保存在类的数据成员中,而应该借助GetSafeHdc函数将它转化为Windows的句柄,以便持久的保存GDI的标识。

上例做如下修改:

CFont m_Font;

HFONT m_hOldFont;

m_Font.CreateFont(12, 12, 0, 0, FW_NORMAL, 0, 0, 0,

               DEFAULT_CHARSET,

OUT_DEFAULT_PRECIS,

               CLIP_DEFAULT_PRECIS,

DEFAULT_QUALITY,

DEFAULT_PITCH|FF_ROMAN, "黑体");

CDC* pDC = GetDC();

pDC->SetTextColor(RGB(255,0,0));

CFont *pOldFont = pDC->SelectObject(&m_Font); //选中字体对象并保存旧

m_hOldFont = (HFONT)pOldFont->GetSafeHandle();

pDC->TextOut(20, 50, "No man is wise at all times.");   //输出文本

pDC->SelectObject(CFont::FromHandle(m_hOldFont);

原文地址:https://www.cnblogs.com/lxshanye/p/3088580.html