windows GDI+ 繪圖的簡單封裝

由於用mfc經常需要在界面上進行一些繪製輸出,所以用windows GDI比較多,但是用windowsGDI 繪圖比較麻煩,剛開始學的時候還經常弄不清一堆DC, Object, HANDLE到底是幹啥的。後來就琢磨清楚了,但爲了用起來更方便,就弄個類,這樣畫什麼就直接調對應的函數和常用的控制參數,比如大小位置顏色,而不需要自己去操控上下文、繪製畫筆畫刷等等麻煩事,而且一個函數完成一個簡單圖形的繪製,後面又學了gdi+,就重寫了部分函數實現,用了更簡單的方式完成。

爲了避免閃爍,這裏用了雙緩存的原理,其實就是相當於在內存裏開闢空間畫完後在顯示在屏幕上。至於閃爍的緣由,在我的另一篇博文裏面有淺淺的探究:http://www.straka.cn/blog/flickering-in-mfc/

這裏也不得不指明這麼做是有損效率的,因爲期間會重複創建和銷燬畫筆畫刷等對象。但對於多數應用場景,這個損失是可以接受的。

要使用GDI+(Graphics device interface),要做些鋪墊工作,

一般爲了方便在應用程序的實例初始化階段就可以把gdiplus一起初始化了,然後實現ExitInstance虛函數,在其中釋放使用gdiplus所佔的資源。

封裝的類:

class CDrawMethod
{
	HWND m_dlgHWND; //the handle of dialog window
	CDC *m_pDC;     //the device context of dialog
	CDC m_dcMem;    //the memory dc, to contain all the drawing than flush onto screen
	CBitmap m_bmpMem;  //bitmap bind to memory dc--m_dcMem 
	Gdiplus::Graphics* m_pGraph; //point to the object of Gdiplus
	
	CDrawMethod(HWND hwnd, CDC *pDC);
	~CDrawMethod();
	//call this func to init the member before any draw method
	int BeginDraw();
	//after all operate has been executed(drawn on memory DC), call this to draw on screen
	void DrawOnScreen();
	//call this func after all operate has done, free or release the resources, in case of memory leak
	int EndDraw();
	
	//save picture in memory DC to path as jpg file
	int SaveMemDCAsJPG(char* strPath);
	int SaveMemDCAsBMP(char* strPath);

	//return the memory bitmap member 
	CBitmap *GetMemBitmap();
	//return the memory DC member
	CDC *GetMemDC();
public:
	CRect m_rtClient;
};

主要的成員和函數都在上述代碼中列出,使用的話每次新建類實例,傳入對話框句柄HANDLE和設備上下文DC,然後調用BeginDraw()初始化,等全部函數執行完畢,再調用DrawOnScreen()畫到屏幕上,最後EndDraw()釋放資源。如果需要更進一步的操作可以用GetMemBitmap() 和 GetMemDC()方法取得內存位圖和畫布進一步操作。但是注意這裏的指針是指向成員的,用完不可釋放,類內部管理。如果畫完不需要顯示在顯示器上也可以用SaveMemDCAsJPG 和 SaveMemDCAsBMP 函數輸出到文件。

而具體承擔繪圖任務的函數是自定義可以添加的:

我就把常用的一些添加了進來,畫矩形、橢圓形、多邊形框、及填充矩形、橢圓形、多邊形內部、畫矩形、橢圓形陰影,畫圓角矩形、畫立方體,繪製圖片,以及輸出文字。

其中畫矩形陰影實現就是畫了尺寸稍大的多個矩形,這種比較簡單,當然也有別的處理方法,根據大家需要另外添加函數即可。

使用示例:

在對話框OnPaint函數中添加代碼:

在第11行處添加畫圖代碼,比如:

上述代碼繪圖效果:


Demo源碼等更多信息見原博客:

http://www.straka.cn/blog/encapsulate-gdi-draw-method/

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