//当系统闲置时,用户定制的回调
/*如果下面的两个回调之一存在S循环,调用CreateIdlingProc将会不返回 */
//头文件
#ifndef FengFunlib
#define FengFunlib
#pragma once
#include <windows.h>
typedef BOOL (CALLBACK* PIDLINGPROC)(LPVOID lpParam);//当系统进入闲置状态的回调函数,要继续执行返回TRUE,返回FALSE退出,不再继续执行
typedef PIDLINGPROC PIDLINGPROC;
typedef BOOL (CALLBACK* PTOUCHEDPROC)(LPVOID lpParam);//当系统首次从闲置状态返回到非闲置状态时的回调函数,要继续执行返回TRUE,返回FALSE退出,不再继续执行
typedef PTOUCHEDPROC PTOUCHEDPROC;
typedef void* HIDLINGOBJECT;
/* 当系统长时间闲置时,在dwSecondDueTime(按毫秒计算)的等待之后,执行由用户定制的pfnIdlingFun回调函数
,如果pfnIdlingFun返回TURE,则在每次dwSecondDueTime定义的时间到达后,会继续执行pfnIdlingFun函数;
另外:当系统从闲置时返回(如果一个新的应用程序被运行,或是用户移动鼠标、按动键盘则会触发PTOUCHEDPROC
回调函数的调用,这个函数只被调用一次,当系统从闲置状态返回到非闲置状态时,如果已进入非闲置状态并且存在连续的活动(例如:
鼠标、键盘的活动、应用程序的运行,都不会再次被调用.如果再次从闲置进入非闲置状态,会再一次被调用一次.
如果pfnIdlingFun返回FALSE,则不会继续执行pfnIdlingFun函数。当不使用时,调用ReleaseIdlingProc释放
需要特别注意的是,不允许在CreateIdlingProc的两个回调函数的实现中存在长时间的执行过程(或者是S循序),
否则会使后台线程对系统的状态的监视失效*/
__out
HIDLINGOBJECT WINAPI
CreateIdlingProc(
__in PIDLINGPROC pfnIdlingFun,/*当系统进入闲置状态时,用户定制的回调函数 */
__in LPVOID lpIdlingFunParam,/* pfnIdlingFun函数的参数 */
__in DWORD dwDueTime ,/*按毫秒为单位的计时等待,达到后执行pfnIdlingFun */
__in PTOUCHEDPROC pfnTouchedFun,/*当系统从闲置状态转到非闲置状态时,用户定制的回调函数 */
__in LPVOID lpTouchedFunParam/*pfnTouchedFun的参数 */
);
/*释放从CreateIdlingProc返回的对象 */
BOOL ReleaseIdlingProc(__in HIDLINGOBJECT hIdlingObj);
//-------------------------------------------------------------------------------
//cpp 这个函数只能运行在win2000或之后的版本
#define _WIN32_WINNT 0x0500
#include "..FengFunlib.H"
typedef struct {
PIDLINGPROC pfnIdlingFun;/*系统闲置状态下,用户定制的回调函数 */
LPVOID lpIdlingFunParam;/* pfnIdlingFun函数的参数 */
DWORD dwDueTime ;/*按毫秒为单位的计时等待,达到后执行pfnIdlingFun */
HANDLE IdlingWorkingThread;/*指向IdlingWorkingThread的线程句柄 */
PTOUCHEDPROC pfnTouchedFun;/*从闲置进入非闲置状态的第一次通知 */
LPVOID lpTouchedParam;/* pfnTouchedFun函数的参数*/
BOOL fIdlingStatus;//是否为闲置状态,如果是为TRUE,否则为FALSE
HANDLE hEvt;/* 事件对象 */
}IDLINGDATA,*PIDLINGDATA;
DWORD CALLBACK IdlingWorkingThread(LPVOID lpParam){
/*这个函数的回调都是在当前线程的,如果回调不返回,那么当前线程就被挂起 */
if(lpParam==NULL) return (DWORD)(FALSE);
PIDLINGDATA pIdlingData=(PIDLINGDATA)lpParam;
DWORD dwWaitObjStatus=0;
DWORD dwLastInputTime=0;
DWORD dwTimeCount=1;//默认值为1
DWORD dwFinallyCount=1;//最终次数,按每500毫秒,半秒
//如果等待的毫秒数小于,例如200毫秒的等待,在这里都为500毫秒
BOOL fReturnValueOfpfnIdlingFun=TRUE;//pfnIdlingFun回调的返回值
BOOL fReturnValueOfpfnTouchedFun=TRUE;//pfnTouchedFun回调的返回值
if(pIdlingData->dwDueTime<500)/*小于500毫秒,立即执行 */
dwFinallyCount=1;//dwTimeCount%dwFinallyCount总是为0
else
if(pIdlingData->dwDueTime==INFINITE)
dwFinallyCount=INFINITE;/*无限等待 ,如果dwTimeCount%dwFinallyCount总是不为0,除非等到*/
else
if(pIdlingData->dwDueTime==0)/* 立即执行不等待 */
dwFinallyCount=1;//dwTimeCount%dwFinallyCount总是为0
else
dwFinallyCount=pIdlingData->dwDueTime/500;//按每500毫秒计算,有多少个500毫秒
LASTINPUTINFO _lastInfo={sizeof(LASTINPUTINFO)};
__try{
while(1){
dwWaitObjStatus=WaitForSingleObject(
pIdlingData->hEvt,
500/*每500毫秒 */
);
switch(dwWaitObjStatus){
case WAIT_TIMEOUT:
// if(!fReturnValueOfpfnIdlingFun) __leave;//如果回调为FALSE,跳到__finally
GetLastInputInfo(&_lastInfo);
if(dwLastInputTime!=_lastInfo.dwTime){
dwLastInputTime=_lastInfo.dwTime;//赋值,上次的最后时间
dwTimeCount=1;//设为默认值
if(pIdlingData->fIdlingStatus==TRUE
&&pIdlingData->pfnTouchedFun!=NULL
&&fReturnValueOfpfnTouchedFun==TRUE){
pIdlingData->fIdlingStatus=FALSE;
fReturnValueOfpfnTouchedFun=
pIdlingData->pfnTouchedFun(pIdlingData->lpTouchedParam);
}
}else
if(dwLastInputTime==_lastInfo.dwTime){
if( dwTimeCount%dwFinallyCount==0){
if(pIdlingData->pfnIdlingFun!=NULL)
fReturnValueOfpfnIdlingFun=
pIdlingData->pfnIdlingFun(pIdlingData->lpIdlingFunParam);
dwTimeCount=1;//清空为默认值
pIdlingData->fIdlingStatus=TRUE;
}
else
dwTimeCount++;
}
break;
case WAIT_OBJECT_0:
__leave;
default :
break;
}//switch
}//while
}
__finally{
}
return 0;
}
HIDLINGOBJECT WINAPI
CreateIdlingProc(
PIDLINGPROC pfnIdlingFun,/*当系统进入闲置状态时,用户定制的回调函数 */
LPVOID lpIdlingFunParam,/* pfnIdlingFun函数的参数 */
DWORD dwDueTime ,/*按毫秒为单位的计时等待,达到后执行pfnIdlingFun */
PTOUCHEDPROC pfnTouchedFun,/*当系统从闲置状态转到非闲置状态时,用户定制的回调函数 */
LPVOID lpTouchedFunParam/*pfnTouchedFun的参数 */
){
PIDLINGDATA pIdlingData=(PIDLINGDATA)GlobalAlloc(GPTR,sizeof(IDLINGDATA));
if(pIdlingData==NULL) return NULL;
__try{
pIdlingData->hEvt= CreateEvent(NULL,FALSE,FALSE,NULL);
if(pIdlingData->hEvt==NULL)__leave;
pIdlingData->dwDueTime= dwDueTime;
pIdlingData->fIdlingStatus=FALSE;
pIdlingData->lpIdlingFunParam=lpIdlingFunParam;
pIdlingData->pfnIdlingFun=pfnIdlingFun;
pIdlingData->pfnTouchedFun=pfnTouchedFun;
pIdlingData->lpTouchedParam=lpTouchedFunParam;
pIdlingData->IdlingWorkingThread=CreateThread(
NULL,0,
(LPTHREAD_START_ROUTINE)IdlingWorkingThread,
pIdlingData,0,NULL);
if(pIdlingData->IdlingWorkingThread==NULL) __leave;
SetThreadPriority(pIdlingData->IdlingWorkingThread,THREAD_PRIORITY_IDLE);
return pIdlingData;
}__finally{
}
if(NULL!=pIdlingData->IdlingWorkingThread){
DWORD dwExitCode=0;
GetExitCodeThread(pIdlingData->IdlingWorkingThread,&dwExitCode);
if(dwExitCode!=0)
SetEvent(pIdlingData->hEvt);
WaitForSingleObject(pIdlingData->IdlingWorkingThread,INFINITE);
}
if(NULL!=pIdlingData->hEvt)CloseHandle(pIdlingData->hEvt);
pIdlingData->dwDueTime=0;
pIdlingData->lpIdlingFunParam=NULL;
pIdlingData->lpTouchedParam=NULL;
pIdlingData->pfnIdlingFun=NULL;
pIdlingData->pfnTouchedFun=NULL;
if(NULL!=pIdlingData->IdlingWorkingThread)
CloseHandle(pIdlingData->IdlingWorkingThread);
GlobalFree( pIdlingData);
pIdlingData=NULL;
return NULL;
}
BOOL ReleaseIdlingProc(__in HIDLINGOBJECT hIdlingObj){
PIDLINGDATA pIdlingData=(PIDLINGDATA)hIdlingObj;
__try{
if(pIdlingData!=NULL){
if(pIdlingData->IdlingWorkingThread==NULL)
__leave;
else{
DWORD ThdExitCode=0;
GetExitCodeThread(pIdlingData->IdlingWorkingThread,&ThdExitCode);
if(ThdExitCode!=0)
SetEvent(pIdlingData->hEvt);
WaitForSingleObjectEx(pIdlingData->IdlingWorkingThread,
INFINITE,TRUE);//等待线程结束
}
pIdlingData->dwDueTime=0;
pIdlingData->lpIdlingFunParam=NULL;
pIdlingData->lpTouchedParam=NULL;
pIdlingData->pfnIdlingFun=NULL;
pIdlingData->pfnTouchedFun=NULL;
if(pIdlingData->hEvt!=NULL) CloseHandle(pIdlingData->hEvt);
if(pIdlingData->IdlingWorkingThread!=NULL)CloseHandle(pIdlingData->IdlingWorkingThread);
GlobalFree( pIdlingData);
pIdlingData=NULL;
return TRUE;
}
}
__finally{}
return FALSE;
}