VC++ .Net 实例学习
生活随笔
收集整理的這篇文章主要介紹了
VC++ .Net 实例学习
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
VC++.NET中添加由C#編譯的DLL引用的方法
http://blog.csdn.net/much0726/article/details/4986627關于VC.NET的資料網絡上確實非常少,除了一些MSDN上的資料和英文資料就沒有了,查找引用DLL文件的
方法都找不到,DLL文件是有C#編譯的,是托管模塊,即.netModule ,如果敢興趣可以查查。添加托管
的DLL文件和C#中的方法是一樣的:
1.打開項目,選擇項目右鍵菜單中的引用。
2.通用屬性->框架和引用,添加新引用就可以了。
注意,在項目中不要使用:
#using "dll的絕對路徑"
using namespace 命名空間
這樣會引起引用沖突,而且這樣的做法也是不對的,在調用DLL的方法中會提示為導入的DLL引用模塊等
錯誤提示信息。
小結
VC.net比較也是托管語言,使用CLR公共語言庫編譯,因此也是需要FRAMEWORK支持的,但是本身有是支
持系統庫文件的調用USER32.DLL等,因此熟悉C#的人想開發類似MFC或者WIN32程序的時候VC.Net倒是挺
適合的。畢竟C#調用API挺麻煩的。
========
VC++和VC++.NET中與圖像處理有關的幾個概念、結構和類
http://blog.csdn.net/okaimee/article/details/5559064 ?最近一直在看VC++有關圖像處理方面的書,終于把以前一直混淆的幾個概念、結構和類弄清楚了,
特整理如下。如有錯誤,請大家批評指正,不勝感激。下一步想好好學習學習OpenCV,希望也能總結點
東西。
一、DDB與DIB位圖
一個Windows的位圖實際上是一些和顯示像素相對應的位陣列,它有兩種類型:一種稱之為GDI
(Graphic Device Interface)位圖,另一種是DIB位圖(Device-Independent Bitmap)。
GDI位圖包含了一種和Windows的GDI模塊有關的Windows數據結構,該數據結構是與設備有關的,故
此位圖又稱為DDB位圖(Device-Dependent Bitmap)。當用戶的程序取得位圖數據信息時,其位圖顯示方
式視顯示卡而定。由于GDI位圖的這種設備依賴性,當位圖通過網絡傳送到另一臺PC,很可能就會出現問
題。
DIB比GDI位圖有很多編程優勢,例如它自帶顏色信息,從而使調色板管理更加容易。且任何運行
Windows的機器都可以處理DIB,并通常以后綴為.BMP的文件形式被保存在磁盤中或作為資源存在于程序
的EXE或DLL文件中。
二、CBitmap類、BITMAP結構?
CBitmap類繼承自CGdiObject,是封裝了圖形設備接口(GDI)的位圖,提供成員函數來操縱位圖。
要使用一個CBitmap對象,構造該對象,用初始化成員函數之一把一個位圖句柄連接到該對象,然后調用
該對象的成員函數。
CBitmap類主要用于處理DDB位圖,封裝了與DDB位圖操作函數相關的數據結構和操作函數。結構體
BITMAP定義了DDB位圖的類型、寬度、高度、顏色和像素值,其定義如下:
typedef struct _tagBITMAP ? ? ? ?
{
? LONG ? ? ? ? ?bmType ; ? ? ? ? ? ? ? ? ? ? ?// set to 0 ? ? ? ?
? LONG ? ? ? ? ?bmWidth ; ? ? ? ? ? ? ? ? ? ? // width in pixels ? ? ? ?
? LONG ? ? ? ? ?bmHeight ; ? ? ? ? ? ? ? ? ? // height in pixels ? ? ? ?
? LONG ? ? ? ? ?bmWidthBytes ; ? ? ? ? ? ? ? ?// width of row in bytes ? ? ? ?
? WORD ? ? ? ? bmPlanes ; ? ? ? ? ? ? ? ? ? ?// number of color planes ? ? ? ?
? WORD ? ? ? ? bmBitsPixel ; ? ? ? ? ? ? ? ? // number of bits per pixel ? ? ? ?
? LPVOID ? ? ? bmBits ; ? ? ? ? ? ? ? ? ? ? ? ? ? ? // pointer to pixel bits ? ? ? ?
} ? ? ? ?
BITMAP, * PBITMAP ;
而CBitmap的LoadBitmap、CreateCompatibleBitmap、SetBitmapBits、GetBitmap等成員函數則定義
了對DDB位圖的裝載、創建、設定位值和屬性查詢等操作。
創建或裝入內存的位圖必須用CDC::SelectObject函數來將其選入設備上下文中,然后用CDC的
BitBlt或StretchBlt函數顯示出來,這兩個函數的原型如下:
BOOL BitBlt(int x, int y, int nWith, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD?
dwRop);
該函數把源設備上下文中的位圖復制到本身的設備上下文中,兩個設備下下文可以是內存設備下下
文,也可以是同一個設備上下文。
三、Image類和Bitmap類
在VC++.NET中,GDI+的Image類封裝了對BMP、GIF、JPEG、PNG、TIFF、WMF(Windows元文件)和EMF(
增強WMF)圖像文件的調入、顯示、格式轉換以及簡單處理(如縮放、旋轉、拉伸等)的功能。而Bitmap類
(注意不是結構BITMAP)是從Image類繼承的一個圖像(另一個從Image繼承的類是Metafile類),它封
裝了Windows位圖操作的常用功能。例如,Bitmap::SetPixel和Bitmap::GetPixel分別用來對位圖進行讀
寫像素操作,從而可以為圖像的柔化和銳化處理提供一種可能。這些功能和MFC的新類CImage功能基本一
樣,如果僅用于圖像的讀取與顯示,用Bitmap類或Image類是不錯的選擇,如果是做圖像處理,則CImage
可能更符合MFC程序員的編程習慣。
四、CImage類
CImage類是VC++.NET中MFC和ATL共享的新類,它能從外部磁盤中調入一個JPEG、GIF、BMP和PNG格式
的圖像文件加以顯示,而且這些文件格式可以相互轉換。
CImage既能處理DIB位圖也能處理非DIB位圖,但你可以僅用DIB位圖來Create或CImage::Load。你也
可以使用Attach把一個非DIB位圖連接給CImage對象,但你不能使用下列方法,這些方法僅支持DIB位圖
:GetBits、GetColorTable、GetMaxColorTable、Entries、GetPitch、GetPixelAddress、IsIndexed、
SetColorTable。要確定一個連接的位圖是否是一個DIB位圖,調用IsDibSection。
由于CImage在不同的Windows操作系統中其某些性能是不一樣的,因此在使用時要特別注意。例如,
CImage::PlgBlt和CImage::MaskBlt只能在 Windows NT 4.0 或更高版本中使用,但不能運行在Windows?
95/98 應用程序中。CImage::AlphaBlend和CImage::TransparentBlt也只能在 Windows 2000/98或其更
高版本中使用。即使在Windows 2000運行程序還必須將stdafx.h文件中的WINVER和_WIN32_WINNT的預定
義修改成0x0500才能正常使用。 CImage可以在MFC或ATL中使用。當使用CImage創建一個項目時,必須包
含atlimage.h文件。
CImage封裝了DIB(設備無關位圖)的功能,因而可以讓我們能夠處理每個位圖像素。
CImage提供了HBITMAP操作符,因此HBITMAP為參數的地方,都可以用CImage來替代。
五、傳統的VC++中的圖像處理方法與VC++.NET中的圖像處理方法
由于DIB圖不依賴于具體設備,因此可以用來永久性地保存圖象。DIB一般是以*.BMP文件的形式保存
在磁盤中的,有時也會保存在*.DIB文件中。運行在不同輸出設備下的應用程序可以通過DIB來交換圖象
。因而在數字圖象處理中會經常用到DIB位圖。DIB還可以用一種RLE算法來壓縮圖像數據,但一般來說
DIB是不壓縮的。
在VC++.net之前MFC未提供現成的類來封裝DIB,這給MFC用戶帶來很多不便。因為用戶要想使用DIB
,首先應該了解DIB的結構。
?
? ? 在內存中,一個完整的DIB由兩部分組成:一個BITMAPINFO結構和一個存儲像素陣列的數組。
BITMAPINFO描述了位圖的大小,顏色模式和調色板等各種屬性,其定義為
typedef struct tagBITMAPINFO {?
? ? BITMAPINFOHEADER bmiHeader;?
? ? RGBQUAD bmiColors[1]; //顏色表
} BITMAPINFO;
RGBQUAD結構用來描述顏色,其定義為
typedef struct tagRGBQUAD {
? BYTE ? ? rgbBlue; //藍色的強度
? BYTE ? ? rgbGreen; //綠色的強度
? BYTE ? ? rgbRed; //紅色的強度
? BYTE ? ? rgbReserved; //保留字節,為0
} RGBQUAD;
注意,RGBQUAD結構中的顏色順序是BGR,而不是平常的RGB。
BITMAPINFOHEADER結構包含了DIB的各種信息,其定義為
typedef struct tagBITMAPINFOHEADER{?
? DWORD ? ? biSize; //該結構的大小
? LONG ? ? biWidth; //位圖的寬度(以像素為單位)
? LONG ? ? biHeight; //位圖的高度(以像素為單位)
? WORD ? ? biPlanes; //必須為1
? WORD ? ? biBitCount //每個像素的位數(1、4、8、16、24或32)
? DWORD ? ? biCompression; //壓縮方式,一般為0或BI_RGB (未壓縮)
? DWORD ? ? biSizeImage; //以字節為單位的圖象大小(僅用于壓縮位圖)
? LONG ? ? biXPelsPerMeter; //以目標設備每米的像素數來說明位圖的水平分辨率
? LONG ? ? biYPelsPerMeter; //以目標設備每米的像素數來說明位圖的垂直分辨率
? DWORD ? ? biClrUsed; /*顏色表的顏色數,若為0則位圖使用由biBitCount指定的最大顏色數*/
? DWORD ? ? biClrImportant; //重要顏色的數目,若該值為0則所有顏色都重要
} BITMAPINFOHEADER;
與DDB不同,DIB的字節數組是從圖象的最下面一行開始的逐行向上存儲的,也即等于把圖象倒過來
然后在逐行掃描。另外,字節數組中每個掃描行的字節數必需是4的倍數,如果不足要用0補齊。
DIB可以存儲在*.BMP或*.DIB文件中。DIB文件是以BITMAPFILEHEADER結構開頭的,該結構的定義為
typedef struct tagBITMAPFILEHEADER {?
? WORD ? ? bfType; //文件類型,必須為“BM”
? DWORD ? ? bfSize; //文件的大小
? WORD ? ? bfReserved1; //為0
? WORD ? ? bfReserved2; //為0
? DWORD ? ? bfOffBits; //存儲的像素陣列相對于文件頭的偏移量
} BITMAPFILEHEADER;
緊隨該結構的是一個BITMAPINFOHEADER結構,然后是RGBQUAD結構組成的顏色表(如果有的話),文件
最后存儲的是DIB的像素陣列。
DIB的顏色信息儲存在自己的顏色表中,程序一般要根據顏色表為DIB創建邏輯調色板。在輸出一幅
DIB之前,程序應該將其邏輯調色板選入到相關的設備上下文中并實現到系統調色板中,然后再調用相關
的GDI函數(如::SetDIBitsToDevice或::StretchDIBits)輸出DIB。在輸出過程中,GDI函數會把DIB轉換
成DDB,這項工作主要包括以下兩步:將DIB的顏色格式轉換成與輸出設備相同的顏色格式;將DIB像素的
邏輯顏色索引轉換成系統調色板索引。
看到這么多結構,你是不是已經眼花繚亂了,然而更不幸的還在后面。以上說的DIB是Windows中的
DIB,還有一種DIB是OS/2 DIB,它和Windows DIB的主要區別是位圖信息結構(信息頭和顏色表結構)。
它們的圖像數據的存儲方式是完全一樣的。在OS/2 DIB中,與WIndows DIB的BITMAPFILEHEADER、
BITMAPINFOHEADER、RGBQUAD相對應的結構分別是BITMAPCOREHEADER、BITMAPCOREINFO、和RGBTRIPLE。
它們的定義分別如下:
typedef struct tagBITMAPCOREHEADER ?// bmch ? ? ? ?
{ ? ? ? ?
? DWORD ? ? ? ? bcSize ; ? ? ? ? ? ? ?// size of the structure = 12 ? ? ? ?
? WORD ? ? ? ? ?bcWidth ; ? ? ? ? ? ? // width of image in pixels ? ? ? ?
? WORD ? ? ? ? ?bcHeight ; ? ? ? ? ? // height of image in pixels ? ? ? ?
? WORD ? ? ? ? ?bcPlanes ; ? ? ? ? ? ?// = 1 ? ? ? ?
? WORD ? ? ? ? ?bcBitCount ; ? ? ? ? ?// bits per pixel (1, 4, 8, or 24) ? ? ? ?
} ? ? ? ?
BITMAPCOREHEADER, * PBITMAPCOREHEADER ;
typedef struct tagBITMAPCOREINFO ?// bmci
{ ? ? ? ?
? BITMAPCOREHEADER ? ? ?bmciHeader ; ? ? ? ? ? ? ? ? ?// core-header structure ? ? ? ?
? RGBTRIPLE ? ? ? ? ? ? bmciColors[1] ; ? ? ? ? ? ? ? // color table array ? ? ? ?
} ? ? ? ?
BITMAPCOREINFO, * PBITMAPCOREINFO ;
typedef struct tagRGBTRIPLE ?// rgbt ? ? ? ?
{ ? ? ? ?
? BYTE ? ? rgbtBlue ; ? ? ? // blue level ? ? ? ?
? BYTE ? ? rgbtGreen ; ? ? ?// green level ? ? ? ?
? BYTE ? ? rgbtRed ; ? ? ? ?// red level ? ? ? ?
} ? ? ? ?
RGBTRIPLE;
因此再操作之前你應該先根據BITMAPINFOHEADER的大小來判斷是哪一種DIB,然后再進行操作。
由于MFC未提供一個封裝好的易用的DIB類,用戶在使用DIB時將面臨繁重的Windows API編程任務。
不信你看看Microsoft提供的MFC的DibLook例程提就知道了。所以傳統的圖像處理方法一般都會把這些
Win32 SDK中的操作DIB位圖的APIs做一個封裝,作為一個通用的類來使用,以減少后續算法編寫中的編
程負擔。
VC++.NET提供了多種常用圖像文件格式(如BMP、TIF、GIF、JPEG與PNG等)的輸入/輸出模塊,ATL中
的CImage類極大地簡化了圖像數據的操作,因此VC++.NET中的圖像處理應以CImage為基礎。
現在市面上有一些冠名教用VC++.NET做圖像處理的書,但是編程方法還是老的一套,沒有跳出設備相
關位圖(DDB)與設備無關位圖(DIB)概念的條框,編程方法比較復雜、繁瑣、低效。用VC++.NET環境做圖像
處理,應該以CImage類為基礎,完全跳出DDB、DIB概念的條框,才能使得處理方法返樸歸真,大為簡化。
轉載自:http://conner-wang.spaces.live.com
========
實例解析C++/CLI中的接口與泛型
http://dev.yesky.com/msdn/285/3039285.shtml接口
某些時候,讓不相關的類分享一組公有成員,以便產生相同的行為,是非常有用的。一個最基本的
方法可能是通過一個公共的基類來定義它們,但這種方法太受局限,因為它要求這些類通過繼承而互相
關聯,另外,它們也許還有著各自的基類,且CLI類型只支持單一類繼承。
C++/CLI提供了一種方法,可利用多個類實現一組通用的功能,這就是我們通稱的"接口",而一個接
口則是一組成員函數的聲明。要注意,這些函數只是聲明,沒有定義,也就是說,一個接口定義了一個
由抽象函數組成的類型--這些函數實際上是純虛函數,且在適當的時候,這些函數由客戶類來實現。一
個接口可允許不相關的類用同一名稱和類型,實現同一功能,而無須要求這些類分享公共基類。在例1中
演示了怎樣定義一個接口。?
例1:
using namespace System;
public interface class ICollection
{
void Put(Object^ o); //隱式public abstract
Object^ Get(); //隱式public abstract
};
一個接口的定義看上去非常像一個類,除了用interface取代了ref或value,所有的函數都沒有函數
體,且均隱式為public和abstract。按照通常的約定,一個接口名帶有起始字母I,后再接一個大寫字母
。(接口類與接口結構是等價的。)與類相似,一個接口也能有public或private訪問可見性。
一個接口能有一個或多個"基接口",在這種情況下,它將繼承這些接口中的所有抽象函數,例如,
在例2中,接口I2顯式繼承自I1,而I3顯式繼承自I1與I2,并通過I2隱式繼承自I1。
例2:
interface class I1 { /* ... */ };
interface class I2 : I1 { /* ... */ };
interface class I3 : I1, I2 { /* ... */ };
一個類可像從基類繼承時那樣,來實現一個接口,見例3。
例3:
public ref class List : ICollection
{
public:
void Put(Object^ o)
{
// ...
}
Object^ Get()
{
// ...
}
// ...
};
一個類能實現一個以上的接口,在這種情況下,必須使用逗號來分隔接口列表,順序倒不是很重要
。當然,一個類在實現一個或多個接口時,也能顯式地帶有一個基類,在這種情況下,基類通常(但不
是必須)寫在最前面。
如果一個類實現了一個接口,但沒有定義接口中所有的函數,這個類就必須聲明為abstract。當然
了,任何從抽象類繼承而來的類也是抽象類,除非定義了之前的這些抽象函數。
========
實例解析C++/CLI之代理與事件
http://dev.yesky.com/msdn/77/2661077.shtml在C++/CLI中,代理是對函數進行包裝的對象;而事件是一種為客戶程序提供通知的類機制。?
在前幾篇文章中,已經多次演示了如果讓一個句柄在不同的時間,被引用至不同的對象,從而以更
抽象的方法來解決程序中的問題,但是,也能使用代理通過函數來達到同樣的效果;代理是包裝了函數
的一個對象,且對實例函數而言,也能通過特定的實例,與這些函數發生聯系。一旦一個代理包裝了一
個或多個函數,你就能通過代理來調用這些函數,而無須事先了解包裝了哪些函數。
請看例1中的代碼,在標號1中,定義一個代理類型Del,由于使用了上下文關鍵字delegate,所以有
點像函數的聲明,但與函數聲明不同的是,此處聲明的是一個代理類型Del的實例,其可包裝進任意接受
一個int類型作為參數并返回一個int值類型的函數(任意有效的參數列表及返回類型組合都是允許的)
。一旦定義了某種代理類型,它只能被用于包裝具有同樣類型的函數;代理類型可被定義在源文件中或
命名空間的范圍內,也能定義在類中,并可有public或private訪問控制屬性。
例1:
using namespace System;
ref struct A
{
static int Square(int i)
{
return i * i;
}
};
ref struct B
{
int Cube(int i)
{
return i * i * i;
}
};
/*1*/
delegate int Del(int value);
int main()
{
/*2*/ Del^ d = gcnew Del(&A::Square);
/*3*/ Console::WriteLine("d(10) result = {0}", d(10));
/*4*/ B^ b = gcnew B;
/*5*/ d = gcnew Del(b, &B::Cube);
/*6*/ Console::WriteLine("d(10) result = {0}", d(10));
}
靜態函數A::Square與實例函數B::Cube對Del來說,都具有相同的參數類型及返回類型,因此它們能
被包裝進同類型的代理中。注意,即使兩個函數均為public,當考慮它們與Del的兼容性時,它們的可訪
問性也是不相關的,這樣的函數也能被定義在相同或不同的類中,主要由程序員來選擇。
一旦定義了某種代理類型,就可創建此類型實例的句柄,并進行初始化或賦值操作,如標號2中所示
的靜態函數A::Square,及標號5中所示的實例函數B::Cube。(此處只是出于演示的目的,否則把Cube做
成實例函數沒有任何好處。)
創建一個代理實例涉及到調用一個構造函數,如果是在包裝一個靜態函數,只需傳遞進一個指向成
員函數的指針;而對實例函數而言,必須傳遞兩個參數:一個實例的句柄及指向實例成員函數的指針。
在初始化代理實例之后,就能間接地調用它們包裝的函數了,用法與直接調用原函數一樣,只不過
現在用的是代理實例名,如標號3與6,由包裝函數返回的值也是像直接調用函數時那樣獲得。如果一個
代理實例的值為nullptr,此時再試圖調用被包裝的函數,會導致System::NullReferenceException類型
異常。
以下是輸出:
d(10) result = 100
d(10) result = 1000
傳遞與返回代理
有時,把包裝好的函數傳遞給另一個函數,會非常有用,接受一方的函數并不知道會傳遞過來哪個
函數,并且它也無須關心,只需簡單地通過包裝好的代理,間接調用此函數就行了。
下面以集合中元素排序來說明,大多數時候,集合中元素排序所依據的規則,只在對某對元素進行
比較的方法上存在區別。如果在運行時提供進行比較的函數,一個排序過程就能用相應定義的比較函數
排出任意的順序,請看例2。
例2:
using namespace System;
ref struct StrCompare
{
static int CompareExact(String^ s1, String^ s2)
{
Console::WriteLine("Comparing {0} and {1} " "using CompareExact", s1, s2);
// ...
return 0;
}
static int CompareIgnoreCase(String^ s1, String^ s2)
{
Console::WriteLine("Comparing {0} and {1}" "using CompareIgnoreCase", s1, s2);
// ...
return 0;
}
};
delegate int Compare(String^ s1, String^ s2);
/*1*/
Compare^ FindComparisonMethod()
{
// ...
}
void Sort(Compare^ compare)
{
int result;
/*3*/ result = compare("Hello", "Hello");
/*4*/ result = compare("Hello", "HELLO");
/*5*/ result = compare("Hello", "Hell");
}
int main()
{
/*6*/ Sort(gcnew Compare(&StrCompare::CompareIgnoreCase));
/*7*/ Sort(FindComparisonMethod());
/*8*/ FindComparisonMethod()("Red", "RED");
}
Compare代理類型可對任意接受兩個String^參數并返回一個int結果的函數進行包裝,在此,有兩個
函數為StrCompare::CompareExact和StrCompare::CompareIgnoreCase。
在標號6中,創建了一個Compare代理類型的實例,用它來包裝StrCompare::CompareIgnoreCase,并
把此代理句柄傳遞給Sort函數,其將會利用比較函數進一步進行處理。
正如大家所看到的,Sort可接受一個代理類型的參數--而此參數可像其他函數參數一樣,可為傳值
、傳址、傳引用。
在標號7中,調用了FindComparisonMethod函數,其返回一個Del代理類型,接著在標號7及8中調用
了包裝過的函數。此處要重點說一下標號8:首先,FindComparisonMethod函數是被調用來獲取代理實例
--其常用于調用底層函數;其次,這兩個函數的調用操作符都有同等的優先級,所以它們從左至右調用
。
FindComparisonMethod函數中也用了一些邏輯用于確定到底需要包裝哪個函數,此處就未作詳細說
明了。
========
VC++.NET中使用GDI+創建特效字體
http://dev.yesky.com/msdn/338/2037838.shtml來自于微軟.NET技術的C++托管擴展所包含的GDI+技術功能十分強大,本文將介紹如何使用GDI+的畫
刷來繪制文本。
一、使用畫刷繪制文本的基本技術
本文所帶的例子程序允許用戶定義所要顯示的文本、字體尺寸、顯示文本所用的畫刷(網格畫刷或
漸變畫刷)以及繪制文本的顏色等。例子代碼下載:GDIPlusTextWithBrushes.zip
下面是GDI+中使用漸變畫刷或網格畫刷繪制文本的基本步驟:
1、 在控件的繪制(Paint)事件中添加一個事件處理函數。
在這個處理函數中進行繪制文本的相關處理,這樣控件才能正確地進行重繪。
2、 獲取一個圖形(Graphics)對象。
正如我們所熟悉的設備上下文一樣,圖形對象是NET封裝的一個繪制平面,例如,當在一個
PictureBox控件上進行繪制時,可以調用PictureBox::CreateGraphics方法來獲取一個Graphics對象,
并在控件上繪圖時使用這個圖形(Graphics)對象。互聯網上有很多例子都是這么做的,但是,有一個
問題是,這樣得到的Graphics對象不是永久對象,如果用戶從當前程序轉到另一個應用程序并再次返回
時,這個控件將無法正確地進行重繪。所以 ,要得當圖形對象應當使用傳遞給控件Paint方法的
PaintEventArgs對象中的Graphics對象,代碼如下所示:
private: System::Void picText_Paint(System::Object * sender,?
System::Windows::Forms::PaintEventArgs * e)
{
...
Graphics* g = e->Graphics;
3、實例化一個字體對象
在字體類的13個構造函數中,最基本的一個構造函數只需要你提供字體名及字體的大小。在下面的
例子中,創建了一個20點,"Times New Roman"類的常規字體:
using namespace System::Drawing;
...
Font* font = new Font(S"Times new Roman", 20, FontStyle::Regular);
4、測量將被繪制的文本尺寸
為了繪制文本需要使用Graphics::MeasureString方法來測量文本尺寸。可以使用
Graphics::MeasureString方法來完成這個任務。這個方法需要提供被測量的文本及字體對象,并返回
SizeF結構對象,這個結構包含了將要進行繪制文本的尺寸。
SizeF textSize = g->MeasureString(S"My Sample Text", font);
5、實例畫刷對象
可以使用各種各樣的畫刷進行繪制文本,包括網格畫刷、線性漸變畫刷、路徑漸變畫刷、實體畫刷
及紋理畫刷等,只是在創建各個不同的實例畫刷時傳遞的參數有一些小小的不同而已。對各種畫刷進行
探討不是本文的內容,在本文的實例中只使用兩種畫刷(網格畫刷及線性漸變畫刷)。
// HatchBrush example
Brush* brush = new HatchBrush(HatchStyle::Cross,
Color::Black, Color::Blue);?
// LinearGradientBrush example
RectangleF* rect = __nogc new RectangleF(PointF(0, 0), textSize);
brush= new LinearGradientBrush(*rect, Color::Black, Color::Blue,?
LinearGradientMode::ForwardDiagonal);
6、(選項)填充背景
為了使應用程序有特色,可以在繪制文本前對背景進行顏色填充,這有兩個標準的方法。較簡單的
方法是調用Graphics::Clear方法并定義將使用的顏色;但是有時需要更高級的控制,這時候需要使用
Graphics::FillRectange方法。
Graphics::FillRectange方法允許開發人員規定所選擇的畫刷對象并定義確切的矩形坐標位置。關
于畫刷對象,可以使用實例化的自定義畫刷或者是系統畫刷SystemBrushes,系統畫刷定義了若干屬性成
員,它們是實心畫刷,各自用來表現窗口的不同的元素,包括激活的邊框及標題條等。
// Use the Windows-defined color for controls?
// and explicitly state the rectangle coordinates
g->FillRectangle(SystemBrushes::Control, picText->Left, picText->Top,?
picText->Right - picText->Left, picText->Bottom - picText->Top);
// Color the entire drawing surface using White
g->Clear(Color::White);
7、繪制文本
一旦將所有的GDI+對象實例化后,下面所需要做的事就是調用Graphics::DrawString方法。下面的
例子使用了這個方法,在這個方法里規定了需要顯示的文本、畫刷和字體及顯示文本的位置。
// Center the text on the drawing surface
g->DrawString(txtToDisplay->Text, font, brush,
(picText->Width - textSize.Width) / 2,
(picText->Height - textSize.Height) / 2);
========
總結
以上是生活随笔為你收集整理的VC++ .Net 实例学习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: windbg 脚本学习总结
- 下一篇: s3c2440移植MQTT