1.圖形輸出裝置分為光棚裝置和向量裝置。大部分pc輸出裝置都是光棚裝置,即以點模式表示映像。向量裝置使用線來繪製映像,如繪圖器。使用向量的程式是在硬體之上的一層抽象。
2.GDI函數的分類。
擷取(建立)、釋放(清除)裝置描述表的函數,如GetDc,ReleaseDC;擷取裝置描述表資訊的函數,如GetTextMetrics;繪圖函數,如TextOut;設著和擷取裝置描述表參數的函數,如SetTextColor控制TextOut輸出字顏色;使用GDI對象的函數,如CreatePen等。
3.圖元。直線和曲線,由Pen畫;填充地區;位元影像;文本;
4.裝置描述表的擷取方式:
1)hdc = BeginPaint(hwnd,&ps);
EndPaint(hwnd,&ps);
2)hdc = GetDC(hwnd); // Note:GetDC(NULL)擷取整個螢幕的DC
ReleaseDC(hwnd,hdc);
3)hwd = GetWindowDC(hwnd);
ReleaseDC(hwnd,hdc);
4)hdc = CreateDC(lpszDriverName, lpszDeviceName, lpszOutput, lpInitData); // Note:CreateDC(_T("DISPLAY"),NULL,NULL,NULL)擷取整個螢幕DC
DeleteDC(hdc);
5)hdcMem = CreateCompatibleDC(hdc); //使用位元影像時,可用記憶體裝置描述表
DeleteDC(hdcMem);
6)hdcMeta = CreateMetaFile(pszFileName); //擷取元檔案裝置描述表
hmf = CloseMetaFile(hdcMeta);
5.一個裝置描述表通常就是一個物理顯示裝置。
iValue = GetDeviceCaps(hdc, iIndex); //根據iIndex擷取dc的相關屬性。
6.儲存裝置描述表。
wndclass.style = CS_OWNDC; //可以為視窗建立自己的DC,在修改DC之後DC一直有效直到EndPaint或者ReleaseDC。
idSaved = SaveDC(hdc);
//修改DC屬性
RestoreDC(hdc,idSaved); //恢複儲存的DC
上述語句等價於 SaveDC(hdc);
RestoreDC(hdc,-1);
7.畫線。
影響畫線的dc屬性:當前畫筆位置;畫筆;背景方式;背景色;繪圖模式。
畫直線:
MoveToEx(hdc,xBeg,yBeg,NULL);
LineTo(hdc,xEnd,yEnd);
GetCurrentPositionEx(hdc,&pt);//擷取當前位置
8.畫筆。
HPEN hPen,hPenOld;
hPen = GetStockObject(WHITE_PEN); //擷取現有畫筆的控制代碼
hPenOld = SelectObject(hdc,hPen);//將畫筆選進裝置描述表,hPenOld記錄老的畫筆
//CreateOwnPen
HPEN hPen = CreatePen(iPenStyle,iPenWidth,crColor); // 一種方法
LOGPEN logpen;
HPEN hPen = CreatePenIndirect(&logpen);//另一種方法
DelectObject(SelectObject(hdc,hPen));//及時刪除畫筆,節省資源
//擷取畫筆資訊
GetObject(hPen,sizeof(LOGPEN),(LPVOID)&logpen);//擷取hPen屬性
hPen = GetCurrenObject(hdc,OBJ_PEN);//擷取當前dc中HPEN
//點畫線和虛線的空隙填充,受dc的背景模式和背景色影響
SetBkColor(hdc,crColor);//設定背景顏色
SetBkMode(hdc,TRASPARENT);//TRANSPARENT組織填充背景,OPAQUE模式將用背景色填充空隙
//繪圖方式
//畫筆像素與目標位置處原來像素之間按位元運算,叫做“光柵運算”ROP,畫線只有二維,稱為ROP2,有意思的東西。
SetROP2(hdc,iDrawMode);
iDrawMode=GetROP2(hdc);//預設為R2_COPYPEN,畫筆色彩替代背景
9.填充地區。
Rectangle、Ellipse、RoundRect、Chord、Pie、Polygon、PolyPolygon
邊界框畫法跟畫線一樣、封閉地區使用HBRUSH填充。
HBRUSH hBrush = GetStockObject(WHITE_BURSH);
SelectObject(hdc,hBrush);
SelectObject(hdc,GetStockObject(NULL_PEN));//畫無邊界框
SelectObject(hdc,GetStockObject(NULL_BRUSH));//不填充地區
//多邊形的填充方式有ALTERNATE和WINDING兩種,區別很神奇。
10.畫刷。
HBRUSH hBrush = CreateSolidBrush(crColor);//建立畫刷
hBrush = CreateHatchBrush(iHatchStyle,crColor);//建立斜影畫刷
hBrush = CreatePatternBrush/*CreateDIBPatternBrushPt*/; //建立基於位元影像的畫刷
LOGBRUSH logBrush;
hBrush = CreateBrushIndirect(&logBrush);
//其餘操作類似HPEN
11.GDI映射方式。
SetMapMode(hdc,iMapMode);
iMapMode = GetMapMode(hdc);
//至於其他相關映射方式,個人認為使用的可能性很小。
12.矩形、地區、剪裁。
FillRect(hdc,&rect,hBrush);//無需將hBrush選進hdc
FrameRect(hdc,&rect,hBrush); //用brush畫矩形框,但不填充
InvertRect(hdc,&rect); //將矩形框中所有像素翻轉
SetRect(&rect,xLeft,yTop,xRight,yBottom);
OffsetRect(&rect,x,y);//將矩形移動幾個單元
InflateRect(&rect,x,y);//增減矩形的尺寸
SetRectEmpty(&rect);//矩形為0
CopyRect(&rcDest,&rcSrc);//拷貝
IntersectRect(&rcDest,&rcSrc1,&rcSrc2);//取兩矩形交集
UnionRect(&rcDest,&rcSrc1,&rcSrc2);//取兩矩形並集
bEmpty = IsRectEmpty(&rect);//確定是否為空白
bInRect = PtInRect(&rect,Point);//點是否在矩形內
13.PeekMessage(&msg,NULL,0,0,PM_REMOVE);//大傢伙,值得注意
The PeekMessage function normally does not remove
WM_PAINT messages from the queue. WM_PAINT messages remain in the queue until they are processed. However, if a
WM_PAINT message has a NULL update region, PeekMessage does remove it from the queue.
—— 摘自MSDN 貌似跟書上說的有出入,需要注意
14.地區
HRGN hRgn = CreateRectRgn(xLeft,yTop,xRight,yBottom);
hRgn = CreateRectRgnIndirect(&rect);
hRgn = CreateEllipticRgn(xLeft,yTop,xRight,yBottom);
hRgn = CreateEllipticRgnIndirect(&rect);
iRgnType = CombineRgn(hDestRgn,hSrcRgn1,hSrcRgn2,iCombine);
//地區填充參數類似Rect
小結:
最近公司項目用到了大量畫圖操作,主要設計介面自畫,重複的將bitmap貼到特定rect,設定透明色。作為windows程式設計,不可避免的都會涉及到自畫控制項的開發,而自畫控制項很大一部分工作就是改變控制項的UI,畫圖基礎可以讓自己更好的理解代碼,