張曉慧, 徐向文, 姚恒傳
(1.上海船舶運輸科學研究所 艦船自動化分所,上海 200135; 2.蘇州杜科設備工程有限公司,江蘇 昆山 215300)
隨著計算機技術的發(fā)展,監(jiān)控系統(tǒng)對界面顯示的要求也從簡單的文字顯示轉化為以圖形界面為主,顯示風格從簡單的WINDOWS灰白界面向多種顯示基色發(fā)展,對顯示內容也提出了更高的要求。由于通用WINDOWS提示在顯示時會擋住一部分正常顯示界面,這樣就有用戶提出了在提示窗進行半透明顯示的要求。
圖形設備接口+(GraphicsDeviceInterfacePlus,GDI+)是微軟的.NET Framework類庫的組成部分,用于圖形編程。在微軟以前的開發(fā)工具中,使用GDI進行圖形編程,相當復雜,而GDI+是GDI的包裝器,簡化了圖形程序設計任務。GDI+與GDI的不同之處在于不僅提供了很多新功能,如像素消除鋸齒技術,漸變畫筆,變形和矩陣對象,獨立的路徑對象、基數(shù)樣條、對多圖像格式的支持和Alpha混合等;更重要的是它改變了編程模型,GDI是基于句柄的而GDI+是基于對象模型的。使用GDI+,只需創(chuàng)建1個Graphics對象,然后以熟悉的面向對象樣式調用其方法,而沒有必要去考慮句柄和設備環(huán)境(DeviceContext)的概念。設備環(huán)境位于GDI的核心,Graphics對象也位于GDI+核心,其作用相似, 但在使用設備環(huán)境的基于句柄的編程模式和使用Graphics對象的基于面向對象的編程模型之間,存在一些基本的差異。Graphics對象(和設備環(huán)境一樣)與屏幕上特定的窗口關聯(lián),并具有指定如何繪制項目的屬性(如SmoothingMode),但是,Graphics對象不受鋼筆、畫筆、路徑、圖像或字體的約束,這與設備環(huán)境不同,例如,使用設備環(huán)境繪制線條之前,必須先調用SelectObject以使鋼筆對象和設備環(huán)境關聯(lián),將鋼筆選入設備環(huán)境中。在設備環(huán)境中繪制的所有線條均使用該鋼筆(只有一支畫筆是可以使用的),直到選擇另一支不同的鋼筆為止。而在GDI+中,將Pen對象作為參數(shù)傳遞給Graphics類的DrawLine方法,可以在一系列DrawLine調用的每個調用中使用不同的Pen對象,而不必使給定的Pen對象和Graphics對象關聯(lián)。也就是說,在GDI+中,可以同時使用多個畫筆進行不同的繪圖操作[1]。
要實現(xiàn)透明顯示,可在VC(Microsoft Visual C++)開發(fā)環(huán)境下使用GDI+技術完成。
由于VC6.0 本身并不帶有GDI+函數(shù)庫,需要下載GDI+函數(shù)庫,在工程目錄下建立GdiFiles目錄,將下載的GDI+文件拷貝到該目錄下,并使工程包含GdiFilesGdiPlus.lib庫文件,包含gdiplus.h頭文件,并為GDI+申請using namespace Gdiplus。這樣就能在VC6.0中使用GDI+。
在VC2010中由于開發(fā)工具已包含GDI+,因此可直接使用。
在使用GDI+庫前必須先向系統(tǒng)注冊,使用語句為:
Gdiplus::GdiplusStartupInput gdiplusStartupInput
然后初始化GDI+相關句柄,使用語句為:
Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL)
在程序退出前必須注銷GDI+,使用語句為:
Gdiplus::GdiplusShutdown(m_gdiplusToken)
使用GDI+庫,建立與顯示關聯(lián)的graphics指針
Graphics graphics(pDC->m_hDC).
設置半透明顯示的底色
COLORREF col = RGB(250,250,250)
設置半透明顯示的文字色
COLORREF coltxt = RGB(0,0,0)
設置半透明度
int fillair=150;(透明度范圍在0-255,值越小透明度越高)
建立半透明畫刷
SolidBrush brush(Color(Color::MakeARGB(BYTE(fillair), GetRValue(col), GetGValue(col), GetBValue(col)))) 創(chuàng)建筆刷,第一項是透明度,后三項是RGB值
建立半透明區(qū)域 Rect rcFill(25,25,200,100),其參數(shù)為left,top,Width,Height
顯示半透明區(qū)域 graphics.FillRectangle(&brush, rcFill)
建立半透明畫刷
SolidBrush brush1(Color(Color::MakeARGB(BYTE(fillair), GetRValue(coltxt), GetGValue(coltxt), GetBValue(coltxt)))) 創(chuàng)建一個筆刷,第一項是透明度,后三項是RGB值
選擇顯示文字字體
FontFamily fontFamily(L"Latha")
設置字體大小和顯示風格
Font font(&fontFamily,0.15,FontStyleRegular,UnitInch)
設置顯示位置
PointF pointF(25,25)
顯示提示信息
graphics.DrawString(L"測點信息:",-1,&font,pointF,&brush1)
pointF.Y=pointF.Y+20;
graphics.DrawString(L"1#發(fā)電機曲軸箱進口滑油溫度",-1,&font,pointF,&brush1);
pointF.Y=pointF.Y+20;
graphics.DrawString(L"安裝部位:",-1,&font,pointF,&brush1);
pointF.Y=pointF.Y+20;
graphics.DrawString(L"1#電站1#發(fā)電機曲軸",-1,&font,pointF,&brush1);
按照上述步驟進行編程,執(zhí)行效果見圖1。
圖1
完成以上步驟,就能實現(xiàn)提示窗體的半透明顯示,并且顯示的透明度還可自由調節(jié)。但在實際應用中還會遇到以下問題:由于半透明顯示時GDI系統(tǒng)將會取得該區(qū)域屏幕顯存,如果用戶定時對屏幕進行畫屏顯示操作,由于獲取的是上次已顯示的半透明顯存,疊加后會產生顯示透明度逐漸加深的情況。解決這一問題的方法是使用顯示雙緩沖[3]的方法。雙緩沖就是除了在屏幕上有圖形進行顯示以外,在內存中也有圖形在繪制??梢园岩@示的圖形先在內存中繪制好,然后再一次性的將內存中的圖形按照一個點一個點地覆蓋到屏幕上。這樣在內存中繪圖時,由于內存中的圖形未進行半透明顯示,所以可以避免疊加效果。
參考文獻:
[1] 李順亮,王新輝,鐘碧良.應用GDI+和C#開發(fā)船舶壓載水監(jiān)控系統(tǒng)控件[J].廣州航海高等??茖W校學報,2012,20(1):4-6.
[2] 於文雪,李松毅,羅立民.基于Windows GDI的圖形圖像處理探討[J].計算機工程,2003,29(2):270-272.
[3] 韓麗娜,石昊蘇.使用雙緩存來解決GDI下的閃爍問題[J].計算機工程與設計,2006,27(17):3257-3260.