Windows编程 从消息窗口到基本窗口 游戏循环窗口框架的简单实现

版本:VS2015 语言:C++

 

本来想昨天写个消息窗口的内容,讲一些好玩的东西,不过没有时间了,就放到一起了。

 

今天正好把书的第二章看完了,感觉良好,Windows的编程确实难度要高,一下子会有一大堆的参数概念,但随着书本深入了解每个参数的含义,Windows编程大致的一些思路基本就出来了。

 

题外话,这本书绝对神书,游戏编程者都应该去看看,仅仅两个章节我就对整个游戏的循环有个大致的了解了,还有各类事件是如何进行处理的,从两个章节来看我第一次用Java编的贪吃蛇简直是渣渣,什么都没有,勉勉强强能够运行罢了。

 

首先来介绍一下一个最简单的窗口,打开VS2015,新建工程,把多余的代码删除,只留下一个返回的操作,然后在wWinMain函数中写下这样一行代码:

int i = MessageBox(NULL, TEXT("HELLO"), TEXT("TITLE"), MB_OKCANCEL | MB_ICONERROR);


运行效果:

 

 

红叉、HELLO、确定取消,该有的都有了。

1.第一参数hwnd:是父窗口的句柄,因为没有父窗口代表桌面,所以设置为NULL

2.第二参数lptext:正如所见是文本的内容

3.第三参数lpcaption:标题文本

4.第四参数utype:消息窗口的类型,就是有哪些按钮,我这边就设定了确定和取消两个按钮,并且如果点击确定和取消,外部的变量i还会获取到对应的值,有兴趣可以断个点看看

 

很简短对吧。关于类型能取一些什么值,我就不详细罗列了。

 

在正式玩基本窗口之前还有个好玩的东西就是MessageBeep,上面的是创建一个消息窗口,而这个是提示一个声音:

MessageBeep(MB_OK);	//win10中警告声音都一样了。。。


嗯,试一下就有声音了。注释的意思是不管你设置成什么参数,都是那个声音。怎么形容呢,反正起到了提示玩家的作用。

 

OK,用Ctrl+K,松开K再按一下C注释一下代码,我们开始正式学习Windows基本窗口的程序了。让我学一下红孩儿,直接发代码,在代码上注释:

// Win32Project1.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "Win32Project1.h"

static int windowNum = 0;	//当前窗口的计数

// 消息处理函数,相当于cocos中的callback
LRESULT CALLBACK WindowProc(HWND hwnd,
	UINT msg,
	WPARAM wParam,
	LPARAM IParam)
{
	switch (msg)
	{
	case WM_CREATE:	//创建消息
		{
			//初始化需要的资源
		}
		break;
	case WM_DESTROY:	//WM_DESTROY是一个窗口销毁的消息,而WM_QUIT是退出应用程序的消息,也就是说一个应用程序可以包含0、1个或多个窗口
		{
			//窗口数量为0的时候发送结束应用程序的消息
			if(0 == --windowNum)	
				PostQuitMessage(0);
		}
		break;
	default:
		DefWindowProc(hwnd, msg, wParam, IParam);	//自动处理其他的消息
	}
	return (1);
}

// 主函数,程序入口
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
	// 来个消息框
	//int i = MessageBox(NULL, TEXT("HELLO"), TEXT("TITLE"), MB_OKCANCEL | MB_ICONERROR);

	// 来个声音
	//MessageBeep(MB_OK);	//win10中警告声音都一样了。。。
	//MessageBeep(0xFFFFFFFF);
	//MessageBeep(MB_ICONASTERISK);
	//MessageBeep(MB_ICONHAND);
	//MessageBeep(MB_ICONQUESTION);

	// 开始创建一个基本的窗口

	// 创建窗口类
	WNDCLASSEX wndclass;
	wndclass.cbSize = sizeof(WNDCLASSEX);
	wndclass.style = NULL;// CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;	//窗口的样式:改变宽度刷新、改变高度刷新、分配设备描述表、双击信息
	wndclass.lpfnWndProc = WindowProc;	//回调函数
	wndclass.cbClsExtra = 0;
	wndclass.cbWndExtra = 0;
	wndclass.hInstance = hInstance;
	wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);	//图标
	wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);	//光标
	wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);	//窗口背景
	wndclass.lpszMenuName = NULL;
	wndclass.lpszClassName = TEXT("MyFirstWindow");	//窗口的名字
	wndclass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);	//小应用图标
	if (!RegisterClassEx(&wndclass))
		return 0;

	// 创建窗口,上面的窗口类是一个模版,可以根据上面的模版创建多个窗口,但请注意第二个参数
	HWND hwnd = CreateWindowEx(NULL,//WS_EX_TOPMOST,	//窗口特性,注释里设置为永远在最上方显示
				TEXT("MyFirstWindow"),	//窗口名称,一定要和窗口类的lpszClassName对应
				TEXT("TITLE"),	//标题
				WS_OVERLAPPEDWINDOW | WS_VISIBLE,	//窗口的样式
				0, 0,	//左上角坐标
				800, 600,	//宽高
				NULL,	//父窗口句柄,如果是桌面则为NULL
				NULL,	//菜单窗口句柄
				hInstance,	//应用程序实例
				NULL	//高级特性
		);
	if (!hwnd)	//创建失败返回
		return 0;
	++windowNum;	//窗口数量加1

	
	ShowWindow(hwnd, nCmdShow);	//显示窗口
	UpdateWindow(hwnd);	//刷新窗口

	MSG msg;	//消息缓存

	// 进入主循环
	while (true)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))	//有消息事件,注意最后一个参数,如果设置为PM_NOREMOVE的话不会销毁消息队列中的消息
		{
			/* 这边详细说一下GetMessage和PeekMessage的区别:
			 * 1.首先说明,使用GetMessage是实现不了像游戏循环一样的效果的
			 * 2.GetMessage像是事件触发一下,有了消息马上运行;而PeekMessage会反复的检查消息队列
			 * 3.GetMessage,返回true代表消息不为WM_QUIT(退出应用程序的消息),返回false代表消息是WM_QUIT
			 * 4.PeekMessage,返回true代表有消息,false没有消息,像游戏这样每帧需要刷新的使用这个是最好的
			 *
			 */

			if (msg.message == WM_QUIT)
				break;
			TranslateMessage(&msg);	//转译消息
			DispatchMessage(&msg);	//将消息发送给WindowProc函数处理
		}
		else	//没有消息
		{
			//GameMain()	//进入游戏的主循环
		}
	}

	return msg.wParam;
}

最终结果:

 

 

嗯,看到这里想必大家对游戏需要怎样一个窗口循环都有所了解了吧。最好是把上面代码给打一遍,好记性不如烂键盘嘛。

 

在这一章的结束,书的作者说你已经成为Windows专家了,我当时内心只浮现了四个字——神TMD。不同同样想把这句话送给学完上述程序的玩家们,恭喜你已经完成了Windows的教程了!

 

至于作者的问题,创建两个窗口,只有在关闭两个窗口后才会退出应用程序。很简单,在我的程序中有个静态变量来表示当前窗口的数量,在关闭窗口后判断一下是否为0,再决定是否要关闭应用程序。

 

有想了解相关编程的玩家们,希望能跟我一起学习,能有个关注是最好的了,哈哈。我会隔几天发一下自己的学习总结,直到这本书学完。

 

总结(创建Windows窗口的步骤):

1.WNDCLASSEX创建模版的窗口类

2.CreateWindowEx创建窗口,需要注册别忘了

3.编写主循环

4.写回调函数

 

书上有一个写的很好,消息是这样往下传的:

PeekMessage -> TranslateMessage -> DispatchMessage -> 你的回调函数





  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值