DLL中的定时器(无窗口句柄定时器)控制和动态变化

fnwyq 2008-04-01 11:17:18
大家好!
先申明定时器的创建方法是搜索本论坛获得,测试过正常就拿来用了,呵呵~
DWORD tidTimer;
UINT uElapse;

unsigned __stdcall TimerThreadProc(void *param)
{
MSG msg;
UINT_PTR hTimer;

if ((hTimer = SetTimer(NULL, NULL, uElapse, 0)) == 0)
MessageBox(NULL, L"Set Timer failed.", L"Error", MB_OK);
while (GetMessage(&msg, NULL, 0, 0))
{
switch(msg.message)
{
case WM_TIMER:
//...
break;

default:
break;
}
}
if (hTimer)
KillTimer(NULL, hTimer);
return 0;
}

_beginthreadex(NULL, 0, TimerThreadProc, NULL, 0, &tidTimer);

...

PostThreadMessage(tidTimer, WM_TIMER, 0, 0); //随后的某个事件处理中启动定时器


虽然定时器测试过正常运行,但是有些困惑,所以首先请大家给解释一下:
1、beginthreadex创建线程后,应该有先执行处理函数TimerThreadProc吧,然后在GetMessage的时候挂起,对吗?如果这个认识没有错误的话,那么为什么SetTimer之后GetMessage没能马上得到连续的timer消息,而是等到PostThreadMessage后才能连续得到之前SetTimer设置的周期时间消息呢?

在实际应用中,我需要随时启动和停止定时,以及改变定时器的周期,大家帮忙给些意见或新的处理方法。
2、如果先不考虑改变定时器周期,请问PostThreadMessage启动定时器后,如何让定时器“暂停”,然后又继续开始定时?
3、如果要改变定时器周期,按上面的方法,个人思路是先终止线程,然后设置不同的uElapse再创建新的线程启动定时器。
期待大家的见解。
...全文
463 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
wencan2010 2011-05-11
  • 打赏
  • 举报
回复
不能用在类中
没有使用价值
aj3423 2008-04-01
  • 打赏
  • 举报
回复

bool PauseTimer=false;//暂停标志

while (GetMessage(&msg, NULL, 0, 0))
{
switch(msg.message)
{
case WM_TIMER:
if(PauseTimer) break;//加上这个
//...
break;

default:
break;
}
}

这样也可以吧。。
fnwyq 2008-04-01
  • 打赏
  • 举报
回复
谢谢vrace的提示,原来还有一个WaitableTimer。
谢谢gomoku,2的思路不错,这样可以在TimerThreadProc内部修改timer,使得可以不用重新创建线程来处理。顺便提一下我也是用的VS2005。
gomoku 2008-04-01
  • 打赏
  • 举报
回复
vrace的办法比较好,SetTimer本来就是面向窗口的。
如果你坚持用SetTimer,那么:

1、我不知道你的运行环境,不过据我所知,有些函数,像SetWindowsHookEx(WH_KEYBOARD_LL...) 是通过发送消息到所在线程的消息泵来实现的。
你在调用SetTimer之前,线程还没有一个消息泵。
你可以试着在SetTimer之前调用PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); 强制系统关联一个消息泵到你的线程。

注:我用Visual Studio 2005 编译运行时,并不需要调用PostThreadMessage(tidTimer, WM_TIMER, 0, 0)。定时器正常运行。


3、终止定时器线程比较简单,PostThreadMessage(tidTimer, WM_QUIT, 0, 0); 就可以了。

2、你可以试着用'用户消息'来暂停定时器和改变时间,就像这样:
case WM_APP + 1:
  uElapse = (UINT)msg.wParam;
  hTimer = SetTimer(NULL, NULL, uElapse, 0);
  break;
...


//每500毫秒触发一次
PostThreadMessage(tidTimer,WM_APP+1,500,0);







fnwyq 2008-04-01
  • 打赏
  • 举报
回复
抱歉,第一个问题弄错了,SetTimer之后有直接得到timer消息。
vrace 2008-04-01
  • 打赏
  • 举报
回复
使用 WaitableTimer

CreateWaitableTimer
SetWaitableTimer

15,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧