分享
 
 
 

如何使用Win32中新增的GDI对象——路径

王朝厨房·作者佚名  2007-01-04
窄屏简体版  字體: |||超大  

路径是Win32中新增的一个GDI对象,下面先从概念上谈起。

1 路径的概念

在Windows 95/NT 这样的Win32操作系统中,除了已有的位图,画笔,画刷,字体,调色板和区域之外,还增加了一个新的GDI对象:路径。路径是可以被填充,画出轮廓或同时被画出轮廓并填充的一个或多个图形。路径的引入,大大地丰富了Windows的图形功能,使得应用程序可以方便地建立复杂区域,绘制和填充不规则图形。这里说的不规则图形是指由直线和贝塞尔曲线组成的图形(相对于矩形,多边形,椭圆等规则图形)。

2 路径的使用

与其它原有的GDI对象不同的是,MFC类库没有专门用一个C++类来封装路径对象(或许在以后的版本中会得到支持)。有关路径的定义和使用等各种操作都必须通过调用API函数(或CDC类中对应的成员函数)来实现。

路径的使用过程大致如下:

(1)调用BeginPath()函数开始路径定义;

(2)调用GDI绘图函数来定义路径;

在Win32中,可以用于定义路径的GDI绘图函数包括:

AngleArc Arc ArcTo Chord *CloseFigure

Ellipse *ExtTextOut *LineTo *MoveToEx Pie

*PolyBezier *PolyBezierTo PolyDraw *Polygon *Polyline

*PolyLineTo *PolyPolygon *PolyPolylin Rectangl RoundRect

*TextOut

其中,在Windows 95中只能使用上述带*的GDI函数。

(3)调用EndPath()函数结束路径定义;

完成路径定义后,所定义的路径即被同时选进设备描述表,设备描述表中原有的路径对象在调用BeginPath()函数开始路径定义时即被废弃。

(4)使用路径对象。

完成路径定义工作之后,应用程序便可以利用有关GDI函数来使用路径,这些函数包括绘制路径轮廓StrokePath(),填充路径FillPath(),绘制轮廓并填充StrokeAndFillPath(),把路径转换成区域PathToRegion(),把路径直线化FlattenPath(),提取路径数据GetPath(),加宽路径WidenPath()和设置裁剪路径SelectClipPath()等。这些函数的具体使用方法可参阅有关的SDK文档。

3 应用举例

路径的引入为我们在应用程序中定义复杂区域提供了极大的方便,而不再局限于直线和椭圆弧这两种线形,这一点是很容易理解的。

另外,注意到在定义路径时可以使用TextOut()和ExtTextOut()函数,我们便可以在文字特色显示方面巧妙地使用路径,克服以往文字特显对位图操作的倚赖,从而方便快捷地制作出堪与WPS和Word等文字处理软件相媲美的“艺术汉字”来。

本文下面所提供的这个示例程序执行后,在窗口中显示出按正弦曲线起伏排列的“龙腾虎跃”五个楷体大字。窗口背景为灰色,文字前景则为一幅256色位图,就好象是把彩图剪成文字粘贴在窗口上一样(见下图)。下面具体说明该示例程序的创建方法。

(1)启动VC++,创建一个单文档应用,项目名取为Path,其它选项保留原缺省设置。

(2)在CPathView类中增加一个成员变量:

// PathView.h : interface of the CPathView class

……

class CPathView : public CView

{

……

// Implementation

public:

CFont m_fontKaiTi;

……

并在CPathView类的构造函数中创建该Cfont对象,在CPathView类的析构函数中撤消该Cfont对象:

// PathView.cpp : implementation of the CPathView class

……

CPathView::CPathView()

{

// TODO: add construction code here

m_fontKaiTi.CreateFont(200 , 0 , 0 , 0 , FW_BLACK ,

FALSE , FALSE , FALSE ,

GB2312_CHARSET ,

OUT_DEFAULT_PRECIS ,

CLIP_DEFAULT_PRECIS ,

DEFAULT_QUALITY ,

FIXED_PITCH | FF_MODERN,

"楷体_GB2312");

}

CPathView::~CPathView()

{

m_fontKaiTi.DeleteObject();

}

(3)在CPathView::OnDraw()函数中添加如下代码:

void CPathView::OnDraw(CDC* pDC)

{

……

// TODO: add draw code for native data here

RECT rect;

GetClientRect(&rect);

CFont* pOldFont=(CFont*)pDC->SelectObject(&m_fontKaiTi);

pDC->SetBkMode(TRANSPARENT);

//定义路径

pDC->BeginPath();{

pDC->TextOut(0,10,"龙",2);

pDC->TextOut(200,10,"腾",2);

pDC->TextOut(400,10,"虎",2);

pDC->TextOut(600,10,"跃",2); }

pDC->EndPath();

pDC->SelectObject(pOldFont);

//检取路径数据

int nCount=pDC->GetPath(NULL,NULL,0);

CPoint* points=new CPoint[nCount];

BYTE* bytes=new BYTE[nCount];

pDC->GetPath(points,bytes,nCount);

//对路径定义点按正弦曲线进行变换

int i;

for(i=0;i< nCount;i++)>/p>

points[i].y=points[i].y+(int)(80*sin(points[i].x

/300.*3.1415926)+100);

//重建一个新的路径

CPoint ptStart;

pDC->BeginPath();{

for(i=0;i< nCount;i++){>/p>

switch(bytes[i]){

//移动当前点位置

case PT_MOVETO:

pDC->MoveTo(points[i]);

ptStart=points[i];

break;

//画直线

case PT_LINETO:

pDC->LineTo(points[i]);

break;

//画贝塞尔曲线

case PT_BEZIERTO:

pDC->PolyBezierTo(points+i,3);

i=i+2;

break;

//画贝塞尔曲线并封闭图形

case PT_BEZIERTO|PT_CLOSEFIGURE:

points[i+2]=ptStart;

pDC->PolyBezierTo(points+i,3);

i=i+2;

break;

//画直线并封闭图形

case PT_LINETO|PT_CLOSEFIGURE:

pDC->LineTo(ptStart);

break;

}

}

pDC->CloseFigure();

}

pDC->EndPath();

//绘制窗口灰色背景

CBrush* pOldBrush=(CBrush*)(pDC->SelectStockObject(GRAY_BRUSH));

pDC->Rectangle(&rect);

pDC->SelectObject(pOldBrush);

//设置裁剪路径

pDC->SetPolyFillMode(WINDING);

pDC->SelectClipPath(RGN_COPY);

//用位图填充裁剪区域

CBitmap bmp;

CBitmap* pBmpOld;

bmp.LoadBitmap(IDB_BMP);

CDC dcMem;

dcMem.CreateCompatibleDC(pDC);

pBmpOld=dcMem.SelectObject(&bmp);

pDC->StretchBlt(0,0,rect.right,rect.bottom,

&dcMem,0,0,600,100,SRCCOPY);

dcMem.SelectObject(pBmpOld);

dcMem.DeleteDC();

bmp.DeleteObject();

}

(4)在资源中添加文字前景位图,其ID为IDB_BMP。

(5)编译,连接,运行该应用程序。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有