Upload
rico
View
118
Download
0
Embed Size (px)
DESCRIPTION
§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 消息的产生 无效矩形 打开一个窗口 改变窗口大小 移动窗口 切换窗口 - PowerPoint PPT Presentation
Citation preview
§3 Windows 图形设备接口及绘图
1. 响应 WM_PAINT 消息2. 图形设备接口 (GDI)
3. 使用设备描述表3. 获取设备描述表句柄5. CDC 及其派生类6. 使用 CDC 成员函数绘制文本7. 使用 CDC 成员函数绘制图形8. 正确使用 GDI 对象9. 设备坐标与逻辑坐标10. OpenGL 绘图
实验作业
1.习题 2,3,4
1. WM_PAINT 消息的产生 无效矩形
打开一个窗口 改变窗口大小 移动窗口 切换窗口 最小化、最大化窗口 调用 InvalidateRect 函数 调用 UpdateWindow 函数
2. 响应 WM_PAINT 消息 OnPaint
§3.1 响应 WM_PAINT 消息
§3.2 图形设备接口 (GDI)
1 . 图形设备接口—提供专门的数据结构即设备描述表( DC )和对 DC操作的绘图函数。
2 . 设备描述表( DC )—用于代表图形输出设备如显示屏、打印机;
3 . 设备无关性—利用 GDI ,所有的绘图操作都对设备描述表而不是具体的物理设备。
设备描述表• 一种专门用于代表图形输出设备 ( 如屏幕、打
印机和绘图仪等 ) 的数据结构– 画布– 绘图工具 ( 设备描述表属性 )
• 使用句柄 (HDC) 访问设备描述表 – 设置设备描述表属性– 绘制图形和文本
设备描述表属性 缺省值 设置属性值函数 获取属性值函数映射方式 MM_TEXT SetMapMode GetMapMode
窗口原点 (0,0) SetWindowOrg GetWindowOrgOffsetWindowOrg
视口原点 (0,0) SetViewportOrg GetViewportOrgOffsetViewportOrg
窗口限度 (1,1) SetWindowExt GetWindowExtSetMapMode
视口限度 (1,1) SetViewportExt GetViewportExtSetMapMode
画笔 BLACK_PE SelectObject SelectObject
画刷 WHITE_BRUSH SelectObject SelectObject
字模 SISTEM_FONT SelectObject SelectObject
位图 NONE SelectObject SelectObject
当前画笔位置 (0,0) MoveToLineTo
GetCurrentPosition
背景方式 OPAQUE SetBkMode GetBkMode
背景色彩 White SetBkColor GetBkColor
文本色彩 Black SetTextColor GetTextColor
作图方式 R2_COPYPEN SetROP2 GetROP2
伸展方式 BLACK_ONWHIE SetPollyFillMode GetPollyFillMode
多边形填充方式 ALTERNATE SetPollyFillMode GetPollyFillMode
字符间距 0 SetTextCharacterExtra GetTextCharacterExtra
画刷原点 (0,0)屏幕坐标 SetBrushOrg GetBrushOrg
裁剪区 NONE SelectObjectSelectClipRgnIntersectClipRectOffsetClipRgnExcludeClipRect
SelectObjectGetClipBox
设备描述表属性
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;
(1) 获取设备描述表句柄(2) 设置设备描述表属性(3) 调用绘图函数绘图(4) 释放设备描述表
3.3 使用设备描述表绘图
1. BeginPaint 和 EndPaint 函数 (1) BeginPaint function• 准备在窗口绘图• 获得代表窗口的设备描述表句柄• 把有关绘图的信息放到 PAINTSTRUCT 结构
变量中。• 响应 WM_PAINT 消息绘图,必须调用该函数
获取设备描述表句柄。
3.4 获取窗口设备描述表句柄
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
• 标志对指定窗口的绘图结束•释放设备描述表句柄•必须与 BeginPaint 函数成对调用•函数原型
BOOL EndPaint( HWND hWnd,
CONST PAINTSTRUCT *lpPaint
);
(2) EndPaint function
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 类
句柄 对象HGDI OBJ 所有 GDI 对象HBRUSH 画刷HPEN 画笔HBI TMAP 位图HRGN 区域HPALETTE 调色板
GDI 对象与句柄
使用 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 、 C
Bitmap 、 CPallete 和 CRgn 类
逻辑坐标系TextOut(hdc, x,y,szBuffer,nLength) 设备坐标系 屏幕坐标系 窗口坐标系 窗口工作区坐标系 视口(设备坐标)与窗口(逻辑坐标)
§3.7 设备坐标与逻辑坐标
映像模式 定义了逻辑坐标与设备坐标的转换 CDC:: SetMapMode();
映射模式 逻辑单元 坐标轴方向MM_TEXT 象素 X:向右 Y:向下MM_I SOTROPI C 任意(X=Y) X:向右 Y:向上MM_ANI SOTROPI C 任意(X!=Y) X:向右 Y:向上MM_HI ENGLI SH 0. 001英寸 X:向右 Y:向上MM_HI METRI C 0. 01MM X:向右 Y:向上MM_LOENGLI SH 0. 01英寸 X:向右 Y:向上MM_LOMETRI C 0. 1MM X:可选 Y:可选MM_TWI PS 1/1440英寸 X:可选 Y:可选
• 窗口原点和视口原点– 调整逻辑坐标的原点
• 窗口限度和视口限度– 调整逻辑坐标轴的方向和单位
• 逻辑坐标与设备坐标的转换公式– xViewport=(xWindow-xWinOrg)*(xViewExt/xW
inExt)+xViewOrg;– yViewport=(yWindow-yWinOrg)*(yViewExt/y
WinExt)+xViewOrg;
• 设置逻辑坐标系的原点– SetViewportOrgEx 函数
BOOL SetViewportOrgEx(
HDC hdc, // 设备描述表句柄 int X, // 使用设备单位,视口原点的 X 坐标值 int Y, // 使用设备单位,视口原点的 Y 坐标值 LPPOINT lpPoint // 指向 POINT 结构变量,存放
原始的视口原点坐标 );
SetViewportOrgEx(hdc,cx/2,cy/2,NULL);
– SetWindowOrgExBOOL 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 // 原始视口限度);
坐标系的转换1. DPToLP()2. LPToDP()3. ClientToScreen()4. 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, POIN
T point );– BOOL Pie( LPCRECT lpRect, POINT ptStar
t, POINT ptEnd );– BOOL Polygon( LPPOINT lpPoints, int nC
ount );– BOOL PolyPolygon( LPPOINT lpPoints, LP
INT lpPolyCounts, int nCount );
• CPen 类和画笔
函数原型 说明CPen( ); 构造 Cpen对象CPen( int nPenStyle, int nWidth,COLORREF crColor );
构造 Cpen对象,并创建样式为 nPenStyle,宽度为 nWidth,颜色为 crColor的 GDI画笔对象
BOOL CreatePen( int nPenStyle, int nWidth,COLORREF crColor );
并创建样式为 nPenStyle,宽度为 nWidth,颜色为 crColor的 GDI画笔对象
BOOL CreatePenIndirect( LPLOGPENlpLogPen );
创建 GDI 画笔对象,参数为 lpLogPen 指向 LOGPEN结构对象。
LOGPEN结构的定义如下:typedef struct tagLOGPEN { /* lgpn */ UINT lopnStyle; //画笔样式 POINT lopnWidth; //画笔宽度 COLORREF lopnColor; //画笔颜色} LOGPEN;
样式 线形PS_SOLID
PS_DASH
PS_DOT
PS_DASHDOT
PS_DASHDOTDOT
PS_NULL
PS_INSIDEFRAME
(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 );
• 1 . 画刷和 CBrush 类函数原型 说明CBrush( ); 构造 CBrush对象CBrush( COLORREF crColor ); 构造 CBrush 对象,并创建实心画刷,颜
色由参数 crColor指定CBrush( int nIndex, COLORREF crColor ); 构造 CBrush 对象,并创建阴影线画刷,
阴影线样式由 nIndex指定,颜色由 crColor指定
CBrush( CBitmap* pBitmap ); 构造 CBrush 对象,并创建位图画刷,位图由 pBitmap指定
BOOL CreateSolidBrush( COLORREFcrColor );
创建实心画刷,颜色由参数 crColor指定
BOOL CreateHatchBrush( int nIndex,COLORREF crColor );
创建阴影线画刷,阴影线样式由 nIndex指定,颜色由 crColor指定
BOOL CreateBrushIndirect( constLOGBRUSH* lpLogBrush );
创建画刷,画刷类型由 lpLogBrush 指向的 LOGBRUSH结构变量指定
BOOL CreatePatternBrush( CBitmap*pBitmap );
创建位图画刷,位图由 pBitmap指定
LOGBRUSH 的结构定义如下:typedef struct tagLOGBRUSH { // lb
UINT lbStyle;
COLORREF lbColor;
LONG lbHatch;
} LOGBRUSH; LbStyle 画刷类型BS_HATCHED 阴影线画刷BS_HOLLOW, BS_NULL 空心画刷BS_PATTERN,BS_PATTERN8X8 位图画刷BS_SOLID 实心画刷
样式 阴影线图式HS_HORIZONTAL
HS_VERTICAL
HS_FDIAGONAL
HS_BDIAGONAL
HS_CROSS
HS_DIAGCROSS
阴影线的样式:
( 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);
1 . TextOut 2 . DrawText-- 在指定矩形区域以一定格式输出字符串
DT_BOTTOM DT_CENTERDT_LEFT DT_RIGHTDT_SINGLELINEDT_TOPDT_VCENTER …
3.9 使用 CDC 成员函数绘制文本 文本输出函数
3. ExtTextOut• 函数功能:在指定位置输出字符串,并且在文本周围给矩形填充背景色。
• 函数原型: BOOL ExtTextOut( int x, int y, UINT nOptions, LPCRECT lpRect, const CString& str, LPINT lpDxWidths );
参数 说明x,y 字符串输出起始位置 x,y坐标NOpti ons 指定矩形框的样式;如果设置为 ETO_CLI PPED则字符串被矩形框剪切,
如果设置为 ETO_OPAQUE则矩形框将被背景色填充。LpRect 指定矩形,可以设置为 NULL。Str 绘制的字符串LpDxWi dths
指向一个数组;数组元素 i 的值决定了第 I 个字符与第 I +1个字符的间隔距离;可以设置为 NULL。
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 );
参数 说明x,y 字符串输出起始位置 x,y坐标Str 绘制的字符串NTabPosi ti ons 指定制表符的个数LpnTabStopPosi ti ons 指向一个存放制表符位置的数组NTabOri gi n 制表符的扩展宽度
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. SetTextAlignTA_BASELINE
TA_BOTTOM
TA_TOP
TA_CENTER
TA_LEFT
TA_RIGHT …
文本格式控制
2. SetTextCharacterExtra• 函数功能:设置字符间距• 函数原型: int SetTextCharacterExtra(
int nCharExtra );•参数说明: nCharExtra为添加的空白数
(逻辑单位)
3. SetTextJustification• 函数功能 : 设置词间距• 函数原型: int SetTextJustification( int nB
reakExtra, int nBreakCount );
•参数说明: nBreakExtra 为所有空格添加的空白数(逻辑单位); nBreakCount 为一行字符串中的空格数。
GetTextExtent 函数• 函数原型: CSize GetTextExtent( const C
String& str )
• 函数功能: 返回输出字符串 str 所占用的显示空间(逻辑单位)
void CChildView::OnPaint()
{
CPaintDC dc(this); dc.SetTextAlign(TA_RIGHT);
dc.TextOut(100,20,CString("right aligned"));
dc.SetTextAlign(TA_LEFT);
dc.TextOut(100,60,CString("left aligned"));
int oldextra=dc.SetTextCharacterExtra(5);
dc.TextOut(100,100,CString("left aligned and add 5 extra"));
CSize size=dc.GetTextExtent(CString("left aligned and add 5 extra and justified"));
CRect rect;
GetClientRect(&rect);
dc.SetTextJustification(rect.Width()-size.cx,7);
dc.TextOut(0,140,CString("left aligned and add 5 extra and justified"));
dc.SetTextCharacterExtra(oldextra);
dc.SetTextJustification(0,0);
dc.TextOut(100,180,CString("left aligned"));
}
3.6.3 获取文本尺寸
1.GetTextMetrics2.GetTextExtentPoint
typedef struct tagTEXTMETRIC
{ LONG tmHeight; LONG tmAscent; LONG tmDescent; LONG tmInternalLeading; LONG tmExternalLeading; LONG tmAveCharWidth; LONG tmMaxCharWidth; LONG tmWeight; … } TEXTMETRIC;
设置字符和背景颜色
(1)SetTextColor 函数(2)SetBKColor 函数
CFont 类与字体• Windows 字体
– 栅格型 (Raster)– 矢量型 (Vector)– TrueType
• 字体要素– 字型(字体名称)– 字型样式(字体样式)– 大小(从低端到顶端的距离)
成员类型
成员名 使用说明
LONG l fHei ght 字符高度(使用逻辑单位)设置为 0时,使用缺省高度
LONG l fWi dth 字符平均宽度, 设置为 0时,使用匹配宽度LONG l fEscapement 字符与 X轴的角度,缺省为 0LONG l fOri entati on 字符排列角度,值为角度*10,如 900代表 90度,
1800为逆向LONG l fWei ght 字符中线的粗细度, 取值范围:
FW_DONTCARE, FW_THI N, …FW_NORMAL, FW_REGULAR….FW_BOLD, . . FW_BLACK, FW_HEAVY
BYTE l f I tal i c 非 0为斜体BYTE l fUnderl i ne 非 0为加下划底线BYTE l fStri keOut 非 0为在字符中央加线
BYTE l fCharSet 字符集,可以设置以下字符集:ANSI _CHARSET,DEFAULT_CHARSET,SYMBOL_CHARSET,SHI FTJ I S_CHARSET,HANGUL_CHARSET,GB2312_CHARSET,…
BYTE l fOutPreci si on 精确度: OUT_DEFAULT_PRECI S,OUT_DEVI CE_PRECI S, (devi ce)OUT_RASTER_PRECI S, (Raser)OUT_TT_ONLY_PRECI S(onl y true type)OUT_TT_PRECI S(true type)
BYTE l fCl i pPreci si on 裁剪字符的方法: CLI P_DEFAULT_PRECI SBYTE l fQual i ty 字体质量: DEFAULT_QUALI TY
DRAFT_QUALI TY, PROOF_QUALI TYBYTE l fPi tchAndFami l y 宽度种类与字体家族,可以设置以下值:
宽度种类: DEFAULT_PI TCH,VARI ABLE_PI TCH, FI XED_PI TCH字体家族:FF_DECORATI VE(Ol d Engl i sh),FF_DONTCARE,FF_MODERN(Couri er New),FF_ROMAN(Ti mesNewRoman),FF_SCRI PT(Scri pt),FF_SWI SS(Ari al)
TCHAR l fFaceName[LF_FACESIZE]
字体名称
获取字体尺寸信息• GetTextMetrics 函数• BOOL GetTextMetrics ( LPTEXTMETRI
C lptm )
typedef struct tagTEXTMETRIC
{ int tmHeight;
int tmAscent;
int tmDescent;
int tmInternalLeading;
int tmExternalLeading;
int tmAveCharWidth;
int tmMaxCharWidth;
int tmWeight;
BYTE tmItalic;
BYTE tmUnderlined;
BYTE tmStruckOut;
BYTE tmFirstChar;
BYTE tmLastChar;
BYTE tmDefaultChar;
BYTE tmBreakChar;
BYTE tmPitchAndFamily;
BYTE tmCharSet;
int tmOverhang;
int tmDigitizedAspectX;
int tmDigitizedAspectY;
} TEXTMETRIC;
使用 CFont 类创建字体• 构造 CFont 对象• 调用成员函数创建字体对象
– CreateFontIndirect 函数• 函数原型: BOOL CreateFontIndirect(const L
OGFONT* lpLogFont );•参数说明: lpLogFont 就是 LOGFONT 的指针
类型。
– (2)CreateFont 函数• 函数原型: BOOL CreateFont( int nHeight, in
t 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 );
– (3)CreatePointFont 函数• 函数原型: BOOL CreatePointFont( i
nt nPointSize, LPCTSTR lpszFaceName, CDC* pDC = NULL );
void CChildView::OnPaint()
{ CPaintDC dc(this);
CString fontname[5]={“宋体” ,”隶书” ,”仿宋体” ,”楷书” ,”黑体” } ;LOGFONT flog;
ZeroMemory(&flog,sizeof(flog));
flog.lfHeight=48;
flog.lfWeight=FW_BOLD;
flog.lfCharSet=GB2312_CHARSET;
for(int i=0;i<5;i++)
{ strcpy(flog.lfFaceName,fontname[i]);
CFont font;
font.CreateFontIndirect(&flog);
dc.SelectObject(&font);
dc.TextOut(20,20+i*48,fontname[I];
}
}
本章重点及编程要求:
1 . 绘图的基本步骤2 . 设备环境的获取与使用3 . GDI 对象的使用5 . 逻辑坐标的设 置