SetWindowExt And SetViewportExt,GetDeviceCaps



//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。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值