`
blogfeifei
  • 浏览: 1198949 次
文章分类
社区版块
存档分类
最新评论

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;
this->GetClientRect(rect);
pDC->StretchBlt(0,0,rect.right,rect.bottom,&MemDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
MemDC.SelectObject(pOldBitmap);

分享到:
评论

相关推荐

    c#编写的 WindowsMobile GDI绘图程序

    c#编写的 WindowsMobile GDI绘图程序源代码,很好很强大哦

    深入c# GDI+简单绘图的具体操作步骤(一)

    最近对GDI+这个东西接触的比较多,也做了些简单的实例,比如绘图板,仿QQ截图等. 最早接触这个类,是因为想做仿QQ截图的效果.巧的很,学会了如何做截图后,.NET课堂上老师也正巧要讲关于c#绘图方面的知识,并且我...

    深入c# GDI+简单绘图的具体操作步骤(四)

    前几篇我已经向大家介绍了如何使用GDI+来绘图,并做了一个截图的实例,这篇我向大家介绍下如何来做一个类似windows画图的工具.个人认为如果想做一个功能强大的绘图工具,那么单纯掌握GDI还远远不够,我的目前也只能...

    深入c# GDI+简单绘图的具体操作步骤(三)

    前两篇已经基本向大家介绍了绘图的基本知识.那么,我就用我们上两篇所学的,做几个例子.我们先来做一个简单的--仿QQ截图

    深入c# GDI+简单绘图的具体操作步骤(二)

    本篇文章是对GDI+简单绘图的绘图知识进行了详细的分析介绍,需要的朋友参考下

    GDI+双缓冲高效绘制点

    实现GDI+双缓冲绘图的具体代码步骤,也提供了整个思路,期望能够给后来的人节约点研究时间,个人感觉使用GDI+绘制提高效率最好的办法。

    C#使用GDI画圆的方法

    您可能感兴趣的文章:深入C# winform清除由GDI绘制出来的所有线条或图形的解决方法深入c# GDI+简单绘图的具体操作步骤(一)深入c# GDI+简单绘图的具体操作步骤(二)深入c# GDI+简单绘图的具体操作步

    基于MFC的OpenGL绘图.doc

     GDI是通过设备句柄(Device Context以下简称"DC")来绘图,而OpenGL则需要绘制环境(Rendering Context,以下简称"RC")。每一个GDI命令需要传给它一个DC,但与GDI不同,OpenGL使用当前绘制环境(RC)。一旦在一个...

    TabCtrl:控件具有27种内置的选项卡绘制样式,包括VS2003,VS2008,VS2010和VS2019选项卡。 MFC控件,使用GDI和GDI +绘图

    Control具有27种内置的选项卡绘图样式,包括VS2003,VS2008,VS2010和VS2019选项卡。 所有样式的工程图都是通过编程方式创建的,不需要资源。 您可以通过编辑现有的渲染类或创建一个新的渲染类来创建自己的样式。 ...

    c++面试题基础分享.doc

    40.GDI对象绘图步骤 41.设备上下文DC 42.GDI位图绘制步骤 43.当模态对话框点开后,主窗口还能响应处理消息吗 44.MFC的消息分类 45.CListCtrl 虚拟列表技术 46.虚函数是怎么实现的 47.什么是内存泄漏?面对...

    精通MFC (光盘) 源代码

    11.1 GDI绘图的编程模型 11.1.1 逻辑空间和设备空间 11.1.2 设备上下文 11.1.3 GDI对象 11.1.4 坐标变量和坐标映射 11.2 绘制图形 11.2.1 画线 11.2.2 绘制矩形 11.2.3 绘制椭圆 11.2.4 绘制弧线 11.2.5 ...

    天罡gg - C# 代码挑战画【动态带魔法】圣诞树

    对于圣诞树,网上各像编程语言像python、css、java、c/c++都有见到过了,那么在绘图方面,还有一位实力强劲的语言,那就C#语言,它的GDI+技术也可以称的上是笑傲江湖,但网上鲜见C#代码画的圣诞树,所以今天我就使用...

    Visual C# 2005程序设计自学手册 源码--iso文件!!(切记)

    学后效果:可以编写小型实例,提高篇(快速提高)掌握如何使用ADO.NET技术操作数据库,掌握文件处理技术及帮助文件的使用,掌握GDI+绘图Windows打印技术,掌握网络开发技术及注册表技术,熟悉Windows应用程序打包与...

    visual c++ 开发宝典 源码

    7.3.2 图形绘制基本原则 7.3.3 画笔 7.3.4 画刷 小结 第2篇 关键控件篇(MFC) 第8章 常用界面控件 8.1 静态文本(staticText)控件 8.1.1 传统控件通知消息 8.1.2 静态控件的使用 8.1.3 CStatic类的主要成员函数 8.2...

    Visual C++2010开发权威指南(共三部分).part1.rar

    9.3 微软GDI绘图简介 416 9.3.1 GDI基础 416 9.3.2 GDI结构 417 9.3.3 GDI函数调用 417 9.3.4 GDI基本图形 418 9.4 GDI笔绘图 419 9.4.1 CPen类简介 419 9.4.2 使用GDI绘制线条 419 9.4.3 使用CPen类绘制指定的线条 ...

Global site tag (gtag.js) - Google Analytics