`

C/C++游戏之旅(二)————窗体上添加控件和图形

阅读更多
人山人海的十一假期结束了,继续我们的游戏开发学习,今天继续我们的win32基础编程,在窗体上创建菜单、事件响应和绘制图形等。好吧(你已经烦了),废话少说,开始了:
一、窗口上添加菜单
首先,创建菜单头文件MENU.H文件,定义菜单选项,内容如下:
#define MENU_FILE_ID_OPEN     10000
#define MENU_FILE_ID_CLOSE    10001
#define MENU_FILE_ID_SAVE     10002
#define MENU_FILE_ID_EXIT     10003

然后,创建资源文件MENU.RC,声明菜单按钮,内容如下:
#include "MENU.H"

MainMenu MENU DISCARDABLE
{
	POPUP "文件"
	{
		MENUITEM "打开",MENU_FILE_ID_OPEN
		MENUITEM "关闭",MENU_FILE_ID_CLOSE
		MENUITEM "保存",MENU_FILE_ID_SAVE
		MENUITEM "退出",MENU_FILE_ID_EXIT
	}
}

最后加载菜单:
winclass.lpszMenuName="MainMenu";//菜单资源名称
//将菜单句柄传入createWindow()函数
LoadMenu(hinstance,"MainMenu")//返回菜单句柄
好了运行的你的工程,出现结果了吗?我相信你肯定出现了,因为你超牛的!
二、响应菜单事件
其实,很简单啦,当您每次单击菜单时,就向我们定义的winproc回调函数发送了一个WM_COMMAND类型的消息,所以我们只要处理该消息,便可以达到响应事件的效果,我们在毁掉函数中加入如下代码:
case WM_COMMAND:
		{
			switch(LOWORD(wparam)){//老实说:我也不知道这个函数是什么意思,从何而来,起什么作用
                case MENU_FILE_ID_EXIT:
                     {
                     // 退出
                     PostQuitMessage(0);
                     } break;
                case MENU_FILE_ID_OPEN:                 
                     {
                     } break;
                case MENU_FILE_ID_CLOSE:
                     {
                     } break;

                case MENU_FILE_ID_SAVE:
                     {
                     } break;
			}
		}

好了,随便你怎么搞了,总之,在里面做你想做的事情!
三、在窗体上画点东西
根据windows的处理方法,我们需要创建画笔和刷子这两个对象,然后,让他和图形设备描述表关联之后,我们才能驱动硬件在屏幕上绘制图形。所以,我们的步骤如下:
先获取图形设备描述表
HDC hdc = GetDC(hwnd);
其次,创建画笔和刷子
HPEN   white_pen = CreatePen(PS_SOLID, 1, RGB(255,255,255));
HPEN   black_pen = CreatePen(PS_SOLID, 1, RGB(0,0,0));
HBRUSH green_brush = CreateSolidBrush(RGB(0,255,0));
HBRUSH black_brush = CreateSolidBrush(RGB(0,0,0));
然后,关联
SelectObject(hdc, black_pen);
SelectObject(hdc, black_brush);
之后,画圆
Ellipse(hdc, ball_x, ball_y, ball_x + 50, ball_y + 50);
上面只是关键得代码,下面我贴上完整的代码:
#include "main2.h"
#include "MENUs.h"
#define WIN32_LEAN_AND_MEAN
#include <stdlib.h>
#include <windows.h>       
#include <windowsx.h>
#include <stdio.h>
#include <math.h>
#include <mmsystem.h>
#define WINDOW_CLASS_NAME "MY_CLASS"
#define WINDOW_WIDTH  GetSystemMetrics(SM_CXFULLSCREEN)
#define WINDOW_HEIGHT GetSystemMetrics(SM_CYFULLSCREEN)

//系统进程回调函数
LRESULT CALLBACK WindowProc(HWND hwnd, 
						    UINT msg, 
                            WPARAM wparam, 
                            LPARAM lparam)
{
PAINTSTRUCT		ps;//图形绘制结构体	
HDC				hdc;//句柄	
switch(msg)
	{	
	case WM_CREATE: //窗口创建时
        {
		return(0);
		} break;

	case WM_PAINT: //窗口重绘时
		{
		hdc = BeginPaint(hwnd,&ps);	//开始绘制
        EndPaint(hwnd,&ps);//结束绘制
		return(0);
   		} break;

	case WM_DESTROY://窗口销毁时
		{
		PostQuitMessage(0);
		return(0);
		} break;
	case WM_COMMAND:
		{
			switch(LOWORD(wparam)){//老实说:我也不知道这个函数是什么意思,从何而来,起什么作用
                case MENU_FILE_ID_EXIT:
                     {
                     // 退出
                     PostQuitMessage(0);
                     } break;
                case MENU_FILE_ID_OPEN:                 
                     {
                     } break;

                // handle each of sounds
                case MENU_FILE_ID_CLOSE:
                     {
                     } break;

                case MENU_FILE_ID_SAVE:
                     {
                     } break;
			}
		}

	default:break;

    }
//将消息队列中 不属于该进程的消息发送给系统进程
return (DefWindowProc(hwnd, msg, wparam, lparam));

}
//程序入口
int WINAPI WinMain(HINSTANCE hinstance,//应用程序当前事例的句柄
			       HINSTANCE hprevinstance,//应用程序的前事例的句柄。对于一个32的位程序,该参数总为NULL
			       LPSTR lpcmdline,//指向应用程序命令行的空字符串的指针,不包括函数名。获得整个命令行,参看GetCommandLine
			       int ncmdshow//指明窗口如何显示
				   )
{
WNDCLASSEX winclass;//声明窗体信息结构体
HWND hwnd=NULL;
MSG		   msg;		 
HDC		   hdc;

winclass.cbSize=sizeof(WNDCLASSEX);//计算结构体大小
winclass.style=CS_DBLCLKS | CS_OWNDC;//设置窗口风格,宽和高改变时刷新窗口
winclass.lpfnWndProc=WindowProc;//指向时间句柄的函数指针,基本上都是响应某个操作的回调函数(是我们自己定义的函数),这里设为空。
//下面两个字段原本是为了指示windows将附加的运行时间告诉系统的,大多数人都设为0
winclass.cbClsExtra=0;
winclass.cbWndExtra=0;
winclass.hInstance=hinstance;//系统传给winmain函数的句柄
winclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);//设置窗体图标
winclass.hCursor=LoadCursor(NULL,IDC_ARROW);//设置光标
winclass.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);//获取系统画刷、画笔、调色板或字体的一个句柄。
winclass.lpszClassName=WINDOW_CLASS_NAME;//为自己创建的结构体赋别名,将来用它可以来引用该结构体
winclass.lpszMenuName="MainMenu";//菜单资源,以后再作解释
winclass.hIconSm=LoadIcon(NULL,IDI_APPLICATION);//应用程序图标

//注册结构体
if(!RegisterClassEx(&winclass)){
	return(0);
}
int x=GetSystemMetrics(SM_CXFULLSCREEN);//获取全屏 x的宽度
int y=GetSystemMetrics(SM_CYFULLSCREEN);//获取全屏 y的高度
//创建窗口
hwnd=CreateWindowEx(
	NULL,
	WINDOW_CLASS_NAME,
	"哥的第一个窗口",
	WS_OVERLAPPEDWINDOW|WS_VISIBLE,
	0,
	0,
	x,
	y,
	NULL,
	LoadMenu(hinstance,"MainMenu"),
	hinstance,
	NULL
	);
if(NULL==hwnd){
	return(0);
}
//得到图形设备描述表
hdc = GetDC(hwnd);
//创建花笔和刷子
HPEN   white_pen = CreatePen(PS_SOLID, 1, RGB(255,255,255));
HPEN   black_pen = CreatePen(PS_SOLID, 1, RGB(0,0,0));
HBRUSH green_brush = CreateSolidBrush(RGB(0,255,0));
HBRUSH black_brush = CreateSolidBrush(RGB(0,0,0));
// 园的开始坐标
int ball_x = WINDOW_WIDTH/2;
int ball_y = WINDOW_HEIGHT/2;
// 园的移动距离
int xv = 5;
int yv = 5;
// 循环发送消息
while(TRUE)
	{
    // 获取消息
	if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
	   { 
	   // 是否退出
       if (msg.message == WM_QUIT)
           break;
	
	   //转换消息
	   TranslateMessage(&msg);

	   // 发送消息
	   DispatchMessage(&msg);
	   }
    // 图形设备描述表选择画笔和刷子
    SelectObject(hdc, black_pen);
    SelectObject(hdc, black_brush);
    //画圆
    Ellipse(hdc, ball_x, ball_y, ball_x + 50, ball_y + 50);
    //移动园
    ball_x+=xv;
    ball_y+=yv;
    // 边界检测
    if (ball_x < 0 || ball_x > WINDOW_WIDTH - 50)
       { 
			xv=-xv;
			ball_x+=xv;
       } 
    else
   // 边界检测
    if (ball_y < 0 || ball_y > WINDOW_HEIGHT - 50)
       { 
       yv=-yv;
       ball_y+=yv;
       }
    // 图形设备描述表选择画笔和刷子
    SelectObject(hdc, white_pen);
    SelectObject(hdc, green_brush);

    // 画圆
    Ellipse(hdc, ball_x, ball_y, ball_x +50, ball_y + 50);
    //休眠10毫秒
    Sleep(50);  
	} // end while

//释放所有笔和刷子
DeleteObject(white_pen);
DeleteObject(black_pen);
DeleteObject(green_brush);
DeleteObject(black_brush);

//释放图形设备描述表
ReleaseDC(hwnd,hdc);
return(msg.wParam);
}
分享到:
评论

相关推荐

    Qt和C/C++实现的可视化景点旅游信息系统——包含详细注释与txt说明文件

    1. 熟悉 C/C++ 的人员 2. 正在做关于 Qt 可视化却无从下手的人员 3. 希望做一个小项目,但没有合适的框架的人员 我主要能学到什么: 1. 该项目包含 鼠标点击响应与绘图相关的算法 2. 该项目包含 创建、删除、编辑 ...

    MinGW64与32——C/C++快速配置编译环境

    为了考虑到程序兼容性,通常我们编译C/C++程序会编译32位和64位两个版本,像VisualStudio,devcpp这类集成开发环境确实不用自己设置就能做到,但是他们都有不方便的地方,如VisualStudio的占用空间太大,如果初学C/...

    一个好玩的c++游戏——生死枪战!

    生死枪战游戏目前以3个模式运行(持续更新),玩家可以通过自己的喜好来选择,如:新手训练营,无限闯关,打怪,以及能调用时间而改变战力的暗月阁长老。更多特殊技能、特殊武器等你发掘! 改进或交流该游戏的建议...

    Linux C/C++后端开发学习路线图——对标腾讯T9

    腾讯后端T9开发学习路线图,内容路线非常详细。可以作为自身学习参考。 Linux C/C++ 后端开发学习路线。

    C/C++——控制台贪吃蛇的实现以及自动操作

    用C写的控制台游戏——贪吃蛇。可以调整游戏速度,蛋的数量并有两种自动操作模式。自动操作模式将由电脑控制贪吃蛇,能够轻易取得高分。详见:https://blog.csdn.net/Eyizoha/article/details/89388115

    pzqu.rar_组合框控件_C/C++_

    【标题】"pzqu.rar" 是一个压缩包文件,它主要关注的是在C/C++编程环境中使用的一个关键组件——“组合框控件”。这个压缩包包含了一系列与开发相关的源代码和项目文件,用于演示或教学如何在Visual C++环境下利用...

    exalusive.rar_Delphi控件源码_C/C++_

    《Delphi控件源码与C/C++编程实践——基于列表视图的探索》 在IT领域,Delphi和C/C++是两种广泛使用的编程语言,各有其独特的优点和应用场景。Delphi以其高效的Windows应用程序开发能力著称,而C/C++则以其底层控制...

    womajiang.rar_棋牌游戏_C/C++_

    C++在C语言的基础上增加了面向对象的特性,使得代码更加模块化,易于维护和扩展。 【描述】"麻将程序.是学习是用的.玩玩试试就知道了" 这段描述暗示了这个项目是一个教学资源,适合那些想要学习如何使用C/C++开发...

    零基础学C/C++03——Very Good!

    零基础学C/C++03——Very Good! #include&lt;bits/stdc++.h&gt; using namespace std; int main() { cout***************"!"***************"; return 0; }

    从C/C++迁移到PHP——判断字符类型的函数

    在C/C++中,头文件ctype.h中定义了关于字符类型一组宏,可以得到给定字符的类型。 而PHP中没有相关函数。前些天发现在www.mm4.de下载的PHP中提供了一个名为php_ctype.dll的扩展库, 加载后发现提供一部分此类的函数...

Global site tag (gtag.js) - Google Analytics