一般在维持消息循环时,都是用while()语句来实现的,下面是我对这两种写法理解,如果错了,请一定指正..//这种写法是当消息队列中有WM_QUIT消息时,循环结束,也就是程序窗口要关闭了,当消息队列中没有消息时,会处于"阻塞"状态,..
//就像是网络编程中的Recv()函数一样,如果没收到信息,则一直处于阻塞.
//我见过大部分书都是这样写的.
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;下面是另外一种写法//这种写法是一直无限循环,当消息队列中有消息时,PeekMessage()会立刻返回,不像GetMessage(GetMessage不将控制传回给程
//序,直到从程序的消息队列中取得消息,),所以,可以利用这个特性,在程序空闲时处理一些事情..
while (TRUE)
{
if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break ;
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
else
{
// 完成某些工作的其它行程序
}
}
return msg.wParam ;我现在想问的就是,我读过的关于游戏编程的书中,都用的是第二种方法来维持消息循环,为什么光游戏编程书籍才用这种方法??
而且我觉得第二种方法也不好,它会使CPU的使用率一直保持在90%以上,几乎一直处于100%..
//就像是网络编程中的Recv()函数一样,如果没收到信息,则一直处于阻塞.
//我见过大部分书都是这样写的.
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;下面是另外一种写法//这种写法是一直无限循环,当消息队列中有消息时,PeekMessage()会立刻返回,不像GetMessage(GetMessage不将控制传回给程
//序,直到从程序的消息队列中取得消息,),所以,可以利用这个特性,在程序空闲时处理一些事情..
while (TRUE)
{
if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break ;
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
else
{
// 完成某些工作的其它行程序
}
}
return msg.wParam ;我现在想问的就是,我读过的关于游戏编程的书中,都用的是第二种方法来维持消息循环,为什么光游戏编程书籍才用这种方法??
而且我觉得第二种方法也不好,它会使CPU的使用率一直保持在90%以上,几乎一直处于100%..
解决方案 »
- CDaoRecordSet delete 出错. 急...
- 问几个极极极菜的问题~回答是或不是就行了(有解释更好)
- 《深入浅出mfc》的问题
- 怎样把CString改为int型
- 一般关于菜单的事件(比如,COMMAND)绑定在那里?是类CMainFrame or MyAppApp or MyAppDoc or ...???
- 哪儿有Programming Windows的配套光盘代码下载?
- 关于用odbc加ado控件远程访问数据库的问题
- CRichEditCtrl::GetSelText取得的字符串没有换行符'\n'
- 在中国,一个VC程序员能有前途吗?(只能给47分,我会再加!)
- 输入法高手请进,分数不多,下次补上
- 消息覆盖问题!
- Win32 API:WM_KEYDOWN消息处理问题,按键盘时,怎么没有响应事件?||希望大家帮忙,谢谢!!!
而且我觉得第二种方法也不好,它会使CPU的使用率一直保持在90%以上,几乎一直处于100%..说一点:玩过游戏的都知道 大型游戏中要处理的图形,数据,网络传输等都很多,稍微有点迟钝就会引起整个程序的不流畅,特别是网游用PostMessage则可以将某些优先级较低的处理延迟,从而有更多时间处理UI的互动机制而SendMessage则要求函数返回值,不能区分优先级,整体比较会慢上好多
{
if(ret==-1)
{
return -1;
}
else
{
TranslateMessage(&msg);//翻译消息
DispatchMessage(&msg);//消息转发
}
}
return msg.wParam;不然你的机器一直都是100%cpu,即使窗口关闭了,事实上程序还没结束,看任务管理器,可以看到进程依然存在
PeekMessage无论是否有消息都立即返回,在没有消息的时候可以执行其它代码,在没有事情要处理时应该自己调用Sleep或等待函数(例如WaitMessage),让线程挂起一小段时间。
PeekMessage无论是否有消息都立即返回,在没有消息的时候可以执行其它代码,在没有事情要处理时应该自己调用Sleep或等待函数(例如WaitMessage),让线程挂起一小段时间。
你看的是哪的做游戏的书呀.现代的游戏客户端为了更快地得到用户输入等,基本不用系统的消息,用的是directx的方式得到用户输入(键盘或mouse).现在还用系统消息来得到用户输入的游戏估计都是老掉牙的了吧.你第二个例子中如果不加入Sleep()的话,CPU肯定是100%的,随便加个Sleep(1)就不会有这问题的了.
而且一般玩游戏也不需要考虑和其他的应用软件一起运行,当然不用节省cpu空间了............
我知道WM_TIMER存在很多的弊端,一般游戏的帧周期都不会使用WM_TIMER吗???
我知道WM_TIMER存在很多的弊端,一般游戏的帧周期都不会使用WM_TIMER吗???
===================,
这个要看具体的程序要求,也不绝对就不用,不过定时器的缺陷比较多。
int Run()
{
BOOL bDoIdle = TRUE;
int nIdleCount = 0;
BOOL bRet; for(;;)
{
while(bDoIdle && !::PeekMessage(&m_msg, NULL, 0, 0, PM_NOREMOVE))
{
if(!OnIdle(nIdleCount++))
bDoIdle = FALSE;
} bRet = ::GetMessage(&m_msg, NULL, 0, 0); if(bRet == -1)
{
ATLTRACE2(atlTraceUI, 0, _T("::GetMessage returned -1 (error)\n"));
continue; // error, don't process
}
else if(!bRet)
{
ATLTRACE2(atlTraceUI, 0, _T("CMessageLoop::Run - exiting\n"));
break; // WM_QUIT, exit message loop
} if(!PreTranslateMessage(&m_msg))
{
::TranslateMessage(&m_msg);
::DispatchMessage(&m_msg);
} if(IsIdleMessage(&m_msg))
{
bDoIdle = TRUE;
nIdleCount = 0;
}
} return (int)m_msg.wParam;
}
我简单提一点:消息循环的存在与否不是以窗口为基础的!一般情况下,你在一个线程中创建了一个窗口,OS 自动为该线程创建一个消息队列,但不只是创建窗口的时候才为线程创建消息队列的,你随便新建一个线程并在其中调用 GetMessage ,OS 就会为它创建消息队列;另外消息循环的退出也不一定与窗口的销毁相对应!我就作过一程序,根本没有窗口,其与其它进程通过线程消息过通讯的!
即使没有用户输入,也要进行处理,比如一个动作要显示动画,你不按帧不断循环处理,就得用timer,
问题是timer这个东西不准,而且不能保证一定送达,而且用timer来实现动画,代码的复杂度比 处理、刷新的循环高多了
当你界面上很多物体都要动画的时候,就要N多timer,代码的逻辑乱的不成样子