在VC中使用CPen繪製寬度大於1的虛線

2021-06-27 21:22:57 字數 4323 閱讀 6358

vc中畫筆類為cpen, 該類最方便使用方式為:

cpen(intnpenstyle, intnwidth, colorrefcrcolor);

或者是:

bool createpen(intnpenstyle, intnwidth, colorrefcrcolor);

如果想要繪製虛擬中需要設定畫筆的樣式為ps_dash即可, 但是有乙個限制是這樣的畫筆寬度只能是1, 不能繪製粗線條的虛線, 或者其它的什麼線.

實際上, 只需要使用另外一對函式即可實現粗線條繪製各種樣式的線, 函式為:

cpen(intnpenstyle, intnwidth, const logbrush*plogbrush, intnstylecount= 0, const dword*lpstyle= null);

bool createpen(intnpenstyle, intnwidth, const logbrush*plogbrush, intnstylecount= 0,const dword*lpstyle= null);

前兩個引數npenstyle和nwidth還是和第一組函式一樣的. 但後面多了兩組引數:

1. 第一組引數是logbrush指標, 該指標用來指明繪製畫筆時所用的刷子(事實上, 個人認為, 畫筆尤其是寬度》1的畫筆, 繪製文字時類似於使用乙個畫刷將文字所佔區域填充, 所以這兒類似於提供了乙個繪製時的畫刷). 畫刷很簡單, 結構體如下:

typedef struct taglogbrush logbrush, *plogbrush;

注意這兒, 第乙個style是說的畫刷的樣式, 要與畫筆的樣式相區分一下, 兩個不同的東西, 不要相混了.

//// 示例乙個

最簡單的使用方式如下:

logbrush logbrush;

logbrush.lbstyle = bs_solid;

logbrush.lbcolor = rgb(0,0,0);

cpen pen1;

pen1.createpen(ps_dot|ps_geometric|ps_endcap_round, 2, &logbrush);

這樣, 就類似於是: cpen pen(ps_dot, 2, rgb(0,0,0))當然了, 這樣肯定是出不來的, 因為該建構函式中若樣式是ps_dot, 則寬度必須是1才行.

2. 第二組引數是int nstylecount, dword *lpstyle. 該值就是設定自定義畫筆的實現了. 如果熟悉opengl相信這兒應該是很容易理解的, opengl必比這個要複雜一些. 這兒nstylecount應該是個偶數, 用來說明指標lpstyle中有效的dword的個數. 該指標中可以有許多對兒的dword, 每對兒的第乙個表示該對兒中實線的長度, 第二個表示虛線的長度. 比如如果指標中資料是(5, 10, 15, 20), 則表示先畫5個畫素, 之後空10個畫素, 再畫15個, 接著空20個. 依次累推.

注意: !!!!!!!!!!!如果要使用這兩個引數, 則npenstyle必須要有ps_userstyle才行!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

注意: 應該不會有人故意搞個奇數個點傳進去吧. 我試過了, 如果傳奇數個, 還是拿例子說吧, 比如傳遞過去(5, 10, 15), 則相當於傳遞了(5, 10, 15, 5, 10, 15), 也就是相當於把資料擴大了2倍, 後面半部分跟前面一樣.

來個完全的示例啊:

logbrush logbrush;

memset(&logbrush, 0, sizeof(logbrush));

logbrush.lbstyle = bs_solid;

logbrush.lbcolor = rgb(0, 0, 0);

dword dwf = ;

cpen pen1;

pen1.createpen(ps_userstyle|ps_geometric|ps_endcap_flat, 10, &logbrush,4,dwf);

pdc->selectobject(&pen1);

pdc->moveto(50, 50);

pdc->lineto(550, 50);

恩, 這樣, 就可以了.

接下來呢, 介紹幾個必須要注意的東西:

1. 畫筆的樣式

畫筆的樣式, 對這兩套函式來說是不一樣的, 比如使用自定義畫筆的時候, 就有乙個ps_userstyle. 下面就說說:

兩組函式都有的:

ps_solid 

-- 實線畫筆

ps_dash 

-- 虛線畫筆, 只有當畫筆寬度為1或更小(以裝置單位計算)時才有效

ps_dot 

-- 點線畫筆, 只有當畫筆寬度為1或更小(以裝置單位計算)時才有效

ps_dashdot 

-- 虛線和點交替, 只有當畫筆寬度為1或更小(以裝置單位計算)時才有效

ps_dashdotdot -- 建立一支虛線和兩點交替的畫筆。只有當畫筆寬度為1或更小(以裝置單位計算)時才有效

ps_null 

-- 空畫筆

ps_insideframe-- 建立一支畫筆,該畫筆在windows gdi輸出函式所產生的封閉形狀的框架內畫線,此輸出函式指定乙個限定矩形(例如,ellipse,rectangle,roundrect,pie和chord成員函式),當此風格用於沒有指定限定矩形的windows gdi輸出函式(例如lineto成員函式)時,此畫筆的繪製區域不受框架的限制

第二組函式特有的, 又可以分兩幾組:

第一組, 畫筆的樣式

ps_geometric -- 幾何畫筆

ps_cosmetic  -- 裝飾畫筆

ps_alternate -- 建立一支交替設定畫素的畫筆(此風格只用於裝飾畫筆) 

ps_userstyle -- 建立一支使用使用者提供的風格陣列的畫筆

2. 筆帽的樣式

所謂筆帽是個很奇怪的東西, 如果搞不好的話, 很容易被迷惑到了. 筆帽會在每繪製每一截線時, 在起點和終點都新增一點點的東西, 而且這一些筆帽的長度是和筆的寬度有關係的. 如圓筆帽會在每截線開頭結尾處新增乙個圓頭.

注: 我被迷惑了很久!!!! 就是在預設情況下是有筆帽的, 因此如果兩截線之間的空白處不太大的話, 這部分會被筆帽給填充滿了, 從而看不到使用者自定義的畫筆. 所以, 有時候務必要去掉該筆帽, 也就是使用flat

ps_endcap_round 

-- 尾帽是圓的

ps_endcap_square  -- 尾帽是方的

ps_endcap_flat 

-- 尾帽是平面的(注: 沒有筆帽)

3. 連線的樣式

ps_join_bevel -- 連線是斜截式的

ps_join_miter -- 當連線在::setmiterlimit函式所設定的當前限制之內時, 連線是斜接式的. 如果連線超出這個限制則成為斜截式的

ps_join_round -- 連線是圓的

我做的乙個試驗, **如下:

logbrush logbrush;

memset(&logbrush, 0, sizeof(logbrush));

logbrush.lbstyle = bs_solid;

logbrush.lbcolor = rgb(0, 0, 0);

dword dwf = ;

cpen pen1;

pen1.createpen(ps_userstyle|ps_geometric|ps_endcap_flat, 10, &logbrush,4,dwf);

cpen pen2;

pen2.createpen(ps_userstyle|ps_geometric|ps_endcap_square, 10, &logbrush,4,dwf);

pdc->selectobject(&pen1);

pdc->moveto(50, 50);

pdc->lineto(550, 50);

pdc->selectobject(&pen2);

pdc->moveto(50, 100);

pdc->lineto(550, 100);

轉至

在VC中使用CCheckListBox

在軟體應用中經常會遇到需要複選功能的列表框。類cchecklistbox實現了windows複選列表框。複選列表框顯示項的乙個列表,例如檔名列表。列表中的每項都有乙個核取方塊,方便使用。但是vc的控 件列表中並新增cchecklistbox,因此在使用cchecklistbox還要進行一些手動設定,...

在VC中使用Debug

選定debug編譯選項 build set active configuration win32 debug 或者在build工具欄上的listbox中選擇debug。debug定義了 debug巨集,而release定義了ndebug巨集。先按f12編譯browse資訊 這樣編譯後可以查到變數定義...

在VC中使用GDI

gdi 可應用於二維向量圖象,柵格圖象及排版,是為c c 程式設計師而設計的表現為c 類而存在的介面,能用於一切基於windows的應用中。作為gdi的後繼者,gdi 在gdi中增加了新功能,如文字的反鋸齒,漸變筆刷,alpha溶合 也優化了gdi許多已有的功能。此外,gdi 改變了程式設計模式,使...