流川的Blog

流川的Blog

<2005年9月>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

导航

统计

公告

终于有自己的blog啦。不过还不怎么会用。慢慢适应。

留言簿(0)

随笔分类

随笔档案

文章分类

文章档案

vckbase的好友们

搜索

最新评论

  • 1. re: 写一个"实时"定时器
  • 好东西,支持
  • --飞凌
  • 2. re: 无界面程序中使用ActiveX控件完成其功能
  • 好东西,收藏了
  • --配线架
  • 3. re: 我负责的项目进度回顾。
  • XD,你这个太快了吧,PF啊,看你们好象只有2三个人在做事情,一个新项目2个月左右就出了几个版本最后稳定下来真是很难得啊
  • --XC
  • 4. re: 乘错车的后果
  • 呵呵,我也经常坐错车的。有几次朋友来我们这里旅游,我们做错了公车,最后到的地方我也不熟悉了。感觉都很搞笑的呢。
  • --精灵
  • 5. 素衣女服饰
  • --素衣女服饰
  • 6. re: 畸形的中国共享软件产业
  • 你的文章非常精彩,秀逗邀请您加入秀逗博客联盟.中国最大最专业的博客推荐联盟,秀逗博客联盟不截取流量,推荐后的文章指向作者本人的BLOG,文章24小时循环首页展示,真正意义上迅速提升你的博客流量!欢迎注册,注册后将推荐代码添加到自己的BLOG相应位置即可轻松推荐文章,让更多人分享你的文章!后期更有秀逗市场、同心琐秀、商业联盟以及社区陆续登场,更多娱乐功能、商业展示机会,完全免费使用,名人博客,不用再眼红,使用秀逗推荐,流量迅速上升,好的博客,秀逗为您宣传!地址:http://www.sodooo.com
  • --ss
  • 7. re: 畸形的中国共享软件产业
  • 唉~~~~~~~~~~~~....................
  • --freedk
  • 8. re: 畸形的中国共享软件产业
  • 唉~~~~~~~~~~~~....................
  • --freedk
  • 9. re: 软件项目进度的估算
  • 写的很好!
  • --黄道余生
  • 10. re: 畸形的中国共享软件产业
  • 补充: 我的意思是这个问题是社会问题,而并非个人素质或者品德问题。古人云“仓秉实然后知礼节”,老外也有马斯诺五个需求层次之说。如果我们吃、穿、住、用都不能保障(或者要斤斤计较),谈道德、谈素质有点太远了。毕竟这是一个物欲横生的社会,大家又都是俗人。
  • --一笑

阅读排行榜

评论排行榜

2005年9月15日

写一个"实时"定时器

微软提供的SetTimer,KillTimer这样的函数设置定时器很简单。
但WM_TIMER这样的消息却是优先级很低。
很多情况下,如果你需要定时的去调用你的函数来实现功能。但是当系统繁忙的时候,你可能迟迟响应不到这样的消息。
我就有过这样的经历,需要定时的把视频流写入到文件。本来设置成1、2分钟,结果有时候竟然30分钟才响应。如果用CreateWaitableTimer之类的函数又太繁琐。要是设置很多定时器怎么办呢?

一怒之下,自己写了一组函数。

头文件:
TimerEx.h:
#pragma once

#include <list>
using namespace std;

class TimerParam
{
public:
 HWND hWnd;
 UINT nIDEvent;
 UINT uElapse;
 HANDLE hTimer;
 CWinThread* pThread;
};

//list<TimerParam*> m_listpTimer;
UINT SetTimerEx(HWND hWnd, UINT nIDEvent,UINT uElapse);
BOOL KillTimerEx(HWND hWnd, UINT uIDEvent);

TimerEx.cpp
#include "StdAfx.h"
#include ".\timerex.h"

UINT SetTimerEx(HWND hWnd, UINT nIDEvent,UINT uElapse);
BOOL KillTimerEx(HWND hWnd, UINT uIDEvent);

UINT MyControllingTimerFunction( LPVOID pParam );
list<TimerParam*> m_listpTimer;

UINT MyControllingTimerFunction( LPVOID pParam )
{
 TimerParam*pTimerParam=(TimerParam*)pParam;
 int nSleep=0;
 while(WaitForSingleObject(pTimerParam->hTimer,nSleep)==WAIT_TIMEOUT)
 {
  SendMessage(pTimerParam->hWnd,WM_TIMER,pTimerParam->nIDEvent,0);
  nSleep=pTimerParam->uElapse;  
 }
 return 0;
}

UINT SetTimerEx(HWND hWnd, UINT nIDEvent,UINT uElapse)
{
 TimerParam*pParam=new TimerParam;
 pParam->hWnd=hWnd;
 pParam->nIDEvent=nIDEvent;
 pParam->uElapse=uElapse;
 pParam->hTimer=CreateEvent(NULL,TRUE,NULL,NULL);
 pParam->pThread=AfxBeginThread(MyControllingTimerFunction,pParam);
 m_listpTimer.push_back(pParam);
 return 0;
}
BOOL KillTimerEx(HWND hWnd, UINT uIDEvent)

 MSG msg;
 for(list<TimerParam*>::iterator _Iter=m_listpTimer.begin();
  _Iter!=m_listpTimer.end();_Iter++)
 {
  TimerParam*pTimer=*_Iter;
  if(pTimer->hWnd==hWnd&&pTimer->nIDEvent==uIDEvent)
  {
   SetEvent(pTimer->hTimer);
   Sleep(0);
   PeekMessage(&msg,hWnd,0,0,PM_NOREMOVE);
   Sleep(0);
   WaitForSingleObject(pTimer->pThread->m_hThread,INFINITE);
   CloseHandle(pTimer->hTimer);
   delete pTimer;
   m_listpTimer.erase(_Iter);
   break;
  }
 }
 return TRUE;
}

你可以在窗口类面,用向导加入WM_TIMER消息。
作为测试,你可以在OnCreate函数中加入:
 for(int n=1;n<nMax;n++)
  ::SetTimerEx(m_hWnd,n,1000*n);

OnDestroy()加入:
 for(int n=1;n<nMax;n++)
  ::KillTimerEx(m_hWnd,n);

OnTimer(UINT nIDEvent)中加入你想要的函数就可以了。


如果你想修改以前的代码,只需要
在SetTimer的地方改成::SetTimerEx,
KillTimer的地方::KillTimerEx就可以了。
但请注意参数。
====================
关于KillTimerEx里面的2个小地方稍微做下解释:
Sleep(0);表示切换到另外一个线程。
PeekMessage,表示处理一下SendMessage消息。
这点比较重要,如果万一线程正在SendMessage中,而你又在
WaitForSingleObject(pTimer->pThread->m_hThread,INFINITE);
可能会发生死在那里的情况。虽然这种可能性极小。

有什么疑问和问题或者任何建议都欢迎和我探讨。

发表于 2005-09-15 16:16 liuchuan的Blog 阅读(3853) | 评论 (4)编辑 收藏