您的位置:首页 > 编程语言

windows基础编程----第五篇(实现更为丰富的绘图)

2016-03-20 13:23 288 查看
这一篇继续给大家讲解一下windows编程中的GDI。

通过上一篇的学习,我们简单的用系统自定义的画笔和画刷来调用GDI进行画图。但这是系统自带的,我们更希望有自己的画笔与画刷,这样世界才能够拥有五彩缤纷。

现在就让我们来回顾一下上一篇中进行系统GDI进行画图的步骤吧:

1.设备环境的准备;
2.调用GDI接口;
3.释放设备环境。
好,既然要拥有自己的画笔与画刷,那么我们就需要自己创建,然后代替系统默认的画笔画刷,最后不用的时候就把它洗干净并恢复系统默认的画笔画刷。
具体步骤如下:
1.获得设备环境

2.创建自己的画笔画刷

3.把自己的画笔画刷选入设备环境

4.调用GDI接口

5.恢复设备环境的画笔画刷并删除自己的画笔画刷
6.释放设备环境

现在我们就直接贴代码吧~
#include <windows.h>

HPEN hOldPen, hPen;
HBRUSH hOldBrush, hBrush;
HDC hdc;
//窗口过程处理函数
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
//1.获得设备环境
hdc = GetDC(hwnd);
//这一步是把设备环境的画笔画刷保存起来,以便后面恢复的时候直接代入
hOldPen = (HPEN)GetStockObject(DC_PEN);
hOldBrush = (HBRUSH)GetStockObject(DC_BRUSH);
//2.创建自己的画笔画刷
hPen = CreatePen(PS_SOLID, 2, COLORREF(RGB(255, 0, 0)));
hBrush = CreateHatchBrush(HS_HORIZONTAL, COLORREF(RGB(0, 255, 0)));
//3.把自己的画笔画刷选入设备环境
SelectObject(hdc, hPen);
SelectObject(hdc, hBrush);
return 0;

case WM_PAINT:
//4.调用GDI接口
//矩形
Rectangle(hdc, 0, 200, 100, 300);

return 0;
case WM_DESTROY:

//5.恢复设备环境的画笔画刷并删除自己的画笔画刷
SelectObject(hdc, hOldBrush);
SelectObject(hdc, hOldPen);
DeleteObject(hPen);
DeleteObject(hBrush);
//6.释放设备环境
ReleaseDC(hwnd, hdc);

PostQuitMessage(0);
return 0;
}

return DefWindowProc(hwnd, message, wParam, lParam);
}
//主函数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpszCmdLine, int nCmdShow)
{
//设计窗口类
WNDCLASS wndclass = {
CS_HREDRAW | CS_VREDRAW,
WndProc,
0,
0,
hInstance,
LoadIcon(NULL, IDI_APPLICATION),
LoadCursor(NULL, IDC_ARROW),
(HBRUSH)GetStockObject(WHITE_BRUSH),
NULL,
TEXT("MYDEMO")
};
//注册窗口类
RegisterClass(&wndclass);
//创建窗口类
HWND hwnd = CreateWindow(
TEXT("MYDEMO"),
TEXT("MyDemo"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
//显示窗口
ShowWindow(hwnd, nCmdShow);

//更新窗口
UpdateWindow(hwnd);

//消息循环
MSG Msg;
BOOL bRet;
while ((bRet = GetMessage(&Msg, NULL, 0, 0)) != 0)
{
if (bRet == -1)
{
break;
}
else
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
return Msg.wParam;
}

上面的代码需要说明一下,当窗口被创建的时候,会给窗口处理函数发送一个WM_CREATE消息,所以,我们就在这里进行设备的准备,画刷画笔的创建和选入。当窗口被关闭时,我们就在WM_DESTROY中删除我们创建的画笔画刷,恢复设备环境。

好,这里我们就来说说这个代码的具体实现步骤。
之前我们通过BeginPaint()和EndPaint()来实现设备环境的创建与获取,不过,这两个接口只能在WM_PAINT消息得到实现。那么问题来了,如果我们需要在外面获取DC,可以吗?答案当然是肯定的,微软又给出了一个方法来给予我们在消息之外来获取。那就是GetDC()这个方法,传入一个窗口句柄即可获取当前窗口设备环境。如果使用完成,可调用ReleaseDC()的方法进行设备环境的释放。
设备环境获取了,我们再来说说这个画笔画刷的创建方法,一个CreatePen(),一个是CreateHatchBrush()。如下:
hPen = CreatePen(PS_SOLID, 2, COLORREF(RGB(255, 0, 0)));//PS_SOLID是它的画笔风格,2代表画笔宽度,最后给画笔定义一个颜色,这里是红色
hBrush = CreateHatchBrush(HS_HORIZONTAL, COLORREF(RGB(0, 255, 0)));//同样道理,HS_HORIZONTAL是画刷风格,然后给画刷定义一个颜色,这里是绿色
上面说到画笔和画刷的风格,我们可以把光标定义在PS_SOLID上右键转到定义去看下:

/* Hatch Styles */
#define HS_HORIZONTAL 0 /* ----- */
#define HS_VERTICAL 1 /* ||||| */
#define HS_FDIAGONAL 2 /* \\\\\ */
#define HS_BDIAGONAL 3 /* ///// */
#define HS_CROSS 4 /* +++++ */
#define HS_DIAGCROSS 5 /* xxxxx */
#define HS_API_MAX 12

/* Pen Styles */
#define PS_SOLID 0
#define PS_DASH 1 /* ------- */
#define PS_DOT 2 /* ....... */
#define PS_DASHDOT 3 /* _._._._ */
#define PS_DASHDOTDOT 4 /* _.._.._ */
#define PS_NULL 5
#define PS_INSIDEFRAME 6
#define PS_USERSTYLE 7
#define PS_ALTERNATE 8
#define PS_STYLE_MASK 0x0000000F

#define PS_ENDCAP_ROUND 0x00000000
#define PS_ENDCAP_SQUARE 0x00000100
#define PS_ENDCAP_FLAT 0x00000200
#define PS_ENDCAP_MASK 0x00000F00

#define PS_JOIN_ROUND 0x00000000
#define PS_JOIN_BEVEL 0x00001000
#define PS_JOIN_MITER 0x00002000
#define PS_JOIN_MASK 0x0000F000

#define PS_COSMETIC 0x00000000
#define PS_GEOMETRIC 0x00010000
#define PS_TYPE_MASK 0x000F0000
这里列出很多,大家有空都可以试试,我就不多说了。

创建完画刷之后,我们可以调用DeleteObject()来删除我们的画笔和画刷。
接着,我们调用SelectObject()把画笔画刷选入设备环境,传入设备环境和画笔或画刷。
最终便可以调用我们的GDI来绘画我们所需要的图形,这里只是画了一个矩形。
在窗口结束时我们恢复设备环境以及释放。
以上代码,效果如下:



好了,通过本章的学习,希望读者能够创建出自己满意的画笔画刷来描绘自己的缤纷世界。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: