⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 g03.htm

📁 一本介绍如何开发游戏,如何进行游戏编程的非常值得一看的好书.
💻 HTM
📖 第 1 页 / 共 5 页
字号:
                MMSYSTEM.H——WINMM.LIB的头文件,该文件已被包含在DEMO3_2.CPP和我的所有演示程序中。你所应了解的就是该文件应当位于你的编译器搜索路径中。它也是标准Win32头文件集中的一部分。</p>            <p><b>使用编辑器创建.RC文件</b></p>            <p>  创建Windows应用程序的大多数编译器都需要一个相当大的开发环境。如Windows的Visual Development               Studio等。每一个IDE都含有一个或多个使用即插即用技术的自动创建不同资源、资源脚本程序和相关头文件的工具。<br>                使用这些工具的唯一问题是要学习这些工具!并且,使用IDE创建的.RC文件都是人工可读写的ASCII码文本,但是又有大量的添加的定义(#define)和宏,编译器能够添加它们,以便于自动完成并且简化常量的选择和MFC界面工作。<br>                因为现在我是Microsoft VC++5.0用户,我简单说明一下关于使用VC++5.0资源处理支持的关键要素。首先,向工程中添加资源可以有两种方式:<br>                方法1——从主菜单中使用File、New选项,可以向工程中添加大量的资源。图3.7就是进行该操作后产生的对话框屏图。当添加图标、光标、位图等资源时,IDE编译器自运行生成Image               Editor(如前面图3.4所示)。这是一个原始的图像编译单元,可以用来绘制光标和图标。如果要添加一个菜单资源(该部分内容将在下面部分讨论),就会出现菜单编辑器。<br>                图3.7 使用VC++5.0中的文件、新建来添加资源<br>                方法2——该方法更灵活一点,含有所有可能的资源类型,而方法1只支持其中的一部分。要向工程中添加任何一种类型的资源,可以使用主菜单中的Insert、Resource选项。3.8表示了显示出的对话框。在这种情况下,你还需要进行一些维护(手工进行编辑)。无论何时想添加一个资源,都必须将它添加到资源脚本程序中——对吗?因此,如果你的工程中还没有一个资源脚本程序的话,编译器IDE将为你产生一个脚本程序,你之为SCRIPT*.RC。另外,这两种方法最终都将生成一个名为RESOURCE.H的文件。该文件含有使用编辑器定义的和资源有关的资源符号、标识符值等。<br>                我当然希望深入探讨有关使用IDE进行资源编辑的内容,但由于它只是整章内容的一部分,而不是一整本书,所以你自己阅读一下关于使用编译器进行文档编制的内容。本书中我们将不会使用更多的资源,因此上述讨论的信息已经足够了。下面让我们进行更复杂的资源类型——菜单的学习吧。             </p>            <p><b>使用菜单编程</b></p>            <p>  菜单是Windows程序中最酷的一个内容,可以说是人机交互式界面的关键所在(例如制造一个文字处理器)。了解如何创建和使用菜单是非常重要的,这是因为你可能想制作简单的工具来帮助创建游戏,或者是想有一个视窗基础的前端来作为游戏的开始。而这些工具毋庸置疑地要有大量的菜单(如果要制作一个3D工具的话,可能需要上百万个菜单)。请相信我!无论是哪种情况,都必须掌握如何创建、装载和响应菜单。</p>            <p><b>创建一个菜单</b></p>            <p>  使用编译器的菜单编辑器可以创建一个完整的菜单以及相关的文件,但是现在我们人工编写它,因为我不知道你在使用哪种编译器,这样你也可以学会菜单说明书中的内容。但是当你正在编写一个实际的应用程序创建一个菜单时,大多数是应用IDE编辑器来创建菜单,因为人工输入编写菜单实在是太复杂了。它就像HTML代码——当启动Web后,使用一个文本编辑器来制作一个主页不是一件很复杂的事。但是,不使用任何工具来创建Web站点几乎是不可能的。               <br>                现在就让我们开始制作菜单!实际上菜单和已经讨论过的其他资源完全一样。它们驻留在一个.RC资源脚本程序中,并且必须拥有一个.H文件来解决符号引用问题,符号引用是所有菜单的标识符(一个例外:菜单名必须是符号的,无名称字符串)。下面是在.RC文件中常见的一个菜单说明的基本语法:<br>                MENU_NUME MENU DISCARDABLE<br>                {//you can use BEGIN instead of { if you wish<br>                //menu definitions<br>                }//you can use END instead of } if you wish<br>                MENU_NAME可以是一个名称字符串或这是一个符号,关键字DISCARDABLE是不完整的但又是必须的。看上去非常简单,当然,中间内容省略了,我会在的后讨论!<br>                在编写定义菜单项和子菜单的代码之前,我们首先了解一些直观的相关术语。上述讨论可能参见图3.9中菜单,它有两个一级菜单:File和Help。File菜单中包含四个菜单项:Open、Close、Save、和Exit。帮助菜单中只有一个菜单项:About。因此说本菜单中含有一级菜单和菜单项。但是,这容易令人造成误解,因为菜单中还可能有菜单或者是层叠式菜单。我不准备创建层叠式菜单,但是层叠式菜单的原理很简单:使用一个菜单定义来定义一个菜单项本身,并且可以循环无休止的这样做下去。<br>              ---------<br>              图3.9 有两个子菜单的菜单栏<br>              --------- <br>                现在我们了解相关术语,下面是执行图3.9所示的菜单:<br>                MainMenu MENU DISCARDABLE<br>                {<br>                POPUP &quot;File&quot;<br>                 {<br>                  MENUITEM &quot;Open&quot;, MENU_FILE_ID_OPEN<br>                  MENUITEM &quot;Close&quot;, MENU_FILE_ID_CLOSE<br>                  MENUITEM &quot;Save&quot;, MENU_FILE_ID_SAVE<br>                  MENUITEM &quot;Exit&quot;, MENU_FILE_ID_EXIT<br>                 }// end popup<br>                POPUP &quot;Help&quot;<br>                 {<br>                 MENUITEM &quot;About&quot;, MENU_HELP_ABOUT<br>                 }// end popup<br>                }//end top level menu<br>                我们来逐段分析该菜单定义。首先该菜单名为MainMenu。对于这一点,我们并不知道它是一个名称字符串,还是一个标识符,但是因为我一般都大写所有常量的第一个字母,很清楚它是一个无格式字符串。这也正是我要做的内容。向下看,有两个一级菜单定义,都以关键字POPUP开关——这就是关键所在。POPUP指出了一个菜单可以使用下面ASCII名称和菜单项来定义。<br>                ASCII名必须跟在关键字POPUP后面,并且用括号来包起来。弹出式菜单定义必须放在{}或BEGIN END块中——喜欢使用哪种都可以。(使用Pascal语言的人应当高兴了。)<br>                在该定义块中,后面是所有的菜单项。一定义一个菜单项,应当以下面语法使用关键字MENUITEM:<br>                MENUITEM &quot;name&quot;, MENU_ID<br>                就是这样。当然在该例子中,没有发现任何符号,但是可以在.H文件中看到如下所示的格式:<br>                //defines for the top level menu FILE<br>                #define MENU_FILE_ID_OPEN 1000<br>                #define MENU_FILE_ID_CLOSE 1001<br>                #define MENU_FILE_ID_SAVE 1002<br>                #define MENU_FILE_ID_EXIT 1003<br>                //defines for the top level menu HELP<br>                #define MENU_HELP_ABOUT 2000</p>            <p>  提示:注意标识符的值,我选择1000为第一个一级菜单的开始,然后每个菜单项加1。下一个一级菜单在1000基础上再加1000.由此每一个最高级别的菜单间相差1000,菜单中的每一个菜单项相差1。这是一种良好的工作习惯,并且很少填充。<br>                我没有定义“MainMenu&quot;,因为我希望通过字符串而不是标识符来访问该菜单。这并不是唯一的方式。例如,假如我在.H文件中将一行代码和符号放在一起,<br>                #define MainMenu 100<br>              资源编译器将自动假定我希望通过标识符来访问该菜单。我就必须使用MAKEINTRESOURCE(MainMenu)或MAKEINTRESOURCE(100)来访问该菜单资源。知道了吗?好,继续吧!<br>                技巧:注意许多菜单项才有热键或快捷键,可以不必使用鼠标手动选择一级菜单或菜单项。可以使用&amp;符号表达到目的。所要做的工作就是在POPUP菜单或MENUITEM字符串中将该符号&amp;放在想标识热键或快捷键的符号前面。例如:<br>                MENUITEM &quot;E&amp;xit&quot;,MENU_FILE_ID_EXIT<br>              这样X就成为热键,<br>                POPUP &quot; &amp;File&quot;<br>              通过AST+F使得F成为一个快捷键。<br>                现在已经了解了如何创建和定义一个菜单,让我们看一看如何将它装载到应用程序中以及如何连接到一个窗口。</p>            <p>装载一个菜单</p>            <p>  有许多方法可以将一个菜单连接到一个窗口上。可以将一个菜单和Windows类中的所有窗口建立联系,或者将不同的菜单连接到创建的每一个窗口上。首先,我们讨论一下如何将一下菜单和Windows类本身建立联系。<br>                在Windows类的定义中,有一行代码可以定义菜单:<br>                winclass.lpszMenuName = NULL;<br>                你的要做的工作就是将它赋值为该菜单资源的名称。好,下面就是如何赋值:<br>                Winclass.lpszMenuName = &quot;MainMenu&quot;;<br>                如果“MainMenu”是一个常量的话,可以按下面方式做:<br>                Winclass.lpszMenuName = MAKEINTRESOURCE(MainMenu);<br>                这样做唯一的一个问题就是创建的每个窗口都会有这样一个相同的菜单。要解决该问题,可以在创建菜单过程中通过传递菜单的句柄来将一个菜单指定给一个窗口。但是,要使用菜单句柄,必须使用LoadMenu()装载菜单资源。下面是LoadMenu()的原型:<br>                HMENU LoadMenu(HINSTANCE hInstance//handle of application instance<br>                        LPCTSTR lpMenuName);//menu name string or menu-resource               identifier<br>                如果函数调用成功的话,LoadMenu()向菜单资源返回一个HMENU句柄,这样就可以使用了。<br>                下面是标准的CreateWindow()函数调用,将菜单“MainMenu”装载到该菜单句柄参数中:<br>                //create the window<br>                if(!(hwnd = createWindowEx(NULL,//extended style<br>                              WINDOW_CLASS_NAME,//class<br>                      &quot;Sound Resource Demo &quot;,//title<br>                      WS_OVERLAPPEDWINDOW|WS_VISIBLE,<br>                      0,0//initial x,y<br>                      400,400//initial width,height<br>                      <b>LoadMenu(hinstance,&quot;MainMenu&quot;),//handle to               menu</b><br>                      hinstance,//instance of this application<br>                      NULL)))//extra creation parms<br>                 return(0);<br>                如果MainMenu是一个常数,调用就和下面相似:<br>                LoadMenu(hinstance,MAKEINTRESOURCE(MainMenu)),//handle to menu<br>                提示:你可能会认为我太关注于资源是通过字符串还是通过符号常量来定义的区别了。但考虑到该问题是导致Window程序员自我毁坏的最多的原因,我认为它值得做更多的工作,不是吗?<br>                当然,在.RC文件中可以有许多不同的菜单,因此可以将一个不同的菜单连接到每一个窗口上。<br>                将一个菜单连接到每一个窗口的最后一个方法是调用函数SetMenu():<br>                BOOL SetMenu(HAND hWnd,//handle of widow to attach to<br>                       HMENU hMenu);//hanele of menu<br>                SetMenu()采用窗口句柄和菜单句柄(从LoadMenu()中获取),直接将该菜单连接到一个窗口上。这个菜单将俦于任何以前连接的菜单。下面是一个例子的清单,假设Windows类定义该菜单为NULL,如同调用CreateWindow()的菜单句柄一样:<br>                //first fill in the window class structure<br>                winclass.cbSize=Sizeof(WNDCLASSEX);<br>                winclass.style = CS_DBLCLKS|CS_OWNDC|<br>                CS_HREDRAW|CS_VREDRAW;<br>                winclass.lpfnWndProc = WindowProc;<br>                winclass.cbClsExtra = 0;<br>                winclass.cbWndExtra = 0;<br>                winclass.hInstance = hinstance;<br>                winclass.hIcon = LoadIcon(hinstance,<br>                              MAKEINTRESOURCE(INCON_T3DX));<br>                winclass.hCursor = LoadCursor(hinstance,<br>                              MAKEINTRESOURCE(CURSOR_CROSSHAIR));<br>                winclass.hbrBackground = GetStockObject(BLACK_BRUSH);<br>                winclass.IpszMenuName = NULL;//note this is null<br>                winclass.lpszClassName = WINDOW_CLASS_NAME;<br>                winclass.hIconSm = LoadIcon(hinstance,MAKEINTRESOURCE(ICON_T3DX));<br>                // register the window class<br>                if (!RegisterClassEx(&amp;winclass))<br>                 return(0);</p>            <p>  // create the window<br>                if (!(hwnd = CreateWindowEx(NULL, // extended style<br>                 WINDOW_CLASS_NAME, // class<br>                 &quot;Menu Resource Demo&quot;, // title<br>                 WS_OVERLAPPEDWINDOW | WS_VISIBLE,<br>                 0,0, // initial x,y<br>                 400,400, // initial width, height<br>                 NULL, // handle to parent <br>                 <b>NULL, // handle to menu, note it's null</b><br>                 hinstance,// instance of this application<br>                 NULL))) // extra creation parms<br>                return(0);<br>                //Since the window has been created you can<br>                //attach a new at any time<br>                //load the menu reource<br>                HMENU hmenuhandle = loadMenu(hinstance,&quot;MainMenu&quot;);<br>                //attach the menu to the window<br>                SetMenu(hwnd,hmenuhandle);</p>            <p>  使用第二种方法创建菜单和将该菜单连接到一个窗口上的例子(也就是说在该窗口的创建调用过程中),可以参见CD-ROM上的DEMO3_3.CPP和相关的可执行文件DEMO3_3.EXE,图3.10表示了DEMO3_3.EXE正在运行的情况。<br>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -