VC中加入定时机制的几种方法

C++定时器实现定时任务 1、单次定时任务实现  boost的asio库里有几个定时器,老的有deadline_timer, 还有三个可配合 C++11 的 chrono 使用的high_resolution_timer、steady_timer和system_timer。deadline_timer是asio早期版本提供的定时器,使用boost.date_time库提供时间支持,deadline_timer会被逐渐淘汰。 仅仅固定时间后去执行某任务,可以使用boost中的asio库提供了steady_ti... 阅读详情
    定时机制是指在程序运行当中间隔特定的时间引发指定的事件。在DOS下编程时,主要依靠时钟中断Int 8及其调用中断 Int 1cH来实现,应用程序通过修改这些系统中断来达到实现定时触发。而在Windows下,若想象在DOS下肆无忌惮的修改系统是不现实的,那么应当如何实现定时机制呢?下面在下就在学习当中的几点体会谈谈这个问题,提出几种方案供大家参考。
第一种方案是大家熟悉的截获定时消息的途径。
在Windows提供给我们使用的系统资源当中,有一种称为“定时器(Timer)”的特殊资源,在申请了这类资源的程序当中每间隔一段时间会接收到值为WM_TIMER的消息。需要定时执行的代码可以放在该消息的处理部分。如果在VC中,我们可以具体按照以下步骤实现这一目的: 
1.            利用MFC AppWizard创建一个标准的工程,接受所有缺省选项。名为s1 
2.            在Classview中选中“CMainFrame”类,然后按Ctrl+W激活ClassWizard,在“Message Map”选项卡中Class Name选“CMainFrame”,接着在“Message”中选“WM_TIMER”,最后按下“Add Funcation”。以上步骤加入了对WM_TIMER消息的映射处理。 
3.            回到Classview中,双击“OnCreate”成员函数,在函数的末尾添加申请Timer的语句:
申请一个标识值为100的Timer,定时间隔为1000毫秒(1秒)。
4.            在“Classview”中双击OnTimer函数,输入要定时实现的代码。本例子中为:
MessageBeep(1000);;//每隔一秒发出通告声
5.            编译并执行之,我们可以每隔一秒就听到声音。这正是我们在OnTimer函数内要求执行的。 
实际当中,我们可以将“MessageBeep(1000);”换成任何我们想完成的任务,譬如定时存盘等。 
 
第二种方案也利用Timer资源,但却是采用已经编写好的代码;
我们可以加入一个具有定时功能的组件至当前工程当中。这种方法特别适用于基于对话框的工程。具体步骤如下: 
1.            利用MFC AppWizard创建一个基于对话框的工程,其余接受所有缺省选项。名为s2。 
2.            在ResourceView中,双击IDD_S2_DIALOG,显示对话框,将其中的“To do:”改为“定时触发演示的例子”,表明工程的作用。 
3.            右击对话框编辑区,在弹出的右键菜单中选择“Insert ActiveX Control”,从弹出的列表框中选择“Timer Object”,确定后会在对话框内出现一个Timer对象。 
4.            我们右击Timer对象,从弹出的菜单中选择“Properties”,接着选“All”选项卡,将其中的Interval值设为5000,即每隔5秒发生一次Timer事件。 
5.            回到对话框编辑界面,双击Timer,产生一个CS2Dlg::OnTimerTimer1成员函数,接受缺省值,并在函数实现部分输入:
MessageBox("定时触发消息框","定时演示" ,MB_OK);
6.            编译并运行此工程,将会在产生的对话框运行期间,每隔5秒弹出一个消息框。 
同样,我们可以以任何自己的代码来替换5中的消息框语句。详细见附例s2。 
7.            第三种方法是采用线程技术。众所周知,Windows 9X是一个基于多线程的多任务操作系统,在内核中以线程作为调度的基本单位,由系统分时间片进行调度。利用这一点,我们可以在程序当中创建一个“司职”计时的线程,通过线程间的同步来定时触发我们要完成的任务的代码。不象前两种方法需要至少有一个窗口作为接受消息的主窗口,采用线程技术实现定时触发将免去创建窗口的麻烦以及带来的系统各种资源的消耗。下面我们来举一个例子来说明这个问题:我们在CmyApp类的Initstance成员中不建立主窗口而是创建一个工作线程,该线程休眠一定的时间后,自动调用主线程的SomeThing函数。为了支持线程的运行,我们需要给CmyApp类增加相应的线程函数。下面,我们还是一步一步的实现: 
8.            利用MFC AppWizard创建一个标准工程,其中为不产生多余的代码,不选文档/视图支持,并选择单文档。工程名为S3。 
9.            在CS3App:: InitInstance()中用“/* … */”注释掉“return TRUE;”之前的所有代码。这是为了不建立窗口。并添加以下代码:
ExitFlag=TRUE;//是否结束主线程的循环的标志变量。因为子线程严重依赖主线程,所以在本例子中为了避免没有主窗口而提前结束应用程序,从而使子线程无法存在,所以给主线程一个循环,知道全局变量ExitFlag在子线程退出前被设置成FALSE为止.
StartThread();//启动线程

do{}while(ExitFlag);//直到结束子线程
::MessageBox(NULL,"主线程结束!","定时触发演示",MB_OK);
return TRUE;
10.        在Globals中增加一标志变量“ExitFlag”,类型为BOOL。它被主线程用来判断是否结束自身运行。 
11.        通过ClassView在CS3App的Public部分声明以下函数:
void StartThread(void); //启动线程

static UINT ThreadFunction(void); //主要执行代码的函数
static UINT StaticThreadFunc(LPVOID lpparam);//设置线程时用到的函数
需要特别指出的是,用AfxBeginThread进行线程设置时,第一参数必须象本例所指出的那样声明为Static ,不然参数转换的错误会扰得你不得安宁。
12.        在StartThread中输入如下代码:
AfxBeginThread(StaticThreadFunc,this);//建立并启动线程
13.        在StaticThreadFunc中输入如下代码:
return ThreadFunc();//调用完成主要线程代码的函数,注意一定要是Static. 实现
ThreadFunction:
int i;
i=5;//触发5次
while(i--)
{
    Sleep(5000);//间隔5秒
    ::MessageBox (NULL,"我被定时触发了!","定时触发演示",MB_OK);
}
ExitFlag=FALSE;//ExitFlag是一全局变量,通知主线程结束运行。
return 0;
}
     编译并运行工程,将看不到应用程序窗口,但可以看到每隔5秒,桌面上出现一个消息框,5次后弹出主线程结束的消息框。 
 
第三种方案是利用多媒体定时器
多媒体定时器(Multimedia Timer)。它使用自己单独的线程(Thread),来调用一个自己的回调函数(Callback Function)。它的优先级很高,它每隔一定时间就发送一个消息而不管其它消息是否执行完。此外,对于现在的Intel CPU来说,它的最小定时精度通常都可以达到1毫秒,足够满足实时数据采集的定时精度。
多媒体定时器可直接用Component Gallery在项目中插入Windows Multimedia组件,此时多媒体定时器所需的头文件和库将自动插入工程的Stdafx.h中,或用手直接将以下语句添入Stdafx.h,即
#include
// CG: The following line was added by the Windows Multimedia component.
#pragma comment(lib, "winmm.lib")
1.       定义定时器参数
#define TEN_MILLI_SECOND 200 //定时器间隔
#define TIMER_ACCURACY 1      //定时器精度
UINTTimer_ID;         //定时器句柄
UINTwAccuracy;        //定时器精度参数
2.       通过多媒体定时器设备函数timeGetDeviceCaps获得本微机的最大分辨率。
TIMECAPS tc; //定时器分辨率的结构
If(timeGetDeviceCaps(&tc,sizeof(TIMECAPS))
   = = TIMERR_NOERROR)
{
 //获得本系统的最小定时器分辨率,所有应用必须大于等于该分辨率
 wAccuracy=min(max(tc.wPeriodMin,
 TIMER_ACCURACY),tc.wPeriodMax);
 //设定本应用的所需的定时器分辨率,本例为微机的所允许的最大分辨率
 timeBeginPeriod(wAccuracy);
}
3.       应用多媒体定时器的timeSetEvent函数设定事件的触发方式,它的函数原形是:
MMRESULT timeSetEvent( UINT uDelay,
                   UINT uResolution,
                   LPTIMECALLBACK lpTimeProc,
                   DWORD dwUser, UINT fuEvent);
uDelay        用于设定事件触发间隔;
uResolution   用于设定程序所需的最小分辨率;
lpTimeProc    调用回调函数;
dwUser        用户提供的回调数据;
fuEvent       事件触发方式,在Visual C++中有两种方式:
              TIME_ONESHOT:事件仅触发一次
              TIME_PERIODIC:每隔一定时间触发一次
TimeSetEvent函数返回定时器句柄;
 
具体应用:
Timer_ID=timeSetEvent(TEN_MILLI_SECOND,wAccuracy,
                  ( LPTIMECALLBACK)CatchMMTimer,
                  (DWORD)hWnd,TIME_PERIODIC);
4.       声明一个全局的回调(Callback)函数
void CALLBACK TwoHundredMilliSecondProc (UINT wTimerID,UINT nMsg,DWORD dwUser,DWORD dw1,DWORD dw2),在回调函数中调用事件触发消息且在回调函数中语句尽量简单,不要在回调函数内做一些耗时的操作;
5.       添加用户消息CatchMMTimer函数,用来接收多媒体定时器的事件通知。其过程是首先在类的头文件定义:#define MYMSG_TIMER WM_USER+101,然后在类头文件的AFX_MSG块中说明消息处理函数:afx_msg LRESULT OnMymsgTimer(WPARAM wParam, LPARAM lParam); 在类实现的消息映射块中,使用ON_MESSAGE宏指令将消息映射到消息处理函数中:ON_MESSAGE (MYMSG_TIMER, OnMymsgTimer)。最后在相应类中实现消息处理函数。关于用户自定义消息具体可参考Visual C++ s书籍。如:PostMessage((HWND)dwUser,MYMSG_TIMER,0,0); //PostMessage发送消息
6.       定时器的任务完成后,要及时删除,否则占用太多内存,系统会越来越慢。删除定时器分两步,首先调用timeKillEvent函数删除定时器句柄,然后用timeEndPeriod函数删除定时器的分辨率。具体应用如下:
timeKillEvent(Timer_ID);
timeEndPeriod(wAccuracy);
SetTimer(100,1000,NULL);//
VC6.0 MFC定时器应用详解 MFC(Microsoft Foundation Classes)是微软公司提供的一套C++类库,主要用于简化Windows平台下的应用程序开发。MFC封装了Win32 API,提供了大量的可重用类,简化了Windows编程,使开发者能够使用面向对象的方法开发GUI应用程序。MFC提供了一系列功能强大的类,如文档/视图结构、对话框、控件以及各种标准Windows组件的封装。在MFC框架中,定时器的应用是十分重要的。 阅读详情

相关推荐

关于token无痛刷新的两个方案

目录方案一方案二 方案一 思路: 后端需要返回一个token过期的时间,在请求发起前拦截每个请求,判断token的有效时间是否已经过期,如果已过期,则暂时将请求挂起,先刷新token后再继续请求。 前期思考: 返回过期时间是为了判断是否过期的,但是如果服务器时间和系统时间不一致呢? 如果同时发起多个请求时怎么办? 实现: 因为是在请求前进行拦截,所以这里用axios的axios.interceptors.request.use()方法 首先,关于服务器时间和系统时间不一致的问题,我的解决方法是:

Yugoup的博客 2716

MFC中定时器OnTimer()的使用

在MFC中我们可能需要定时读写数据或是更新状态,这时候就需要用到定时器,其实现函数是OnTimer(),下面对其用法做一些简单的介绍(基于VS2015) 1、在工程的类视图中点击需要使用定时器的对话框类,在属性窗口中选择消息,在下面的消息函数中选中WM_TIMER,后面下拉框选择添加OnTimer函数,如下图所示: 添加完毕后会在CxxxDlg.cpp中自动添加OnTimer(UINT_PTR nIDEvent),如下图 之后就可以在OnTimer函数中进行相应的处理了。OnTimer的.

the_sea1的博客 1万+

从理论到实践:使用Sigrity SystemSI完成DDR4信号完整性仿真全流程解析

本文详细解析了使用Sigrity SystemSI完成DDR4信号完整性仿真的全流程,从核心挑战到实战操作。文章深入探讨了DDR4信号完整性问题,介绍了SystemSI工具链的演进与分工,并提供了从前期准备到高级技巧的详细指南,帮助工程师有效解决DDR4设计中的信号完整性问题。

weixin_30505225的博客 511

MFC中定时器的用法

前段时间因为做图像处理的综合实验,需要用到MFC编写调试程序,要做到能够实时采集图像然后立刻处理图像,所以用到了MFC中的定时器。关于定时器MFC的CWnd类提供的成员函数SetTimer实现定时器功能,而Windows API函数SetTimer来实现。两者使用方法实际上很类似,但也有不同。 CWnd类的SetTimer成员函数只能在CWnd类或其派生类中调用,而API函数SetTimer则没有...

qq_43987474的博客 3292

STM32F030C8烧录实战:用J-Link Commander实现一键批量烧写(附完整脚本)

本文详细介绍了如何使用J-Link Commander工具链实现STM32F030C8的一键批量烧录,包括环境配置、批处理脚本设计、命令脚本解析以及生产环境实战技巧。通过自动化烧录流程,显著提升效率并降低人为错误,特别适合量产和频繁迭代的开发场景。

weixin_30505225的博客 461

从零构建智能ai语音助手:ESP32s3+Python+大语言模型实战指南

本文详细介绍了基于ESP32S3硬件和Python后端的智能语音助手系统开发指南。系统采用ESP32S3采集语音,通过WebSocket实时传输到Python后端处理,利用大语言模型实现自然语言理解和意图识别,再通过TTS合成语音返回。文章从系统架构、工作流程、技术实现(包括OPUS编码、WebSocket通信、ESP32音频处理)等方面进行了详细讲解,并提供了分阶段学习路线和常见问题解决方案。该项目展示了物联网技术与AI技术的融合应用,相比传统语音系统具有更高的灵活性和智能性,为开发者提供了完整的实现方案

Despacito0o的博客 2630

C/C++编程:定时器

什么是定时器 很多场景都会用到定时器,比如心跳检测、倒计时、技能冷却等。 定时器分类 一般定时任务的形式表现为: 经过固定时间后触发 按照固定频率周期性触发 在某个时刻触发。 定时器的本质 那定时器到底是什么呢?可以理解为这样一个数据结构: 存储一系列的任务集合,并且deadline越接近的任务,拥有越高的执行优先权 一般定时器支持如下几种操作: add:新增任务 delete:取消某个任务 run:执行到期的任务 update:更新到期时间 那应该如何判断一个任务是否到期呢? 轮询,每隔一

OceanStar的博客 1万+

奇异值分解(SVD)C++实现

奇异值分解SVD(紧奇异值分解,截断奇异值分解)C++实现

weixin_45804601的博客 4172

VC中的定时器与消息机制

用VC编程,最重要的是要熟悉消息机制。但这一点好像并不是那么容易搞懂,至少现在我还不是完全明白,只有遇到问题时才想办法把它查清楚。      案例:通过SetTimer设置一个定时器,在OnTimer中,设置弹出一个对话框,如MessageBox("Hello")。你会发现对话框会不断的弹出,而不是阻塞在那里?如果你对这个问题很清楚,并且不会认为这是多线程机制,那恭喜你,你一定对Windows消

成长伴随牢骚 542

YOLOv8/v9轻量化优化:剪枝30%+蒸馏提精,模型体积缩至4MB还能跑Jetson

剪枝:用敏感度分析找到“可牺牲的30%”,不碰核心特征;蒸馏:借大模型的“经验”补回精度,甚至反超原始小模型;量化:针对边缘设备特性优化量化策略,把体积和延迟压到最低。如果你的项目卡在边缘部署(速度慢/体积大),按“剪枝→蒸馏→量化”三步走,90%能在Jetson上跑通30FPS+的实时检测。需要轻量化模型文件(v8s/v9s剪枝蒸馏后权重)、剪枝工具和Jetson部署脚本的,评论区扣“轻量化”,直接发你可运行版本~

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 669

搭建自己的MQTT服务器,实现设备上云(Ubuntu+EMQX)

这篇文章教大家在ECS云服务器上部署EMQX,搭建自己私有的MQTT服务器,配置EMQX实现设备上云,设备数据转发,存储;服务器我采用的华为云的ECS服务器,系统选择Ubuntu系统。

2万+

VC中基于 Windows 的精确定时

最近涉及到时钟方面的编程,觉得这篇文章总结的不错,收藏了摘自http://www.vckbase.com/document/viewdoc/?id=1301在工业生产控制系统中,有许多需要定时完成的操作,如定时显示当前时间,定时刷新屏幕上的进度条,上位 机定时向下位机发送命令和传送数据等。特别是在对控制性能要求较高的实时控制系统和数据采集系统中,就更需要精确定时操作。  众所周知,Wind

幸福村的人 1204

Xilinx系FPGA学习笔记(三)Vivado的仿真及ILA使用

接着学习vivado的使用方法。

贾saisai的博客 2546

[C++ VC MFC] Windows 的定时机制

方式一:VC中的WM_TIMER消息映射能进行简单的时间控制。首先调用函数SetTimer()设置定时间隔,如SetTimer(0,200,NULL)即为设置200ms的时间间隔。然后在应用程序中增加定时响应函数 OnTimer(),并在该函数中添加响应的处理语句,用来完成到达定时时间的操作。这种定时方法简单,但精度非常低,最小计时精度仅为30ms,CPU占用低,且定时器消息在多任务操作系统中的优

毛C毛Py的专栏 1048

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

用VC编写基于Windows的精确定时程序

 用VC编写基于Windows的精确定时程序作者: haixiao ouyang    在工业生产控制系统中,有许多需要定时完成的操作,如定时显示当前时间,定时刷新屏幕上的进度条,上位 机定时向下位机发送命令和传送数据等。特别是在对控制性能要求较高的实时控制系统和数据采集系统中,就更需要精确定时操作。  众所周知,Windows 是基于消息机制的系统,任何事件的执行都是通过发送和接收消

Jesse's Sky的专栏 1206

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

上一篇: VC++6.0编译环境介绍
下一篇: VC制作使用图片做为背景的对话框
Mr-Chen
博客等级 码龄24年 57粉丝 31原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值