时间回调函数中如何调用窗体可视按键的事件?

秋天之落叶 2019-09-28 12:31:32
procedure MyCallBack(uTimerID, uMessage: UINT; dwUser, dw1, dw2: DWORD) stdcall;
begin
TestFrm.lbl_Count.Caption := IntToStr(iCount);
Inc(iCount);
TestFrm.btn_DoSomethingClick(nil);{1、这里想调用窗体的一个按键事件,却总是执行完成后死机,如何处理?}
end;

procedure TTestFrm.btn_StartClick(Sender: TObject); //按开始按钮,开始计数
begin
timeid := timeSetEvent(1,1,@MyCallBack,0,TIME_PERIODIC);
end;

procedure TTestFrm.btn_StopClick(Sender: TObject);
begin
timeKillEvent(timeid); {2、我自己加上 timeid:=0 没什么问题吧?}
iCount := 0;
end;

1.调用窗体的一个可视按键事件,却总是执行完成后死机,如何处理?
2.timeKillEvent(timeid)后timeid依然大于0,比如是16,32等,因为我有timeid>0的判断,给timeid:=0赋值,有什么问题吗?
...全文
137 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
6秒时间,你的多媒体计时器都回调6000次了,回调执行时间应小于计时器的调用周期
  • 打赏
  • 举报
回复
那你可以先调用一下timeBeginPeriod:
timeBeginPeriod(1);
timeSetEvent(...)'
//...
timeEndPeriod(1);
秋天之落叶 2019-09-29
  • 打赏
  • 举报
回复
我自己测试,感觉1毫秒回调更准确一些。
  • 打赏
  • 举报
回复
在同一台机器上,精确程度是一样的,逻辑上当然设置一个5分钟调用更简单了
秋天之落叶 2019-09-29
  • 打赏
  • 举报
回复
引用 6 楼 早打大打打核战争 的回复:
6秒时间,你的多媒体计时器都回调6000次了,回调执行时间应小于计时器的调用周期

哦,这样啊。
那么,假如我定5分钟时间,是timesetevent(5*60*1000,0,@mycallback,0,time_periodic)精确呢?还是timesetevent(1,0,@mycallback,0,time_periodic)回调5*60*1000次精确呢?
或者说,那个受外部影响更小一些?
秋天之落叶 2019-09-28
  • 打赏
  • 举报
回复
SendMessage(FormMain.Button121.Handle, WM_LBUTTONDOWN, 0, 0);
SendMessage(FormMain.Button121.Handle, WM_LBUTTONUP, 0, 0);

我用这个解决了,暂时没有出错。
各位高手还有什么好的方法吗?请赐教!
  • 打赏
  • 举报
回复
估计是你调用的代码执行时间比较长,导致计时器回调重入了,设置消息、信号量、事件之类的都可以。最简单的是使用异步调用:
TestFrm.btn_DoSomethingClick(nil);
改成:
TestFrm.BeginInvoke(
procedure
begin
TestFrm.btn_DoSomethingClick(nil);
end);

timeKillEvent(timeid); 只是删除多媒体计时器,并没有修改你获得的id,好比xxx.Free;没有把xxx置0一样。
秋天之落叶 2019-09-28
  • 打赏
  • 举报
回复
引用 4 楼 早打大打打核战争 的回复:
那肯定长啊,你的多媒体计时器1毫秒执行一次,里面调用的代码执行5分钟这肯定不行

没问题了,不过我用0.1分测试也是不行。
反正我是一看到多线程就头疼,玩不转这个。
  • 打赏
  • 举报
回复
那肯定长啊,你的多媒体计时器1毫秒执行一次,里面调用的代码执行5分钟这肯定不行
秋天之落叶 2019-09-28
  • 打赏
  • 举报
回复
引用 2 楼 早打大打打核战争的回复:
估计是你调用的代码执行时间比较长,导致计时器回调重入了,设置消息、信号量、事件之类的都可以。最简单的是使用异步调用:
TestFrm.btn_DoSomethingClick(nil);
改成:
TestFrm.BeginInvoke(
procedure
begin
TestFrm.btn_DoSomethingClick(nil);
end);

timeKillEvent(timeid); 只是删除多媒体计时器,并没有修改你获得的id,好比xxx.Free;没有把xxx置0一样。
5分10分算不算时间长? OK,我试一下。

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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