Windows Api教案4(推荐)由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“windows系统编程教案”。
教
案
用
纸
⒊ 填充空隙
问题:在使用点式画笔和虚线画笔时,点和虚线之间的空隙会怎样呢? 这取决于DC的两个属性━━背景模式和背景颜色。默认背景模式为OPAQUE,在这种方式下,Windows使用背景色来填充空隙,默认的背景色为白色。
① SetBkColor函数
COLORREF SetBkColor(HDC hdc, // handle of device context COLORREF crColor // background color value);
② GetBkColor函数
COLORREF GetBkColor(HDC hdc // handle of device context);
③ SetBkMode函数
int SetBkMode(HDC hdc, // handle of device context int iBkMode // flag specifying background mode);其中iBkMode为TRANSPARENT或者OPAQUE ④ GetBkMode函数
int GetBkMode(HDC hdc // handle to device context of interest);
说明:通过SetBkColor函数可以改变填充空隙的背景色,通过SetBkMode将背景模式转换为TRANSPARENT,可以阻止Windows填充空隙。
⒋ 绘图方式 ① 光栅运算
像素间的按位布尔运算叫做“光栅运算”,简记为“ROP”。由于绘图只涉及两种像素(画笔和目标),因此又称为“ROP2”运算。即当Windows使用画笔来画线时,它实际上执行画笔像素与目标位置处原来像素之间的某种按位布尔运算。
② 绘图模式种类 绘图模式
布尔操作 R2_BLACK
0 R2_NOTMERGEPEN
~(P|D)R2_MASKNOTPEN
~P&D R2_NOTCOPYPEN
~P R2_MASKPENNOT
P&~D R2_NOT
~D 吉
林
化
工
学
院 第 54 页 教
案
用
纸
R2_XORPEN
P^D R2_NOTMASKPEN
~(P&D)R2_MASKPEN
P&D R2_NOTXORPEN
~(P^D)R2_NOP
D R2_MERGENOTPEN
~P|D R2_COPYPEN(默认)
P R2_MERGEPENNOT
P|~D R2_MERGEPEN
P|D R2_WHITE注意:以上模式指在单色系统中绘图的模式。
③ SetROP2函数
int SetROP2(HDC hdc, // handle of device context int fnDrawMode // drawing mode);
④ GetROP2函数
int GetROP2(HDC hdc // handle of device context);
六
绘制填充区域
图形以当前设备描述表中选择的刷子来填充。⒈ 现有画刷 WHITE_BRUSH LTGRAY_BRUSH GRAY_BRUSH DKGRAY_BRUSH BLACK_BRUSH NULL_BRUSH(HOLLOW_BRUSH)⒉ 选择现有画刷 HBRUSH hBrush;hBrush=GetStockObject(GRAY_BRUSH);SelectObject(hdc,hBrush);用下面语句画一个没有边界框的图形。
SelectObject(hdc,GetStockObject(NULL_PEN));用下面语句画一个没有填充的图形。
SelectObject(hdc,GetStockObject(NULL_BRUSH));⒊ Polygon函数和多边形填充方式 ① Polygon函数
BOOL Polygon(HDC hdc, // handle to device context 吉
林
化
工
学
院 第 55 页 教
案
用
纸
CONST POINT *lpPoints, // pointer to polygon's vertices int nCount // count of polygon's vertices);
其中nCount是点的数目,如果该数组中的最后一个点与第一个点不同,则Windows将会再加一条线,将最后一个点与第一个点连起来。(在Polyline函数中,Windows不会这么做)。
② SetPolyFillMode函数
int SetPolyFillMode(HDC hdc, // handle to device context int iPolyFillMode // polygon fill mode);
其中,iPolyFillMode取值ALTERNATE或WINDING。
说明:ALTERNATE方式,即假设从一个无穷大的封闭区域内部的点画线,只有假想的线穿过了奇数条边界线时,才填充封闭区域。
WINDING方式,即假设从一个无穷大的封闭区域内部的点画线,如果假想的线穿过了奇数条边界线,区域就被填充。如果假想的线穿过了偶数条边界线,则如果一个方向的边界线数与另一个方向的边界线数不相等,就填充区域,否则不填充。
例如,见上图中的物体。线上的箭头指出了画线的方向。两种方式都会填充三个封闭的L形区域,号码为1~3。号码为4和5的两个小内部区域,在ALTERNATE方式下不会被填充。但是,在WINDING方式下,号码为5的区域会被填充,因为从区域内必须穿过两条相同方向的线才能到达图形外部。号码为4的区域不会被填充,因为必须穿过两条方向相反的线。
吉
林
化
工
学
院 第 56 页 教
案
用
纸
④ ALTWIND程序关键部分
LRESULT CALLBACK WndProc(HWND hwnd, UINT meage, WPARAM wParam, LPARAM lParam){
static POINT aptFigure [10] = { 10,70, 50,70, 50,10, 90,10, 90,50,30,50, 30,90, 70,90, 70,30, 10,30 };
static int
cxClient, cyClient;
HDC
hdc;
int
i;
PAINTSTRUCT ps;
POINT
apt[10];
switch(meage)
{
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
SelectObject(hdc, GetStockObject(GRAY_BRUSH));
for(i = 0;i
{
apt[i].x = cxClient * aptFigure[i].x / 200;
apt[i].y = cyClient * aptFigure[i].y / 100;
}
SetPolyFillMode(hdc, ALTERNATE);
Polygon(hdc, apt, 10);
for(i = 0;i
{
apt[i].x += cxClient / 2;
}
SetPolyFillMode(hdc, WINDING);
Polygon(hdc, apt, 10);
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMeage(0);
return 0;
}
return DefWindowProc(hwnd, meage, wParam, lParam);} ⒋ 创建画刷
① CreateSolidBrush函数
HBRUSH CreateSolidBrush(COLORREF crColor // brush color value);
吉
林
化
工
学
院 第 57 页 教
案
用
纸
说明:函数中的Solid并不是指画刷为纯色。在将画刷选入DC中时,Windows创建一个抖动色的位图,并为画刷使用该位图。
② CreateHatchBrush函数
HBRUSH CreateHatchBrush(int fnStyle, // hatch style COLORREF clrref // color value);
说明:其中,iHatchStyle参数描述影线标记的外观。取值如下:
③ CreateBrushIndirect函数
HBRUSH CreateBrushIndirect(CONST LOGBRUSH *lplb // pointer to structure describing brush);
typedef struct tagLOGBRUSH { // lb UINT lbStyle;COLORREF lbColor;LONG lbHatch;} LOGBRUSH;
lbStyle BS_SOLID BS_HOLLOW BS_HATCHED BS_PATTERN BS_DIBPATTERNPT
lbColor
画刷的色彩 忽略
影线的色彩 忽略 忽略
lbHatch
忽略 忽略
影线画刷风格 位图的句柄
指向DIB的指针
④ 选择、删除和获得画刷 SelectObject(hd,hBrush);DeleteObject(hBrush);GetObject(hBrush,sizeof(LOGBRUSH),(LPVOID)&logbrush);七 GDI映射方式
“映射方式”是一种几乎影响任何客户区绘图的设备描述表属性。另外有4种设备描述表属性━━窗口原点、视口原点、窗口范围和视口范围与映射方式密切相关。
大多数GDI绘图函数都需要使用坐标值,这种坐标值使用的都是一种“逻辑单位”。Windows必须将逻辑单位转换为“设备单位”,即像素。这吉
林
化
工
学
院 第 58 页 教
案
用
纸
种转换是由映射方式、窗口和视口的原点,以及窗口和视口的范围所控制的。映射方式还隐含地给出了x轴和y轴的指向。
⒈ 映射方式种类
增 加 值
映射方式 逻辑单位 x值 y值
MM_TEXT MM_LOMETRIC MM_HIMETRIC MM_LOENGLISH MM_HIENGLISH MM_TWIPS MM_ISOTROPIC MM_ANISOTROPIC 像素 0.1mm 0.01mm 0.01in.0.001in.1/1440 in.任意(x=y)任意(x!=y)
右 右 右 右 右 右 可选 可选
下 上 上 上 上 上 可选 可选
默认映射方式为MM_TEXT ⒉ SetMapMode函数
int SetMapMode(HDC hdc, // handle of device context int fnMapMode // new mapping mode);
⒊ GetMapMode函数
int GetMapMode(HDC hdc // handle of device context);
注意:虽然在GDI函数中指定的坐标是32位的值,但是仅有Windows NT 能够处理全32位。在Windows 98中,坐标被限制为16位,范围从-32768到32767。
⒋ 设备坐标和逻辑坐标 ① 使用设备坐标的情况
Windows对所有消息(如WM_MOVE、WM_SIZE和WM_MOUSEMOVE),对所有非GDI函数,甚至对一些GDI函数,永远使用设备坐标。
GetSystemMetrics不是GDI函数,所以它总是以设备单位为量度来返回大小的。
尽管GetDeviceCaps是GDI函数,但是Windows仍然对HORZRES和VERTRES以设备单位作为返回值,因为该函数的目的之一就是给程序提供以像素为单位的设备大小。
② 使用逻辑坐标的情况
基本上大多数GDI函数使用逻辑坐标。而且GetTextMetrics调用中返回的TEXTMETRIC结构的值是使用逻辑单位的。
⒌ 设备坐标系
吉
林
化
工
学
院 第 59 页 教
案
用
纸
Windows将GDI函数中指定的逻辑坐标映射为设备坐标。① 屏幕坐标
当我们使用整个屏幕时,就根据“屏幕坐标”进行操作。屏幕的左上角为(0,0)点,屏幕坐标用在WM_MOVE消息(对于非子窗口)以及下列Windows函数中:CreateWindow和MoveWindow(都是对于非子窗口)、GetMeagePos、GetCursorPos、SetCursorPos、GetWindowRect、WindowsFromPoint等。它们或者是与窗口无关的函数,或者是必须相对于整个屏幕点来移动(或者寻找)窗口的函数。如果以DISPLAY为参数调用CreateDC,以获取整个屏幕的设备描述表,则默认情况下GDI调用中指定的逻辑坐标将被映射为屏幕坐标。
② 整窗口坐标
“整窗口坐标”以程序的整个窗口为基准,如标题栏、菜单、滚动条和窗口框都包括在内。整窗口坐标在Windows极少使用,但是如果用GetWindowDC获取设备描述表,GDI函数中的逻辑坐标就会转换为整个窗口坐标。
③ 客户区坐标
客户区坐标是最常使用的坐标系,点(0,0)是客户区的左上角。当使用GetDc或BeginPaint获取设备表述表时,GDI函数中的逻辑坐标就会默认地转换为客户区坐标。
④ ClientToScreen函数
BOOL ClientToScreen(HWND hWnd, // window handle for source coordinates LPPOINT lpPoint // pointer to structure containing screen
coordinates);
⑤ ScreenToClient函数
BOOL ScreenToClient(HWND hWnd, // window handle for source coordinates LPPOINT lpPoint // addre of structure containing coordinates);
⑥ GetWindowRect函数
BOOL GetWindowRect(HWND hWnd, // handle to window LPRECT lpRect // addre of structure for window coordinates);
说明:该函数用于获取屏幕坐标下的整个窗口的位置和大小。⒍ 视口和窗口 ① 视口
“视口”是基于设备坐标(像素)的。通常,视口和客户区相同,但是,如果用户已经用GetWindowDC或CreateDC获取了一个设备描述表,则视吉
林
化
工
学
院 第 60 页 教
案
用
纸
口也可以指整窗口坐标或者屏幕坐标。点(0,0)是客户区(或者整个窗口或屏幕)的左上角,x的值向右增加,y的值向下增加。
② 窗口
“窗口”是基于逻辑坐标的,逻辑坐标可以是像素、mm、英寸,或者用户想要的任何其他单位。
③ 转换公式
◆ 从窗口坐标转化为视口坐标:
xViewExtxViewport(xWindowxWinOrg)xViewOrg
xWinExtyViewExtyViewport(yWindowyWinOrg)yViewOrg
yWinExt其中,(xWindow,yWindow)是待转换的逻辑点;(xViewport,yViewport)是转换后的设备坐标点,更像客户区坐标;(xWinOrg,yWinOrg)是逻辑坐标的窗口原点;(xViewOrg,yViewOrg)是设备坐标的视口原点。在默认的设备描述表中,这两个点均被设置为(0,0),但是它们可以改变。这表明,逻辑点(xWinOrg,yWinOrg)总被映射为设备点(xViewOrg,yViewOrg)。如果窗口和视口的原点是默认值(0,0),则公式简化为:
xViewExtxViewportxWindow
xWinExtyViewExtyViewportyWindow
yWinExt在上公式中,(xWinExt,yWinExt)是逻辑坐标的窗口范围;(xViewExt,yViewExt)是设备坐标的窗口范围。在多数映射方式中,范围是映射方式所隐含的,不能够改变。每个范围自身没有什么意义,但是视口范围与窗口范围的比是逻辑单位转换为设备单位的换算因子。
例如,当用户设置MM_LOENGLISH映射方式时,Windows将xViewExt设置为某个像素而将xWinExt设置为xViewExt像素占据的一英寸内有几百像素的长度。比值给出了一英寸内有几百个像素的数值。
注意:范围可以为负,逻辑x轴上的不一定非得在向右时增加;逻辑y轴上的值不一定非得在向下时增加。
◆ 从视口坐标转换为窗口坐标
xWinExtxWindow(xViewportxViewOrg)xWinOrg
xViewExtyWinExtyWindow(yViewportyViewOrg)yWinOrg
yViewExt④ DPtoLP函数
BOOL DPtoLP(吉
林
化
工
学
院 第 61 页 教
案
用
纸
HDC hdc, // handle to device context LPPOINT lpPoints, // pointer to array of points int nCount // count of points);
⑤ LPtoDP函数
BOOL LPtoDP(HDC hdc, // handle of device context LPPOINT lpPoints, // array of points int nCount // count of points);
例如:GetClientRect(hwnd,&rect);DPtoLP(hdc,(PPOINT)&rect,2);⒎ 处理MM_TEXT ① 默认值
窗口原点:(0,0)可以改变 视口原点:(0,0)可以改变 窗口范围:(1,1)不可改变 视口范围:(1,1)不可改变 ② 简化公式
xViewportxWindowxWinOrgxViewOrg yViewportyWindowyWinOrgyViewOrg ③ SetViewportOrgEx函数
BOOL SetViewportOrgEx(HDC hdc, // handle of device context int X, // new x-coordinate of viewport origin int Y, // new y-coordinate of viewport origin LPPOINT lpPoint
// addre of structure receiving original origin);
说明:用于改变视口的原点。
④ SetWindowOrgEx函数
BOOL SetWindowOrgEx(HDC hdc, // handle of device context int X, // new x-coordinate of window origin int Y, // new y-coordinate of window origin LPPOINT lpPoint
// addre of structure receiving original origin);
说明:用于改变窗口的原点。
如果将视口原点改变为(xViewOrg,yViewOrg),则逻辑点(0,0)就会映射为设备点(xViewOrg,yViewOrg)。如果将窗口原点改变为吉
林
化
工
学
院 第 62 页 教
案
用
纸
(xWinOrg,yWinOrg),则逻辑点(xWinOrg,yWinOrg)将会映射为设备点(0,0)。
例如,假设客户区为cxClient个像素宽和cyClient个像素高。如果将逻辑点(0,0)定义为客户区的中心,则进行如下调用:
SetViewportOrgEx(hdc,cxClient/2,cyClient/2,NULL);则客户区的坐标系变成如下形状:
这时在客户区的左上角开始显示文本,需进行如下调用: TextOut(hdc,-cxClient/2,-cyClient/2,”HELLO”,5);
用以下调用代替上述调用:(效果相同)
SetWindowOrgEx(hdc,-cxClient/2,-cyClient/2,NULL)TextOut(hdc,-cxClient/2,-cyClient/2,”HELLO”,5);
一般情况下,不会将这两个函数一起用,除非知道这么做的结果: SetViewportOrgEx(hdc,cxClient/2,cyClient/2,NULL);SetWindowOrgEx(hdc,-cxClient/2,-cyClient/2,NULL);
⑤ GetViewportOrgEx函数
BOOL GetViewportOrgEx(HDC hdc, // handle of device context LPPOINT lpPoint
// addre of structure receiving the viewport origin);
⑥ GetWindowOrgEx函数
BOOL GetWindowOrgEx(HDC hdc, // handle of device context LPPOINT lpPoint
吉
林
化
工
学
院 第 63 页 教
案
用
纸
// addre of structure receiving the window origin);
⒏ “度量”映射方式
Windows包含5种以物理尺寸来表示逻辑坐标的映射方式。由于x轴和y轴的逻辑坐标映射为相同的物理单位,这些映射方式能使用户画出不变形的圆和矩形。
映射方式 逻辑单位 英寸 mm MM_LOENGLISH MM_LOMETRIC MM_HIENGLISH MM_TWIPS MM_HIMETRIC 0.01英寸 0.1mm 0.001英寸 1/1400英寸 0.01mm
0.01 0.00394 0.001 0.000694 0.000394
0.254 0.1 0.0254 0.0176 0.01 ① 默认值
窗口原点:(0,0)
可以改变 视口原点:(0,0)
可以改变 窗口范围:(?,?)不可改变 视口范围:(?,?)不可改变
对于MM_LOENGLISH,Windows计算的范围如下: xViewExt0.01英寸中的水平像素数
xWinExtyViewExt0.01英寸中的垂直像素数
yWinExt例如:假设Windows 98使用96 dpi的系统字体,这样对MM_LOENGLISH来说,96除以100的比值是0.01英寸装像素数。对MM_LOMETRIC来说,96除以254的比值是0.1mm中的像素数。
Windows 98下的映射方式: 映射方式 视口范围(x,y)窗口范围(x,y)
MM_LOMETRIC MM_HIMETRIC MM_LOENGLISH MM_HIENGLISH MM_TWIPS
(96,96)(96,96)(96,96)(96,96)(96,96)
(254,-254)(2540,-2540)(100,-100)(1000,-1000)(1440,-1440)
Windows NT下的映射方式: 映射方式 视口范围(x,y)
MM_LOMETRIC MM_HIMETRIC MM_LOENGLISH MM_HIENGLISH MM_TWIPS
(1024,-768)(1024,-768)(1024,-768)(1024,-768)(1024,-768)
窗口范围(x,y)
(3200,2400)(32000,24000)(1260,945)(12598,9449)(18142,13606)
吉
林
化
工
学
院 第 64 页 教
案
用
纸
② 例子 例1:
SetMapMode(hdc,MM_LOENGLISH);TextOut(hdc,100,-100,”Hello”,5);
将把文本显示在距离客户区左边和上边各1英寸的地方。例2:
SetViewportOrgEx(hdc,0,cyClient,NULL);此时的坐标系如下图所示:
例3:
SetViewportOrgEx(hdc,cxClient/2,cyClient/2,NULL);此时的坐标系如下图所示:
例4:也可使用SetWindowOrgEx函数来改变(0,0)点,因为该函数的参数必须使用逻辑单位,因此需用DPtoLP函数转换为逻辑坐标。程序如下:
pt.x=cxClient;pt.y=cyClient;DPtoLP(hdc,&pt,1);SetWindowOrgEx(hdc,-pt.x/2,-pt.y/2,NULL);上面的代码将逻辑(0,0)点改变到客户区的中央。
吉
林
化
工
学
院
第 65 页 教
案
用
纸
⒐ “自作主张”映射方式
只有MM_ISOTROPIC和MM_ANISOTROPIC这两种映射方式可以改变视口和窗口范围,即可以改变Windows用来转换逻辑和设备坐标的换算因子。词“isotropic”的意思是“各向同性”;“anisotropic”的意思是“各向异性”。MM_ISOTROPIC使用相同的轴,x轴上的逻辑单位与y轴上的逻辑单位的物理尺寸相等。这对用户创建纵横比与显示比无关的图像是有很大帮助的。
MM_ISOTROPIC与度量映射方式之间的区别是,使用MM_ISOTROPIC,用户可以控制逻辑单位的物理尺寸。Windows程序完全可以通过调整窗口的大小和视口的范围来处理图像大小的变化。因此,不管窗口尺寸怎样变化,Windows程序都可以在绘图函数中使用相同的逻辑单位。
MM_TEXT和度量映射方式称为“全约束”映射方式,即用户不能改变窗口和视口的范围以及Windows将逻辑坐标换算为设备坐标的方法。
MM_ISOTROPIC是一种“半约束”的映射方式,Windows允许用户改变窗口和视口范围,但只是调整它们,以便x和y逻辑单位代表同样的物理尺寸。
MM_ANISOTROPIC映射方式是“无约束”的,用户可以改变窗口和视口范围,但是Windows不调整这些值。
① MM_ISOTROPIC映射方式
设置为MM_ISOTROPIC时,Windows使用与MM_LOMETRIC同样的窗口和视口范围。区别在于,用户可以调用SetWindowExtEx和SetViewportExtEx来根据自己的偏好改变范围了,然后,Windows将调整范围的值,以便两条轴上的逻辑单位有相同的物理距离。
例如:假设用户想要一个“传统的”单象限虚拟坐标系,其中(0,0)在客户区的左下角,宽度和高度的范围都是0~32767,并且希望x和y轴的单位具有同样的物理尺寸。程序如下:
SetMapMode(hdc,MM_ISOTROPIC);SetWindowExtEx(hdc,32767,32767,NULL);SetViewportExtEx(hdc,cxClient,-cyClient,NULL);SetViewportOrgEx(hdc,0,cyClient,NULL);注意:如果其后用GetWindowExtEx和GetViewportExtEx 函数获得了窗口和视口的范围,可以发现,它们并不是先前指定的值。Windows将根据显示设备的纵横比来调整范围,以便两条轴上的逻辑单位表示相同的物理尺寸。
② MM_ANISOTROPIC:根据需要放缩图像
在MM_ANISOTROPIC映射方式下,Windows不对用户所设置的值进行调整,即不需要维持正确的纵横比。
例1:下面的代码将(0,0)设置为客户区的左下角,x轴和y都为0~32767。
SetMapMode(hdc,MM_ANISOTROPIC);SetWindowExtEx(hdc,32767,32767,NULL);吉
林
化
工
学
院
第 66 页 教
案
用
纸
SetViewportExtEx(hdc,cxClient,-cyClient,NULL);SetViewportOrgEx(hdc,0,cyClient,NULL);与MM_ISOTROPIC方式下,相似的代码导致客户区的一部分在轴的范围之外。但是对于MM_ANISOTROPIC,不论其尺度多大,客户的右上角总是(32767,32767)。如果客户区不是正方形的,则逻辑x和y的单位具有不同的物理尺度。
例2:
SetMapMode(hdc,MM_ANISOTROPIC);SetWindowExtEx(hdc,1000,1000,NULL);SetViewportExtEx(hdc,cxClient/2,-cyClient/2,NULL);SetViewprotOrgEx(hdc,cxClient/2,cyClient/2,NULL);例3:
另一种使用MM_ANISOTROPIC的方法是将x和y轴的单位固定,但其值不相等,程序如下:
SetMapMode(hdc,MM_ANISOTROPIC);SetWindowExtEx(hdc,1,1,NULL);SetViewportExtEx(hdc,cxChar,cyChar,NULL);TextOut(hdc,3,2,TEXT(“Hello”),5);
在距离客户区左边三个字符,上边二个字符处显示文本。例4:
当用户第一次设置MM_ANISOTROPIC映射方式时,它总是继承前面所设置的映射方式的范围,这会很方便。
SIZE size;SetMapMode(hdc,MM_LOENGLISH);SetMapMode(hdc,MM_ANISOTROPIC);GetViewportExtEx(hdc,&size);SetViewportExtEx(hdc,size.cx,-size.cy,NULL);⒑ WHATSIZE程序片段
void Show(HWND hwnd, HDC hdc, int xText, int yText, int iMapMode,TCHAR * szMapMode){
TCHAR szBuffer [60];
RECT rect;
SaveDC(hdc);
SetMapMode(hdc, iMapMode);
GetClientRect(hwnd, &rect);
DPtoLP(hdc,(PPOINT)&rect, 2);
RestoreDC(hdc,-1);
TextOut(hdc, xText, yText, szBuffer,wsprintf(szBuffer, TEXT(“%-20s %7d %7d %7d %7d”), szMapMode,rect.left, rect.right, rect.top, rect.bottom));}
吉
林
化
工
学
院 第 67 页 教
案
用
纸
LRESULT CALLBACK WndProc(HWND hwnd, UINT meage, WPARAM wParam, LPARAM lParam){
static TCHAR szHeading [] =
TEXT(“Mapping Mode
Left
Right
Top Bottom”);
static TCHAR szUndLine [] =
TEXT(“------------
----
-----
---------”);
static int
cxChar, cyChar;
HDC
hdc;
PAINTSTRUCT ps;
TEXTMETRIC
tm;
switch(meage)
{
case WM_CREATE:
hdc = GetDC(hwnd);
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
GetTextMetrics(hdc, &tm);
cxChar = tm.tmAveCharWidth;
cyChar = tm.tmHeight + tm.tmExternalLeading;
ReleaseDC(hwnd, hdc);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
SetMapMode(hdc, MM_ANISOTROPIC);
SetWindowExtEx(hdc, 1, 1, NULL);
SetViewportExtEx(hdc, cxChar, cyChar, NULL);
TextOut(hdc, 1, 1, szHeading, lstrlen(szHeading));
TextOut(hdc, 1, 2, szUndLine, lstrlen(szUndLine));
Show(hwnd, hdc, 1, 3, MM_TEXT,TEXT(“TEXT(pixels)”));
Show(hwnd, hdc, 1, 4, MM_LOMETRIC, TEXT(“LOMETRIC(.1 mm)”));
Show(hwnd, hdc, 1, 5, MM_HIMETRIC, TEXT(“HIMETRIC(.01 mm)”));
Show(hwnd, hdc, 1, 6, MM_LOENGLISH, TEXT(“LOENGLISH(.01 in)”));
Show(hwnd, hdc, 1, 7, MM_HIENGLISH, TEXT(“HIENGLISH(.001 in)”));
Show(hwnd, hdc, 1, 8, MM_TWIPS,TEXT(“TWIPS(1/1440 in)”));
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMeage(0);
return 0;
}
return DefWindowProc(hwnd, meage, wParam, lParam);} 吉
林
化
工
学
院 第 68 页