前言:
GDI+從Windows XP操作系統(大概2002-2003年)開始引入的,現在都9102年了,再學習這么古老的技術肯定是過時了。windows桌面程序沒落了,隨着移動的興起,用戶被慣壞了,現在,用戶對界面的要求不只是可以用,
而且天生(自發、自然而然)的希望界面能夠順滑、流暢、微動畫、抽屜效果、淡入淡出等等。使用GDI+去實現這些高端的界面需求是十分困難而工作量巨大的。因此,建議轉前端學習html5,跨平台,效果又炫。如果硬要在windows
上開發,可以關注下NUI(natural user interface)。
那,我為什么仍然寫這個博客呢。額,一言難盡,個人目前面臨轉型的困難。一直都在windows平台上開發與工作,去轉個前端新手肯定不太樂意。而且,也沒系統得學習過GDI+,覺得花一個月系統學習下還是值得的吧。人,
往往想的太多,做的太少。寫這個系列也為了督促自己。如果對他人有益就更好了。
我接觸GDI+是因為最近的兩個需求,項目是基於網易雲信Duilib開發的。
一個是圓角矩形(GDI+抗鋸齒比較好) github:https://github.com/netease-im/NIM_Duilib_Framework/pull/98
另外個是圓形進度條。 github:https://github.com/netease-im/NIM_Duilib_Framework/pull/105
ok,廢話不多說,開始學習吧。(本文的源碼可以參考github:https://github.com/xuhuajie-NetEase/GDI-Study/)
GDI+ 提供二維的矢量圖形,改進舊有的GDI,加強的可視化屬性,例如邊界,漸變和透明。通過GDI+,能夠直接將BMP轉成JPG或其它格式的圖片,還能夠生成SVG、Flash等。GDI+ 使用ARGB的值來表示顏色。GDI+的雙緩
沖技術可以提高繪圖效率,可避免屏幕閃爍。關於GDI的詳細使用可以參考《windows程序設計》一書,該書非常的有質量。也是我從事windows客戶端開發的啟蒙書。最重要的就是DC的概念(一般翻譯成設備上下文), 通過往DC里
面加畫筆、畫刷、字體等等元素,然后就可以畫畫了。對,整個窗口(准確的說是窗口有效區域【額,更准確的說是刷新區域】)可以理解為一張畫布,你可以通過DC(提前准備好筆【粗細、顏色】)然后在合適的位置做畫。GDI+
最重要的概念則是Graphics對象(所以這個UI模型稱為GUI,注意與目前流行的NUI的區別),再新建額外的筆(pen)對象,通過Graphics去畫畫。
void GDIDrawLine(HDC hdc)
{
HPEN hPen, hPenOld;
hPen = CreatePen(PS_SOLID,3,RGB(255,0,0));
hPenOld=(HPEN)::SelectObject(hdc, hPen); //往DC放畫筆對象
::MoveToEx(hdc, 50, 50, NULL);
::LineTo(hdc, 700, 50);
::SelectObject(hdc, hPenOld); //這是個好習慣
::DeleteObject(hPen); //釋放畫筆
hPen = CreatePen(PS_SOLID, 3, RGB(0, 255, 0));
hPenOld = (HPEN)::SelectObject(hdc, hPen); //往DC放畫筆對象
::MoveToEx(hdc, 50, 100, NULL);
::LineTo(hdc, 700, 100);
::SelectObject(hdc, hPenOld); //這是個好習慣
::DeleteObject(hPen); //釋放畫筆
}
void GDIPlusDrawLine(HDC hdc)
{
Graphics graphics(hdc);
Pen blue(Color(255/*不透明*/, 255, 0, 0), 3);
graphics.DrawLine(&blue, 50, 150, 700, 150);
Pen green(Color(255/*不透明*/, 0, 255, 0), 3);
graphics.DrawLine(&green, 50, 200, 700, 200);
}
如上可見,GDI+對於復雜地繪畫,邏輯簡單了很多,GDI的DC與各類繪畫工具強綁定,而 GDI+則取消了這種關聯。
我們先來簡單的試試吧。1、打開vs工具,新建一個窗口程序(win32),點擊確定。再點擊完成。
2、 在cpp上加上引用項與庫文件
#include <objidl.h> #include <gdiplus.h> #pragma comment(lib, "gdiplus.lib") using namespace Gdiplus;
3、在合適地方加上GDI+的初始化
// Initialize GDI+ GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
4、 在WM_PAINT方法下面非常加上GDI與GDI+的函數
5、編譯運行看下效果吧。