您的位置:首页 > 其它

Windows游戏开发学习笔记之三

2013-05-08 22:49 344 查看
本章主要学习下Windows开发中如何使用资源。

我们希望Windows开发中除程序代码外还能存储更多的资源,即在.EXE文件中除了代码之外,还包含其他称之为资源的东西。在Windows中预定义了几种资源类型。如图标(.ico)、光标资源(.cur)、字符串、声音(.wav)、位图(.bmp)、对话框、图元文件等。

在vs2010中,我们可以在资源文件中添加扩展名为.rc的ASCII文本资源文件作为输入,如下图1。之后VS2010的资源编译器装载所有的资源,并将所有的资源放置在一个具有.res扩展名的大数据文件中,Windows编译及链接时的资源数据流程如图2所示。



图1



图2

总结下Windows如何处理资源:可以向应用程序中添加许多数据类型和对象,然后它们以资源的形式和实际程序代码一起驻留在.EXE文件中(一般在文件的尾端)。在程序运行过程中,可以访问这个资源数据库,并且可以从程序本身(而不是作为一个单独的文件从磁盘中)装载资源文件。

下面的demo将展示如何使用图标资源、光标资源、.wav声音资源、菜单。

使用的文件如下:

Demo3_4.cpp:C++主文件

Demo3_4RES.h:定义符号的头文件

Demo3_4.rc:资源脚本

t3dx.ico:图标的位图数据

crosshair.cur:光标的位图数据

create.wav、techno.wav:声音资源

以上的资源均放在工程的工作目录下。

Demo3_4RES.h代码如下:

//定义声音资源ID
#define SOUND_ID_CREATE 1
#define    SOUND_ID_MUSIC  2

//定义图标资源ID
#define ICON_T3DX 100

//定义光标资源ID
#define CURSOR_CROSSHAIR 200

//定义菜单资源ID
#define MENU_FILE_ID_OPEN  1000
#define MENU_FILE_ID_CLOSE 1001
#define MENU_FILE_ID_SAVE  1002
#define MENU_FILE_ID_EXIT  1003

#define MENU_HELP_ABOUT    2000


Demo3_4.rc资源脚本代码如下:

#include "Demo3_4RES.h"

//声音资源
SOUND_ID_CREATE WAVE create.wav
SOUND_ID_MUSIC WAVE techno.wav

//图标资源
ICON_T3DX ICON t3dx.ico

//光标资源
CURSOR_CROSSHAIR CURSOR crosshair.cur

//菜单资源
MainMenu MENU DISCARDABLE
{
POPUP "File"
{
MENUITEM "Open",   MENU_FILE_ID_OPEN
MENUITEM "Close",  MENU_FILE_ID_CLOSE
MENUITEM "Save",   MENU_FILE_ID_SAVE
MENUITEM "Exit",   MENU_FILE_ID_EXIT
}
POPUP "Help"
{
MENUITEM "About",  MENU_HELP_ABOUT
}
}


Demo3_4.cpp C++主文件代码:

注意:

1、

winclass.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(ICON_T3DX)); //装载应用程序图标资源,注意这里是hinstance,不是NULL!!!

winclass.hCursor = LoadCursor(hinstance, MAKEINTRESOURCE(CURSOR_CROSSHAIR)); //装载光标资源,注意这里是hinstance,不是NULL!!!

2、装载菜单:通过传递菜单句柄将一个菜单指定给一个窗口。要使用菜单句柄,必须使用LoadMenu()装载菜单资源

LoadMenu(hinstance,"MainMenu")

3、选择菜单时,是将一个WM_COMMAND消息发送到与该菜单关联的窗口的WinProc()函数中。

WM_COMMAND和WM_NOTIFY消息:

即控件通知消息,是指这样一种消息,一个窗口内的控件发生了一些事情,需要通知父窗口。当用户与控件窗口交互时,控件通知消息就会从控件窗口发送到它的主窗口,这种消息一般不是为了处理用户命令,而是为了让主窗口能够改变控件。
WM_COMMAND和WM_NOTIFY都是控件通知消息。

在最初的Windows 3.x中,还没有WM_NOTIFY,只存在WM_COMMAND消息,wParam参数中包含一个通知码和控件ID。

在程序中,利用LOWORD()宏从wParam中提取低位的WORD,即菜单资源的ID。

/*******************************************
*    文件名称:Windows游戏编程大师:demo3_3
*   完成作者:JackyLiu
*   完成时间:2013.5.8
*******************************************/

//头文件
#include <Windows.h>
#include <WindowsX.h>
#include <stdio.h>
#include <math.h>
#include "Demo3_4RES.h"

//链接相应的库
#pragma comment(lib, "WINMM.LIB")   //Windows多媒体库扩展
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "gdi32.lib")

//宏定义
#define    WINDOWS_CLASS_NAME "WINCLASS1"

//保存应用程序实例句柄的全局变量
HINSTANCE g_hInstance;

/**
*    函数功能:回调函数,即事件处理程序,当事件发生时,Windows从主事件循环中调用的回调函数
*   @param HWND hwnd: 窗口句柄,只有当使用同一个窗口类建立多个窗口时才会用到
*          UINT msg: WinProc处理的消息标识符
*          WPARAM wparam: 进一步匹配或分类发送到msg参数中的消息
*          LPARAM lparam: 同上
*/
LRESULT CALLBACK WindowProc(HWND hwnd,
UINT msg, WPARAM wparam, LPARAM lparam)
{
PAINTSTRUCT ps;  //用于窗口重绘的结构体
HDC hdc;         //图形设备环境句柄

switch(msg)
{
case WM_CREATE:
{
//在这里放置初始化代码
//创建窗口时播放音乐
PlaySound(MAKEINTRESOURCE(SOUND_ID_CREATE),
g_hInstance, SND_RESOURCE | SND_SYNC);

//声音事件异步播放,即开始播放后PlaySound()立即放回,并循环播放声音
PlaySound(MAKEINTRESOURCE(SOUND_ID_MUSIC),
g_hInstance, SND_RESOURCE | SND_ASYNC | SND_LOOP);

return 0;
}break;
case WM_COMMAND:
{
switch(LOWORD(wparam))
{
case MENU_FILE_ID_OPEN:
{

}break;
case MENU_FILE_ID_CLOSE:
{

}break;
case MENU_FILE_ID_SAVE:
{

}break;
case MENU_FILE_ID_EXIT:
{

}break;
case MENU_HELP_ABOUT:
{

}break;
}
}break;
case WM_PAINT:
{
hdc = BeginPaint(hwnd, &ps);   //激活窗口的客户区
//在这里可以进行窗口重绘
EndPaint(hwnd, &ps);
return 0;
}break;
case WM_DESTROY:
{
PostQuitMessage(0);   //发送终止应用程序的消息WM_QUIT
return 0;
}break;
default:
break;
}
//缺省函数处理不关心的消息
return (DefWindowProc(hwnd, msg, wparam, lparam));
}

/**
*    函数功能:WinMain函数,Windows程序的入口函数
*/
int WINAPI WinMain( HINSTANCE hinstance,
HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow)
{
WNDCLASSEX winclass;    //定义Windows窗口类
HWND hwnd;              //定义一般窗口句柄
MSG msg;                //定义一般消息结构体

///////////////设计窗口类///////////////
winclass.cbSize = sizeof(WNDCLASSEX);   //WNDCLASSEX结构体本身的大小
winclass.style = CS_DBLCLKS | CS_OWNDC  //描述窗口一般属性的样式信息标志
| CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc = WindowProc;      //指向事件处理程序的函数指针,即回调函数
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hinstance;         //启动时传给WinMain()函数的hInstance

winclass.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(ICON_T3DX));  //装载应用程序图标资源,注意这里是hinstance,不是NULL!!!
winclass.hCursor = LoadCursor(hinstance, MAKEINTRESOURCE(CURSOR_CROSSHAIR));    //装载光标资源,注意这里是hinstance,不是NULL!!!

winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);  //获取Windows系统画刷句柄,用于绘制或刷新一个窗口
winclass.lpszMenuName = NULL;
winclass.lpszClassName = (WINDOWS_CLASS_NAME);
winclass.hIconSm = LoadIcon(hinstance, MAKEINTRESOURCE(ICON_T3DX));  //装载一个自定义最小应用程序图标

g_hInstance = hinstance;   //保存应用程序实例句柄到全局变量

///////////注册窗口类//////////////
if(!RegisterClassEx(&winclass))
return 0;

///////////创建窗口///////////////
if(!(hwnd = CreateWindowEx(NULL,       //扩展样式
WINDOWS_CLASS_NAME,                //所创建窗口的基础类名
("Demo of Custom Cursor and Icon"),//窗口标题的空值终止字符串
WS_OVERLAPPEDWINDOW | WS_VISIBLE,  //窗口外观和行为的通用窗口标志
0,0,                               //窗口左上角位置的像素坐标
400,400,                           //窗口的宽度和高度
NULL,                              //指向父窗口的句柄
LoadMenu(hinstance,"MainMenu"),    //指向附属于该窗口菜单的句柄
hinstance,                         //应用程序的实例
NULL)))                            //其他高级特性
return 0;

///////////主事件循环/////////////
while(true)
{
//从应用程序线程消息队列中取走下一个消息
//与GetMessage()不同,它执行后会立即返回,消息队列有消息时,返回True,没有消息时,返回false
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
//检测消息队列中是否有WM_QUIT消息
if(msg.message == WM_QUIT)
break;

//虚拟加速键翻译
TranslateMessage(&msg);

//将消息回传给系统,由操作系统调用窗口过程函数对消息进行处理(将消息结构体MSG中的前四个参数作为一个参数传递给函数)
DispatchMessage(&msg);
}
}

return msg.wParam;
}


运行结果图:注:光标的图标没有显示出来,创建时将会播放一段音乐。



资源下载:http://download.csdn.net/detail/liu_jun66/5346587
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐