//SetWindowExt设定窗口尺寸,SetViewportExt设定视口尺寸。
//窗口尺寸以逻辑单位计算,视口尺寸以物理单位计算。
//在窗口中显示一个与之限定的圆,并且会随着窗口大小的改变亦会跟着改变。
CRect rectClient; GetClientRect(rectClient); //获取物理设备大小(单位:像素) pDC->SetMapMode(MM_ANISOTROPIC); //设置映射模式 pDC->SetWindowExt(CSize(1000,1000)); //设备逻辑窗口大小(可能与物理窗口大小不一样) pDC->SetViewportExt(rectClient.right,-rectClient.bottom); //改变Y坐标方向,设置物理设备范围,为设定圆点作准备 pDC->SetViewportOrg(rectClient.right/2,rectClient.bottom/2); //设置物理设备坐标原点,当然是在上一行代码的基础之上 pDC->Ellipse(-500,-500,500,500); //以物理设备坐标原点为基础,以逻辑单位大小,画圆。
//默认方式下,物理/逻辑值是1:1关系,可换用。但使用SetWindowExt/SetViewportExt后两者不可混用。
所谓映射就是物理和逻辑的映射。使用GetClientRect方法后,获取到窗口的物理大小;然后再使用SetWindowExt,设置了窗口的逻辑大小,
与之相对应的是SetViewportExt,也就是说在这里作了一个映射。SetWindowExt中的第一个参数
cx
Specifies the x-extent (in logical units) of the window.X宽度(可以这么理解吗?)与 SetViewportExt中的第一个参数
Cx
Specifies the x-extent of the viewport (in device units).相对应起来。逻辑宽度和物理宽度映射,逻辑高度和物理高度映射。
这样,一旦映射关系确立之后,再使用后面的方法进一步的操作。
稍稍把其中的参数改变一下。
CRect rectClient; GetClientRect(rectClient); pDC->SetMapMode(MM_ANISOTROPIC); pDC->SetWindowExt(CSize(800,800)); pDC->SetViewportExt(rectClient.right,-rectClient.bottom); pDC->SetViewportOrg(rectClient.right/2,rectClient.bottom/2); pDC->Ellipse(-500,-500,500,500);
会发现,实现中的圆的轨迹会超出窗口。
只是把物理与逻辑之前的映射调整了一下。
CRect rectClient; GetClientRect(rectClient); pDC->SetMapMode(MM_ANISOTROPIC); pDC->SetWindowExt(CSize(500,500)); pDC->SetViewportExt(rectClient.right,-rectClient.bottom); pDC->SetViewportOrg(rectClient.right/2,rectClient.bottom/2); pDC->Ellipse(0,0,250,250);//右上 pDC->Ellipse(0,0,-250,-250);//左下
再调整一下参数,画出来的图你会发现,真正的成了二维坐标图。
CRect rectClient; GetClientRect(rectClient); pDC->SetMapMode(MM_ANISOTROPIC); pDC->SetWindowExt(CSize(1000,1000)); pDC->SetViewportExt(rectClient.right,-rectClient.bottom); pDC->SetViewportOrg(rectClient.left,rectClient.bottom); //设置窗口左下角为原点坐标 pDC->Ellipse(0,0,1000,1000);
CDC::GetDeviceCaps()物理长度与屏幕像素间的转换
作用:
读取DC的一些打印区域信息,主要是像素和英寸方面的数据.声明:
GetDeviceCaps(int )使用例子:
//所有像素数(使用显示屏的像素分辨率)
int pagecx=dc.GetDeviceCaps(HORZRES);
int pagecy=dc.GetDeviceCaps(VERTRES);//即每英寸点数(96dpi)
short cxInch = dc.GetDeviceCaps(LOGPIXELSX);
short cyInch = dc.GetDeviceCaps(LOGPIXELSY);// 计算一个设备单位等于多少0.1mm
double scaleX = 254.0 / (double)GetDeviceCaps(dc.m_hAttribDC,LOGPIXELSX);
double scaleY = 254.0 / (double)GetDeviceCaps(dc.m_hAttribDC, LOGPIXELSY);
说明:
主要用到的参数见例子中的:HORZRES,VERTRES,LOGPIXELSX,LOGPIXELSY.总的来说是为了方便控制打印或重画时的控制,如为了定制打印时,一般依据的是物理的长度,而不是像素,而DC一般是用像素的映射模式,所以需要一下转换,上面这个函数就为这种转换设计的.GDI中有一个函数是GetDeviceCaps(),可以获取一些关于设备的一些属性,如HORZSIZE/HORZRES/LOGPIXELSX等。
以上三者的关系通常满足:HORZSIZE = 25.4 * HORZRES/LOGPIXELSX (宽度mm为单位 = 25.4*水平像素数/每英寸像素数)
HORZSIZE为屏幕水平尺寸(定为度量尺寸,以mm计),HORZRES为水平的像素总数(定为像素大小,平时所说的屏幕分辨率,但在这不这么称呼。这里,分辨率定为“每英寸的像素数”),LOGPIXELSX为逻辑像素(假设的每英寸的像素数,并不是刚才所说的实际的“分辨率”)。因此HORZSIZE也称为逻辑宽度。
当我们选择“显示”属性里的大字体时,LOGPIXELSX(通常分为96dpi与120dpi)变大了,这样假设原来的字体为10磅,则原来的字体横向所占像素(实际所占的像素数)为10*(1/72)*LOGPIXELSX,现在LOGPIXELSX变大了,则字体所占像素也大了,因此看起来字体大了。如果HORZRES不变的话,则HORZSIZE应该变小。然后这是和Windows有关的,在16位OS中,HORZSIZE值是固定的。
发现HORZSIZE值与LOGPIXELSX的值也是不变的,如果改变HORZRES的话,则HORZSIZE会发生相应变化,但LOGPIXELSX不变,一直是96。
SetWindowExt And SetViewportExt,GetDeviceCaps
最新推荐文章于 2018-07-04 10:36:02 发布