首 页 | 新 闻 | 技术中心 | 第二书店 | 《程序员》 | 《开发高手》 | 社 区 | 黄 页 | 人 才
移 动专 题SUNIBM微 软微 创精 华Donews人 邮
我的技术中心 
我的分类 我的文档
全部文章 发表文章
专栏管理 使用说明



 RSS 订阅 
最新文档列表
Windows/.NET
.NET  (rss)    
Visual C++  (rss)    
Delphi  (rss)    
Visual Basic  (rss)    
ASP  (rss)    
JavaScript  (rss)    
Java/Linux
Java  (rss)    
Perl  (rss)    
综合
其他开发语言  (rss)    
文件格式  (rss)    
企业开发
游戏开发  (rss)    
网站制作技术  (rss)    
数据库
数据库开发  (rss)    
软件工程
其他  (rss)    

积极原创作者 
capsicum29 (8)
qdzx2008 (51)
ShowLong (1)
cyp403 (16)
yjz0065 (114)
lphpc (31)
smallnest (63)
tellmenow (22)
cutemouse (22)
softj (78)
CSDN - 文档中心 - Visual C++ 阅读:7698   评论: 1    参与评论
标题   VC函数中的延时操作     选择自 pomelowu 的 Blog
关键字   VC函数中的延时操作
出处  

        说到程序中的延时,你会想到怎么做,新开一个线程?如果我的程序只用单线程,却又想让函数等上10秒才返回值,而且还不能像使用Sleep函数那样不能处理其它消息呢?

        我在这里把论坛里能见到的几种延时方式总结一下。另外,主要是学习的别人的sources,版权不在我,如果本文对大家有用,请分别感谢文中的这些作者(CSDN上的ID):laiyiling(最熟悉的陌生人)QunKangLi(雾痕)tyzyx(炸平日本岛)

        从陌生人的处理方式说起,这是延时中时间跨度最大的,单位至少在秒以上:
http://community.csdn.net/Expert/FAQ/FAQ_Index.asp?id=195559
见过不只一个人问起过。其实估计陌生人是直接手写的这段代码,不是从程序段中copy出来的,有一些手误,大家自己调整一下就行了
#include

COleDateTime  start_time = COleDateTime::GetCurrentTime(); 
COleDateTimeSpan  end_time = COleDateTime::GetCurrentTime() - start_time; 
while(end_time.GetTotalSeconds()  <=  2) 
{  
   MSG  msg;  
   GetMessage(&msg,NULL,0,0);  
   TranslateMessage(&msg); 
   DispatchMessage(&msg); 
   end_time = COleDateTime::GetCurrentTime() - start_time; 
}
注意到我把原文中的
 PreTranslateMessage(&msg);
替换为了:
 TranslateMessage(&msg);
 DispatchMessage(&msg);
原因是,可以不仅仅在MFC中使用,而且 PreTranslateMessage有局限性,而且可能会造成线程消息阻塞。
        还有一点说明,因为COleDateTimeSpan类的成员函数还有:
GetTotalMinutes、GetTotalHours、GetTotalDays,能够实现更大时间段的延时。


        往更小的时间跨度上说,执行毫秒级的延时用GetTickCount就行:
DWORD dwStart = GetTickCount();
DWORD dwEnd = dwStart;
do
{  
   MSG  msg;  
   GetMessage(&msg,NULL,0,0);  
   TranslateMessage(&msg); 
   DispatchMessage(&msg); 
   dwEnd = GetTickCount(); 
} while((dwEnd - dwStart)  <=  2000);


        然后是微秒级延时:
LARGE_INTEGER  litmp ;
LONGLONG  QPart1,QPart2 ;
double d=0;
QueryPerformanceCounter(&litmp) ;
// 获得初始值
QPart1 = litmp.QuadPart ;
while (d<40)//你想要的时间
{
    QueryPerformanceCounter(&litmp) ;
    QPart2 = litmp.QuadPart ;
    d=(double)(QPart2 - QPart1);
}
出处:http://community.csdn.net/Expert/TopicView1.asp?id=2663023。未做修改,如果需要微秒级的延时中也处理消息,请参照前例修改。

最后,如果还不能满足,那就去做时钟周期的延时吧:

#define NOP_COUNT 3//需要自己根据NOP及LOOP的指令周期计算.
__asm {
  MOV ECX, NOP_COUNT
DELAY: NOP
  LOOP DELAY
}
不过,用VC做这个工作是不是有点……


相关文章
对该文的评论
CSDN 网友 ( 2004-10-14)
把消息处理机制改成这样更好些:
    if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
    {
        GetMessage(&msg, NULL, 0, 0 );
        TranslateMessage( &msg ); 
        DispatchMessage( &msg );
    }