c# 實現真正的透明控制項(windows桌面程式)
yangshengchuan 發布於2017-02-07
由於上位機程式的需要,需要大量的異性控制項,開始不以為然,心想隨著gdi到gdi+的公升級,微軟應該會給net打造了一套高效絢麗的繪圖方案,使用後才知道完全不是我以為的那麼回事.
其中使用web.transparent的透明方案:
label使用的的透明方案
如圖,這種透明系統參考的是控制項所屬控制項背景色,並不是透明,注意左邊的兩個紅色框,其實是兩個實現真正透明的控制項
而通過背景截圖來作為自己背景圖的方案:
由於需要編寫太多**,就不舉例了,看起來挺不錯,但也經不起推敲,畢竟很多時候,透明者需要蓋住一些與使用者互動的控制項,可想而知,這種設計將是致命的。
因為form有transparencykey屬性,很容易實現真正的透明,就想乾脆繼承form來做控制項,使用的時候,直接setparent豈不美好,先不說資源耗費,使用者體驗.單單位置控制都夠嗆,其訊息佇列性質的不同,帶來的問題,完全不可取,而且在窗體在被指定到窗體後,其透明屬性竟然失效了,大寫的囧
難道就沒辦法了嗎??由於透明控制項的實現尚未有好的方法,該想法被擱置了半年.
某個偶爾的機會,接觸到了region物件,關於該物件詳細資訊請參閱微軟的官方文件,但是官方文件也只是機械的介紹了該物件成員而已,看不出什麼蹊蹺的。
我是這麼理解這個物件的,該物件告訴了系統這個控制項需要占用的介面ui資訊,而且這個資訊是可以隨意編輯的,,,,好知道這麼多就夠了,如果我把這個物件編輯成我要的形狀呢?是不是其他不需要的就消失了?懷著這樣疑問寫下**:
region rion = new region(new rectangle(0, 0, 20, 20));
region = rion;
乖乖,控制項竟然無論我怎麼繪製,在視窗上都只有 20×20 大了,儘管我拖得了很大
而情況也恰是如此,通過控制region的資訊,完全可以控制控制項需要現實和不現實(透明)的部分,
那麼問題來了,一些規則的透明還好辦,但是如果需要按某種特定無規則來異形呢..難道要一點點去算嗎?那也太不科學了,想到這裡,自然想到通過 image(bitemap)轉換成region
首先看region的建構函式
使用乙個graphicspath 物件來構造,通過搜尋影象的每個畫素,來將需要顯示的區域新增的路徑畫布裡,是否可行呢!
由於主題關係,這裡延伸對graphicspath物件講解,不熟悉的朋友參考相關資料,謝謝。
根據這一想法,編寫轉換**
/// 根據計算graphicspath路徑(低效率)
/// 影象資源
/// 欲透明掉的顏色
/// 路徑畫布,已過濾掉了透明顏色
public static graphicspath imagetographicspath(image imgx,color trancolor)
}else
}//if curcolor
istransrgn = curcolor == trancolor; }}
return g;
}
結果如圖:
達到目的...似乎任務完成了,,但是回頭想想不對呀!為什麼要通過graphicspath來中間轉換呢?為什麼不直接把座標填充到region 裡呢,
因為region 有乙個方法是:
通過graphicspath來轉換,可能帶來其他資源類問題,直接使用這方法估計是不錯的選擇,於是增加函式:
///
/// 根據計算region路徑(低效率)
///
/// 影象資源
/// 欲透明掉的顏色
/// 乙個離散的路徑資訊
public static region imagetoregion(image imgx, color trancolor)
}else//非透明色
}//if curcolor
istransrgn = curcolor == trancolor;}}
return rregion;
}結果同樣成功,就不在上圖..
然而似乎沒什麼問題了,但是細心的朋友可能感覺到了,這種方法讀取影象資源是一種極度效率低下的方法,這種直接
getpixel怎麼都不像用在如此大量影象處理上的,,,如果用來展示動畫類,豈不夠嗆!
這裡不對c#指標,影象處理的知識擴充套件,不安全**等知識擴充套件。儘管我們在接下來的函式使用到相關知識,如果有興趣的請自行參閱相關文件
修改相關函式提公升效率,減少資源耗費
/** 為了鼓勵學習研究精神,該函式,僅能用於本示例
* 如果使用到其他專案,可能會存在錯誤
* 如果您確實需要正確**,請學習位圖相關資訊
*////
/// 取得乙個中非透明色部分的區域。
///
/// 取其區域的。
/// 透明色。
/// 中非透明色部分的區域
public unsafe static region imagetoregionpx(image picture, color transparentcolor)
else if (start > -1 && (p[0] == p0 && p[1] == p1 && p[2] == p2)) //如果 之前的點是不透明 且 透明
if (x == width - 1 && start > -1) //如果 之前的點是不透明 且 是最後乙個點
p += 3;//下乙個記憶體位址
}p += offset;
}bitmap.unlockbits(bmdata);
bitmap.dispose();
return rgn;
}到此,真正的c#桌面程式透明控制項設計完成...
相關源**(vs2008)開發
已刪除,資源積分到50了,自己會變大)
C 實現透明背景的垂直Label控制項
本文描述如何在c 中建立乙個透明背景色的垂直label使用者控制項。該使用者控制項允許你從底部或頂部開始繪製文字。本文是vertical label control in vb.net的延續。其實,更準確的說,我是把他的工作翻譯到c 中,並新增了從下向上顯示文字的功能。另外,支援背景透明。使用 本文...
C 透明控制項(WinForm)
public partial class tspcontrol usercontrol private image img public image image set protected override void onlocationchanged eventargs e protected o...
EVC中透明控制項的實現
本文從建立乙個工程開始詳細說明如何用 evc實現 wince 應用程式下的透明控制項 這裡實現按鈕和static 1.新建乙個 mfc對話方塊工程取名 transbutton 2.在 resourceview 處插入一背景 idb bitmap1 3.在對話方塊中拉 4個控制項 兩個按鈕,兩個 st...