5.4 几何图形绘制实例

特殊说明:版权归个人所有,请勿转载,谢谢合作。

【例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条竖线,将棋盘内部分离开,从而达到了棋盘的效果。

 

转载请附上原文出处链接及本声明
李老师的博客 » 5.4 几何图形绘制实例

发表评论

提供最优质的文章集合

立即查看 了解详情