GDI+學(xué)習(xí)筆記之GDI+環(huán)境初始化 收藏
作者:朱金燦
來(lái)源:http://blog.csdn.net/clever101/
盡管以前接觸過(guò)一下GDI+,但決心從現(xiàn)在開(kāi)始系統(tǒng)學(xué)習(xí)GDI+,所用的教材為《精通GDI編程》。在VS 2010以下版本的VS 編譯器使用GDI+都需要對(duì)GDI+環(huán)境進(jìn)行初始化操作(VS 2010中的MFC 10依賴GDI+,故不用初始化)。
VS 2003、VS 2005和VS 2008的GDI+環(huán)境初始化操作步驟一樣。
在應(yīng)用程序類添加一個(gè)保護(hù)權(quán)限的數(shù)據(jù)成員:
view plaincopy to clipboardprint?
ULONG_PTR m_gdiplusToken;
ULONG_PTR m_gdiplusToken;
在應(yīng)用程序類的實(shí)現(xiàn)文件包含gdi+的頭文件:
view plaincopy to clipboardprint?
#include <GdiPlus.h>
#include <GdiPlus.h>
在工程附加庫(kù)加上:GdiPlus.lib
然后在應(yīng)用程序類的InitInstance加上下面初始化代碼:
view plaincopy to clipboardprint?
BOOL C***App::InitInstance()
{
Gdiplus::GdiplusStartupInput StartupInput;
GdiplusStartup(&m_gdiplusToken,&StartupInput,NULL);
}
BOOL C***App::InitInstance()
{
Gdiplus::GdiplusStartupInput StartupInput;
GdiplusStartup(&m_gdiplusToken,&StartupInput,NULL);
}
上面代碼的作用是初始化GDI+資源。
在應(yīng)用程序類的InitInstance加上下面代碼:
view plaincopy to clipboardprint?
int C***App::ExitInstance()
{
// TODO: 在此添加專用代碼和/或調(diào)用基類
Gdiplus::GdiplusShutdown(m_gdiplusToken);
return __super::ExitInstance();
}
int C***App::ExitInstance()
{
// TODO: 在此添加專用代碼和/或調(diào)用基類
Gdiplus::GdiplusShutdown(m_gdiplusToken);
return __super::ExitInstance();
}
上面代碼的作用是銷毀GDI+資源。
VC 6.0中使用GDI+庫(kù),請(qǐng)參考這篇文章:在VC6.0中使用GDI+的兩種辦法
現(xiàn)在測(cè)試一下我們初始化GDI+環(huán)境是否成功。我們使用GDI+的類接口在視圖客戶區(qū)繪制一個(gè)字符串,具體代碼如下:
view plaincopy to clipboardprint?
CDC *pDC = pView->GetDC();
Gdiplus::Graphics graphics(pDC->m_hDC);
Gdiplus::Pen pen(Gdiplus::Color(255,0,0,255));
Gdiplus::SolidBrush brush(Gdiplus::Color(255,0,0,255));
Gdiplus::FontFamily fontfm(L"宋體");
Gdiplus::Font font(&fontfm,24,Gdiplus::FontStyleRegular,Gdiplus::UnitPixel);
CRect rt;
pView->GetClientRect(&rt);
Gdiplus::PointF pointF(rt.Width()/2,rt.Height()/2);
graphics.DrawString(L"GDI+程序示意",-1,&font,pointF,&brush);
graphics.ReleaseHDC(pDC->m_hDC);
pView->ReleaseDC(pDC);
CDC *pDC = pView->GetDC();
Gdiplus::Graphics graphics(pDC->m_hDC);
Gdiplus::Pen pen(Gdiplus::Color(255,0,0,255));
Gdiplus::SolidBrush brush(Gdiplus::Color(255,0,0,255));
Gdiplus::FontFamily fontfm(L"宋體");
Gdiplus::Font font(&fontfm,24,Gdiplus::FontStyleRegular,Gdiplus::UnitPixel);
CRect rt;
pView->GetClientRect(&rt);
Gdiplus::PointF pointF(rt.Width()/2,rt.Height()/2);
graphics.DrawString(L"GDI+程序示意",-1,&font,pointF,&brush);
graphics.ReleaseHDC(pDC->m_hDC);
pView->ReleaseDC(pDC);
效果圖如下:
使用GDI+一些注意事項(xiàng):
1.在DLL中使用GDI+庫(kù),只需要包含GdiPlus.h和GdiPlus.lib,初始化GDI+環(huán)境的工作只需要在主調(diào)用程序做,否則在DLL初始化代碼中初始化GDI+環(huán)境容易發(fā)生DLL重入的錯(cuò)誤(以前我犯過(guò)這樣的錯(cuò)誤)。
2.GDI+接口參數(shù)使用的是unicode字符集,因?yàn)檎{(diào)用任何GDI+類接口時(shí)其字符串參數(shù)都必須確保是unicode字符。在多字節(jié)字符集環(huán)境下開(kāi)發(fā)常量字符串可以通過(guò)L宏轉(zhuǎn)換,變量多字節(jié)字符轉(zhuǎn)unicode字符可以使用Windows API函數(shù)MultiByteToWideChar或ATL的A2W宏。
3. GDI+的對(duì)象和GDI句柄一樣,同樣會(huì)占用資源,一次使用過(guò)多的GDI+的對(duì)象甚至?xí)l(fā)生程序崩潰的現(xiàn)象。因此必須隨時(shí)將不必要的GDI+的對(duì)象占用的資源釋放掉,如上例的:graphics.ReleaseHDC(pDC->m_hDC)。
本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/clever101/archive/2010/12/08/6063670.aspx
作者:朱金燦
來(lái)源:http://blog.csdn.net/clever101/
我發(fā)現(xiàn)使用GDI+來(lái)制作畫(huà)圖工具的調(diào)色板極為方便(這個(gè)工作如果讓GDI來(lái)做不知要寫(xiě)多少代碼)。下面我們學(xué)習(xí)一下GDI+的線性漸變畫(huà)刷:LinearGradientBrush類的用法,具體代碼如下:
view plaincopy to clipboardprint?
CDC *pDC = pView->GetDC();
// 定義一個(gè)畫(huà)圖對(duì)象
Gdiplus::Graphics graphics(pDC->m_hDC);
// 獲取視圖客戶區(qū)大小
CRect rt;
pView->GetClientRect(&rt);
// 定義一個(gè)線性漸變畫(huà)刷,按紅黃藍(lán)綠的順序四種顏色漸變
LinearGradientBrush linGrBrush(Point(100,0),Point(100,rt.Height()/2),Color(255,255,0,0),Color(255,0,0,255));
Color colors[] = {
Color(255, 255, 0, 0), // red
Color(255, 255, 255, 0), //yellow
Color(255, 0, 0, 255), // blue
Color(255, 0, 255, 0)}; // green
REAL positions[] = {
0.0f,
0.33f,
0.66f,
1.0f};
linGrBrush.SetInterpolationColors(colors, positions,4);
// 填充指定區(qū)域矩形
graphics.FillRectangle(&linGrBrush,rt.Width()/2,0,80,rt.Height()/2);
CDC *pDC = pView->GetDC();
// 定義一個(gè)畫(huà)圖對(duì)象
Gdiplus::Graphics graphics(pDC->m_hDC);
// 獲取視圖客戶區(qū)大小
CRect rt;
pView->GetClientRect(&rt);
// 定義一個(gè)線性漸變畫(huà)刷,按紅黃藍(lán)綠的順序四種顏色漸變
LinearGradientBrush linGrBrush(Point(100,0),Point(100,rt.Height()/2),Color(255,255,0,0),Color(255,0,0,255));
Color colors[] = {
Color(255, 255, 0, 0), // red
Color(255, 255, 255, 0), //yellow
Color(255, 0, 0, 255), // blue
Color(255, 0, 255, 0)}; // green
REAL positions[] = {
0.0f,
0.33f,
0.66f,
1.0f};
linGrBrush.SetInterpolationColors(colors, positions,4);
// 填充指定區(qū)域矩形
graphics.FillRectangle(&linGrBrush,rt.Width()/2,0,80,rt.Height()/2);
效果如下:
這個(gè)線性漸變畫(huà)刷很簡(jiǎn)單,就是按垂直方向(即y軸方向)漸變的。我感興趣的是畫(huà)刷的兩個(gè)參數(shù)Point(100,0),Point(100,rt.Height()/2),書(shū)上介紹的起點(diǎn)的顏色和終點(diǎn)顏色的位置和要填充的矩形之間的關(guān)系是怎樣的?我們看到上面的畫(huà)刷的起點(diǎn)和終點(diǎn)的高度和要填充的矩形的高度是一樣的,都是rt.Height()/2。我們把畫(huà)刷的高度縮小為原來(lái)的一般,看看有什么效果,即定義為:
view plaincopy to clipboardprint?
LinearGradientBrush linGrBrush(Point(100,0),Point(100,rt.Height()/4),Color(255,255,0,0),Color(255,0,0,255));
LinearGradientBrush linGrBrush(Point(100,0),Point(100,rt.Height()/4),Color(255,255,0,0),Color(255,0,0,255));
效果圖如下:
我們發(fā)現(xiàn)上圖等于連續(xù)用兩個(gè)畫(huà)刷填充這個(gè)矩形。假如填充的目標(biāo)矩形的高度小于畫(huà)刷的高度,又會(huì)是怎樣的效果呢?代碼改為:
view plaincopy to clipboardprint?
LinearGradientBrush linGrBrush(Point(100,0),Point(100,rt.Height()/2),Color(255,255,0,0),Color(255,0,255,0));
Color colors[] = {
Color(255, 255, 0, 0), // red
Color(255, 255, 255, 0), //yellow
Color(255, 0, 0, 255), // blue
Color(255, 0, 255, 0)}; // green
REAL positions[] = {
0.0f,
0.33f,
0.66f,
1.0f};
linGrBrush.SetInterpolationColors(colors, positions,4);
// 填充指定區(qū)域矩形
graphics.FillRectangle(&linGrBrush,rt.Width()/2,0,80,rt.Height()/4);
LinearGradientBrush linGrBrush(Point(100,0),Point(100,rt.Height()/2),Color(255,255,0,0),Color(255,0,255,0));
Color colors[] = {
Color(255, 255, 0, 0), // red
Color(255, 255, 255, 0), //yellow
Color(255, 0, 0, 255), // blue
Color(255, 0, 255, 0)}; // green
REAL positions[] = {
0.0f,
0.33f,
0.66f,
1.0f};
linGrBrush.SetInterpolationColors(colors, positions,4);
// 填充指定區(qū)域矩形
graphics.FillRectangle(&linGrBrush,rt.Width()/2,0,80,rt.Height()/4);
效果圖如下:
我們看到這時(shí)矩形區(qū)域的填充只使用了畫(huà)刷的一部分。這時(shí)或許我們可以得出一個(gè)簡(jiǎn)單的結(jié)論:用畫(huà)刷填充多邊形區(qū)域,有點(diǎn)類似于鋪地磚,地磚好比畫(huà)刷,空地好比要填充的區(qū)域區(qū)域。
思考題:
線性漸變畫(huà)刷的起點(diǎn)和終點(diǎn)的坐標(biāo)值和要填充的矩形之間是什么關(guān)系?
本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/clever101/archive/2010/12/08/6063697.aspx