Yesky首页| 产品报价| 行情| 手机 | 数码 | 笔记本 | 台式机 | DIY硬件 | 外设 | 网络 | 数字家庭 | 评测 | 软件 | e时代 | 游戏 | 图片 | 壁纸 | 群乐 | 社区 | 博客 | 下载
您现在的位置: 天极网 > 开发频道 > 游戏开发新手入门之Win32程序资源
全文

游戏开发新手入门之Win32程序资源

2005-02-26 11:39 作者: ant3000 出处: 编程论坛 责任编辑:方舟
  ☆ 控制菜单事件

  你可能记得,Windows的消息都是通过CALLBACK函数控制的,通常它是这个样子:WindowProc()或类似的样子。我们在上一章中用到的是这个样子:MsgHandler()。它的原形如下:

LRESULT CALLBACK MsgHandler(
 HWND hwnd, // window handle
 UINT msg, // the message identifier
 WPARAM wparam, // message parameters
 LPARAM lparam, // more message parameters
};

  当一个菜单消息被送到,msg将等于WM_COMMAND,所选择的菜单项目将被包含进wparam。这就是为什么菜单的标识符不能是字符串的原因,它需要适合wparam参数。更特别的是,菜单标识符只占用wparam的低位字。WPARAM,LPARAM,int等都是32位,分高、低位字的变量。Windows提供了宏LOWORD()和HIWORD()分别来提取变量中的低位字和高位字,原形如下:

#define LOWORD(l) ((WORD) (l))
#define HIWORD(l) ((WORD) (((DWORD) (l) >> 16) & 0xFFFF))

  LOWORD()宏的实际情况是,由于简单的定义为WORD,就自然的取得了低端的16位。HIWORD()函数把高端的16位向右移,然后同0xFFFF之间调用了逻辑“和”(AND),确保把高于16位的字节变为0。可能你不太熟悉>>和<<操作符号,它们是位移操作符。“<<”操作符把变量中的每一个字节中的数字向左移动,“>>”就是向右移动。例如,我们有一个16位的变量x,它的值是224,二进制表示为0000 0000 1111 0100。下面是一个关于位移的例子:

short int x = 244, y;
y = x << 4;

Contents(内容) of x: 0000 0000 1111 0100
Contents (内容)of y: 0000 1111 0100 0000

  总之,使用LOWORD()宏你得到了wparam的低端字,也就是说你得到了被选择菜单的ID(标识符)。所以,在你的MsgHandler()函数中,你应该这样做:

// handle menu selections
if (msg == WM_COMMAND)
{
switch (LOWORD(wparam))
{
case MENUID_NEW:
// code to handle File->New goes here
break;
case MENUID_OPEN:
// code to handle File->Open goes here
break;

// the rest of the option handlers go here

}

// tell Windows you took care of it
return(0);
}

  当然,还有一些其它的资源类型,如加速表(快捷键)、HTML页、WAV文件等。但我想以上这些是最有用,最要紧学习的。在结束之前,我还要告诉你Windows编程的一大强力特色——定制自己的资源类型。

  ☆ 定制资源

  标准的程序资源给我们带来了很大方便。但不仅仅是这些标准的类型,你还可以创建自己的资源类型。资源可以是你希望的任何一种数据。使用自己定制的资源需要多付出一点劳动,因为你必须手工定位和读取资源数据。比想象的要容易,因为你已经习惯了定义资源的格式:

[identifier] [resource type name] [filename]

  [resource type name]资源类型名称是让你命名的一个字符串。还是举例说明吧:假设我们要用到plconfig.dat文件作为资源,它包含初始化游戏人物的必需信息。我们将把它定义为CHARCONFIG资源类型,脚本文件应该是这个样子:

DATA_PLAYERINIT CHARCONFIG p1config.dat

  很简单,是不是?现在,你已经拥有了数据(plconfig.dat),你还必须分三步使一个指针指向资源数据。这包括我们还没有提到过的需要调用的函数让我们一起解决。第一步,我们必须调用FindResource()函数去发现资源。函数原形如下:

HRSRC FindResource(
 HMODULE hModule, // module handle
 LPCTSTR lpName, // pointer to resource name
 LPCTSTR lpType // pointer to resource type
);

  返回值是一个资源信息块儿的句柄,如果调用失败,返回NULL。参数意义如下:

   HMODULE hModule:HMODULE相当于HINSTANCE。不要问我为什么换了另一个名字,你只要把你的程序实例句柄传送给它就好了,你不需要什么类型转换,它们是相同的。

   LPCTSTR lpName:这个是资源的标识符。如果你使用了数字的常量作为标识符,别忘了使用MAKEINTRESOURCE()宏。

   LPCTSTR lpType:这个是资源的类型,你需要把你定义的资源类型名称的字符串传递给它。我们的是CHARCONFIG。
调用函数方式如下:

HRSRC hRsrc = FindResource(hinstance, MAKEINTRESOURCE(DATA_PLAYERINIT), "CHARCONFIG");

  这是信息块儿所在资源的句柄。下一步是要得到指向数据的指针。需要把句柄传递给LoadResource()函数,来调用数据。这将产生一个资源本身的句柄。下面是函数的原形:

HGLOBAL LoadResource(
 HMODULE hModule, // resource-module handle
 HRSRC hResInfo // resource handle
);

  返回类型HGLOBAL是一个普通句柄类型,是相对于我们说过的那些HBITMAP或HICON等句柄类型。如果调用函数失败,将返回NULL。参数解释如下:

   HMODULE hModule:老东西,程序实例的句柄。

   HRSRC hResInfo:把FindResource()得到的句柄传递给它。

  现在,我们有了资源的句柄,就可以得到指向数据(自定义的)的指针了,这需要调用LockResource()函数来完成。原形如下:

LPVOID LockResource(HGLOBAL hResData);

  仅仅把调用LoadResource()函数得到的句柄传递给它就万事大吉了。如果返回值是NULL,说明函数调用失败。否则,我们就得到梦寐以求的指针!现在我们可以自由得处理数据了。注意:返回的类型是LPVOID,(相当于void*),所以若你想把指针指向队列符号,你还要注意转换成类似BYTE*型的哦!现在,我们完成了所有的步骤,这里,我将展示给你一个指针指向特殊资源的实例:

UCHAR* LoadCustomResource(int resID)
{
 HRSRC hResInfo;
 HGLOBAL hResource;

 // first find the resource info block
 if ((hResInfo = FindResource(hinstance, MAKEINTRESOURCE(resID), "CUSTOMRESOURCETYPE")) == NULL)
  return(NULL);

 // now get a handle to the resource
 if ((hResource = LoadResource(hinstance, hResInfo)) == NULL)
  return(NULL);

 // finally get and return a pointer to the resource
  return ((UCHAR*)LockResource(hResource));
}

  总结

  好了,以上就是关于资源的部分。看,Windows编程比想象的容易吧。学了这么多,好像还是不能做什么,所以,下一章,我将向你介绍一些基本的Windows图形设备接口函数,你就可以利用我们所学过的所有东西作一点作品出来了。
共3页。 9 1 2 3
文章阅读排行
周排行
月排行
欢迎订阅天极网RSS聚合资讯:http://www.yesky.com/index.xml