660 likes | 817 Views
§3 Windows 图形设备接口及绘图. 1. 响应 WM_PAINT 消息 2. 图形设备接口 (GDI) 3. 使用设备描述表 3. 获取设备描述表句柄 5. CDC 及其派生类 6. 使用 CDC 成员函数绘制文本 7. 使用 CDC 成员函数绘制图形 8. 正确使用 GDI 对象 9. 设备坐标与逻辑坐标 10. OpenGL 绘图. 实验作业. 习题 2,3,4. §3.1 响应 WM_PAINT 消息. WM_PAINT 消息的产生 无效矩形 打开一个窗口 改变窗口大小 移动窗口 切换窗口
E N D
§3 Windows 图形设备接口及绘图 1. 响应WM_PAINT消息 2. 图形设备接口(GDI) 3. 使用设备描述表 3. 获取设备描述表句柄 5. CDC及其派生类 6. 使用CDC成员函数绘制文本 7.使用CDC成员函数绘制图形 8.正确使用GDI对象 9.设备坐标与逻辑坐标 10. OpenGL绘图
实验作业 • 习题2,3,4
§3.1 响应WM_PAINT消息 • WM_PAINT消息的产生 无效矩形 • 打开一个窗口 • 改变窗口大小 • 移动窗口 • 切换窗口 • 最小化、最大化窗口 • 调用InvalidateRect函数 • 调用UpdateWindow函数 • 2. 响应WM_PAINT消息 • OnPaint
§3.2 图形设备接口(GDI) 1.图形设备接口—提供专门的数据结构即设备描述表(DC)和对DC操作的绘图函数。 2.设备描述表(DC)—用于代表图形输出设备如显示屏、打印机; 3.设备无关性—利用GDI,所有的绘图操作都对设备描述表而不是具体的物理设备。
设备描述表 • 一种专门用于代表图形输出设备(如屏幕、打印机和绘图仪等)的数据结构 • 画布 • 绘图工具(设备描述表属性) • 使用句柄(HDC)访问设备描述表 • 设置设备描述表属性 • 绘制图形和文本
GDI对象 • 画笔 • 画刷 • 字体 • 位图 • 裁剪区
case WM_PAINT: hdc = BeginPaint(hWnd, &ps); RECT rt; GetClientRect(hWnd, &rt); SetTextColor(hdc,RGB(255,0,0)); SetBkColor(hdc,RGB(0,0,255)); DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER); EndPaint(hWnd, &ps); break;
3.3 使用设备描述表绘图 (1)获取设备描述表句柄 (2)设置设备描述表属性 (3)调用绘图函数绘图 (4)释放设备描述表
3.4 获取窗口设备描述表句柄 1. BeginPaint和EndPaint函数 (1) BeginPaint function • 准备在窗口绘图 • 获得代表窗口的设备描述表句柄 • 把有关绘图的信息放到PAINTSTRUCT 结构变量中。 • 响应WM_PAINT消息绘图,必须调用该函数获取设备描述表句柄。
函数原型: HDC BeginPaint ( HWND hwnd, // handle to window LPPAINTSTRUCT lpPaint // pointer to structure for paint information);
PAINTSTRUCT • typedef struct tagPAINTSTRUCT { • HDC hdc; • BOOL fErase; • RECT rcPaint; • BOOL fRestore; • BOOL fIncUpdate; • BYTE rgbReserved[32]; • } PAINTSTRUCT
(2) EndPaint function • 标志对指定窗口的绘图结束 • 释放设备描述表句柄 • 必须与BeginPaint函数成对调用 • 函数原型 BOOL EndPaint ( HWND hWnd, CONST PAINTSTRUCT *lpPaint );
2.GetDC和RealeaseDC函数 (1) GetDC function 获取窗口设备描述表句柄 用于响应非WM_PAINT消息绘图。 函数原型: HDC GetDC( HWND hWnd );
(2)ReleaseDC function 释放设备描述表句柄 必须与GetDC函数成对调用 函数原型: int ReleaseDC(HWND hWnd, // handle to window HDC hDC // handle to device context );
3.5 CDC及其派生类 • CDC: 封装了所有与设备描述表有关的数据和操作。 • 绘图函数:Ellipse()… • 文本输出:TextOut()… • 设置设备描述表属性:SelectObject(), SetTextColor()… • 数据成员m_hdc:设备描述表句柄。
CPaintDC: • construction CWnd::BeginPaint • destruction CWnd::EndPaint • CClientDC : • construction CWnd::GetDC • destruction CWnd::ReleaseDC • CWindowDC • GetWindowDC • ReleaseDC
3.6 GDI对象与CGDIObject类 • GDI对象与句柄 • 使用GDI对象 • 使用CGDIObject类
使用GDI对象基本规则 (1)创建对象 (2)用SelectObject函数把新创建的对象选入设备描述表,并保留原对象 (3)完成绘图函数的调用后,把旧对象选入设备描述表,置换出创建的对象 (4)删除创建的对象,由 DeleteObject函数完成
case WM_PAINT: hdc = BeginPaint(hWnd, &ps); HPEN hNewPen,hOldPen; hNewPen=CreatePen(PS_DASH,1,RGB(255,0,0)); hOldPen=(HPEN)SelectObject(hdc,hNewPen); MoveToEx(hdc,0,0,NULL); LineTo(hdc,100,100); hNewPen=(HPEN)SelectObject(hdc,hOldPen); DeleteObject(hNewPen); EndPaint(hWnd, &ps); break;
使用CGDIObject类 • 数据成员m_hObject • Attach函数 Detach函数 • 派生类: CPen、CBrush、CFont、CBitmap、CPallete和CRgn类
§3.7设备坐标与逻辑坐标 • 逻辑坐标系 TextOut(hdc, x,y,szBuffer,nLength) • 设备坐标系 • 屏幕坐标系 • 窗口坐标系 • 窗口工作区坐标系 • 视口(设备坐标)与窗口(逻辑坐标)
映像模式 定义了逻辑坐标与设备坐标的转换 CDC:: SetMapMode();
窗口原点和视口原点 • 调整逻辑坐标的原点 • 窗口限度和视口限度 • 调整逻辑坐标轴的方向和单位 • 逻辑坐标与设备坐标的转换公式 • xViewport=(xWindow-xWinOrg)*(xViewExt/xWinExt)+xViewOrg; • yViewport=(yWindow-yWinOrg)*(yViewExt/yWinExt)+xViewOrg;
设置逻辑坐标系的原点 • SetViewportOrgEx函数 BOOL SetViewportOrgEx( HDC hdc, // 设备描述表句柄 int X, // 使用设备单位,视口原点的X坐标值 int Y, // 使用设备单位,视口原点的Y坐标值 LPPOINT lpPoint // 指向POINT结构变量,存放原始的视口原点坐标 ); SetViewportOrgEx(hdc,cx/2,cy/2,NULL);
SetWindowOrgEx BOOL SetWindowOrgEx( HDC hdc, // 设备描述表句柄 int X, // 使用逻辑单位,窗口原点的X坐标值 int Y, // 使用逻辑单位,窗口原点的Y坐标值 LPPOINT lpPoint // 指向POINT结构变量,存放原始的窗口原点坐标 ) • SetWindowOrgEx(hdc,-cx/2,-cy/2,NULL);
任意逻辑坐标系的设置 1.设置映射方式 MM_ANISOTROPIC,MM_ISOTROPIC(做适当调整) 2. 设置窗口限度 • SetWindowExt() • BOOL SetWindowExtEx( • HDC hdc, // 设备描述表句柄 • int nXExtent, // 新设置的水平方向窗口限度 • int nYExtent, // 新设置的垂直方向窗口限度 • LPSIZE lpSize // 原始窗口限度 • );
3.设置视口限度 BOOL SetViewportExtEx( HDC hdc, // 设备描述表句柄 int nXExtent, // 新设置的水平方向视口限度 int nYExtent, // 新设置的垂直方向视口限度 LPSIZE lpSize // 原始视口限度 );
坐标系的转换 • DPToLP() • LPToDP() • ClientToScreen() • ScreenToClient()
3.8 使用CDC类绘制图形 • 绘制点和线 • COLORREF SetPixel( POINT point, COLORREF crColor ); • CPoint MoveTo( POINT point ); • BOOL LineTo( POINT point ); • BOOL Arc( LPCRECT lpRect, POINT ptStart, POINT ptEnd ); • BOOL AngleArc( int x, int y, int nRadius, float fStartAngle, float fSweepAngle );
BOOL Polyline( LPPOINT lpPoints, int nCount ); • BOOL PolyPolyline( const POINT* lpPoints, const DWORD* lpPolyPoints, int nCount ); • BOOL PolyBezier( const POINT* lpPoints, int nCount );
绘制封闭图形 • BOOL Ellipse( LPCRECT lpRect ); • BOOL Rectangle( LPCRECT lpRect ) • BOOL RoundRect( LPCRECT lpRect, POINT point ); • BOOL Pie( LPCRECT lpRect, POINT ptStart, POINT ptEnd ); • BOOL Polygon( LPPOINT lpPoints, int nCount ); • BOOL PolyPolygon( LPPOINT lpPoints, LPINT lpPolyCounts, int nCount );
(1)调用带参数的构造函数创建GDI画笔对象,例如:(1)调用带参数的构造函数创建GDI画笔对象,例如: Cpen m_Pen (PS_SOLID,1,RGB(0,0,255)); (2)先调用缺省构造函数创建CPen对象,然后调用Indirect函数创建GDI画笔对象,例如: Cpen m_Pen; LOGPEN logpen; logpen .lopnStyle=PS_SOLID; //画笔样式 logpen .lopnWidth=1; //画笔宽度 logpen .lopnColor=RGB(0,0,255); m_Pen. CreatePenIndirect(&logpen );
LOGBRUSH的结构定义如下: typedef struct tagLOGBRUSH { // lb UINT lbStyle; COLORREF lbColor; LONG lbHatch; } LOGBRUSH;
(1)创建实心画刷 使用带参数的构造函数创建 CBrush brush(RGB(255,0,0)); 先使用缺省的构造函数创建Cbrush对象,然后调用成员函数创建画刷 CBrush brush; brush.CreateSolidBrush(RGB(255,0,0))
(2) 创建阴影线画刷 使用带参数的构造函数创建,例如: CBrush brush(HS_DIAGCROSS,RGB(0,255,0)); 先使用缺省的构造函数创建Cbrush对象,然后调用成员函数创建画刷。如: CBrush brush; brush.CresteHatchBrush(HS_DIAGCROSS,RGB(0,255,0));
(3)创建位图画刷 • 准备一个位图对象 • CBitmap bitmap; • bitmap.LoadBitmap(IDB_BITMAP1); • 使用CBrush类带参数的构造函数创建位图画刷,例如: • CBrush brush(&bitmap); • 先使用缺省的构造函数创建Cbrush对象,然后调用成员函数创建画刷。例如: • CBrush brush; • brush.CrestePatternBrush(&bitmap);
3.9 使用CDC成员函数绘制文本 • 文本输出函数 1.TextOut 2.DrawText--在指定矩形区域以一定格式输出字符串 DT_BOTTOM DT_CENTER DT_LEFT DT_RIGHT DT_SINGLELINE DT_TOP DT_VCENTER …
3. ExtTextOut • 函数功能:在指定位置输出字符串,并且在文本周围给矩形填充背景色。 • 函数原型:BOOL ExtTextOut( int x, int y, UINT nOptions, LPCRECT lpRect, const CString& str, LPINT lpDxWidths );
void CChildView::OnPaint() { CPaintDC dc(this); // device context for painting dc.SetBkColor(RGB(0,255,0)); CRect rect(0,0,200,40); int array[5]={40,25,35,45,15}; dc.ExtTextOut(10,10,ETO_CLIPPED|ETO_OPAQUE,&rect,CString("hello"),array); }
4.TabbedTextOut函数 • 函数功能:和TextOut()的差不多,只是它支持制表符,定义一组制表符的位置。 • 函数原型:CSize TabbedTextOut( int x, int y, const CString& str, • int nTabPositions, LPINT lpnTabStopPositions, int nTabOrigin );
void CChildView::OnPaint() { CPaintDC dc(this); // device context for painting int array[3]={80,140,200}; dc.TabbedTextOut(0,0,CString("hello\thow\tare\tyou"),0,NULL,0); dc.TextOut(0,180,CString("hello\thow\tare\tyou")); }
文本格式控制 1. SetTextAlign TA_BASELINE TA_BOTTOM TA_TOP TA_CENTER TA_LEFT TA_RIGHT …
2. SetTextCharacterExtra • 函数功能:设置字符间距 • 函数原型:int SetTextCharacterExtra( int nCharExtra ); • 参数说明:nCharExtra为添加的空白数(逻辑单位)
3. SetTextJustification • 函数功能: 设置词间距 • 函数原型:int SetTextJustification( int nBreakExtra, int nBreakCount ); • 参数说明:nBreakExtra 为所有空格添加的空白数(逻辑单位);nBreakCount 为一行字符串中的空格数。