实现PC延迟执行函数
头文件内容:
#pragma once typedef function<void ()> DelayClickHandler;
typedef void (*pDelayFun)(); class DelayData
{
public:
DelayData(){}
//cskey主要是为了避免重复调用,如果cskey空,则不考虑,如果不为空,相同cskey如果之前的没有执行到,会remove之前的,然后加入当前的这个函数
DelayData(pDelayFun pFun,DWORD dwDelayTick,CString csKey="")
{
dwStartTick = GetTickCount();
this->pFun = pFun;
this->dwDelayTick = dwDelayTick;
this->csKey = csKey;
}
DelayData(DelayClickHandler FunHandler,DWORD dwDelayTick,CString csKey="")
{
dwStartTick = GetTickCount();
this->dwDelayTick = dwDelayTick;
this->FunHandler = FunHandler;
this->csKey = csKey;
pFun = NULL;
}
DWORD dwStartTick; //记录当时时间
DWORD dwDelayTick; //延迟时间
CString csKey; //表示特征值
pDelayFun pFun; //需要执行的函数,必须是静态函数
DelayClickHandler FunHandler; //需要执行的函数
}; class CDelayHandler:public CWnd
{
public:
static CDelayHandler* GetInstance();
~CDelayHandler(void);
//只能在主线程执行,现在精度是500ms,pDelayFun需要是类的静态函数或者全局函数,没有参数
static void PostDelay(pDelayFun pFun,DWORD dwDelayTime,CString csKey="");
//只能在主线程执行,现在精度是500ms,FunHandler需要是类的函数,可以带参数,具体可以看CHoverButton中的handler使用方法
void PostDelay(DelayClickHandler FunHandler,DWORD dwDelayTime,CString csKey="");
DECLARE_MESSAGE_MAP()
protected:
CDelayHandler(void);
afx_msg void OnTimer(UINT nIDEvent);
void DoDelayHandler();
void AddDelayData(DelayData dd);
private:
vector<DelayData> m_HandlerVec;
set<CString> m_HandlerKey; //避免重复加入同一个延迟函数
};
cpp文件:
#include "stdafx.h"
#include "DelayHandler.h"
#define DW_TIMERID 1001 //外部接口******************************************************************************************
//只能在主线程执行,现在精度是500ms,pDelayFun需要是类的静态函数或者全局函数,没有参数
void CDelayHandler::PostDelay(pDelayFun pFun,DWORD dwDelayTime,CString csKey)
{
CDelayHandler::GetInstance()->AddDelayData(DelayData (pFun,dwDelayTime,csKey));
} void CDelayHandler::PostDelay(DelayClickHandler FunHandler,DWORD dwDelayTime,CString csKey)
{
CDelayHandler::GetInstance()->AddDelayData(DelayData (FunHandler,dwDelayTime,csKey));
} //内部实现***************************************************************************************
BEGIN_MESSAGE_MAP(CDelayHandler, CWnd)
ON_WM_TIMER()
END_MESSAGE_MAP() CDelayHandler* CDelayHandler::GetInstance()
{
static CDelayHandler _Instance;
return &_Instance;
} CDelayHandler::CDelayHandler(void)
{
} CDelayHandler::~CDelayHandler(void)
{
} void CDelayHandler::AddDelayData(DelayData dd)
{
if(NULL == GetSafeHwnd())
{
HCURSOR hCursor = AfxGetApp()->LoadCursor(IDC_ARROW);
LPCTSTR className = AfxRegisterWndClass(CS_DBLCLKS, hCursor);
CreateEx(WS_EX_TOPMOST|WS_EX_TOOLWINDOW, className, NULL, WS_POPUP,
, , , ,
::GetDesktopWindow(), NULL);
ShowWindow(SW_HIDE);
}
if( == m_HandlerVec.size())
SetTimer(DW_TIMERID,,NULL); if(dd.csKey.IsEmpty())
{
m_HandlerVec.push_back(dd);
}
else if(m_HandlerKey.find(dd.csKey)==m_HandlerKey.end())
{
m_HandlerKey.insert(dd.csKey);
m_HandlerVec.push_back(dd);
}
else if(m_HandlerKey.find(dd.csKey)!=m_HandlerKey.end())
{
vector<DelayData>::iterator it = m_HandlerVec.begin();
for(;it!=m_HandlerVec.end();it++)
{
if(dd.csKey == (it->csKey))
{
m_HandlerVec.erase(it);
break;
}
}
m_HandlerVec.push_back(dd);
}
} void CDelayHandler::OnTimer(UINT nIDEvent)
{
if(nIDEvent == DW_TIMERID)
{ DoDelayHandler();
if(==m_HandlerVec.size())
{
KillTimer(DW_TIMERID);
}
}
CWnd::OnTimer(nIDEvent);
} void CDelayHandler::DoDelayHandler()
{
for(int i=;i<m_HandlerVec.size();)
{
DelayData &dd = m_HandlerVec[i];
DWORD curTime = GetTickCount();
if(curTime >= dd.dwStartTick+dd.dwDelayTick)
{
if(dd.pFun)
dd.pFun();
else
dd.FunHandler();
if(!dd.csKey.IsEmpty() && m_HandlerKey.find(dd.csKey)!=m_HandlerKey.end())
{
m_HandlerKey.erase(m_HandlerKey.find(dd.csKey));
}
m_HandlerVec.erase(m_HandlerVec.begin()+i);
continue;
}
++i;
}
}
具体使用:
class A
{
static void DoStaticFun(){}
void DoFun(int n){}
}; //调用1
CDelayHandler::PostDelay(A::DoStaticFun,*);
//调用2
A a;
CDelayHandler::GetInstance()->PostDelay(bind(&A::DoFun,&a,),*1000,_T("DoFun"));
注:可能需要其他库
实现PC延迟执行函数的更多相关文章
- IOS 关于取消延迟执行函数的种种。performSelector与cancelPreviousPerformRequestsWithTarget
本文非本人撰写 @interface NSObject (NSDelayedPerforming) - (void)performSelector:(SEL)aSelector withObj ...
- js自定义延迟执行函数
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- js中的延迟执行和定时执行
在js中,延迟执行函数有两种,setTimeout和setInterval,用法如下: function testFunction(){Console.log('hovertree.com');} s ...
- linux进程编程:子进程创建及执行函数简介
linux进程编程:子进程创建及执行函数简介 子进程创建及执行函数有三个: (1)fork();(2)exec();(3)system(); 下面分别做详细介绍.(1)fork() 函数定 ...
- Go defer延迟执行
defer用于延迟执行,可以类比于java或c++中的析构函数. 查看一段示例代码: func Contents(filename string) (string, error) { //打开文件 f ...
- 立即执行函数(IIFE)的理解与运用
作为JavaScript的常用语法,立即执行函数IIFE(Immediately-Invoked Function Expression)是值得我们认真去学习探究的. 一.创建函数的两种方式 我们先从 ...
- SQL Server游标+延迟执行简介
在项目测试中,我们可能会使用批量生成数据来测试程序的性能. 这里讲一个我遇到的问题,由于我们批量生成数据时基本上是瞬间完成,所以GETDATE()函数获得的时间基本上也是一样的,而我们又要求生成每条数 ...
- setTimeout中所执行函数中的this,永远指向window
注意是要延迟执行的函数中的this哦!! //片段一 setTimeout("alert(this)", 1); // [object Window] //片段二 var obj ...
- 每隔一秒自动执行函数(JavaScript)
http://www.cnblogs.com/xlx0210/archive/2010/03/19/1689497.html 1. setInterval() ——每隔一秒自动执行方法,setInte ...
随机推荐
- HDU 4903 (模拟+贪心)
Fighting the Landlords Problem Description Fighting the Landlords is a card game which has been a he ...
- 最短网络 Agri-Net
题目背景 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场.当然,他需要你的帮助. 题目描述 约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其 ...
- 【UOJ34】高精度乘法(FFT)
题意: 思路:FFT模板,自带10倍常数 type cp=record x,y:double; end; arr=..]of cp; var a,b,cur:arr; n,m,n1,n2,i,j:lo ...
- NOIP2010 提高组合集
NOIP 2010 提高组合集 T1 机器翻译 模拟题,用一个栈模拟,桶记录即可. #include <iostream> #include <cstdio> #include ...
- CentOS设置程序开机启动程序/服务的方法(转)
注意:CentOS 6下基本没什么问题,CentOS 7估计不一定能行. 在CentOS系统下,主要有两种方法设置自己安装的程序开机启动. 1.把启动程序的命令添加到/etc/rc.d/rc.loca ...
- Weblogic补丁升级操作手冊
1.查看Weblogic版本号 方法一 [weblogic@Weblogic201 ~]$ cd /home/weblogic/Oracle/Middleware/wlserver_10.3/serv ...
- LeetCode 350. Intersection of Two Arrays II (两个数组的相交之二)
Given two arrays, write a function to compute their intersection. Example:Given nums1 = [1, 2, 2, 1] ...
- iOS 中删除cookie的正确做法
需求:删除 qq 登录的 cookie,保证下次打开 qq 登录页面不会默认登录 实现: NSString *url =@"https://w.mail.qq.com/cgi-bi ...
- linux系统下用到的小知识点积累
preface:在ubuntu下做事情,在终端下执行一些命令.或者在vim里面做一些操作.自然而然须要用到一些小知识点,没有怎么系统地看<鸟哥的菜>,基本上是遇到了什么问题想要实现什么功能 ...
- Oracle执行存储过程报错——ora-01031:权限不足
执行DDL报错 在oracle存储过程中,默认是可以直接执行DML和DQL的,但是执行CREATE这种的DDL则需要借助EXECUTE IMMEDIATE 如: create or replace p ...