如何使用Win32中新增的GDI對(duì)象——路徑
發(fā)表時(shí)間:2024-06-19 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]路徑是Win32中新增的一個(gè)GDI對(duì)象,下面先從概念上談起。 1 路徑的概念 在Windows 95/NT 這樣的Win32操作系統(tǒng)中,除了已有的位圖,畫(huà)筆,畫(huà)刷,字體,調(diào)色板和區(qū)域之外,還增加了一個(gè)新的GDI對(duì)象:路徑。路徑是可以被填充,畫(huà)出輪廓或同時(shí)被畫(huà)出輪廓并填充的一個(gè)或多個(gè)圖形。路徑的...
路徑是Win32中新增的一個(gè)GDI對(duì)象,下面先從概念上談起。
1 路徑的概念
在Windows 95/NT 這樣的Win32操作系統(tǒng)中,除了已有的位圖,畫(huà)筆,畫(huà)刷,字體,調(diào)色板和區(qū)域之外,還增加了一個(gè)新的GDI對(duì)象:路徑。路徑是可以被填充,畫(huà)出輪廓或同時(shí)被畫(huà)出輪廓并填充的一個(gè)或多個(gè)圖形。路徑的引入,大大地豐富了Windows的圖形功能,使得應(yīng)用程序可以方便地建立復(fù)雜區(qū)域,繪制和填充不規(guī)則圖形。這里說(shuō)的不規(guī)則圖形是指由直線和貝塞爾曲線組成的圖形(相對(duì)于矩形,多邊形,橢圓等規(guī)則圖形)。
2 路徑的使用
與其它原有的GDI對(duì)象不同的是,MFC類(lèi)庫(kù)沒(méi)有專(zhuān)門(mén)用一個(gè)C++類(lèi)來(lái)封裝路徑對(duì)象(或許在以后的版本中會(huì)得到支持)。有關(guān)路徑的定義和使用等各種操作都必須通過(guò)調(diào)用API函數(shù)(或CDC類(lèi)中對(duì)應(yīng)的成員函數(shù))來(lái)實(shí)現(xiàn)。
路徑的使用過(guò)程大致如下:
。1)調(diào)用BeginPath()函數(shù)開(kāi)始路徑定義;
。2)調(diào)用GDI繪圖函數(shù)來(lái)定義路徑;
在Win32中,可以用于定義路徑的GDI繪圖函數(shù)包括:
AngleArc Arc ArcTo Chord *CloseFigure
Ellipse *ExtTextOut *LineTo *MoveToEx Pie
*PolyBezier *PolyBezierTo PolyDraw *Polygon *Polyline
*PolyLineTo *PolyPolygon *PolyPolylin Rectangl RoundRect
*TextOut
其中,在Windows 95中只能使用上述帶*的GDI函數(shù)。
。3)調(diào)用EndPath()函數(shù)結(jié)束路徑定義;
完成路徑定義后,所定義的路徑即被同時(shí)選進(jìn)設(shè)備描述表,設(shè)備描述表中原有的路徑對(duì)象在調(diào)用BeginPath()函數(shù)開(kāi)始路徑定義時(shí)即被廢棄。
(4)使用路徑對(duì)象。
完成路徑定義工作之后,應(yīng)用程序便可以利用有關(guān)GDI函數(shù)來(lái)使用路徑,這些函數(shù)包括繪制路徑輪廓StrokePath(),填充路徑FillPath(),繪制輪廓并填充StrokeAndFillPath(),把路徑轉(zhuǎn)換成區(qū)域PathToRegion(),把路徑直線化FlattenPath(),提取路徑數(shù)據(jù)GetPath(),加寬路徑WidenPath()和設(shè)置裁剪路徑SelectClipPath()等。這些函數(shù)的具體使用方法可參閱有關(guān)的SDK文檔。
3 應(yīng)用舉例
路徑的引入為我們?cè)趹?yīng)用程序中定義復(fù)雜區(qū)域提供了極大的方便,而不再局限于直線和橢圓弧這兩種線形,這一點(diǎn)是很容易理解的。
另外,注意到在定義路徑時(shí)可以使用TextOut()和ExtTextOut()函數(shù),我們便可以在文字特色顯示方面巧妙地使用路徑,克服以往文字特顯對(duì)位圖操作的倚賴(lài),從而方便快捷地制作出堪與WPS和Word等文字處理軟件相媲美的“藝術(shù)漢字”來(lái)。
本文下面所提供的這個(gè)示例程序執(zhí)行后,在窗口中顯示出按正弦曲線起伏排列的“龍騰虎躍”五個(gè)楷體大字。窗口背景為灰色,文字前景則為一幅256色位圖,就好象是把彩圖剪成文字粘貼在窗口上一樣(見(jiàn)下圖)。下面具體說(shuō)明該示例程序的創(chuàng)建方法。
(1)啟動(dòng)VC++,創(chuàng)建一個(gè)單文檔應(yīng)用,項(xiàng)目名取為Path,其它選項(xiàng)保留原缺省設(shè)置。
(2)在CPathView類(lèi)中增加一個(gè)成員變量:
// PathView.h : interface of the CPathView class
……
class CPathView : public CView
{
……
// Implementation
public:
CFont m_fontKaiTi;
……
并在CPathView類(lèi)的構(gòu)造函數(shù)中創(chuàng)建該Cfont對(duì)象,在CPathView類(lèi)的析構(gòu)函數(shù)中撤消該Cfont對(duì)象:
// 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()函數(shù)中添加如下代碼:
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);
//檢取路徑數(shù)據(jù)
int nCount=pDC->GetPath(NULL,NULL,0);
CPoint* points=new CPoint[nCount];
BYTE* bytes=new BYTE[nCount];
pDC->GetPath(points,bytes,nCount);
//對(duì)路徑定義點(diǎn)按正弦曲線進(jìn)行變換
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);
//重建一個(gè)新的路徑
CPoint ptStart;
pDC->BeginPath();{
for(i=0;i< nCount;i++){>/p>
switch(bytes[i]){
//移動(dòng)當(dāng)前點(diǎn)位置
case PT_MOVETO:
pDC->MoveTo(points[i]);
ptStart=points[i];
break;
//畫(huà)直線
case PT_LINETO:
pDC->LineTo(points[i]);
break;
//畫(huà)貝塞爾曲線
case PT_BEZIERTO:
pDC->PolyBezierTo(points+i,3);
i=i+2;
break;
//畫(huà)貝塞爾曲線并封閉圖形
case PT_BEZIERTO PT_CLOSEFIGURE:
points[i+2]=ptStart;
pDC->PolyBezierTo(points+i,3);
i=i+2;
break;
//畫(huà)直線并封閉圖形
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);
//設(shè)置裁剪路徑
pDC->SetPolyFillMode(WINDING);
pDC->SelectClipPath(RGN_COPY);
//用位圖填充裁剪區(qū)域
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)編譯,連接,運(yùn)行該應(yīng)用程序。