特殊说明:版权归个人所有,请勿转载,谢谢合作。
【例5-4】利用绘制图形函数,来实现10×10的五子棋棋盘的绘制。完整代码如下所示:
//**************************************************************
// NAME : Demo_05
//**************************************************************
// POWER : Copyright (c) 2012 for lixinghua.
// AUTHOR : 2012-2-6 11:50 Create by lixinghua for functions.
// VERSION : V1.0.0.1
// NOTE : 手工整理的创建窗口的代码,本程序只创建一个名称
// 为MyWin的窗口。
//**************************************************************
//
#include <windows.h>
#include <stdio.h>
// 回调函数,用于系统消息的处理。
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
// 绘制棋盘
void DrawQiPan(HDC);
//-----------------------------------------------------------------------------
// FUNC : 入口函数
//-----------------------------------------------------------------------------
// IN : hInstance,进程的实例句柄;
// hPrevInstance,前一个进程实例句柄,默认为NULL即可;
// lpCmdLine,命令行参数;
// nCmdShow,当前窗口显示状态。
// OUT : void
// RETURN : 返回为整型,代表窗口的状态,其中APIENTRY描述了
// 压栈的顺序。
// AUTHOR : 2012-2-6 11:18 Create by lixinghua for functions.
// NOTE : 此函数为Win32入口函数。
//-----------------------------------------------------------------------------
//
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// 定义所用到的参数
//
char szWindowClass[] = { "WinClsName" };
// 窗口类的名称
HWND hWnd = NULL; // 用于存放窗口句柄
//char szTitle[] = { "五子棋" }; // 窗口标题名称
char szTitle[] = { "MyWin" }; // 窗口标题名称
MSG msg; // 存放消息的结构体,由系统提供
// 1. 设计一个窗口类
//
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = NULL;
// 2. 注册窗口
//
RegisterClassEx(&wcex);
// 3. 创建窗口
//
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
// 判断创建是否成功
if (!hWnd)
{
return FALSE;
}//end if
// 4. 显示并更新窗口
ShowWindow(hWnd, nCmdShow); // 请注意 nCmdShow 参数
UpdateWindow(hWnd);
// 5. 进入消息循环
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}//end while
return 0;
}
//-----------------------------------------------------------------------------
// FUNC : 回调函数
//-----------------------------------------------------------------------------
// IN : hWnd,窗口句柄;
// message,要处理的消息ID,以此来区分消息;
// wParam,消息参数,根据消息的不同内容也有所不同;
// lParam,消息参数,根据消息的不同内容也有所不同。
// OUT : void
// RETURN : void
// AUTHOR : 2012-2-6 11:36 Create by lixinghua for functions.
// NOTE : 此函数用于系统消息的处理。
//-----------------------------------------------------------------------------
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps; // 结构体包含了用于绘制窗口
// 客户区的信息
HDC hdc; // 设备环境句柄
int i = 0;
// 消息处理
//
switch (message)
{
// 图形绘制事件
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// 绘制棋盘
DrawQiPan(hdc);
EndPaint(hWnd, &ps);
break;
// 窗口销毁消息,关闭窗口时响应。
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
// 调用系统默认消息处理,即交给系统处理。
return DefWindowProc(hWnd, message, wParam, lParam);
}//end switch
return 0;
}
//-----------------------------------------------------------------------------
// FUNC : 棋盘绘制函数
//-----------------------------------------------------------------------------
// IN : hdc,设备环境句柄
// OUT : void
// RETURN : void
// AUTHOR : 2012-2-6 12:58 Create by lixinghua for functions.
// NOTE : 此方法用于棋盘的绘制,默认棋盘为10行10列。
//-----------------------------------------------------------------------------
//
void DrawQiPan(HDC hdc)
{
int nRowNum = 10; // 行与列的数量
int nQzSize = 50; // 每个棋子的大小,直径大小
int nLeft = 100; // 左边空出的位置
int nTop = 100; // 上边空出的位置
int nBank = 5; // 外框与棋盘间距
// 为了好看,外面加一个边框
//
Rectangle(hdc,
nLeft - nBank,
nTop - nBank,
nLeft + nRowNum * nQzSize + nBank + 1,
nTop + nRowNum * nQzSize + nBank + 1);
// 绘制内部棋盘,主要目的是加入颜色,好看一些
//
HBRUSH hBrush = CreateSolidBrush(RGB(188,188,255));
HBRUSH hOldBrush = (HBRUSH)SelectObject(hdc,hBrush);
Rectangle(hdc, nLeft, nTop, nLeft + nRowNum * nQzSize + 1,
nTop + nRowNum * nQzSize + 1);
SelectObject(hdc,hOldBrush);
DeleteObject(hBrush);
// 绘制行与列
//
for(int i = 0; i <= nRowNum; ++i)
{
// 绘制行-MoveToEx为线的起始位置,LineTo为线的结束位置。
MoveToEx(hdc, nLeft, nTop + i * nQzSize, NULL);
LineTo(hdc, nLeft + nRowNum * nQzSize, nTop + i * nQzSize);
// 绘制列-MoveToEx为线的起始位置,LineTo为线的结束位置。
MoveToEx(hdc, nLeft + i * nQzSize, nTop, NULL);
LineTo(hdc, nLeft + i * nQzSize, nTop+ nRowNum * nQzSize);
}//end for
}
实例运行结果如图5.6所示。

- 图5.6 五子棋棋盘
本例中对绘制棋盘操作的代码进行了封装,封装后的函数名称为DrawQiPan,在代码的首部,对函数进行了定义,在代码的最下边,对函数进行了绘制操作。函数在WM_PAINT消息直接调用即可,但由于要遵守Win32编码规则,DrawQiPan函数将绘制图形所需要的设备环境句柄传入到函数内部。
首先,DrawQiPan函数绘制了棋盘的外边框,这个外边框只是为了使界面更加漂亮一些;
其次,绘制内部棋盘,通过创建画刷对棋盘进行了上色;
最后,使用绘制直线的方法,用10条横线,10条竖线,将棋盘内部分离开,从而达到了棋盘的效果。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。