Windows編程 第八回 繪圖課(下)

書接上回,我們先來看一個例子吧,我們畫了一個矩形和一個圓:

         caseWM_PAINT:

         HDChDC;

         PAINTSTRUCTps;

        hDC=BeginPaint(hwnd,&ps);

         Rectangle(hDC,50,50,200,200);

         Ellipse(hDC,100,100,300,300);

 

         Ellipse(hDC,400,100,600,300);

        Rectangle(hDC,350,50,500,200);

        

         EndPaint(hwnd,&ps);

         break;   

你會感到奇怪,這兩個函數畫出的圖形怎麼會相互遮蓋呢?或許你猜出了原因了,這兩個函 數不是單純地畫“邊框”,其內部還被白色的背景填充着,讓它們可以相互遮擋而不是“透明”的。像前面講過的Rectangle、Ellipse、 RoundRect、Chord、Pie和本回要講的Polygon、PolyPolygon這些畫帶邊界框的填充圖形函數都是這樣的。

認識畫刷

在Windows中圖形是以當前設備描述表選中的畫刷來填充的。默認情況下,使用現有的白色畫刷,這意味着圖形內部將畫爲白色。Windows預定義了 六種現有畫刷:WHITE_BRUSH、LTGRAY_BRUSH、GRAY_BRUSH、DKGRAY_BRUSH、BLACK_BRUSH和 NULL_BRUSH (也叫HOLLOW_BRUSH),大家看名字就應該知道它們代表什麼顏色了吧。你可以將任何一種現有畫刷選入你的設備描述表中,就和你選擇一種畫筆一 樣。

Windows用HBRUSH定義畫刷句柄,可以像這樣定義一個畫刷句柄變量:

HBRUSH hBrush;

你可以通過調用GetStockObject來取得GRAY_BRUSH的句柄:

hBrush = (HBRUSH) GetStockObject (GRAY_BRUSH) ;//這裏需要強制類型轉換

你可以調用SelectObject將它選進設備描述表:

SelectObject (hdc, hBrush) ;

現在,如果你要用上面的提到的任意一個函數畫圖,則圖形內部將爲灰色。

 

如果您想畫一個沒有邊界框的圖形,可以將NULL_PEN選進設備描述表:

SelectObject (hdc,(HBRUSH) GetStockObject (NULL_PEN)) ;
上一回我曾提到過NULL_PEN有啥用?我估計這可能就是它的一個用途吧。
 

如果您想畫出圖形的邊界框,但不填入內部,則將NULL_BRUSH選進設備內容:

SelectObject (hdc, (HBRUSH) GetStockobject (NULL_BRUSH) ;
大家看到此,應該想出畫不互相遮蓋的圖形了吧:

               case WM_PAINT:

               HDC hDC;

               PAINTSTRUCT ps;

               hDC=BeginPaint(hwnd,&ps);

           SelectObject(hDC, (HBRUSH) GetStockObject (NULL_BRUSH) ; 

Rectangle(hDC,50,50,200,200);

           Ellipse(hDC,100,100,300,300);

 

           Ellipse(hDC,400,100,600,300);

         Rectangle(hDC,350,50,500,200);


              EndPaint(hwnd,&ps);

              break;

再認識畫刷

我們除了可以使用以上的現有畫刷,還可以創建自己的畫刷,就如同上回我們創建自己的畫筆一樣。而且過程也是類似的:

首先創建邏輯畫刷,這裏Windows爲我們提供了幾個函數可供使用;

然後使用SelectObject把畫刷選進設備描述表

繪圖函數繪圖;

最後在釋放設備描述表(或者在選擇了另一種畫刷到設備內容中)之後,就可以調用DeleteObject來刪除畫刷了。

 

接着我們就來看一下這幾個創建畫刷的函數吧。

下面是建立邏輯畫刷的第一個函數:

hBrush = CreateSolidBrush (crColor) ;

函數中crColor爲COLORREF類型,指定畫刷顏色。

你還可以使用由水平、垂直或者傾斜的線組成的“影線標記(hatch marks)”來創建畫刷,這種風格的畫刷對着色條形圖的內部和在繪圖儀上進行繪圖最有用。創建影線畫刷的函數爲:

hBrush = CreateHatchBrush (iHatchStyle, crColor) ;

iHatchStyle參數描述影線標記的外觀。下圖顯示了六種可用的影線標記風格。

 

CreateHatchBrush中的crColor參數是影線的色彩。

 

你還可以使用這個函數創建邏輯畫刷:

hBrush = CreateBrushIndirect (&logbrush) ;

變量logbrush是一個類型爲LOGBRUSH(“邏輯畫刷”)的結構,該結構的三個字段如表5-4所示,lbStyle字段的值確定了Windows如何解釋其它兩個字段的值:

lbStyle (UINT)

lbColor (COLORREF)

lbHatch (LONG)

BS_SOLID

畫刷的色彩

忽略

BS_HOLLOW

忽略

忽略

BS_HATCHED

影線的色彩

影線畫刷風格

BS_PATTERN

忽略

位圖的句柄

BS_DIBPATTERNPT

忽略

指向DIB的指標

 

上一回我們用SelectObject將邏輯畫筆選進設備描述表,用DeleteObject刪除畫筆,用GetObject來取得邏輯畫筆的信息。對於畫刷,同樣能使用這三個函數。

一旦你取得到了畫刷句柄,就可以使用SelectObject將該畫刷選進設備描述表:

SelectObject (hdc, hBrush) ;

然後,你可以使用DeleteObject函數刪除所建立的畫刷:

DeleteObject (hBrush) ;

但是,不要刪除目前選進設備描述表內的畫刷。

如果您需要取得畫刷的信息,可以調用GetObject:

GetObject (hBrush, sizeof (LOGBRUSH), (LPVOID) &logbrush) ;

其中,logbrush是一個類型爲LOGBRUSH的結構。

Polygon函數和多邊形填充

我們好像還有兩個函數沒有講,趁我還沒有忘記,趕緊把它講完吧。

Polygon函數也是一個畫帶邊界框的填充圖形函數,它的調用與Polyline函數相似:

Polygon (hdc, apt, iCount) ;
        

其中,apt參數是POINT結構的一個數組,iCount是點的數目。如果該數組中的最後一個點與第一個點不同,則Windows將會再加一條線,將最後一個點與第一個點連起來(在Polyline函數中,Windows不會這麼做)。

PolyPolygon函數如下所示:

PolyPolygon (hdc, apt, aiCounts, iPolyCount) ; 

該函數繪製多個多邊形。最後一個參數給出了所畫的多邊形的個數。對於每個多邊形,aiCounts數組給出了多邊形的端點數。apt數組具有全部多邊形的所有點。除返回值以外,PolyPolygon在功能上與下面的代碼相同:

for (i = 0, iAccum = 0 ; i < iPolyCount ; i++)
{
    Polygon (hdc, apt + iAccum, aiCounts[i]) ;
    iAccum += aiCounts[i] ;
}

對於Polygon和PolyPolygon函數,Windows使用定義在設備描述表中的當前畫刷來填充這個帶邊界的區域。至於填充內部的方式,則取決於多邊形填充方式,你可以用SetPolyFillMode函數來設定:

SetPolyFillMode (hdc, iMode) ;

默認情況下,多邊形填入方式是ALTERNATE,但是您可以將它設定爲WINDING。

對於ALTERNATE方式,您可以設想從一個無窮大的封閉區域內部的點畫線,只有假想的線穿過了奇數條邊界線時,才填充封閉區域,當然若爲偶數,則不填充該區域。這就是星的角被填充而中心沒被填充的原因。

對於WINDING方式:方法一樣,如爲奇數,填充該區域;如爲偶數則要根據邊框線的方向來判斷:如果穿過的邊框線在不同方向的邊框線數目相等,則不填充,如不等,則填充。還是來分析個例子吧,比如要繪製下圖,線上的箭頭指出了畫線的方向。

用這兩種方式填充的效果如下圖(左側是ALTERNATE方式,右側是WINDING方式):

兩種方式都會填充三個封閉的L形區域,號碼從13。號碼爲45的兩個小內部區域,在ALTERNATE方式下不會被填充。但是,在WINDING方式下,號碼爲5的區域會被填充,因爲從區域內必須穿過兩條相同方向的線才能到達圖形外部。號碼爲4的區域不會被填充,因爲必須穿過兩條方向相反的線。

 

    經過這兩節繪圖課後,大家應該對Windows中常用的繪圖函數有所瞭解了,發揮你的想象力,去畫一些漂亮的圖形吧!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章