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