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

游戏开发新手入门之Windows编程

2005-05-17 11:31 作者: ant3000 出处: 编程论坛 责任编辑:方舟
  读取消息队列

  我先给你一个switch结构的例子吧:(感性的)

LRESULT CALLBACK MsgHandler(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch(msg)
{
case WM_CREAT:
[初始化游戏]
return 0;
case WM_PAINT:
[画一架飞机]
return 0;
case ……………………
……………………
}

return(DefWindowProc(hwnd, msg, wparam, lparam));
}

  在进入程序的主循环前,你需要看看你的消息控制(就是你在switch结构里编的那些),尤其是还没有用到的消息控制是否被机器存了起来,以备一旦用到,马上响应。做到正确的响应,你需要做几件事。首先你需要PeekMessage()函数。下面是它的原形:

BOOL PeekMessage(
LPMSG lpMsg, // pointer to structure for message
HWND hWnd, // handle to window
UINT wMsgFilterMin, // first message
UINT wMsgFilterMax, // last message
UINT wRemoveMsg // removal flags
);

  这是一个布尔类型,也就是一个int型,不过只有两个值,TRUE和FALSE,如果有一条消息在队列中等待,函数返回TRUE,否则,返回FALSE。它的参数很简单:

  ※ LPMSG lpMsg:这是一个MSG类型的指针变量。如果有消息在等待,消息信息将被填入该变量。

  ※ HWND hWnd:你所要检查的消息队列的窗口的句柄。

  ※ UINT wMsgFilterMin,wMsgFilterMax:索引第一个和最后一个消息,一般你都从第一个消息开始检索,所以把它们都设置为0好了。

  ※ UINT wRemoveMsg:一般来说,它有两个指,PM_REMOVE或者PM_NOREMOVE。使用前者会在消息被读取后从队列中移除,后者是继续保留。通常,我们选择前者PM_REMOVE。

  真正处理消息时,你需要做两件事,很简单,第一件是TranslateMessage(),第二件是DispatchMessage()。它们的原形很相似:

BOOL TranslateMessage(CONST MSG *lpmsg);
LONG DispatchMessage(CONST MSG *lpmsg);

  头一个是把消息翻译过来,第二个是从MSG结构中调用相应的信息。你只需要知道这么多。伴随着程序主循环的反复执行,如果有消息出现,你就调用这两个函数,函数MsgHandler()会安排好一切的。下面是个例子:

if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))【现在有时用GetMessage(&msg,NULL,0,0)】
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

  没问题,你现在完全可以写一个窗口程序了。不坏吧?在结束本章前,我还有几点要提醒你。还记得我们在谈论☆消息时,说要在后面进一步讨论它吗?你忘了?我可没有忘记。怎样主动向Windows发送消息呢?

  发送消息

  有两种办法可以做到。PostMessage()函数或SendMessage()函数。它们的原形很相似:

BOOL PostMessage(
HWND hWnd, // handle of destination window
UINT Msg, // message to post
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);

LRESULT SendMessage(
HWND hWnd, // handle of destination window
UINT Msg, // message to post
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);

  它们的参数相同,并且和前面讲过的函数MsgHandler()的参数功能相同,就不重复了。我只谈谈它们之间的区别。

  PostMessage()被经常用来向队列中加入消息,成功,返回TRUE,否则,返回FALSE。它只是简单的把消息加入到队列中,然后返回。多数情况下,调用它将返回TRUE。

  SendMessage()则有些不同,它并不是把消息加入到队列里,而是直接翻译消息和调用消息处理,直到消息处理完成后才返回。所以,SendMessage()比PostMessage()有更高的应急性。你想立刻干的事情,就应该调用它。

  消息是DOS和Windows编程之间重要的区别标志。

  程序的流程

  在DOS中,我们不必担心消息这种东西,不必担心多个程序同时运行,但在Windows里,你必须考虑这些。在Windows平台上编程,有一些不同于DOS下编程的地方。让我们看看下面这段虚拟的代码:

// main game loop
do
{
// handle messages here

// ...

// update screen if necessary
if (new_screen)
{
FadeOut();
LoadNewMap();
FadeIn();
}

// perform game logic
WaitForInput();
UpdateCharacters();
RenderMap();

} while (game_active);

  假设FadeOut()函数这样工作:当函数被调用,在一秒内屏幕图象暗淡下来,当屏幕完全黑了,函数返回。LoadNewMap()调用一个新的图象;FadeIn()使屏幕逐渐亮起来,好显示新图象。当有键子按下,调用WaitForInput()函数,再继续调用下去。这在DOS游戏编程里是合情合理的,但在Windows下不行。

  为什么呢?让我们看看新画面诞生的过程。画面逐渐变黑,调用图片,逐渐恢复。这大概要2秒钟,用户可以等待,也可能要移动一下窗口,但程序只专心的干调用图片的工作,不会对窗口的移动作出反应。这是很糟糕的,你干了机器不知道的事情,这可能导致系统崩溃,我们必须要让机器对用户的任何操作作出正确的反应。不多说了,总之你要换一换脑筋,如果你从来就没在DOS下编过程序,那正好,你赶上潮流了!

  总结

  本章我们讲了Windows编程的基础,虽然只是一个空白的窗口,但包含了最基本的东西。下一章我们将学习创建资源和利用资源,你就可以用有自己风格的光标、图标、声音、菜单等等,还要生成一个EXE文件呢!
共4页。 9 1 2 3 4
网友关注
最新上市
编辑推荐
文章阅读排行
周排行
月排行
欢迎订阅天极网RSS聚合资讯:http://www.yesky.com/index.xml