中易网

C语言如何实现在每天某个特定时间执行某个函数

答案:3  悬赏:50  
解决时间 2021-02-10 11:45
C语言如何实现在每天某个特定时间执行某个函数
最佳答案
Windows提供了定时器,帮助编写定期发送消息的程序。定时器一般通过一下两中方式通知应用程序间隔时间已到。
⑴ 给指定窗口发送WM_TIMER消息,也就是下面的给出在窗口类中使用的方法。
⑵ 调用一个应用程序定义的回调函数,也就是在非窗口类中使用方法。

4.1 在窗口类中使用定时器
在窗口类中使用定时器比较简单。假如我们想让这个窗口上放置一个电子钟,这样我们必须每1秒或者0.5秒钟去更新显示显见。按照下面的步骤,就可以完成这个电子钟程序,并且知道如何在窗口类中使用定时器:
首先做在我们新建项目的主窗口上添加一个Label控件,用来显示时间。接着
⑴ 用函数SetTimer设置一个定时器,函数格式如下: UINT SetTimer( UINT nIDEvent,
UINT nElapse,
void (CALLBACK EXPORT* lpfnTimer)(HWND, UINT, UINT, DWORD));

这个函数是CWnd类的一个成员函数,其参数意义如下:

nIDEvent: 为设定的定时器指定的定时器标志值,设置多个定时器的时候,每个定时器的值都不同,消息处理函数就是通过这个参数来判断是哪个定时器的。这里我们设定为1。
nElapse: 指定发送消息的时间间隔,单位是毫秒。这里我们设定为1000,也就是一秒。
lpfnTimer: 指定定时器消息由哪个回调函数来执行,如果为空,WM_TIMER将加入到应用程序的消息队列中,并由CWnd类来处理。这里我们设定为NULL。
最后代码如下:SetTimer(1,1000,NULL);
⑵ 通过Class Wizard给主窗口类添加一个WM_TIMER消息的映射函数,默认为OnTimer(UINT nIDEvent)。
⑶ 然后我们就可以在OnTimer(UINT nIDEvent)的函数实现中添加我们的代码了。参数nIDEvent就是我们先前设定定时器时指定的标志值,在这里我们就可以通过它来区别不同的定时器,而作出不同的处理。添加的代码如下:switch(nIDEvent)
{
case 1:
CTime m_SysTime = CTime::GetCurrentTime();
SetDlgItemText(IDC_STATIC_TIME,m_SysTime.Format("%Y年%m月%d日 %H:%M:%S"));
break;
}

代码中的IDC_STATIC_TIME就是我们先前添加的Label控件的ID。
至此,我们的电子钟的程序就完成了。

4.2 在非窗口类中使用定时器
在非窗口类中使用定时器就要用到前面我们介绍到的所有知识了。因为是无窗口类,所以我们不能使用在窗口类中用消息映射的方法来设置定时器,这时候就必须要用到回调函数。又因为回调函数是具有一定格式的,它的参数不能由我们自己来决定,所以我们没办法利用参数将this传递进去。可是静态成员函数是可以访问静态成员变量的,因此我们可以把this保存在一个静态成员变量中,在静态成员函数中就可以使用该指针,对于只有一个实例的指针,这种方法还是行的通的,由于在一个类中该静态成员变量只有一个拷贝,对于有多个实例的类,我们就不能用区分了。解决的办法就是把定时器标志值作为关键字,类实例的指针作为项,保存在一个静态映射表中,因为是标志值是唯一的,用它就可以快速检索出映射表中对应的该实例的指针,因为是静态的,所以回调函数是可以访问他们的。
首先介绍一下用于设置定时的函数:

UINT SetTimer(
HWND hWnd, // handle of window for timer messages
UINT nIDEvent, // timer identifier
UINT uElapse, // time-out value
TIMERPROC lpTimerFunc // address of timer procedure
);

其中的参数意义如下:
hWnd: 指定与定时器相关联的窗口的句柄。这里我们设为NULL。
nIDEvent: 定时器标志值,如果hWnd参数为NULL,它将会被跳过,所以我们也设定为NULL。
uElapse: 指定发送消息的时间间隔,单位是毫秒。这里我们不指定,用参数传入。
lpTimerFunc: 指定当间隔时间到的时候被统治的函数的地址,也就是这里的回调函数。这个函数的格式必须为以下格式:
VOID CALLBACK TimerProc(
HWND hwnd, // handle of window for timer messages
UINT uMsg, // WM_TIMER message
UINT idEvent, // timer identifier
DWORD dwTime // current system time
);

其中的参数意义如下:
hwnd: 与定时器相关联的窗口的句柄。
uMsg: WM_TIMER消息。
idEvent: 定时器标志值。
deTime: 系统启动后所以经过的时间,单位毫秒。
最后设定定时器的代码为:m_nTimerID = SetTimer(NULL,NULL,nElapse,MyTimerProc);
先通过Class Wizard创建一个非窗口类,选择Generic Class类类型,类名称为CMyTimer,该类的作用是每隔一段时间提醒我们做某件事情,然后用这个类创建三个实例,每个实例以不同的时间间隔提醒我们做不同的事情。
MyTimer.h#include

class CMyTimer;
//用模板类中的映射表类定义一种数据类型
typedef CMap CTimerMap;

class CMyTimer
{
public:
//设置定时器,nElapse表示时间间隔,sz表示要提示的内容
void SetMyTimer(UINT nElapse,CString sz);
//销毁该实例的定时器
void KillMyTimer();
//保存该实例的定时器标志值
UINT m_nTimerID;
//静态数据成员要提示的内容
CString szContent;
//声明静态数据成员,映射表类,用于保存所有的定时器信息
static CTimerMap m_sTimeMap;
//静态成员函数,用于处理定时器的消息
static void CALLBACK MyTimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime);
CMyTimer();
virtual ~CMyTimer();
};

MyTimer.cpp#include "stdafx.h"
#include "MyTimer.h"

//必须要在外部定义一下静态数据成员
CTimerMap CMyTimer::m_sTimeMap;

CMyTimer::CMyTimer()
{
m_nTimerID = 0;
}

CMyTimer::~CMyTimer()
{
}

void CALLBACK CMyTimer::MyTimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime)
{
CString sz;
sz.Format("%d号定时器:%s",
idEvent,
m_sTimeMap[idEvent]->szContent);
AfxMessageBox(sz);
}

void CMyTimer::SetMyTimer(UINT nElapse,CString sz)
{
szContent = sz;
m_nTimerID = SetTimer(NULL,NULL,nElapse,MyTimerProc);
m_sTimeMap[m_nTimerID] = this;
}

void CMyTimer::KillMyTimer()
{
KillTimer(NULL,m_nTimerID);
m_sTimeMap.RemoveKey(m_nTimerID);
}

这样就完成了在非窗口类中使用定时器的方法。以上这些代码都在Windwos 2000 Professional 和 Visual C++ 6.0中编译通过。
全部回答
clock()是c/c++中的计时函数,而与其相关的数据类型是clock_t。在msdn中,查得对clock函数定义如下:   clock_t clock(void) ;   这个函数返回从“开启这个程序进程”到“程序中调用clock()函数”时之间的cpu时钟计时单元(clock tick)数,在msdn中称之为挂钟时间(wal-clock);若挂钟时间不可取,则返回-1。其中clock_t是用来保存时间的数据类型 vc++6.0中time.h下宏定义的常量。其值为1000。vc++6.0中该符号常量定义如下:   #define clocks_per_sec 1000   此外,vc++6.0中把tc2.0中time.h下宏定义的常量clk_tck也宏定义成clocks_per_sec,这样tc2.0下值为18.2的clk_tck在vc6.0下值变为1000。该宏定义如下:   #define clk_tck clocks_per_sec   clocks_per_sec,它用来表示一秒钟会有多少个时钟计时单元,其定义如下:   #define clocks_per_sec ((clock_t)1000)   可以看到每过千分之一秒(1毫秒),调用clock()函数返回的值就加1。   可以使用公式clock()/clocks_per_sec来计算一个进程自身的运行时间。 函数名: time   头文件:time.h   函数原型:time_t time(time_t * timer)   功能: 获取当前的系统时间,返回的结果是一个time_t类型,其实就是一个大整数,其值表示从cut(coordinated universal time)时间1970年1月1日00:00:00(称为unix系统的epoch时间)到当前时刻的秒数。然后调用localtime将time_t所表示的cut时间转换为本地时间(我们是+8区,比cut多8个小时)并转成struct tm类型,该类型的各数据成员分别表示年月日时分秒。   补充说明:time函数的原型也可以理解为 long time(long *tloc),即返回一个long型整数。因为在time.h这个头文件中time_t实际上就是:   #ifndef _time_t_defined   typedef long time_t;   #define _time_t_defined   #endif   即long。
开一个线程,一直监视系统时间,到四点的时候做事情. 设置线程的监视间隔时间,比如每隔5分钟线程就把系统时间和设定时间对比一下,你的程序就要判断系统时间-设定时间小于等于5分钟并要大于0,如果小于等于5分钟并且大于0,说明到时间了,可以做事情了
我要举报
如以上问答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
流量管家里没有赠送
有没有一部小说主人公是叫秦林的
想建房但村里说已经没有宅基地可批,怎么办?
双边刷还是单边刷的机器好?
去广州工作,要不要把车开去呢。因为不知道会
央视广告月经不调的药是什么牌子?
大学广播站调设备的相关工作总结
120固态硬盘 500g机器硬盘 怎么分区 每个分多
金盛超市在什么地方啊,我要过去处理事情
顺行加油站(104省道西宋村段长虹汽车电工对面
是不是报读动漫培训学校出来都有工作分配?
买花下面自带的营养水可以浇花吗
王合兴诊所我想知道这个在什么地方
我在上海想办一个摩托车驾驶证请问在哪里办怎
主角生活在未来世界的小说 不论是不是穿越的
推荐资讯
当年基建工程的结算费用是应该入当期费用还是
入手二手iphone6,不想刷机,只恢复出厂设置
双沙经济联合社我想知道这个在什么地方
翠花桥我想知道这个在什么地方
要现代的诗歌,5首,简短的啊~~~快快快,急
从广州市滘口车站怎么坐车到罗岗村
钢结构专业承包三级资质怎么办理
怎么填QQ申诉验证码
疃里现代家电这个地址在什么地方,我要处理点
申请了浦发银行的信用卡金卡一张 2个月后又申
2010年10月初6下午6点40出生姓张的女孩叫什么
我想在家装一个监控器,是要联到手机上的,家
手机登qq时,显示手机磁盘不足,清理后重新登
刺客的套装怎么选啊?