用Win32,写一个自定义的定时器

xiaoxiao2021-02-27  142

创建一个自定义定时器,其重点在于如何定时。

我的解决方案是适合采用观察者模式,分为主题类CPdsTimerSub和观察者类CPdsTimerObj ,这个两个类分别继承IPdsTimerSub和IPdsTimerObj接口 .

#pragma once #include "stdafx.h" #include <map> class IPdsTimer { public: IPdsTimer(){}; virtual ~IPdsTimer(){}; public:     /// @brief响应函数 virtual void OnTimer() = 0; }; class IPdsTimerObj : public IPdsTimer { public: IPdsTimerObj(){}; virtual ~IPdsTimerObj(){}; public: /// @brief设置定时器,nId定时器ID,nTimerSplit间隔时间 virtual void SetTimer(unsigned int nId, unsigned int nTimerSplit) = 0; /// @brief设置新的定时器,并返回新的定时器ID virtual unsigned int SetNewTimer(unsigned int nTimerSplit) = 0; /// @brief销毁定时器 virtual void KillTimer(unsigned int nId) = 0; public: /// @brief计时 virtual void CountTime() = 0; }; class IPdsTimerSub { public: IPdsTimerSub(){}; virtual ~IPdsTimerSub() { m_mapIdTimers.clear(); }; public: /// @brief注册定时器 virtual bool RegisterTimer(unsigned int nId, IPdsTimerObj* timerObj) = 0; /// @brief反注册定时器 virtual bool UnRegisterTimer(unsigned int nId) = 0; /// @brief通知所有定时器 virtual void NotifyAllTimer() = 0; public: std::map<unsigned int, IPdsTimerObj*> m_mapIdTimers; };

在主题类中创建一个线程,线程每隔一秒,去通知所有观察者类过了一秒了。

#pragma once #include "IPdsTimer.h" #include <iostream> #include <windows.h> class CPdsTimerSub : public IPdsTimerSub { public: static IPdsTimerSub* GetInstance(); public: virtual bool RegisterTimer(unsigned int nId, IPdsTimerObj* timerObj); virtual bool UnRegisterTimer(unsigned int nId); virtual void NotifyAllTimer(); protected: CPdsTimerSub(); virtual ~CPdsTimerSub(); private: static IPdsTimerSub* m_Instance; };

#include "stdafx.h" #include "PdsTimerSub.h" IPdsTimerSub* CPdsTimerSub::m_Instance = nullptr; static unsigned int g_nThreadId = 10086; DWORD WINAPI ThreadFun(LPVOID pM) { IPdsTimerSub* pTimerSub = (CPdsTimerSub *)pM; if(pTimerSub == nullptr){return 0;}; long lStartTime = GetTickCount(); while(1) { long lEndTime = GetTickCount(); while(lEndTime - lStartTime >= 1000) { pTimerSub->NotifyAllTimer(); lStartTime = lEndTime; } } return 0; } CPdsTimerSub::CPdsTimerSub() { } CPdsTimerSub::~CPdsTimerSub() { ExitProcess(g_nThreadId); } bool CPdsTimerSub::RegisterTimer(unsigned int nId, IPdsTimerObj* timerObj) { m_mapIdTimers.insert(std::make_pair(nId, timerObj)); return true; } bool CPdsTimerSub::UnRegisterTimer(unsigned int nId) { for(auto iter = m_mapIdTimers.begin() ; iter != m_mapIdTimers.end(); iter++) { if (iter->first == nId) { m_mapIdTimers.erase(iter); return true; } } return false; } void CPdsTimerSub::NotifyAllTimer() { for(auto elem : m_mapIdTimers) { elem.second->CountTime(); } } IPdsTimerSub* CPdsTimerSub::GetInstance() { if (m_Instance == nullptr) { m_Instance = new CPdsTimerSub(); HANDLE handle = CreateThread(NULL, 0, ThreadFun, m_Instance, 0, (LPDWORD)&g_nThreadId); CloseHandle(handle); } return m_Instance; }

这样的话,每个观察者类就可以自己去计时,时间到了,就去执行响应函数

#pragma once #include "IPdsTimer.h" class CPdsTimerObj : public IPdsTimerObj { public: CPdsTimerObj(void); virtual ~CPdsTimerObj(void); public: virtual void SetTimer(unsigned int nId, unsigned int nTimerSplit); virtual unsigned int SetNewTimer(unsigned int nTimerSplit); virtual void KillTimer(unsigned int nId); virtual void OnTimer(); public: virtual void CountTime(); private: unsigned int m_nTimeSplit; unsigned int m_nRealTime; unsigned int m_nTimerId; IPdsTimerSub*m_pPdsTimerSub; }; #include "stdafx.h" #include "PdsTimerObj.h" #include "PdsTimerSub.h" CPdsTimerObj::CPdsTimerObj(void) : m_nTimeSplit(1000) , m_nRealTime(0) , m_nTimerId(0) , m_pPdsTimerSub(nullptr) { m_pPdsTimerSub = CPdsTimerSub::GetInstance(); } CPdsTimerObj::~CPdsTimerObj(void) { } void CPdsTimerObj::SetTimer(unsigned int nId, unsigned int nTimerSplit) { m_nTimerId = nId; m_nTimeSplit = nTimerSplit; m_pPdsTimerSub->RegisterTimer(nId, this); } void CPdsTimerObj::KillTimer(unsigned int nId) { m_pPdsTimerSub->UnRegisterTimer(nId); //m_nTimerId = 0; } void CPdsTimerObj::CountTime() { m_nRealTime++; if ((m_nRealTime * 1000) >= m_nTimeSplit) { m_nRealTime = 0; OnTimer(); } } void CPdsTimerObj::OnTimer() { printf("%d\n", m_nTimerId); } unsigned int CPdsTimerObj::SetNewTimer(unsigned int nTimerSplit) { if (m_pPdsTimerSub != nullptr) { unsigned int nNewId = 1235;//最好替换成随机获取数值的函数 while(true) { for(auto elem : m_pPdsTimerSub->m_mapIdTimers) { if (nNewId != elem.first) { SetTimer(nNewId, nTimerSplit); KillTimer(m_nTimerId); return nNewId; } } nNewId++; } } return 0; }

测试如下:

#include "stdafx.h" #include "PdsTimerObj.h" #include "PdsTimerSub.h" int _tmain(int argc, _TCHAR* argv[]) { IPdsTimerObj *pTimerObj1 = new CPdsTimerObj(); pTimerObj1->SetTimer(1000, 1000); IPdsTimerObj *pTimerObj2 = new CPdsTimerObj(); pTimerObj2->SetTimer(2000, 1000); pTimerObj2->SetNewTimer(2000); IPdsTimerObj *pTimerObj3 = new CPdsTimerObj(); pTimerObj3->SetTimer(3000, 1000); pTimerObj3->KillTimer(3000); while (true); return 0; }

转载请注明原文地址: https://www.6miu.com/read-16257.html

最新回复(0)