当系统闲置时(鼠标,键盘长时间不动),用户定制的回调

本文介绍了一个系统闲置状态下的回调机制,包括如何创建和释放闲置回调对象,以及如何通过回调函数来响应系统进入闲置状态和从闲置状态恢复。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 //当系统闲置时,用户定制的回调
 /*如果下面的两个回调之一存在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;
   }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值