科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件送给初学者的礼物:游戏编程起源连载二 (3)

送给初学者的礼物:游戏编程起源连载二 (3)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

送给初学者的礼物:游戏编程起源连载二 (3)

作者:ant3000 来源:http://bbs.bc-cn.net 2007年11月15日

关键字: 起源 游戏编程 Linux

  • 评论
  • 分享微博
  • 分享邮件

如果创建菜单的功能实现了,将返回TRUE,否则返回FALSE。它的参数是很容易理解的:

※ HWND hWnd:是你所要创建菜单的那个窗口的句柄。也就是你在调用CreateWindowEx()时产生的那个窗口句柄。

※ HMENU hMenu:识别菜单,使用它的形式是:hMenu=LoadMenu(hInstance,菜单标识符),所以它得到的是LoadMenu()函数返回的菜单句柄。如果给它赋值NULL,指定窗口的菜单将被移除。

资源是个好东西,因为它使我们很容易就生成了菜单。但是当我们点击了菜单上的选项,将会发生什么呢?答案是Windows将会发出一个WM_COMMAND的消息给程序,程序再让Windows作出相应的反应。让我们具体看一看。

控制菜单事件

你可能记得,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图形设备接口函数,你就可以利用我们所学过的所有东西作一点作品出来了。

查看本文来源
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章