?一?GDI 繪圖模式(RoP2 Mode)???????
????????在使用·VC++ MFC進行圖形程序編程時,常會用到GDI繪圖指令,而要做到繪圖時有橡皮筋動態效果,就需設置GDI繪圖模式。GDI繪圖模式有多種,如下:
常用R2_NOT模式來實現橡皮筋效果,當使用了R2_NOT模式后,一般需要使用R2_COPYPENQ切換回常規的繪圖效果。設置繪圖模式需用到SetROP2函數,例如實現繪制直線的橡皮筋效果,會用到類似下面的代碼:
pDC->SetROP2(R2_NOT);
pDC->MoveTo(mcpoint[0]);
pDC->LineTo(mcpoint[1]);
pDC->SetROP2(R2_NOT);
pDC->MoveTo(mcpoint[0]);
pDC->LineTo(point);
mcpoint[1] = point;
實現移動鼠標時的動態效果后,最后要繪出直線則會用到類似下面的指令代碼:
pDC->SetROP2(R2_NOT);
pDC->MoveTo(mcpoint[0]);
pDC->LineTo(mcpoint[1]);
pDC->SetROP2(R2_COPYPEN);
pDC->MoveTo(mcpoint[0]);
pDC->LineTo(mcpoint[1]);
?????????二?映射模式
? ? ? ? 通常情況下,GDI繪圖·使用的是邏輯單位,輸入的x,y坐標通常是邏輯數值,是整數類型(對于窗口是邏輯值,對視口來講是像素)。要將邏輯單位與長度單位聯系起來,就需用到映射模式。下面是映射模式的列表:
后面兩種為可編程映射模式,即通過對窗口與視口的合理設置,可以使前面6種模式無法全部顯示的圖形得以完整顯示。常用于根據窗口尺寸按比例自動調節圖畫的輸出大小的場合。當設置為MM_ISOTROPIC模式時,應先調用SetWindowEX函數函數,再繪圖。如下面代碼:
CRect rec;
GetClientRect(rec);
dc.SetMapMode(MM_ISOTROPIC);
dc.SetWindowExt(500,500);
dc.SetViewportExt(rec.Width(),rec.Height());
dc.Lin(CPoint(0,0), CPoint(800,300));
????????MM_ANISOTROPIC模式對先設置窗口還是視口沒有特別要求。????????
? ? ? ? 要獲取顯示設備顯示區域的大小(即我們常說的屏幕分辨率)可以使用GetDeviceCaps函數,如下面代碼:
CClientDC dc(this);
int x = dc.GetDeviceCaps(HORZRES);
int x = dc.GetDeviceCaps(VERTRES);
通過在GetDeviceCaps函數輸入其它參數,還可獲得更多的有用信息,GetDeviceCaps函數可以設置以下參數:
在圖形程序設計時還會遇到坐標原點移動即邏輯坐標與屏幕坐標間的轉換。這時可以使用SetWindowOrg、DPtoLP、LPtoDP等函數。下面是一端示例代碼:
CRect rec;
GetClientRect(&rec);
dc.SetMapMode(MM_LONGENGLISH);
CPoint pt(rec.Width() / 2. rec.Height() / 2);
dc.DPtoLP(&pt);
dc.SEtWindowOrg(-pt.x,-pt.y);
? ? ? ?三?畫筆(刷)(CBrush)
? ? ? ? MFC?封裝一個 Windows 圖形設備接口 (GDI)?類CBrush,這就是我們常說的畫筆,叫畫刷的時候跟多。CBrush類比較簡單其構造函數、公有方法·及·運算法如下:
???構造函數?CBrush有四個重載構造函數。 沒有參數的構造函數構造未初始化的 ?CBrush 對象,必
須先對其進行初始化,然后才能使用。其構造函數的原型如下:
構造函數參數:
CBrush::CreateBrushIndirect?使用 LOGBRUSH 結構中指定的樣式、顏色和圖案初始化畫筆。其原型如下:BOOL CreateBrushIndirect(const LOGBRUSH* lpLogBrush);?參數lpLogBrush指向包含畫筆信息的 LOGBRUSH 結構。返回值:如果該函數成功,則為非 0;否則為 0。
LOGBRUSH
?結構體的定義如下:
typedef struct tag LOGBRUSH { /* lb */?UINT lbStyle;?COLORREF lbColor;?LONG lbHatch;? } LOGBRUSH;
lbStyle
:這個成員指定了畫刷的樣式。它可以取以下值之一:BS_DIBPATTERN
:使用設備無關位圖(DIB)定義的模板畫刷。BS_DIBPATTERNPT
:與BS_DIBPATTERN
類似,但使用指向已打包DIB的指針。BS_HATCHED
:陰影畫刷。BS_HOLLOW
:空畫刷,實際上不繪制任何內容。BS_NULL
:與BS_HOLLOW
相同。BS_PATTERN
:使用內存位圖定義的模板畫刷。BS_SOLID
:實心畫刷。
bColor
:這個成員指定了畫出畫刷的顏色。lbHatch
:這個成員的含義依賴于lbStyle
所定義的畫刷樣式。例如,如果lbStyle
為BS_HATCHED
,則lbHatch
指定了創建陰影時使用的線條的方向。如果lbStyle
是BS_PATTERN
,則lbHatch
為定義了模板的位圖句柄。
示例:
// Initialize a LOGBRUSH structure.
LOGBRUSH logBrush;
logBrush.lbStyle = BS_HATCHED;
logBrush.lbColor = RGB(0, 192, 192);
logBrush.lbHatch = HS_CROSS;
// Declare an uninitialized CBrush ...
CBrush brush;
// ... and initialize it with the LOGBRUSH.
brush.CreateBrushIndirect(&logBrush);
CBrush::CreateDIBPatternBrush?使用與設備無關的位圖 (DIB) 指定的模式初始化畫筆。其原型如下:
BOOL CreateDIBPatternBrush(
HGLOBAL hPackedDIB,
UINT nUsage);
BOOL CreateDIBPatternBrush(
const void* lpPackedDIB,
UINT nUsage);
參數:hPackedDIB標識包含打包的設備無關位圖 (DIB) 的全局內存對象。nUsage指定 BITMAPINFO 數據結構(“打包 DIB”的一部分)的 ?bmiColors[] 字段是否包含顯式RGB 值或當前所實現邏輯調色板的索引。 該參數必須是以下值之一:DIB_PAL_COLORS 顏色表包含一組 16 位索引。DIB_RGB_COLORS 顏色表包含文字 RGB 值。lpPackedDIB?指向由 ?BITMAPINFO 結構組成的壓縮 DIB,其后緊跟定義位圖像素的字節數組。返回值?如果成功,非0;否則為?0。
示例:
// Resource handle to bitmap.
HRSRC hRes;
// Global handles to bitmap resource.
HGLOBAL hData;
void *hLockedData;
CBrush brush;
// Find the resource handle.
hRes = ::FindResource(AfxGetResourceHandle(),
MAKEINTRESOURCE(IDB_BRUSH), RT_BITMAP);
if (hRes != NULL)
{
// Lock and Load (or Load and Lock).
if (((hData = ::LoadResource(AfxGetResourceHandle(),
hRes)) != NULL) &&((hLockedData = ::LockResource(hData)) != NULL))
{
// Initialize the brush.
brush.CreateDIBPatternBrush((const void *)hLockedData,
DIB_RGB_COLORS);
// Select the brush into the device context.
CBrush *pOldBrush = pDC->SelectObject(&brush);
// Draw.
pDC->Rectangle(50, 50, 200, 200);
// Restore the original device context.
pDC->SelectObject(pOldBrush);
// Free the resource.
::FreeResource(hLockedData);
}
}
CBrush::CreateHatchBrush?使用指定的陰影圖案和顏色初始化畫筆。其原型如下:
BOOL CreateHatchBrush(int nIndex,COLORREF crColor);
參數?nIndex指定畫筆的陰影樣式。 可以是以下任一值:HS_BDIAGONAL 45 度向下的陰影(從左到右),HS_CROSS 橫向縮放與縱向陰影線,HS_DIAGCROSS 45 度陰影線,HS_FDIAGONAL 45 度向上的陰影(從左到右),HS_HORIZONTAL 水平陰影,HS_VERTICAL 垂直陰影。crColor?將畫筆的前景色指定為 RGB 顏色(陰影的顏色)。 有關詳細信息,請參閱 Windows
SDK 中的 COLORREF。返回值: 如果成功,非 0;否則為 0。
CBrush::CreatePatternBrush?使用位圖指定的模式初始化畫筆。其原型如下:
BOOL CreatePatternBrush(CBitmap* pBitmap);
參數?pBitmap?標識位圖。返回值?如果成功,則不為 0;否則為 0。
CBrush::CreateSolidBrush?用指定的純色初始化畫筆。其原型如下:
BOOL CreateSolidBrush(COLORREF crColor);
參數?crColor?指定畫筆顏色的 COLORREF 結構。 顏色指定一個 RGB 值,并可以使用 ?WINDOWS.H 中的RGB 宏進行構造。返回值?如果成功,則不為 0;否則為 0。
CBrush::CreateSysColorBrush?初始化畫筆顏色。其原型如下:
BOOL CreateSysColorBrush(int nIndex);
參數??nIndex?指定顏色索引。?
COLOR_3DDKSHADOW? ? ? ?21? 三維顯示元素的深色陰影。
COLOR_3DFACE? ? ? ? ? ? ? ? ? ?15??三維顯示元素和對話框背景的人臉顏色。
COLOR_3DHIGHLIGHT? ? ? ? ?20?三維顯示元素的突出顯示顏色 (面向光源的邊緣。)
COLOR_3DLIGHT? ? ? ? ? ? ? ? ?22?三維顯示元素的淺色 (面向光源的邊緣。)
COLOR_3DSHADOW? ? ? ? ? ?16?三維顯示元素的陰影顏色 (面向遠離光源的邊緣) 。
COLOR_ACTIVEBORDER? ?10?活動窗口邊框。
COLOR_ACTIVECAPTION? ?2?活動窗口標題欄。 關聯的前景色為 COLOR_CAPTIONTEXT。
COLOR_APPWORKSPACE 12?多個文檔界面 (MDI) 應用程序的背景色。
COLOR_BACKGROUND? ? ?1?桌面設備。
COLOR_BTNFACE? ? ? ? ? ? ? 15?三維顯示元素和對話框背景的人臉顏色。 關聯的前景色。?
OLOR_BTNHIGHLIGHT? ? ? ?20?三維顯示元素的突出顯示顏色 (面向光源的邊緣。)
COLOR_BTNSHADOW? ? ? ?16?三維顯示元素的陰影顏色 (面向遠離光源的邊緣) 。
COLOR_BTNTEXT? ? ? ? ? ? ? 18?按下按鈕上的文本。 關聯的背景色為COLOR_BTNFACE。
COLOR_CAPTIONTEXT? ? ? 9??描述文字、大小框和滾動條箭頭框中的文本。
COLOR_DESKTOP? ? ? ? ? ? ?1? ?桌面設備。
COLOR_GRADIENTACTIVECAPTION? 27?活動窗口標題欄顏色漸變中的右側顏色。
COLOR_GRADIENTINACTIVECAPTION 28?非活動窗口標題欄顏色漸變中的右側顏色。
COLOR_GRAYTEXT? ? ? ? ? 17?已禁用?文本的灰色 。 如果當前顯示驅動程序不支持純灰色,則此顏色設置為 0。
COLOR_HIGHLIGHT? ? ? ? ?13?在 控件中選擇的項 () 。
COLOR_HIGHLIGHTTEXT 14 在 控件中選擇的項 () 的文本。
COLOR_HOTLIGHT? ? ? ? ? ? 26?超鏈接或熱跟蹤項的顏色。
OLOR_INACTIVEBORDER 11?非活動窗口邊框。
COLOR_INACTIVECAPTION 3?非活動窗口描述文字。
COLOR_INACTIVECAPTIONTEXT 19?工具提示控件的背景色。
COLOR_INFOBK? ? ? ? ? ? ? ? ? 24?工具提示控件的背景色。
COLOR_INFOTEXT? ? ? ? ? ? ?23?工具提示控件的文本顏色。
COLOR_MENU? ? ? ? ? ? ? ? ? ? 4? ??菜單背景。
COLOR_MENUHILIGHT? ? ?29?當菜單顯示為平面菜單時用于突出顯示菜單項的顏色
COLOR_MENUBAR? ? ? ? ? 30?菜單顯示為平面菜單時菜單欄的背景色
COLOR_MENUTEXT? ? ? ? 7?菜單中的文本。
COLOR_SCROLLBAR? ? ? ?0?滾動條灰色區域。
COLOR_WINDOW? ? ? ? ? ? 5?窗口背景。
返回值? ?如果成功,則不為 0;否則為 0。
CBrush::FromHandle?當給定 Windows HBRUSH 對象的句柄時,返回指向 ?CBrush 對象的指針。其原型如下:
static CBrush* PASCAL FromHandle(HBRUSH hBrush);
參數?hBrush?Windows GDI 畫刷的 HANDLE。返回值?如果成功,則為指向 ?CBrush 對象的指針;否則為 ?NULL 。
CBrush::GetLogBrush?調用此成員函數以檢索 ?LOGBRUSH 結構。其原型如下:
int GetLogBrush(LOGBRUSH* pLogBrush);
參數?pLogBrush?指向包含畫筆信息的 LOGBRUSH 結構。返回值?如果函數成功,并且 ?pLogBrush 是有效指針,則返回值是存儲在緩沖區中的字節數。如果函數成功,并且 ?pLogBrush 是 ?NULL ,則返回值是保存函數將存儲到緩沖區中的信息所需的字節數。如果函數失敗,返回值為 0。
CBrush::operator HBRUSH?使用此運算符獲取 ?CBrush 對象的附加 Windows GDI 句柄。其原型如下:
operator HBRUSH() const;
返回值?如果成功,則由 ?CBrush 對象表示的 Windows GDI 對象的句柄;否則 ?NULL 。
示例:
RECT rc = {50, 50, 200, 200};
Rectangle(pDC->GetSafeHdc(), rc.left, rc.top, rc.right, rc.bottom);
// The Win32 call to FillRect requires an HBRUSH.
// The HBRUSH operator casts the CBrush object
// to the required type.
CBrush brush;
brush.CreateSysColorBrush(COLOR_BTNFACE);
FillRect(pDC->GetSafeHdc(), &rc, (HBRUSH)brush);
可給通過LOGBRUSH?對象賦值,設置畫筆樣式,并用CreateBrushIndirect生成該樣式的畫筆。
在用MFC設計圖形程序,常用畫筆(刷),來填充背景或在封閉區域,如果希望畫出的圓、矩形等不被填充則需選擇空畫筆。
? ? ? ? 四?筆(CPen)
????????CPen?是MFC封裝的一個 Windows 圖形設備接口 (GDI)?類。其構造函數、公共方法、操作符如下:
? ? ? ? 構造函數
????????構造函數函數用于構造 ?CPen 對象。其原型如下:
CPen();
CPen(
int nPenStyle,
int nWidth,
COLORREF crColor);
CPen(
int nPenStyle,
int nWidth,
const LOGBRUSH* pLogBrush,
int nStyleCount = 0,
const DWORD* lpStyle = NULL);
?參數??nPenStyle?指定筆樣式。 此參數在構造函數的第一個版本中可以是以下值之一:
????????PS_SOLID 創建實心筆。
????????PS_DASH 創建短劃線式虛線筆。 僅當筆寬為 1 或更小(以設備單位為單位)時有
效。
????????PS_DOT 創建點式虛線筆。 僅當筆寬為 1 或更小(以設備單位為單位)時有效。
????????PS_DASHDOT 創建短劃線和點交替的筆。 僅當筆寬為 1 或更小(以設備單位為單
位)時有效。
????????PS_DASHDOTDOT 創建短劃線和雙點交替的筆。 僅當筆寬為 1 或更小(以設備單位為
單位)時有效。
????????PS_NULL 創建 null 筆。
????????PS_INSIDEFRAME 創建可在指定邊界矩形的 Windows GDI 輸出函數(例如
????????Ellipse 、 Rectangle 、 RoundRect 、 Pie 和 ?Chord 成員函數)生成的封閉形狀框架
內繪制線條的筆。 如果此樣式與不指定邊界矩形的 Windows GDI 輸出函數(例如
LineTo 成員函數)一起使用,則筆的繪圖區域不受框架限制。
????????CPen 構造函數的第二個版本指定類型、樣式、末端和聯接特性的組合。 應使用按位“或”
( | ) 運算符組合每個類別中的值。 筆類型可以是下列值之一:
????????PS_GEOMETRIC 創建幾何筆。
????????PS_COSMETIC 創建整容筆。
????????CPen 構造函數的第二個版本為 ?nPenStyle 添加了以下筆樣式:
????????PS_ALTERNATE 創建設置所有其他像素的筆。 (此樣式僅適用于整容筆。)
????????PS_USERSTYLE 創建使用用戶提供的樣式數組的筆。
??末端可以是以下值之一:
????????PS_ENDCAP_ROUND 末端是圓的。
????????PS_ENDCAP_SQUARE 末端是正的。
????????PS_ENDCAP_FLAT 末端是平的.? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??聯接可以是以下值之一:
????????PS_JOIN_BEVEL 聯接是斜切的。
????????PS_JOIN_MITER 當聯接位于 SetMiterLimit 函數設置的當前限制內時,聯接是斜接
???的。 如果聯接超出此限制,則是斜切的。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??????????PS_JOIN_ROUND 聯接是圓的。
????????nWidth?指定筆的寬度。對于構造函數的第一個版本,值 0 的處理方式與值 1 類似,但寬度不會受到對筆用于圖形對象的縮放轉換操作的影響:寬度始終為 1 像素。對于構造函數的第二個版本,如果 ?nPenStyle 是 ?PS_GEOMETRIC ,則寬度以邏輯單位提供。 如果 ?nPenStyle 是 ?PS_COSMETIC ,則寬度必須設置為 1。
????????crColor?包含筆的 RGB 顏色。
????????pLogBrush?指向 ?LOGBRUSH 結構。 如果 ?nPenStyle 是 ?PS_COSMETIC ,則 ?LOGBRUSH 結構的 ?lbColor 成員指定筆的顏色,并且 ?LOGBRUSH 的 ?lbStyle 成員必須設置為 ?BS_SOLID 。 如果nPenStyle 是 ?PS_GEOMETRIC ,則必須使用所有成員來指定筆的畫筆性。
????????lpStyle?指向雙字值的數組。 第一個值指定用戶定義的樣式中第一條短劃線的長度,第二個值指定第一個空格的長度,依此類推。 如果 ?nPenStyle 不是 ?PS_USERSTYLE ,則此指針必須為
NULL 。
????????如果使用沒有自變量的構造函數,則必須使用 ?CPen 、 CreatePen 或 ?CreatePenIndirect
成員函數初始化生成的 ?CreateStockObject 對象。如果使用采用自變量的構造函數,則無需進一步初始化。 如果遇到錯誤,具有自變量的構造函數可能會引發異常,而沒有自變量的構造函數將始終成功。示例:
// Create a solid red pen of width 2.
CPen myPen1(PS_SOLID, 2, RGB(255, 0, 0));
/ Create a geometric pen.
LOGBRUSH logBrush;
logBrush.lbStyle = BS_SOLID;
logBrush.lbColor = RGB(0, 255, 0);
CPen myPen2(PS_DOT | PS_GEOMETRIC | PS_ENDCAP_ROUND, 2, &logBrush);
????????CreatePen?創建具有指定樣式、寬度和畫筆特性的邏輯整容筆或幾何筆,并將其附加到 ?CPen 對象。其原型如下:
BOOL CreatePen(
int nPenStyle,
int nWidth,
COLORREF crColor);
BOOL CreatePen(
int nPenStyle,
int nWidth,
const LOGBRUSH* pLogBrush,
int nStyleCount = 0,
const DWORD* lpStyle = NULL);
????????參數 :nPenStyle?指定筆的樣式。 有關可能值的列表,請參閱 CPen 構造函數中的 ?nPenStyle 參數。nPenStyle?指定筆的寬度。對于 ?CreatePen 的第一個版本,值 0 的處理方式與值 1 類似,但寬度不會受到對筆用于圖形對象的縮放轉換操作的影響:寬度始終為 1 像素。對于 ?CreatePen 的第二個版本,如果 ?nPenStyle 是 ?PS_GEOMETRIC ,則寬度以邏輯單位提供。 如果 ?nPenStyle 是 ?PS_COSMETIC ,則寬度必須設置為 1。crColor?包含筆的 RGB 顏色。pLogBrush指向 LOGBRUSH 結構。 如果 ?nPenStyle 是 ?PS_COSMETIC ,則 ?LOGBRUSH 結構的 ?lbColor成員指定筆的顏色,并且 ?LOGBRUSH 的 ?lbStyle 成員必須設置為 ?BS_SOLID 。 如果nPenStyle 是 ?PS_GEOMETRIC ,則必須使用所有成員來指定筆的畫筆特性。nStyleCount
指定 ?lpStyle 數組的長度(以雙字單位為單位)。 如果 ?nPenStyle 不是 ?PS_USERSTYLE ,
則此值必須為零。lpStyle?指向雙字值的數組。 第一個值指定用戶定義的樣式中第一條短劃線的長度,第二個值指定第一個空格的長度,依此類推。 如果 ?nPenStyle 不是 ?PS_USERSTYLE ,則此指針必須為NULL 。
????????返回值?如果成功,則為非零;如果方法失敗,則為零。
????????CreatePen 的第一個版本使用指定的樣式、寬度和顏色初始化筆。 隨后可以選擇該筆作
為任何設備上下文的當前筆。寬度大于 1 像素的筆應始終具有 ?PS_NULL 、 PS_SOLID 或 ?PS_INSIDEFRAME 樣式。如果筆的 ?PS_INSIDEFRAME 樣式和顏色與邏輯顏色表中的顏色不匹配,則筆將以抖色進行繪制。 筆 ?PS_SOLID 樣式不能用于創建具有任一顏色的筆。 如果筆寬小于或等于 1,則樣式 ?PS_INSIDEFRAME 與 ?PS_SOLID 相同。
????????CreatePen 的第二個版本初始化具有指定樣式、寬度和畫筆特性的邏輯整容筆或幾何筆。
整容筆的寬度始終為 1;幾何筆的寬度始終以世界單位指定。 應用程序在創建邏輯筆后,可以通過調用 CDC::SelectObject 函數將該筆選入設備上下文。 將筆選入設備上下文后,可用于繪制線條和曲線。如果 ?nPenStyle 是 ?PS_COSMETIC 和 ?PS_USERSTYLE ,則 ?lpStyle 數組中的條目以樣式單位指定短劃線和空格的長度。 樣式單位由用于繪制線條的設備定義。如果 ?nPenStyle 是 ?PS_GEOMETRIC 和 ?PS_USERSTYLE ,則 ?lpStyle 數組中的條目以邏輯單位指定短劃線和空格的長度。如果 ?nPenStyle 是 ?PS_ALTERNATE ,則忽略樣式單位,并設置所有其他像素。
????????當應用程序不再需要給定筆時,它應調用 CGdiObject::DeleteObject 成員函數或銷毀CPen 對象,以便不再使用資源。 如果設備上下文中選擇了某個筆,則應用程序不應刪除筆。示例:
CPen myPen1, myPen2;
// Create a solid red pen of width 2.
myPen1.CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
// Create a geometric pen.
LOGBRUSH logBrush;
logBrush.lbStyle = BS_SOLID;
logBrush.lbColor = RGB(0, 255, 0);
myPen2.CreatePen(PS_DOT | PS_GEOMETRIC | PS_ENDCAP_ROUND, 2, &logBrush);
?????????CreatePenIndirect?初始化一個筆,該筆的樣式、寬度和顏色在 ?lpLogPen 所指向的結構中給出。其原型如下:
BOOL CreatePenIndirect(LPLOGPEN lpLogPen);
參數?lpLogPen?指向包含有關筆的信息的 Windows LOGPEN 結構。
返回值 如果該函數成功,則為非 0;否則為 0。
????????寬度大于 1 像素的筆應始終具有 ?PS_NULL 、 PS_SOLID 或 ?PS_INSIDEFRAME 樣式。如果筆的 ?PS_INSIDEFRAME 樣式和顏色與邏輯顏色表中的顏色不匹配,則筆將以抖色進行繪制。 如果筆寬小于或等于 1,則 ?PS_INSIDEFRAME 樣式與 ?PS_SOLID 相同。示例:
LOGPEN logpen;
CPen cMyPen;
// Get the LOGPEN of an existing pen.
penExisting.GetLogPen(&logpen);
// Change the color to red and the width to 2.
logpen.lopnWidth.x = 2;
logpen.lopnColor = RGB(255, 0, 0);
// Create my pen using the new settings.
cMyPen.CreatePenIndirect(&logpen);
????????FromHandle?在提供了 Windows GDI 筆對象句柄的情況下,返回指向 ?CPen 對象的指針。其原型如下:
static CPen* PASCAL FromHandle(HPEN hPen);
?????????參數?hPen Windows GDI 筆的 ?HPEN 句柄。
????????返回值?如果成功,則為指向 ?CPen 對象的指針;否則為 ?NULL 。
????????GetExtLogPen?獲取 ?EXTLOGPEN 基礎結構。其原型如下:
int GetExtLogPen(EXTLOGPEN* pLogPen);
????????參數?pLogPen 指向包含有關筆的信息的 EXTLOGPEN 結構。
????????返回值?如果成功,則不為 0;否則為 0。?示例:
EXTLOGPEN extlogpen;
penExisting.GetExtLogPen(&extlogpen);
CPen penOther;
LOGBRUSH LogBrush = { extlogpen.elpBrushStyle, extlogpen.elpColor,
extlogpen.elpHatch };
penOther.CreatePen(PS_COSMETIC, 1, &LogBrush);
????????GetLogPen?獲取 ?LOGPEN 基礎結構。其原型如下:
int GetLogPen(LOGPEN* pLogPen);
????????參數?pLogPen 指向包含有關筆的信息的 LOGPEN 結構。
????????返回值?如果成功,則不為 0;否則為 0。
????????operator HPEN?獲取 ?CPen 對象的附加 Windows GDI 句柄。其原型如下:
operator HPEN() const;
示例:
// Create a solid red pen of width 2.
CPen myPen(PS_SOLID, 2, RGB(255, 0, 0));
// Get the handle of the pen object.
HPEN hPen = (HPEN)myPen;
五?字體(CFont)
CFont是MFC中一個 Windows 圖形設備接口 (GDI) 字體并提供用于操作字體的成員函數的類。其構造函數、公共方法、公共·運算符如下:
????????構造函數?CFont?構造 ?CFont 對象。其原型如下:
CFont();
生成的對象必須用 ?CreateFont 、 CreateFontIndirect 、 CreatePointFont 或CreatePointFontIndirect 初始化后才能使用。? ? ? ? 示例:
CFont font;
????????CreateFont?使用指定的特征初始化 ?CFont 對象。其原型如下:
BOOL CreateFont(
int nHeight,
int nWidth,
int nEscapement,
int nOrientation,
int nWeight,
BYTE bItalic,
BYTE bUnderline,
BYTE cStrikeOut,
BYTE nCharSet,
BYTE nOutPrecision,
BYTE nClipPrecision,
BYTE nQuality,
BYTE nPitchAndFamily,
LPCTSTR lpszFacename);
????????參數
??????????nHeight?指定字體的所需高度(以邏輯單元表示)。 有關說明,請參閱 Windows SDK 中LOGFONT 結構的 ?lfHeight 成員。 轉換后, nHeight 的絕對值不得超過 16,384 個設備單元。 對于所有高度比較,字體映射器查找不超過請求大小的最大字體,或者查找所有字體超過請求大小時的最小字體。
????????nWidth?指定字體中字符的平均寬度(以邏輯單元表示)。 如果 ?nWidth 為 0,則設備的縱橫比將與可用字體的數字化縱橫比匹配,以查找最接近的匹配項,這由差值的絕對值決定。
????????nEscapement 指定轉義矢量與顯示圖面 x 軸之間的角度(以 0.1 度單元表示)。 轉義矢量是通過直線上第一個字符和最后一個字符的原點的直線。 角度是從 x 軸逆時針方向測量的。 有關詳細信息,請參閱 Windows SDK 中 ?LOGFONT 結構的 ?lfEscapement 成員。
????????nOrientation 指定字符基線與 x 軸之間的角度(以 0.1 度單元表示)。 在 y 方向向下的坐標系統中,該角度是從 x 軸逆時針測量的;而在 y 方向向上的坐標系統中,角度是從 x 軸順時針測
量的。
????????nWeight?指定字體粗細(以每 1000 個墨跡像素表示)。 有關詳細信息,請參閱 Windows SDK 中LOGFONT 結構的 ?lfWeight 成員。 描述的值是近似值;實際外觀取決于字樣。 某些字體
只有 ?FW_NORMAL 、 FW_REGULAR 和 ?FW_BOLD 粗細。 如果指定 ?FW_DONTCARE ,則使用默認粗細。
????????bItalic 指定字體是否為斜體。
????????cStrikeOut 指定字體中的字符是否被刪除。如果設置為非零值,則指定刪除線字體。
????????nCharSet 指定字體的字符集。有關值列表,請參閱 Windows SDK 中 ?LOGFONT 結構的 ?lfCharSet 成員。OEM 字符集依賴于系統。系統中可能存在具有其他字符集的字體。 使用具有未知字符集的字體的應用程序不得嘗試翻譯或解釋要使用該字體呈現的字符串。 相反,應將字符串直接傳遞給輸出設備驅動程序。字體映射器不使用 ?DEFAULT_CHARSET 值。 應用程序可以使用該值來允許字體的名稱和大小完全描述邏輯字體。 如果具有指定名稱的字體不存在,則任何字符集中的字體都可以替換指定的字體。 為了避免意外結果,應用程序應謹慎使DEFAULT_CHARSET 值。
????????nOutPrecision?指定所需的輸出精度。 輸出精度定義輸出與所請求字體的高度、寬度、字符方向、轉義和間距的必需匹配程度。 有關值列表和詳細信息,請參閱 Windows SDK 中LOGFONT 結構的 ?lfOutPrecision 成員。
????????nClipPrecision?指定所需的剪裁精度。 剪裁精度定義如何剪裁部分超出剪裁區域的字符。 有關值列表,請參閱 Windows SDK 中 ?LOGFONT 結構的 ?lfClipPrecision 成員。若要使用嵌入的只讀字體,應用程序必須指定 ?CLIP_ENCAPSULATE 。若要實現設備、TrueType 和矢量字體的一致旋轉,應用程序可以使用按位“或”運算符 ( | )將 ?CLIP_LH_ANGLES 值與其他任何 ?nClipPrecision 值組合在一起。 如果設置了CLIP_LH_ANGLES 位,則所有字體的旋轉取決于坐標系統的方向是左側還是右側。 (有關坐標系統方向的詳細信息,請參閱 ?nOrientation 參數說明。)如果未設置CLIP_LH_ANGLES ,則設備字體始終逆時針旋轉,但其他字體的旋轉取決于坐標系統的方向。
????????nQuality?指定字體的輸出質量,它定義 GDI 必須嘗試將邏輯字體屬性與實際物理字體的屬性進行匹配時的謹慎程度。 有關值列表,請參閱 Windows SDK 中 ?LOGFONT 結構的 ?lfQuality
成員。
????????lpszFacename CString 或以 null 結尾的字符串指定字體的字樣名稱。 此字符串的長度不得超過 30 個字符。 Windows EnumFontFamilies 函數可用于枚舉所有當前可用的字體。 如果
lpszFacename 為 ?NULL ,則 GDI 使用獨立于設備的字樣。
????????返回值?如果成功,則不為 0;否則為 0。?示例:
CFont font;
VERIFY(font.CreateFont(
12, // nHeight
0, // nWidth
0, // nEscapement
0, // nOrientation
FW_NORMAL, // nWeight
FALSE, // bItalic
FALSE, // bUnderline
0, // cStrikeOut
ANSI_CHARSET, // nCharSet
OUT_DEFAULT_PRECIS, // nOutPrecision
CLIP_DEFAULT_PRECIS, // nClipPrecision
DEFAULT_QUALITY, // nQuality
DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
_T("Arial"))); // lpszFacename
// Do something with the font just created...
CClientDC dc(this);
CFont *def_font = dc.SelectObject(&font);
dc.TextOut(5, 5, _T("Hello"), 5);
dc.SelectObject(def_font);
// Done with the font. Delete the font object.
font.DeleteObject();
????????CreateFontIndirect?使用 LOGFONT 結構中給定的特征初始化 ?CFont 對象。其原型如下:
BOOL CreateFontIndirect(const LOGFONT* lpLogFont);
????????參數??lpLogFont 指向定義邏輯字體特征的 ?LOGFONT 結構。
????????返回值?如果成功,則不為 0;否則為 0。示例:
CFont font;
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT)); // zero out structure
lf.lfHeight = 12; // request a 12-pixel-height font
_tcsncpy_s(lf.lfFaceName, LF_FACESIZE,
_T("Arial"), 7); // request a face name "Arial"
VERIFY(font.CreateFontIndirect(&lf)); // create the font
// Do something with the font just created...
CClientDC dc(this);
CFont *def_font = dc.SelectObject(&font);
dc.TextOut(5, 5, _T("Hello"), 5);
dc.SelectObject(def_font);
// Done with the font. Delete the font object.
font.DeleteObject();
????????CreatePointFont??提供了一種創建指定字樣和磅值的字體的簡單方法。其原型如下:
BOOL CreatePointFont(
int nPointSize,
LPCTSTR lpszFaceName,
CDC* pDC = NULL);
?參數:
???????? nPointSize?請求的字體高度(以十分之一磅表示)。 (例如,傳遞 120 以請求 12 磅字體。)
????????lpszFaceName CString 或以 null 結尾的字符串指定字體的字樣名稱。 此字符串的長度不得超過 30 個字符。 Windows ?EnumFontFamilies 函數可用于枚舉所有當前可用的字體。 如果
lpszFaceName 為 ?NULL ,則 GDI 使用獨立于設備的字樣。
????????pDC 指向要用于將以 ?nPointSize 表示的高度轉換為邏輯單元的 CDC 對象的指針。 如果為
NULL ,則使用屏幕設備上下文進行轉換。
????????返回值?如果成功,則為非零值;否則為 0。示例:
CClientDC dc(this);
CFont font;
VERIFY(font.CreatePointFont(120, _T("Arial"), &dc));
// Do something with the font just created...
CFont *def_font = dc.SelectObject(&font);
dc.TextOut(5, 5, _T("Hello"), 5);
dc.SelectObject(def_font);
// Done with the font. Delete the font object.
font.DeleteObject();
????????CreatePointFontIndirect?此函數與 CreateFontIndirect 相同,只是 ?LOGFONT 的 ?lfHeight 成員以十分之一磅(而不是設備單元)說明。其原型如下:
BOOL CreatePointFontIndirect(
const LOGFONT* lpLogFont,
CDC* pDC = NULL);
參數:
????????lpLogFont?指向定義邏輯字體特征的 LOGFONT 結構。 結構 ?lfHeight 的成員 ?LOGFONT 以十分之一磅(而不是邏輯單元)進行度量。 (例如,將 ?lfHeight 設置為 120,以請求 12 磅字
體。)
????????pDC 指向要用于將以 ?lfHeight 表示的高度轉換為邏輯單元的 CDC 對象的指針。 如果為
NULL ,則使用屏幕設備上下文進行轉換。
????????返回值?如果成功,則為非零值;否則為 0。
????????在將 ?LOGFONT 結構傳遞到 Windows 之前,此函數使用 ?pDC 指向的 ?CDC 對象自動將以
lfHeight 表示的高度轉換為邏輯單元。完成通過 ?CreatePointFontIndirect 函數創建的 ?CFont 對象后,首先選擇設備上下文中的字體,然后刪除 ?CFont 對象。示例:
LOGFONT lf;
// clear out structure.
memset(&lf, 0, sizeof(LOGFONT));
// request a 12-pixel-height font
lf.lfHeight = 120;
// request a face name "Arial".
_tcsncpy_s(lf.lfFaceName, LF_FACESIZE, _T("Arial"), 7);
CClientDC dc(this);
CFont font;
VERIFY(font.CreatePointFontIndirect(&lf, &dc));
// Do something with the font just created...
CFont *def_font = dc.SelectObject(&font);
dc.TextOut(5, 5, _T("Hello"), 5);
dc.SelectObject(def_font);
// Done with the font. Delete the font object.
font.DeleteObject();
????????FromHandle?在給定 Windows GDI 字體對象的 ?HFONT 句柄時返回指向 ?CFont 對象的指針。其原型如下:
static CFont* PASCAL FromHandle(HFONT hFont);
????????參數?hFont Windows 字體的 ?HFONT 句柄。
????????返回值?如果成功,則為指向 ?CFont 對象的指針;否則為 ?NULL 。示例:
LOGFONT lf;
// clear out structure
memset(&lf, 0, sizeof(LOGFONT));
// request a 12-pixel-height font
lf.lfHeight = 12;
// request a face name "Arial"
_tcsncpy_s(lf.lfFaceName, LF_FACESIZE, _T("Arial"), 7);
// create the font
HFONT hfont = ::CreateFontIndirect(&lf);
// Convert the HFONT to CFont*.
CFont *pfont = CFont::FromHandle(hfont);
// Do something with the font just created...
CClientDC dc(this);
CFont *def_font = dc.SelectObject(pfont);
dc.TextOut(5, 5, _T("Hello"), 5);
dc.SelectObject(def_font);
// Done with the font. Delete the font object.
::DeleteObject(hfont);
????????GetLogFont?調用此函數可檢索 ?CFont 的 ?LOGFONT 結構的副本。其原型如下:
int GetLogFont(LOGFONT* pLogFont);
????????參數?pLogFont 指向用于接收字體信息的 LOGFONT 結構的指針。
????????返回值?如果函數成功,則返回非零值;否則返回 0。示例:
CFont *pFont = pWnd->GetFont();
if (NULL != pFont)
{
LOGFONT lf;
pFont->GetLogFont(&lf);
TRACE(_T("Typeface name of font = %s\n"), lf.lfFaceName);
}
????????operator HFONT?使用此運算符獲取附加到 ?CFont 對象的字體的 Windows GDI 句柄。其原型如下:
operator HFONT() const;
????????返回值?如果成功,則返回附加到 ?CFont 的 Windows GDI 字體對象的句柄;否則返回 ?NULL。示例:
LOGFONT lf;
// clear out structure
memset(&lf, 0, sizeof(LOGFONT));
// request a 12-pixel-height font
lf.lfHeight = 12;
// request a face name "Arial"
_tcsncpy_s(lf.lfFaceName, LF_FACESIZE, _T("Arial"), 7);
CFont font1;
font1.CreateFontIndirect(&lf); // create the font
// CFont::operator HFONT automatically converts font1 from
// CFont* to HFONT.
CFont *font2 = CFont::FromHandle(font1);
// Do something with the font just created...
CClientDC dc(this);
CFont *def_font = dc.SelectObject(font2);
dc.TextOut(5, 5, _T("Hello"), 5);
dc.SelectObject(def_font);
// Done with the font. Delete the font object.
font1.DeleteObject();
CBrush,CPen,CFont皆為GDI接口類,當要使用時一般需要先創建的對象,當不用時需調用DeleteObject()函數刪除對象。Window預定義了一些CBrush、CFont、CPen等對象,使用它們時不需要顯示創建,使用SelectStockObject將其選入設備描述表即可。常用的Windows預定義GDi對象如下:
·