GDI绘图基本步骤总结(经典)
一、獲得繪圖的窗口句柄
方法(詳細參數及其調用可以看考MSDN):
1、????????? HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName)
HWND FindWindowEx(HWND hwndParent, HWND hwndChildAfter,LPCTSTR lpClassName, LPCTSTR lpWindowName)
2、????????? HWND WindowFromPoint(POINT& Point)
3、????????? BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)??
BOOL CALLBACK EnumChildWindows(HWND hWndParent, WNDENUMPROC lpEnumFunc,LPARAM lParam)??
BOOL CALLBACK EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
?
二、由窗口句柄得到設備環境句柄HDC
方法:BeginPaint、GetWindowDC、GetDC。這些函數都需要步驟一中的HWND的句柄。調用這些函數后要釋放句柄,相應的有EndPaint、ReleaseDC進行清理。
1、?? 采用BeginPaint獲取HDC
HDC hdc;
PAINTSTRUCT ps;// 保存
hdc = ::BeginPaint( hwnd, &ps );
// 此處添加繪圖代碼
//...
::EndPaint( hwnd, &ps );
說明:獲得的hdc的有效區域僅限于客戶區無效區域的設備環境句柄,不包括標題欄、邊框等。
?
2、?? 采用GetWindowDC獲取HDC
HDC hdc = ::GetWindowDC( hwnd );
// 此處添加繪圖代碼
//...
::ReleaseDC( hwnd, hdc );
說明:繪制區域是整個窗口(邊框、標題欄、客戶區的總和)。
?
3、?? 采用GetDC獲取HDC
HDC hdc = ::GetDC( hwnd );
// 此處添加繪圖代碼
//...
::ReleaseDC( hwnd, hdc );
說明:獲得的hdc的有效區域僅限于客戶區有效區域的設備環境句柄,不包括標題欄、邊框等。
?
三、圖形繪制方法
1、?? 畫筆CreatePen
繪畫之前先選擇畫筆,畫筆的功能主要是繪制邊框,其函數原型如下:
WINGDIAPI HPEN WINAPI CreatePen(
?__in int iStyle,???????????????????????????????? // 畫筆的類型,比如是實線,還是虛線等等。
__in int cWidth,???????????????????????????????? // 線的寬度。
__in COLORREF color???????????????????????? // 線的顏色。
);
// iStyle參數可選值:
PS_SOLID?????? = 0;// 實線
PS_DASH??????? = 1;// 段線; 要求筆寬<=1
PS_DOT???????? = 2;// 點線; 要求筆寬<=1
PS_DASHDOT???? = 3;// 線、點; 要求筆寬<=1
PS_DASHDOTDOT? = 4;// 線、點、點; 要求筆寬<=1
PS_NULL??????? = 5;// 不可見
PS_INSIDEFRAME = 6;// 實線; 但筆寬是向里擴展
返回值為畫筆類型,SelectObject函數選中。選中后,返回原來畫刷的句柄用來恢復時使用。圖形繪制完畢后使用DeleteObject函數將其釋放。
SelectObject函數說明:
函數功能:該函數選擇一對象到指定的設備上下文環境中,該新對象替換先前的相同類型的對象。
函數原型:HGDIOBJ SelectObject(HDC hdc, HGDIOBJ hgdiobj);
參數:
hdc:設備上下文環境的句柄。
hgdiobj:被選擇的對象的句型,該指定對象必須由如下的函數創建。
位圖:CreateBitmap, CreateBitmapIndirect, CreateCompatible Bitmap, CreateDIBitmap, CreateDIBsection(只有內存設備上下文環境可選擇位圖,并且在同一時刻只能一個設備上下文環境選擇位圖)。
畫筆:CreateBrushIndirect, CreateDIBPatternBrush, CreateDIBPatternBrushPt, CreateHatchBrush, CreatePatternBrush, CreateSolidBrush。
字體:CreateFont, CreateFontIndirect。
筆:CreatePen, CreatePenIndirect。
區域:CombineRgn, CreateEllipticRgn, CreateEllipticRgnIndirect, CreatePolygonRgn, CreateRectRgn, CreateRectRgnIndirect。
返回值:如果選擇對象不是區域并且函數執行成功,那么返回值是被取代的對象的句柄;如果選擇對象是區域并且函數執行成功,返回如下一值;
DeleteObject函數說明:
函數功能:該函數刪除一個邏輯筆、畫筆、字體、位圖、區域或者調色板,釋放所有與該對象有關的系統資源,在對象被刪除之后,指定的句柄也就失效了。
函數原型:BOOL DeleteObject(HGDIOBJ hObject);
參數:
hObject:邏輯筆、畫筆、字體、位圖、區域或者調色板的句柄。
返回值:成功,返回非零值;如果指定的句柄無效或者它已被選入設備上下文環境,則返回值為零。
?
2、?? 畫刷
畫刷的功能主要是填充區域內的顏色,創建畫刷的方法如下:
A、CreateSolidBrush函數
函數功能:該函數創建一個具有指定顏色的邏輯刷子。
函數原理:HBRUSH CreateSolidBrush(COLORREF crColor);
參數:
crColor:指定刷子的顏色。
返回值:如果該函數執行成功,那么返回值標識一個邏輯實心刷子;如果函數失敗,那么返回值為NULL。
B、GetStockObject函數
函數功能:該函數檢索預定義的備用筆、刷子、字體或者調色板的句柄。
函數原型:HGDIOBJ GetStockObject(int fnObject);
參數:
fnObject:指定對象的類型,該參數可取如下值之一;
BLACK_BRUSH:黑色畫筆;
DKGRAY_BRUSH:暗灰色畫筆;
DC_BRUSH:在Windows98,Windows NT 5.0和以后版本中為純顏色畫筆,缺省色為白色,可以用SetDCBrushColor函數改變顏色,更多的信息參見以下的注釋部分。
GRAY_BRUSH:灰色畫筆;
HOLLOW_BRUSH:空畫筆(相當于HOLLOW_BRUSH);
LTGRAY_BRUSH:亮灰色畫筆;
NULL_BRUSH:空畫筆(相當于HOLLOW_BRUSH);
WHITE_BRUSH:白色畫筆;BLACK_PEN:黑色鋼筆;
DC_PEN:在Windows98、Windows NT 5.0和以后版本中為純色鋼筆,缺省色為白色,使用SetDCPenColor函數可以改變色彩,更多的信息,參見下面的注釋部分。
WHITE_PEN:白色鋼筆;
ANSI_FIXED_FONT:在Windows中為固定間距(等寬)系統字體;
ANSI_VAR_FONT:在Windows中為變間距(比例間距)系統字體;
DEVICE_DEFAUCT_FONT:在WindowsNT中為設備相關字體;
DEFAULT_GUI_FONT:用戶界面對象缺省字體,如菜單和對話框;
OEM_FIXED_FONT:原始設備制造商(OEM)相關固定間距(等寬)字體;
SYSTEM_FONT:系統字體,在缺省情況下,系統使用系統字體繪制菜單,對話框控制和文本;
SYSTEM_FIXED_FONT:固定間距(等寬)系統字體,該對象僅提供給兼容16位Windows版本;
DEFAULT_PALETTE:缺省調色板,該調色板由系統調色板中的靜態色彩組成。
返回值:如果成功,返回值標識聲請的邏輯對象,如果失敗,返回值為NULL。
C、CreateHatchBrush函數
函數功能:該函數可以創建一個具有指定陰影模式和顏色的邏輯刷子。
函數原型:HBRUSH CreateHatchBrush(int fnStyle, COLORREF clrref);
參數:
fnStyle:指定刷子的陰影樣式。該參數可以取下列值,這些值的含義為:
HS_BDIAGONAL:表示45度向下,從左至右的陰影;
HS_CROSS:水平和垂直交叉險影;
HS_DIAGCROSS:45度交叉陰影;
HS_FDIAGONAL:45度向上,自左至右陰影;
HS_HORIZONTAL:水平陰影;
HS_VERTICAL:垂直陰影。
cirref:指定用于陰影的刷子的前景色。
返回值:如果函數執行成功,那么返回值標識為邏輯刷子;如果函數執行失敗,那么返回值為NULL。
????????????? 畫刷的選中和釋放,請參照畫筆。
?
3、?? 點SetPixel
函數功能:該函數將指定坐標處的像素設為指定的顏色。
函數原型:COLORREF SetPixel(HDC hdc, int X, int Y, COLORREF crColor);
參數:
hdc:設備環境句柄。
X:指定要設置的點的X軸坐標,按邏輯單位表示坐標。
Y:指定要設置的點的Y軸坐標,按邏輯單位表示坐標。
crColor:指定要用來繪制該點的顏色。
返回值:如果函數執行成功,那么返回值就是函數設置像素的RGB顏色值。這個值可能與crColor指定的顏我色有不同,之所以有時發生這種情況是因為沒有找到對指定顏色進行真正匹配造成的;如果函數失敗,那么返回值是C1。
?
4、?? 直線MoveToEx、LineTo
A、?? MoveToEx
函數功能:將當前位置指定為特定的某一點
函數原型:BOOL MoveToEx( __in HDC hdc, __in int X, __in int Y, __out LPPoint lpPoint )
參數:
hdc:設備環境句柄。
X:指定要設置的點的X軸坐標,按邏輯單位表示坐標。
Y:指定要設置的點的Y軸坐標,按邏輯單位表示坐標。
lpPoint:指向一個POINT結構,用來接收前一位置,為空時,當前位置不被返回。
??????????? 返回值:執行成功返回非零,否則返回值為零。
B、?? LineTo
函數功能:從當前點到目標點進行畫線。
函數原型:BOOL LineTo( int x, int y )
參數說明:
?????? X:目標點的橫坐標。
?????? Y:目標點的縱坐標。
返回值:成功非零,其它返回零。
?
5、?? 矩形Rectangle
函數功能:該函數畫一個矩形,用當前的畫筆畫矩形輪廓,用當前畫刷進行填充。
函數原型:BOOL Rectangle(HDC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
參數:
hdc:設備環境句柄。
nLeftRect:指定矩形左上角的邏輯X坐標。
nTopRect:指定矩形左上角的邏輯Y坐標。
nRightRect:指定矩形右下角的邏輯X坐標。
nBottomRect:指定矩形右下角的邏輯Y坐標。
返回值:如果函數調用成功,返回值非零,否則返回值為0。
?
6、?? 橢圓Ellipse
函數功能:該函數畫一個橢圓形,用當前的畫筆畫矩形輪廓,用當前畫刷進行填充。
函數原型:BOOL Ellipse( HDC hdc, int x1, int y1, int x2, int y2 )
參數:
hdc:設備環境句柄。
x1:指定橢圓形左上角的邏輯X坐標。
y1:指定橢圓形左上角的邏輯Y坐標。
x2:指定橢圓形右下角的邏輯X坐標。
y2:指定橢圓形右下角的邏輯Y坐標。
返回值:如果函數調用成功,返回值非零,否則返回值為0。
7、?? 其它(參考MSDN)
?
四、舉例
void CGameView::DrawBack(CDC *pDC)
{
?HDC hDC = ::CreateCompatibleDC(pDC->GetSafeHdc());
?CRect rect;
?GetClientRect(&rect);
?//畫背景色
?//::StretchBlt(pDC->GetSafeHdc(),0,0,rect.right,rect.bottom,hDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);??
?HBITMAP hOldBmp = (HBITMAP)::SelectObject(hDC,m_bmpBg);
?BITMAP bmp;
?CBitmap::FromHandle(m_bmpBg)->GetBitmap(&bmp);
?pDC->StretchBlt(0,0,rect.right,rect.bottom,CDC::FromHandle(hDC),0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);
?//pDC->TransparentBlt(0,0,rect.right,rect.bottom,CDC::FromHandle(hDC),0,0,bmp.bmWidth,bmp.bmWidth,0);
?//畫中心圖片.
?hOldBmp = (HBITMAP)::SelectObject(hDC,m_bmpBack);
?CBitmap::FromHandle(m_bmpBack)->GetBitmap(&bmp);
?CPoint pt;
?pt.x = rect.right / 2? - bmp.bmWidth / 2;
?pt.y = rect.bottom / 2 - bmp.bmHeight / 2 ;
?pDC->BitBlt(pt.x,pt.y,rect.right,rect.bottom,CDC::FromHandle(hDC),0,0,SRCCOPY);??
?::SelectObject(hDC,hOldBmp);
?::DeleteDC(hDC);
}
void CGameView::DrawPuke(CDC *pDC)
{
?HDC hDC = ::CreateCompatibleDC(pDC->GetSafeHdc());
?CPoint pt;
?RECT rc;
?GetClientRect(&rc);
?HBITMAP hOldBmp = (HBITMAP)::SelectObject(hDC, m_bmpCards);
?BITMAP bmp;
?CBitmap::FromHandle(m_bmpCards)->GetBitmap(&bmp);
?int width = bmp.bmWidth / 13;? //每張牌的寬度和高度.
?int height = bmp.bmHeight / 4;
?//畫1號位撲克? 左上1,左中2 自己3,右中4,右上5
?HBITMAP hBmp = m_bmpCardPlus;
?::SelectObject(hDC, hBmp);
?for (BYTE i=0; i<5; i++)
?{
??BitBlt(pDC->GetSafeHdc(),m_pt[1].x,m_pt[1].y,width,height,hDC,0,0,SRCCOPY);
??m_pt[1].y += 20;
?}
?//畫2號位撲克
?//hBmp = m_bmpCardPlus;
?//::SelectObject(hDC, hBmp);
?for (BYTE i=0; i<5; i++)
?{
??BitBlt(pDC->GetSafeHdc(),m_pt[2].x,m_pt[2].y,width,height,hDC,0,0,SRCCOPY);
??m_pt[2].y += 20;
?}
?//畫3號位撲克 自己的
?hBmp = m_bmpCards;
?::SelectObject(hDC, hBmp);
?COLORREF color = ::GetPixel(hDC, 0, 0);
?
?for (BYTE i=0; i<6; i++)
?{
??int srcX = ((int)GetCardValue(g_byPuke[2][i]) - 1) *width;
??int srcY = ((int)GetCardHua(g_byPuke[2][i]) / 16 ) *height;
??//if (/*選中*/)
??//{
??//?BitBlt(pDC->GetSafeHdc(),m_pt[1].x,m_pt[1].y + 30,/*畫高一點*/width,height,hDC,0,0,SRCCOPY);
??//}
??//else
??//{
??BitBlt(pDC->GetSafeHdc(),m_pt[3].x,m_pt[3].y,width,height,hDC,srcX,srcY,SRCCOPY);
??//}
??m_pt[3].x += 15;
?}
?//畫4號位撲克
?hBmp = m_bmpCardPlus;
?::SelectObject(hDC, hBmp);
?for (BYTE i=0; i<5; i++)
?{
??BitBlt(pDC->GetSafeHdc(),m_pt[4].x,m_pt[4].y,width,height,hDC,0,0,SRCCOPY);
??m_pt[4].y += 20;
?}
?//畫5號位撲克
?//hBmp = m_bmpCardPlus;
?//::SelectObject(hDC, hBmp);
?for (BYTE i=0; i<5; i++)
?{
??BitBlt(pDC->GetSafeHdc(),m_pt[5].x,m_pt[5].y,width,height,hDC,0,0,SRCCOPY);
??m_pt[5].y += 20;
?}
?::SelectObject(hDC, hOldBmp);
?DeleteDC(hDC);
}
HDC hDC = ::CreateCompatibleDC(pDC->GetSafeHdc());
?SelectObject(hDC,m_bmpBack);
?CBitmap bitmap;??
?bitmap.LoadBitmap(IDB_CENTER_PIC);??
?CDC MemDC;??
?MemDC.CreateCompatibleDC(pDC);??
?CBitmap *pOldBitmap=MemDC.SelectObject(&bitmap);??
?BITMAP bm;??
?bitmap.GetBitmap(&bm);??
?CRect rect;
?GetClientRect(rect);
?pDC->StretchBlt(0,0,rect.right,rect.bottom,&MemDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);??
?MemDC.SelectObject(pOldBitmap);
轉載于:https://www.cnblogs.com/weiqubo/archive/2010/03/22/1929990.html
總結
以上是生活随笔為你收集整理的GDI绘图基本步骤总结(经典)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 入侵思路新手学习内容
- 下一篇: [转 TDD] 如何坚持TDD:使用者出