设计一个矩形类rectangle_VC设计漂亮界面

vc++图形编程基础 转载

724ad50e8d20b3a76a2a3b9121cb8acd.png

1.2.2构造和析构CDC对象

void CMyView::MyFunction()

{.......

CRect rect;

CClientDC dc(this);

dc.GetClipBox(rect);

.............

}

or

void CMyView::MyFunction()

{.......

CRect rect;

CDC* pDC=GetDC();

pDC->GetClipBox(rect);

.......

ReleaseDC(pDC);

}

1.3设备环境中的坐标映射

显示器的逻辑尺寸和物理尺寸

设备坐标,逻辑坐标和物理坐标

映射模式:1.

MM_TEXT映射模式

*************************************************************************************************************

『VC++技术内幕』学习笔记(6)

第六篇:映射模式  在此篇之前我们已经学会了在窗口显示图形,更准确的说是在窗口指定位置显示图形或文字,我们使用的坐标单位是象素,称之为设备坐标。看下面语句:
pDC->Rectangle(CRect(0,0,200,200));
  画一个高和宽均为200个象素的方块,因为采用的是默认的MM_TEXT映射模式,所以在设备环境不一样时,画的方块大小也不一样,在1024*768的显示器上看到的方块会比640*480的显示器上的小(在不同分辨率下的屏幕象素,在WINDOWS程序设计一书中有示例程序可以获得,或者可以用GetClientRect函数获得客户区的矩形大小。在这里就不说了,大家只要知道就行了),在输出到打印机时也会有类似的情况发生。如何做才能保证在不同设备上得到大小一致的方块或者图形、文字呢?就需要我们进行选择模式映射,来转换设备坐标和逻辑坐标。
Windows提供了以下几种映射模式:
MM_TEXT
MM_LOENGLISH
MM_HIENGLISH
MM_LOMETRIC
MM_HIMETRIC
MM_TWIPS
MM_ISOTROPIC
MM_ANISOTROPIC
下面分别讲讲这几种映射模式:
MM_TEXT:
  默认的映射模式,把设备坐标被映射到象素。x值向右方向递增;y值向下方向递增。坐标原点是屏幕左上角(0,0)。但我们可以通过调用CDC的SetViewprotOrg和SetWindowOrg函数来改变坐标原点的位置看下面两个例子:
//************************************************
// 例子6-1
void CMyView::OnDraw(CDC * pDC)
{
pDC->Rectangle(CRect(0,0,200,200));//全部采用默认画一个宽和高为200象素的方块
}
//**************************************************
// 例子6-2
void CMyView::OnDraw(CDC * pDC)
{
pDC->SetMapMode(MM_TEXT);//设定映射模式为MM_TEXT
pDC->SetWindowOrg(CPoint(100,100));//设定逻辑坐标原点为(100,100)
pDC->Rectangle(CRect(100,100,300,300));//画一个宽和高为200象素的方块
}  这两个例子显示出来的图形是一样的,都是从屏幕左上角开始的宽和高为200象素的方块,可以看出例子2将逻辑坐标(100,100)映射到了设备坐标(0,0)处,这样做有什么用?滚动窗口使用的就是这种变换。

固定比例映射模式:MM_LOENGLISH、MM_HIENGLISH、MM_LOMETRIC、MM_HIMETRIC、MM_TWIPS这一组是Windows提供的重要的固定比例映射模式。
它们都是x值向右方向递增,y值向下递减,并且无法改变。它们之间的区别在于比例因子见下:(我想书上P53页肯定是印错了,因为通过程序实验x值向右方向也是递增的)

MM_LOENGLISH 0.01英寸
MM_HIENGLISH 0.001英寸
MM_LOMETRIC 0.1mm
MM_HIMETRIC 0.01mm
MM_TWIPS 1/1440英寸 //应用于打印机,一个twip相当于1/20磅,一磅又相当于1/72英寸。看例3

//**************************************************
// 例子6-3
void CMyView::OnDraw(CDC * pDC)
{
pDC->SetMapMode(MM_HIMETRIC);//设定映射模式为MM_HIMETRIC
pDC->Rectangle(CRect(0,0,4000,-4000));//画一个宽和高为4厘米的方块
}
  还有一种是可变比例映射模式,MM_ISOTROPIC、MM_ANISOTROPIC。用这种映射模式可以做到当窗口大小发生变化时图形的大小也会相应的发生改变,同样当翻转某个轴的伸展方向时图象也会以另外一个轴为轴心进行翻转,并且我们还可以定义任意的比例因子,怎么样很有用吧。
MM_ISOTROPIC、MM_ANISOTROPIC两种映射模式的区别在于MM_ISOTROPIC模式下无论比例因子如何变化纵横比是1:1而M_ANISOTROPIC模式则可以纵横比独立变化。让我们看例子4

//**************************************************
// 例子6-4
void CMy002View::OnDraw(CDC* pDC)
{
CRect rectClient; //
GetClientRect(rectClient);//返回客户区矩形的大小
pDC->SetMapMode(MM_ANISOTROPIC);//设定映射模式为MM_ANISOTROPIC
pDC->SetWindowExt(1000,1000);
pDC->SetViewportExt (rectClient.right ,-rectClient.bottom );
//用SetWindowExt和SetViewportExt函数设定窗口为1000逻辑单位高和1000逻辑单位宽
pDC->SetViewportOrg(rectClient.right/2,rectClient.bottom/2 );//设定逻辑坐标原点为窗口中心
pDC->Ellipse(CRect(-500,-500,500,500));//画一个撑满窗口的椭圆。
// TODO: add draw code for native data here
}
怎么样,屏幕上有一个能跟随窗口大小改变而改变的椭圆。把 pDC->SetMapMode(MM_ANISOTROPIC);这句改为pDC->SetMapMode(MM_ISOTROPIC)会怎样?大家可以试试。那还有一个问题就是上例的比例因子是多少呢?看下面公式(注意是以例子4为例的)
x比例因子=rectClient.right/1000 //视窗的宽除以窗口范围
y比例因子=-rectClient.bottom/1000 //视窗的高除以窗口范围
  从Windows的鼠标消息可以获得鼠标指针的当前坐标值(point.x和point.y)此坐标值是设备坐标。
很多MFC库函数尤其是CRect的成员函数只能工作在设备坐标下。
还有我们有时需要利用物理坐标,物理坐标的概念就是现实世界的实际尺寸。
设备坐标-逻辑坐标-物理坐标之间如何进行转换便成为我们要考虑的一个问题,物理坐标和逻辑坐标是完全要我们自己来做的,但WINDOWS提供了函数来帮助我们转换逻辑坐标和设备坐标。
CDC的LPtoDP函数可以将逻辑坐标转换成设备坐标
CDC的DPtoLP函数可以将设备坐标转换成逻辑坐标
下面列出我们应该在什么时候使用什么样的坐标系一定要记住:
◎CDC的所有成员函数都以逻辑坐标为参数
◎CWnd的所有成员函数都以设备坐标为参数
◎区域的定义采用设备坐标
◎所有的选中测试操作应考虑使用设备坐标。
◎需要长时间使用的值用逻辑坐标或物理坐标来保存。因设备坐标会因窗口的滚动变化而改变。
用书上的例子作为以前几篇的复习,如果你能够独立完成它说明前面的内容已经掌握。另外有些东西是新的,我会比较详细的做出说明,例如客户区、滚动窗口等。

"可变比例”映射模式

#include <iostream> #include <string> using namespace std; struct CPoint { int x ; int y ; }; class CRectangle { private: const int id;//常量数据成员 static int total;//静态数据成员 const static string sclass; const static int f=1.0f; CPoint lefttop ; CPoint rightdown ; public: CRectangle( ); CRectangle( CPoint& lt, CPoint& rd ); CPoint GetLefttop() const { return lefttop; } CPoint GetRightdown() const { return rightdown; } void SetLefttop(CPoint & pt) { lefttop=pt; } void SetRightdown(CPoint & pt) { rightdown=pt; } int Getid() const { return id; } static int Gettotal() { return total; } int Area( ) const; int Perimeter( ) const; }; int CRectangle::total=0;//静态数据成员必须在的外部定义(正好一次)。 const string CRectangle::sclass="CRectangle"; CRectangle::CRectangle( ):id(++total) { lefttop.x=0; lefttop.y=0; rightdown.x=1; rightdown.y=1; } CRectangle::CRectangle( CPoint& lt, CPoint& rd ):id(++total) { lefttop = lt ; rightdown = rd ; } int CRectangle::Area( ) const { int wd= rightdown.x - lefttop.x ; int ht= rightdown.y - lefttop.y ; return wd * ht ; } int CRectangle::Perimeter( ) const { int wd= rightdown.x - lefttop.x ; int ht= rightdown.y - lefttop.y ; return 2 * ( wd + ht ) ; } int main() { CPoint lt, rd; cin >> lt.x >> lt.y; cin >> rd.x >> rd.y; CRectangle crt(lt,rd);//调用有参构造函数 CRectangle crt2;//调用默认构造函数 //创建常量对象 const CRectangle crt3(lt,rd); cout<<"当前创建的矩形个数为:"; cout<<CRectangle::Gettotal()<<endl; //返回矩形的左上和右下点 CPoint lt1=crt.GetLefttop(); CPoint lt2=crt.GetRightdown(); //显示矩形的坐标 cout<<crt.Getid()<<"号矩形的坐标是:"<<"("<<lt1.x<<","<<lt1.y<<"), "; cout<<"("<<lt2.x<<","<<lt2.y<<")"<<endl; //显示矩形的面积和周长 cout << "Area:"<<crt.Area( )<<endl; cout <<"Perimeter:"<<crt.Perimeter( )<<endl; //修改矩形的左上角点 cout<<"请输入矩形新的左上点坐标:"; cin>> lt.x>>lt.y; crt.SetLefttop(lt); lt1=crt.GetLefttop(); //显示修改后矩形的坐标 cout<<"矩形的坐标是:"<<"("<<lt1.x<<","<<lt1.y<<"), "; cout<<"("<<lt2.x<<","<<lt2.y<<")"<<endl; //显示修改后矩形的面积和周长 cout << "Area:"<<crt.Area( )<<endl; cout <<"Perimeter:"<<crt.Perimeter( )<<endl; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值