国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

對C#中的TreeView添加背景圖

2024-07-21 02:28:48
字體:
來源:轉載
供稿:網友

最大的網站源碼資源下載站,

  在微軟的.net的forms窗口控件中,比如treeview和listview,僅僅是對通用控件的簡單封裝,因此他們不正常的引發paint事件。 微軟所發布內容中,能看到的唯一建議就是設置控件的controlstyles.userpaint類型,然后自己為控件做所有的繪圖操作。 (譯注:老外提供了一個treeviewwithpaint控件類,派生自treeview類,提供了paint事件的掛接。)

  一、為了解決這個問題,我們在類內部使用了一個基于bitmap類的graphics對象。當任何窗口重新定義大小時候,對象都會重建。

//recreate internal graphics object
protected override void onresize( system.eventargs e )
{
 if( internalbitmap == null || internalbitmap.width != width || internalbitmap.height != height )
 {
  if( width != 0 && height != 0 )
  {
   disposeinternal();
   internalbitmap = new bitmap( width, height );
   internalgraphics = graphics.fromimage( internalbitmap );
  }
 }
}

  二、重寫窗口過程

  當控件收到了wm_paint消息時候,將執行下面的三個步驟:

  1. 通過一個內部的wm_printclient消息,讓原來的控件過程把圖象畫到內部的graphics對象上。

//draw internal graphics
intptr hdc = internalgraphics.gethdc();
message printclientmessage = message.create( handle, wm_printclient, hdc, intptr.zero );
defwndproc( ref printclientmessage );
internalgraphics.releasehdc( hdc );

  2. 使用內部的graphics對象建立painteventargs參數,引發用戶的onpaint()函數。

//add the missing onpaint() call
onpaint( new painteventargs( internalgraphics, rectangle.fromltrb(
updaterect.left,
updaterect.top,
updaterect.right,
updaterect.bottom ) ) );

  3. 把內部graphics對象的位圖拷貝到屏幕的graphics設備上。

//draw screen graphics
screengraphics.drawimage( internalbitmap, 0, 0 );

wm_erasebkgnd消息被過濾掉,什么都不做。 case wm_erasebkgnd:
//removes flicker
return;

  三、所提供的代碼和測試程序能使用paint事件在treenode在被選中的時候,在其邊框上畫個黃色的邊框。但是,其實對于我實際要用的項目來說,需要添加背景圖的功能沒有實現。而這里離我們的目的還有一步之遙,我們對前文繪圖過程2和3之間加一個步驟:

bitmap temp = new bitmap(internalbitmap, internalbitmap.size); // 建立一個臨時的位圖temp,保存前面繪好的界面

temp.maketransparent(color.white); // 設置白色為透明色
internalgraphics.fillrectangle(brushes.white, 0, 0, this.bounds.width, this.bounds.height);
// 在原來的內部位圖對象上,用白色重畫背景
if (image != null) // 如果設置了背景圖,就在內部對象上畫背景
internalgraphics.drawimage (image, 0, 0, image.width, image.height);
internalgraphics.drawimage(temp, 0, 0, temp.width, temp.height);// 把前面繪好的界面按白色為透明色復合到內部位圖上
screengraphics.drawimage( internalbitmap, 0, 0 ); // 把合成的臨時位圖刷到屏幕上

  其實,這里還存在一個問題:在處理wm_paint消息時候,通常的做法是使用beginpaint和endpaint函數來操作dc畫圖的,當樹結點展開或者折疊時候,我們收到wm_paint消息,并由消息得到的刷新區域或者說刷新矩形。關鍵就是在于,這里的刷新區域不是整個客戶區,背景圖會出現重疊的部分而變形。

  解決方法:考慮使用getdc和releasedc操作,可以避開刷新區域的限制,我們可以把整個客戶區重畫,而實現背景圖的完整性。這里要非常注意的是:beginpaint和endpaint函數會自動把需要刷新的區域設為有效,而getdc和releasedc函數不會,所以我們要自己增加兩個操作getupdaterect和validaterect,也就是自己把需要刷新的區域設置為有效。否則:會不停的得到wm_paint消息,和死循環一樣,cpu占用達到100%。


圖一 測試程序

  四、結束語

  由于使用了win32的api函數,因此附加了一個win32內部類,導入了自己需要的函數。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 松阳县| 碌曲县| 中江县| 三亚市| 玉环县| 扶沟县| 东阿县| 姜堰市| 海门市| 皮山县| 敖汉旗| 昌邑市| 缙云县| 东乌珠穆沁旗| 河南省| 岳普湖县| 正蓝旗| 安多县| 平江县| 石屏县| 来凤县| 察哈| 万州区| 将乐县| 阿克陶县| 南康市| 安仁县| 衡南县| 长顺县| 繁峙县| 新竹市| 北票市| 环江| 满洲里市| 紫阳县| 高清| 嘉禾县| 喀喇沁旗| 长乐市| 永城市| 新疆|