SetWindowExt And SetViewportExt,GetDeviceCaps

来源:互联网 发布:辐射4射击手感优化 编辑:程序博客网 时间:2024/06/05 01:12


//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); //以物理设备坐标原点为基础,以逻辑单位大小,画圆。



//默认方式下,物理/逻辑值是11关系,可换用。但使用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。


0 0
原创粉丝点击