Author:秋时残叶
Date:2017.12.30
《windows程序设计》笔记
1.GDI函数
GDI包含几百个函数,可以分类为:
- 获取(建立)和释放(销毁)设备环境的函数
- 获取设备环境信息的函数
- 绘图函数
- 设置和获取设备环境属性的函数
- 使用GDI"对象"的函数
2. GDI基本图形
- 线条和曲线
- 可被填充的封闭区域
- 位图
- 文本
3. 其它
- 映射模式和转换
- 图元文件
- 区域
- 路径
- 剪裁
- 调色板
- 打印
4. GetDC和BeginPaint区别:
从GetDC函数返回的句柄可以在整个窗口客户区的客户区内绘制,并且, GetDC和RealseDC并不使任何客户区的无效区域变为有效。
还有一个更通用的获取设备环境句柄的函数:
hdc = CreateDC(pszDriver, pszDevice, pszOutput, pData,; ...... DeleteDC(hdc);
可以通过这样获取整个屏幕的设备环境句柄:
CreateDC(L"DISPLAY", NULL, NULL, NULL);
可以通过在调用GetDC时使用一个NULL参数来获取整个屏幕的设备环境。
5. 信息上下文
仅需要环境信息,而不需要在上面绘制东西,可以用:
CreateIC(L"DISPALY", NULL, NULL, NULL);
6. 处理位图时,用到"内存设备环境"
hdcMem = CreateCompatibleDC(hdc); .... DeleteDC(hdcMem);
可以把位图选入内存设备环境,并调用GDI函数绘制一个位图
7. 图元设备环境
hdcMeta = CreateMetaFile(pszFilename); ...... hmf = CloseMetaFile(hdcMeta);
8. 获取设备环境的信息
iValue = GetDeviceCaps(hdc, iIndex);
参数说明:
iIndex:
- HORZRES:以像素为单位返回设备的宽度
- VERTRES:以像素为单位返回设备的高度
hdc:
- 如果为屏幕设备环境句柄,获取到时的信息和GetSystemMetrics一样。
- 如果为打印机设备环境,将以像素为单位返回打印机显示区域的高度和宽度。
9. 在释放设备环境时保存对属性做的改变
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
只需初始一次,在下次改变前一直有效。
只对GetDC和BeginPaint有效,对GetWindowDC无效
10. 保存设备环境的状态:
idSaved = SaveDC(hdc);
11. 返回调用SavaDC函数之前存在的设备环境
RestoreDC(hdc, idSaved);
可以这样使用:
SaveDC(hdc); //不必保存返回值 ... //改变一些属性 SaveDC(hdc); //再次调用 RestoreDC(hdc, -1); //将设备环境恢复到已保存的状态 //类似push pop //使环境恢复到最近一次由SaveDC函数保存的状态
12. 点(并不常用的)
SetPixel(hdc, x, y, crColor); //将坐标为x, y的像素设为color色 GetPixel(hdc, x, y); //返回指定坐标位置像素的颜色
13. 直线
LineTo //画直线 Polyline PolylineTo //画一条由多条首尾相连的直线构成的拆线 PolyPolyline //画多条直线 Arc //画椭圆弧线 PolyBezier PolyBezierTo //画贝赛尔样条曲线 ArcTo AngleArc //画椭圆弧线 PolyDraw //画多条贝赛尔样条曲线或者一条由多条首尾相连直线构成的拆线
既完成画线还填充的封闭图形:
Rectangle //矩形 Ellipse //椭圆 RoundRect //圆角矩形 Pie //椭圆的一部分,看起来像扇形 Chord //由弦分割出的部分椭圆,呈弓形
画一条直线:
MoveToEx(hdc, xBeg, yBeg, NULL); //最后一个参数为指向POINT的指针 LineTo(hdc, xEnd, yEnd);
14. 获取当前位置
GetCurrentPosition(hdc, &pt);
15. 获取客户区大小
GetClientRect(hwnd, &rect);
16. 将点连成线
Polyline(hdc, apt, 5); //5:点的个数
17. 画矩形
Rectangle(hdc, xLeft, yTop, xRight, yBottom);
18. 画椭圆
Ellipse(hdc, xLeft, yTop, xRight, yBottom);
19. 圆角矩形
RoundRect(hdc, xLeft, yTop, xRight, yBottom, xCornerEllipse, yCornerEllipse); //xCornerEllipse:小椭圆宽度 //yCornerEllipse:小椭圆高度
20. 椭圆弧线
Arc(hdc, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd);
21. 弓形
Chord(hdc, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd);
22. 扇形
Pie(hdc, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd);
23. 贝塞尔曲线
PolyBezier(hdc, apt, iCount); //iCount = 曲线条数的三倍加上1 PolyBezierTo(hdc, apt, iCount); //把当前位置当作第一个起点 DrawBezier(hdc, apt);
24. 创建钢笔
hPen = CreatePen(iPenStyle, iWidth, crColor); //iPenStyle: PS_SOLID ------ PS_DASH - - - - PS_DOT . . . . .. PS_DASHDOT -.-.-.-. PS_DASHDOTDOT -..-..-.. PS_NULL PS_INSIDEFRAME --------- 唯一可以使用抖动色的画笔样式
25. 建立不同画笔
LOGPEN logpen; hPen = CreatePenIndirect(&logPen); //建立一个画笔,需要创建很多不同的画笔时,很有效
26. 创建,选择,删除
static HPEN hPen1, hPen2, hPen3; hPen1 = CreatePen(PS_SOLID, 1, 0); hPen2 = CreatePen(PS_SOLID, 3, RGB(255, 0, 0)); hPen3 = CreatePen(PS_DOT, 0, 0); SelectObject(hdc, hPen1); ... DeleteObject(hPen1); ....
27.
LOGPEN logpen; GetObject(hPen, sizeof(LOGPEN), (LPVOID)&logpen); //获取logpen信息 hPen = GetCurrentObject(hdc, OBJ_PEN); //获取当前被选入设备环境的画笔句柄
28. 调置填充空隙的背景颜色
SetBkColor(hdc, crColor);
29. 背景模式为透明来阻止windows填充空隙
SetBkMode(hdc, TRANSPARENT);
ROP2——绘图模式
SetROP2(hdc, iDrawMode); //设置绘图模式 GetDOP2(hdc); //获取当前绘图模式
默认为:
R2_COPYPEN //只是用画笔颜色替代目标颜色 R2_NOTCOPYPEN //画笔为黑,画则为白;白则为黑 R2_BLACK //总是黑色 R2_WHITE //总是白色 R2_NOP //"不操作", 让目标颜色保持不变
30、多边形
Polygon(hdc, apt, iCount); //若最后一点与第一个点不同,会再加一条线连接(Polyline)不会这么做
31、多个多边形
PolyPolygon(hdc, apt, aiCounts, iPolyCount); //多个多边形
32、不含边框的图形
SelectObject(hdc, GetStockObject(NULL_PEN); //绘制不含边框线的图形
33、只绘制边框线
SelectObject(hdc, GetStockObject(NULL_BRUSH); //只想绘制边框线,不想填充
34、 默认使用环境中画刷来填充区域
可以调用设置填充模式:
SetPolyFillMode(hdc, iMode); //ALTERNAME(交替) 默认 //WINDING(螺旋)
35. 邻近色
crPureColor = GetNearestColor(hdc, crColor); //确定与某种颜色值最接近的非合成颜色
36. 画刷
36_1. 建立逻辑画笔:
hBrush = CreateSolidBrush(crColor);
36_2. 建立阴影线画刷:
hBrush = CreateHatchBrush(iHatchStyle, crColor); iHatchStyle: HS_HORIZONTAL ____ HS_BDIAGONAL ////// ____ ////// ____ ////// HS_VERTICAL ||||| HS_CROSS ++++++ ||||| ++++++ HS+FDIAGONAL \\\\\\ HS_DIAGCROSS XXXXXX \\\\\\ XXXXXX
36_3. 建立位图画刷
HBRUSH CreatePatternBrush(HBITMAP hbmp); HBRUSH CreateDIBPatternBrush(HGLOBAL hglbDIBPacked, UINT fuColorSpec);
36_4. 建立逻辑画刷,包含其它4个函数的所有功能
hBrush = CreateBrushIndirect(&logbrush); typedef struct tagLOGBRUSH { // lb UINT lbStyle; COLORREF lbColor; LONG lbHatch; } LOGBRUSH; //param: lbStyle lbColor lbHatch BS_SOLID 画刷的颜色 忽略 BS_HOLLOW 忽略 忽略 BS_HATCHED 阴影线的颜色 阴影线画刷样式 BS_PATTERN 忽略 位图的句柄 BS_DIBPATTERNPT 忽略 指向DIB的指针
选入:
SelectObject(hdc, hBrush);
删除:
DeleteObject(hBrush);
37. 获取画刷信息
GetObject(hBrush, sizeof(LOGBRUSH), (LPVOID)&logbrush);
38. GDI映射模式
MM_TEXT 右(x) 下(y) 像素 MM_LOMETRIC 右(x) 上(y) 0.1mm(LO HI:精度的高低) MM_HIMETRIC 右(x) 上(y) 0.01mm MM_LOENGLISG 右(x) 上(y) 0.01in MM_HIENGLISG 右(x) 上(y) 0.001in MM_TWIPS 右(x) 上(y) 1/1440in 英寸 MM_ISOTROPIC 可选 可选 任意(x = y) MM_ANISOTROPIC 可选 可选 任意(x != y)
38_1. 设置映射模式
SetMapMode(hdc, iMapMode);
38_2. 获取当前映射模式
GetMapMode(hdc);
39. 客户区坐标转换为屏幕坐标
ClientToScreen();
40. 屏幕坐标转换为客户区坐标
ScreenToClient();
41. 以屏幕坐标的形式获取整个窗口的位置和大小
GetWindowRect();
42. 设备点转换为逻辑点
DPtoLP(hdc, pPoints, iNumber); //将设备点转换为逻辑点 //把从GetClientRect()获取的客户区大小转换为逻辑坐标很有用 GetClientRect(hwnd, &rect); DPtoLP(hdc, (PPOINT)&rect, 2);
43. 逻辑点转换为设备点
LPtoDP(hdc, pPoints, iNumber);
44. 设置逻辑点位置
//参数总是以设备单位的形式给出 SetViewportOrgEx(hdc, cxClient /2, cyClient / 2, NULL); //设置逻辑点为客户区中心 //参数总是以逻辑单位的形式给出 SetWindowOrgEx(hdc, -cxClient / 2, -cyClient / 2, NULL); //结果相同
45. 获取当前视口和窗口的原点
GetViewportOrgEx(hdc, &pt); //设备坐标形式 GetWindowOrgEx(hdc, &pt); //逻辑坐标形式
46. 设置/获取窗口和视口的范围
SetViewPortExtEx(hdc, cxClient, -cyClient, NULL); GetViewportExtEx(); SetWindowExtEx(hdc, 32767, 32767, NULL); GetWindowExtEx();
47. 处理矩形
FillRect(hdc, &rect, hBrush); //使用指定画刷填充矩形 不需事先把画刷选入设备环境 FrameRect(hdc, &rect, hBrush); //使用画刷绘制一个矩形框,但并不填充矩形 InvertRect(hdc, &rect); //翻转矩形内所有的像素,1 > 0, 0 > 1。
48.设置rect
SetRect(hdc, xLeft, yTop, xRight, yBottom); //简化了: rect.left = xLeft; rect.top = yTop; ......
49.
OffsetRect(&rect, x, y); //将矩形沿x轴和y轴移动几个单位 InflateRect(&rect, x, y); //增大或减小矩形的尺寸 SetRectEmpty(&rect); //把矩形结构的各字段设置为0 CopyRect(&DestRect, &SrcRect); //将一个矩形结构复制到另一个矩形结构 IntersectRect(&DestRect, &SrcRect1, &SrcRect2); //获取两个矩形的交集 UnionRect(&DestRect, &SrcRect1, &SrcRect2); //获取两个矩形的并集 bEmpty = IsRectEmpty(&rect); //判断矩形是否为空 bInRect = PtInRect(&rect, point); //判断点是否在矩形内部
50. 建立一个矩形区域
hRgn = CreateRectRgn(xLeft, yTop, xRight, yBottom); hRgn = CreateRectRgnIndirect(&rect);
51. 建立椭圆区域
hRgn = CreateEllipticRgn(xLeft, yTop, xRight, yBottom); hRgn = CreateEllipticRgnIndirect(&rect);
52. 创建圆角矩形区域
CreateRoundRectRgn();
53. 创建多边形区域
hRgn = CreatePolygonRgn(&point, iCount, iPolyFillMode);
54. 结合两个源区域组成新区域
iRgnType = CombineRgn(hDestRgn, hSrcRgn1, hSrcRgn2, iCombine); //iCombine: RGN_AND //公共部分 RGN_OR //全部 RGN_XOR //全部,除去公共部分 RGN_DIFF //hSrcRgn1不在hSrcRgn2中的部分 RGN_COPY //hSrcRgn1的全部(忽略hSrcRgn2)
return value:
NULLREGION:空的区域 SIMPLEREGION:指的是一个简单的矩形,椭圆或多边形 COMPLEXREGION:批的是矩形,椭圆或多边形的组合 ERROR:有错误发生
填充区域:
FillRgn(hdc, hRgn, hBrush); FrameRgn(hdc, hRgn, hBrush, xFrame, yFrame); InvertRgn(hdc, hRgn); PaintRgn(hdc, hRgn);
用于区域:
InvalidateRgn(hwnd, hRgn, bErase); ValidateRgn(hwnd, hRgn);
将区域选入设备环境句柄:
SeleteObject(hdc, hRgn); 或 SeleteClipRgn(hdc, hRgn);
55. 从剪裁区域去除一个矩形
ExcludeClipRect();
56.
IntersectClipRect(); //建立一个新的剪裁区域, 新剪裁区域是先前的剪裁区域和某个矩形的交集
57.
OffsetClipRgn(); //把一个剪裁区域移动到客户区的另一部分
来源:https://www.cnblogs.com/coolcpp/p/windows-drawing.html