通过HDC句柄绘图的三种方式
- 标准客户区绘图
必须是在WN_PAINT消息回调时才执行,调用BeginPaint函数获取标准客户区绘图句柄进行绘图,最后调用EndPaint函数释放
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hwndDlg,&ps);
Ellipse(hDC,0,0,40);
EndPaint(hwndDlg,&ps);
- 临时绘图
在任何消息回调时都可以执行,调用GetDC获取临时客户区绘图句柄进行绘图,最后调用ReleaseDC释放
HDC hDc = GetDC();
Ellipse(hDC,0,0,40);
ReleaseDC();
- 非客户区绘图
必须实在WM_NCPAINT消息回调时才能执行,调用GetWindowDC函数获取非客户区绘图句柄进行绘图,最后调用ReleaseDC释放
HDC hDc = GetWindowDC(hwndDlg);
Ellipse(hDC,0,0,40);
ReleaseDC(hwndDlg,hDC);
调用 InvalidateRect强制客户区标准绘图更新,临时客户区的绘图会被强制清除。
InvalidateRect(hwnd, NULL, true);重画时将擦除背景。
InvalidateRect(hwnd, NULL, false);重画时不擦除背景
三种坐标系
在Windows程序开发中常用的三种坐标系,屏幕坐标系,客户区和非客户区窗口坐标系。
- 屏幕坐标系
坐标原点在屏幕的左上角,自左向右X坐标增大,自上而下Y坐标增大,如果屏幕分辨率设置为1024x768,屏幕右上角的坐标是(0,0),屏幕右下角的坐标是(1024,768),例如:GetWindowRect函数获取的窗口坐标就是基于屏幕坐标系。 - (非客户区)窗口坐标系
坐标原点在窗口(包括标题栏)的左上角,xy坐标轴方向同上。
例如:GetWindowDC函数返回的设备环境是基于该坐标系,该函数一般只在WM_NCPAINT消息中使用。 - 客户区坐标系
坐标原点在标题栏以下的客户区左上角,xy轴坐标方向同上。
例如:BeginPaint函数返回的设备环境是基于客户区坐标系,该函数一般只在WM_PAINT回调中使用。GetDC函数返回的设备环境也是基于客户区坐标系,该函数可以在任何消息中使用,GetClientRect函数获取的是客户区矩形,是依据该客户区建立的,左上角的坐标一定是(0,0) - 坐标系转换
ScreenToClient函数将屏幕坐标转换为客户区坐标
ClientToScreen函数将客户区坐标转换为屏幕坐标
基本绘图类CDC封装的GDI函数及功能说明(派生于CDC类)
- CPaintDC类,封装BeginPaint和EndPaint函数。在WM_PAINT消息下使用,用于标准客户区绘图,窗口刷新时不消失
- CWindowDC类,封装了GetWindowDC和ReleaseDC函数。用于非客户区绘图,在WM_NCPAINT消息下使用,窗口刷新时不消息。
- CClientDC类,封装了GetDC和ReleaseDC函数,用于临时客户去绘图,窗口刷新时消失,任何时候都可以用。
- CMemDC类,封装CreateComptibleDC和DeleteDC等函数。现在暂时未用到,一般是在内存中绘图,常用于双缓冲防止画面闪烁。
GDI对象包括的六种类型,全部由CGdiObject类派生
-
CPen(画笔):用于修饰线条的颜色、宽度和线型(实线、虚线等等)
CPen(int nPenStyle,int nWidth,COLOREF crColor);
在构造函数中创建一个画笔
BOOL CreatePen(int nPenStyle,int nWidth,COLOREF crColor);
根据指定值创建一个画笔
BOOL CreatePenIndirect(LPLOGPEN plLpgPen);
根据LOGPEN结构体创建一个画笔
static CPen* FromHandle(HPEN hPen);
将HPEN句柄转换为CPen对象
operate HPEN() const;
从CPen对象中获取HPEN句柄
int GetLoogPen(LOGPEN* pLogPen);
获取画笔的颜色粗细等相关参数 -
CBrush(画刷):用于修饰一个闭合图形内部填充的内容(填充颜色、填充线条以及平铺位图)。
CBrush(COLORREF crColor);
在构造函数中根据填充色创建画刷
CBrush(int nIndex,COLORREF crColor);
在构造函数中根据影线和颜色创建画刷
CBrush(CBittmap* pBitmap);
在构造函数中根据平铺位图创建画刷
BOOL CreateSolidBrush(COLORREF crColor);
根据填充色创建画刷
BOOL CreateHatchBrush(int nIndex,COLORREF crColor);
根据影线和颜色创建画刷
BOOL CreatePatternBrush(CBittmap* pBitmap);
根据平铺位图创建画刷
BOOL CreateBrushIndirect(const LOGBRUSH* lpBrush);
根据LOGBRUSH结构创建一个画刷
static CBrush* FromHandle(HBRUSH hBrush);
将hBrush句柄转换为CBrush对象
operate HBRUSH() const;
从CBrush对象获取NBRUSH句柄
int GetLogBrush(LOGBRUSH* pLogBrush);
获取画刷的颜色和影线等属性信息 -
CFont(字体):用于修饰输出文字的形式、高度、粗细以及字间距等等。
BOOL CreateFontIndirect(const LOGFONT* lpLogFont);
根据LOGFONT结构创建一个字体
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 );
根据指定数值创建一个字体,包括字体名称,字体高度等。
BOOL CreatePointFont(int nPointSize,LPCTSTR lpszName,CDC* pDC = NULL);
根据字体名称和字体高度(大小)创建一个字体
BOOL CreatePointFontIndirect(const LOGFONT* lpLogFont,CDC* pDC = NULL );
根据LOGFONT结构创建一个字体
static CFont* FromHandle(HFONT hFont);
将HFONT句柄转换为CFont对象
operator HFONT() const;
将CFont对象转换为HFONT句柄
int GetLogFont(LOGFONT* pLogFont);
获取字体的名称高度等属性信息 -
CBitmap(位图):用于显示和处理点阵图像的GDI对象(就是贴图)。
BOOL LoadBitmap(LPCTSTR lpszResourceName );
BOOL LoadBitmap( UINT nIDResource );
BOOL LoadOEMBitmap( UINT nIDBitmap );
从工程资源中加载一张位图
BOOL CreateBitmap( int nWidth,int nHeight,UINT nPlanes, UINT nBitcount,const void* lpBits );
根据指定高度以及点阵数据创建一张位图
BOOL CreateCompatibleBitmap(CDC* pDC,int nWidth,int nHeight );
根据指定高度创建一张兼容位图
BOOL CreateBitmapIndirect(LPBITMAP lpBitmap );
根据BITMAP结构创建一张位图
static CBitmap* FromHandle(HBITMAP hBitmap);
根据HBITMAP句柄获取CBitmap对象
operator HBITMAP() const;
从CBitmap对象中获取HBITMAP句柄
位图装载和显示的主要步骤:
位图装载CBitmap::LoadBitmap(GetBitmap取得高宽)
a)创建兼容的内存DC:CDC::CreateCompatibleDC()
b)使用内存DC选择装载了的位图资源的对象:CDC::SelectObject
c)使用贴图函数显示内存DC中的位图资源:CDC::BitBlt
d)如果要压缩或者拉伸原始图片(旋转)则使用:CDC::StretchBlt -
CRgn(区域):用于修饰图像的不规则边界,例如:椭圆或多边形等等。
BOOL CreateRectRgn(int x1,int y1,int x2,int y2);
创建一个矩形区域
BOOL CreateEllipticRgn(int x1,int y1,int x2,int y2);
创建一个椭圆形区域
BOOL CreatePolygonRgn(LPPOINT lpPoints,int nCount,int nMode);
创建一个多边形区域
BOOL CreateRoundRectRgn( int x1,int y1,int x2,int y2,int x3,int y3 );
创建一个圆角矩形区域
int CopyRgn(CRgn* pRgnSrc);
从已有区域对象中复制
int CombineRgn(CRgn* pRgn1,CRgn* pRgn2,int nConbineMode);
将两个区域合并成一个区域
static CRgn* FromHandle(HRGN hRgn);
从HRGN句柄转化为CRgn对象
operator HRGN() const;
从CRgn对象中获取HRGN句柄
int GetRegionDate(LPRGNDATA lpRgnData,int nCount) const;
获取区域的属性信息 -
CPalette(调色板):用于修饰输出图像的色调,例如:16色或256色等。