//========================================================================
//TITLE:
// WinCE实时获取电源状态变化
//AUTHOR:
// norains
//DATE:
// Friday 20-July-2007
//Environment:
// EVC4.0 + Windows CE 5.0 Standard SDK
//========================================================================
使用CTpowerThread很简单实现实时获取电源的状态.在该类的内部创建了一个获取电量的线程,只要设置好回调函数,就可以自动接收设定间隔的电源状态.
现在我们来看看该类的具体操作方法:
//获取类的实例
CPowerThread *pPowThrd = CPowerThread::GetInstance();
if(pPowThrd != NULL)
{
//设置回调函数
pPowThrd->SetCallbackFunction(NotifyPowerStatus);
//启动线程,开始捕抓电量
pPowThrd->StartCapture();
}
这段代码中最重要的是设置回调函数,该函数的声明如下:
void NotifyPowerStatus(PowerStatusType powStatus, int iBatteryPercent)
powStatus是电源的简易状态,分为七个部分,取值为其中之一:
POW_UNKNOW, //Unknow the status
POW_CHARGING, //It's charging now
POW_CHARGEFULL, //Full charge
POW_VLOW, //The battery level is very low
POW_LOW,
POW_NORMAL,
POW_HIGH,
iBatteryPercent为当前电源的百分比,取值为:0~1.
下面给出一个回调函数的样例代码:
void NotifyPowerStatus(PowerStatusType powStatus, int iBatteryPercent)
{
switch(powStatus)
{
case POW_UNKNOW:
//当前状态不明
break;
case POW_CHARGING:
//充电中
break;
case POW_VLOW:
//电池电量非常低
break;
...
}
}
再来看看该类的其它接口函数:
SetWaitTime(ULONG ulTime)
该函数设置线程的超时时间.如果设置为INFINITE,则只有当电源状态有变化时才会调用回调函数.
GetCallbackFunction(void (* *pCallbackFunc)(PowerStatusType powStatus, int iBatteryPercent))
获取已设置的回调函数的指针
StopCapture()
停止线程.如果超时时间设为为INFINITE,则只有获取下次电源状态后才退出.
GetRunStatus()
获取当前线程的运行状态.
以下为该CPowerthread的完整源码:
源代码的具体原理可参考此篇文章:<EVC获取电源属性>http://blog.youkuaiyun.com/norains/archive/2006/09/07/1189157.aspx
//////////////////////////////////////////////////////////////////////
//PowerThread.h:interfacefortheCPowerThreadclass.
//
//Version:
//1.0.1
//Date:
//2007.07.20
//////////////////////////////////////////////////////////////////////
#ifndefPOWERTHREAD_H
#definePOWERTHREAD_H
#include"Pm.h"
//-----------------------------------------------------------------
//Enumdatatype
enumPowerStatusType
{
POW_UNKNOW,//Unknowthestatus
POW_CHARGING,//It'schargingnow
POW_CHARGEFULL,//Fullcharge
POW_VLOW,//Thebatterylevelisverylow
POW_LOW,
POW_NORMAL,
POW_HIGH,
POW_VHIGH//Thebatterylevelisveryhigh
};
//----------------------------------------------------------------
classCPowerThread
{
public:
voidGetCallbackFunction(void(**pCallbackFunc)(PowerStatusTypepowStatus,intiBatteryPercent));
voidSetCallbackFunction(void(*pCallbackFunc)(PowerStatusTypepowStatus,intiBatteryPercent));
voidStopCapture();
BOOLStartCapture();
BOOLGetRunStatus();
voidSetTimeout(ULONGulTime);
staticCPowerThread*GetInstance();
virtual~CPowerThread();
protected:
CPowerThread();
PowerStatusTypeGetPowerStatus(PPOWER_BROADCASTpPowerInfo,int*piPercent);
staticDWORDWINAPIPowerThread(PVOIDpArg);
staticCPowerThread*m_pInstance;
BOOLm_bExitThread;
ULONGm_ulWaitTime;
BOOLm_bRunning;
CRITICAL_SECTIONm_csLock;
//Thecriticalsectionfunction
inlinevoidInitLock(){InitializeCriticalSection(&m_csLock);}
inlinevoidLockThis(){EnterCriticalSection(&m_csLock);}
inlinevoidUnLockThis(){LeaveCriticalSection(&m_csLock);}
inlinevoidDelLock(){DeleteCriticalSection(&m_csLock);}
//Thisisforcallbackfunction.
void(*m_pNotifyPower)(PowerStatusTypepowStatus,intiBatteryPercent);
};
#endif//#ifndefPOWERTHREAD_H
//////////////////////////////////////////////////////////////////////
//PowerThread.cpp:implementationoftheCPowerThreadclass.
//
//////////////////////////////////////////////////////////////////////
#include"stdafx.h"
#include"PowerThread.h"
#include"Msgqueue.h"
//--------------------------------------------------------------------
//Macrodefine
#defineDEFAULT_TIMEOUT1000ms//1000ms
//---------------------------------------------------------------------
//Initialize
CPowerThread*CPowerThread::m_pInstance=NULL;
//----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////
//Construction/Destruction
//////////////////////////////////////////////////////////////////////
CPowerThread::CPowerThread():
m_bExitThread(TRUE),
m_ulWaitTime(DEFAULT_TIMEOUT),
m_bRunning(FALSE),
m_pNotifyPower(NULL)
{
InitLock();
}
CPowerThread::~CPowerThread()
{
if(m_pInstance!=NULL)
{
deletem_pInstance;
m_pInstance=NULL;
}
DelLock();
}
//------------------------------------------------------------------
//Description:
//GetthelevelofpowerfromthePPOWER_BROADCASTstruct
//
//Parameters:
//pPowerInfo:[in]Thestructincludesthepowerinformation
//piPercent:[out]Thebatterylifepercent.
//
//ReturnValues:
//Thepowerstatus
//----------------------------------------------------------------
PowerStatusTypeCPowerThread::GetPowerStatus(PPOWER_BROADCASTpPowerInfo,int*piPercent)
{
PowerStatusTypepowStatus=POW_UNKNOW;
if(!pPowerInfo)
{
returnPOW_UNKNOW;
}
PPOWER_BROADCAST_POWER_INFOppbpi=(PPOWER_BROADCAST_POWER_INFO)pPowerInfo->SystemPowerState;
if(!ppbpi)
{
returnPOW_UNKNOW;
}
*piPercent=ppbpi->bBatteryLifePercent;
if(ppbpi->bACLineStatus==AC_LINE_ONLINE)
{
if(ppbpi->bBatteryFlag==BATTERY_FLAG_CHARGING)
{
//Charging
powStatus=POW_CHARGING;
}
else
{
//Maybefullcharging,ormaybenobattery
powStatus=POW_CHARGEFULL;
}
}
else
{
//Usebattery
if(0<=ppbpi->bBatteryLifePercent&&ppbpi->bBatteryLifePercent<=20)
{
powStatus=POW_VLOW;
}
elseif(20<ppbpi->bBatteryLifePercent&&ppbpi->bBatteryLifePercent<=40)
{
powStatus=POW_LOW;
}
elseif(40<ppbpi->bBatteryLifePercent&&ppbpi->bBatteryLifePercent<=60)
{
powStatus=POW_NORMAL;
}
elseif(60<ppbpi->bBatteryLifePercent&&ppbpi->bBatteryLifePercent<=80)
{
powStatus=POW_HIGH;
}
elseif(80<ppbpi->bBatteryLifePercent&&ppbpi->bBatteryLifePercent<=100)
{
powStatus=POW_VHIGH;
}
else
{
powStatus=POW_UNKNOW;
}
}
returnpowStatus;
}
//------------------------------------------------------------------
//Description:
//Threadtogetthepowerstatus
//----------------------------------------------------------------
DWORDWINAPICPowerThread::PowerThread(PVOIDpArg)
{
m_pInstance->m_bRunning=TRUE;
BYTEpbMsgBuf[sizeof(POWER_BROADCAST)+sizeof(POWER_BROADCAST_POWER_INFO)];
PPOWER_BROADCASTppb=(PPOWER_BROADCAST)pbMsgBuf;
MSGQUEUEOPTIONSmsgopts;
//Createourmessagequeue
memset(&msgopts,0,sizeof(msgopts));
msgopts.dwSize=sizeof(msgopts);
msgopts.dwFlags=0;
msgopts.dwMaxMessages=0;
msgopts.cbMaxMessage=sizeof(pbMsgBuf);
msgopts.bReadAccess=TRUE;
HANDLErghWaits[1]={NULL};
rghWaits[0]=CreateMsgQueue(NULL,&msgopts);
if(!rghWaits[0])
{
//erro
return0x10;
}
HANDLEhReq=NULL;
//Requestnotifications
hReq=RequestPowerNotifications(rghWaits[0],PBT_POWERINFOCHANGE);
if(!hReq)
{
CloseHandle(rghWaits[0]);
//erro
return0x15;
}
while(m_pInstance->m_bExitThread==FALSE)
{
DWORDdwWaitCode=MsgWaitForMultipleObjectsEx(1,rghWaits,m_pInstance->m_ulWaitTime,QS_ALLINPUT,MWMO_INPUTAVAILABLE);
if(dwWaitCode==WAIT_OBJECT_0)
{
DWORDdwSize,dwFlags;
BOOLbReadResult=ReadMsgQueue(rghWaits[0],ppb,sizeof(pbMsgBuf),&dwSize,0,&dwFlags);
if(bReadResult==TRUE)
{
intiPowPercent;
PowerStatusTypepowStatus=m_pInstance->GetPowerStatus(ppb,&iPowPercent);
m_pInstance->LockThis();
if(m_pInstance->m_pNotifyPower!=NULL)
{
m_pInstance->m_pNotifyPower(powStatus,iPowPercent);
}
m_pInstance->UnLockThis();
}
else
{
//Weshouldnevergethere
break;
}
}
}
m_pInstance->m_bRunning=FALSE;
return0;
}
//------------------------------------------------------------------
//Description:
//Getinstance
//----------------------------------------------------------------
CPowerThread*CPowerThread::GetInstance()
{
if(m_pInstance==NULL)
{
m_pInstance=newCPowerThread();
}
returnm_pInstance;
}
//------------------------------------------------------------------
//Description:
//Setthetimeoutforthewaitthread.ItisonlyfortheMsgWaitForMultipleObjectsEx()
//ThedefaultvalueisDEFAULT_TIMEOUT
//----------------------------------------------------------------
voidCPowerThread::SetTimeout(ULONGulTime)
{
m_ulWaitTime=ulTime;
}
//------------------------------------------------------------------
//Description:
//Getthestatusofthread
//
//ReturnValues:
//TRUE:Thethreadisrunningforcapturingthepowerstatus.
//FALSE:Nothreadrunning.
//----------------------------------------------------------------
BOOLCPowerThread::GetRunStatus()
{
returnm_bRunning;
}
//------------------------------------------------------------------
//Description:
//startcapturingthepowerstatus.Ifthereisthreadrunning,
//itwillreturnFALSE;
//
//------------------------------------------------------------------
BOOLCPowerThread::StartCapture()
{
if(m_bRunning==TRUE)
{
returnFALSE;
}
m_bExitThread=FALSE;
//Createthethreadforbattersampled
DWORDdwPwrThdID;
HANDLEhdThrd=CreateThread(NULL,0,PowerThread,NULL,0,&dwPwrThdID);
if(hdThrd==NULL)
{
returnFALSE;
}
CloseHandle(hdThrd);
returnTRUE;
}
//-----------------------------------------------------------------------------
//Description:
//Stopcapturing.
//
//--------------------------------------------------------------------------------
voidCPowerThread::StopCapture()
{
m_bExitThread=TRUE;
}
//------------------------------------------------------------------
//Description:
//Setthecallbackfunctionforreceivethepowerstatus
//------------------------------------------------------------------
voidCPowerThread::SetCallbackFunction(void(*pCallbackFunc)(PowerStatusTypepowStatus,intiBatteryPercent))
{
LockThis();
m_pNotifyPower=pCallbackFunc;
UnLockThis();
}
//------------------------------------------------------------------
//Description:
//Getthecallbackfunction
//------------------------------------------------------------------
voidCPowerThread::GetCallbackFunction(void(**pCallbackFunc)(PowerStatusTypepowStatus,intiBatteryPercent))
{
LockThis();
*pCallbackFunc=m_pNotifyPower;
UnLockThis();
}
//TITLE:
// WinCE实时获取电源状态变化
//AUTHOR:
// norains
//DATE:
// Friday 20-July-2007
//Environment:
// EVC4.0 + Windows CE 5.0 Standard SDK
//========================================================================
使用CTpowerThread很简单实现实时获取电源的状态.在该类的内部创建了一个获取电量的线程,只要设置好回调函数,就可以自动接收设定间隔的电源状态.
现在我们来看看该类的具体操作方法:
//获取类的实例
CPowerThread *pPowThrd = CPowerThread::GetInstance();
if(pPowThrd != NULL)
{
//设置回调函数
pPowThrd->SetCallbackFunction(NotifyPowerStatus);
//启动线程,开始捕抓电量
pPowThrd->StartCapture();
}
这段代码中最重要的是设置回调函数,该函数的声明如下:
void NotifyPowerStatus(PowerStatusType powStatus, int iBatteryPercent)
powStatus是电源的简易状态,分为七个部分,取值为其中之一:
POW_UNKNOW, //Unknow the status
POW_CHARGING, //It's charging now
POW_CHARGEFULL, //Full charge
POW_VLOW, //The battery level is very low
POW_LOW,
POW_NORMAL,
POW_HIGH,
iBatteryPercent为当前电源的百分比,取值为:0~1.
下面给出一个回调函数的样例代码:
void NotifyPowerStatus(PowerStatusType powStatus, int iBatteryPercent)
{
switch(powStatus)
{
case POW_UNKNOW:
//当前状态不明
break;
case POW_CHARGING:
//充电中
break;
case POW_VLOW:
//电池电量非常低
break;
...
}
}
再来看看该类的其它接口函数:
SetWaitTime(ULONG ulTime)
该函数设置线程的超时时间.如果设置为INFINITE,则只有当电源状态有变化时才会调用回调函数.
GetCallbackFunction(void (* *pCallbackFunc)(PowerStatusType powStatus, int iBatteryPercent))
获取已设置的回调函数的指针
StopCapture()
停止线程.如果超时时间设为为INFINITE,则只有获取下次电源状态后才退出.
GetRunStatus()
获取当前线程的运行状态.
以下为该CPowerthread的完整源码:
源代码的具体原理可参考此篇文章:<EVC获取电源属性>http://blog.youkuaiyun.com/norains/archive/2006/09/07/1189157.aspx
//////////////////////////////////////////////////////////////////////
//PowerThread.h:interfacefortheCPowerThreadclass.
//
//Version:
//1.0.1
//Date:
//2007.07.20
//////////////////////////////////////////////////////////////////////
#ifndefPOWERTHREAD_H
#definePOWERTHREAD_H
#include"Pm.h"
//-----------------------------------------------------------------
//Enumdatatype
enumPowerStatusType
{
POW_UNKNOW,//Unknowthestatus
POW_CHARGING,//It'schargingnow
POW_CHARGEFULL,//Fullcharge
POW_VLOW,//Thebatterylevelisverylow
POW_LOW,
POW_NORMAL,
POW_HIGH,
POW_VHIGH//Thebatterylevelisveryhigh
};
//----------------------------------------------------------------
classCPowerThread
{
public:
voidGetCallbackFunction(void(**pCallbackFunc)(PowerStatusTypepowStatus,intiBatteryPercent));
voidSetCallbackFunction(void(*pCallbackFunc)(PowerStatusTypepowStatus,intiBatteryPercent));
voidStopCapture();
BOOLStartCapture();
BOOLGetRunStatus();
voidSetTimeout(ULONGulTime);
staticCPowerThread*GetInstance();
virtual~CPowerThread();
protected:
CPowerThread();
PowerStatusTypeGetPowerStatus(PPOWER_BROADCASTpPowerInfo,int*piPercent);
staticDWORDWINAPIPowerThread(PVOIDpArg);
staticCPowerThread*m_pInstance;
BOOLm_bExitThread;
ULONGm_ulWaitTime;
BOOLm_bRunning;
CRITICAL_SECTIONm_csLock;
//Thecriticalsectionfunction
inlinevoidInitLock(){InitializeCriticalSection(&m_csLock);}
inlinevoidLockThis(){EnterCriticalSection(&m_csLock);}
inlinevoidUnLockThis(){LeaveCriticalSection(&m_csLock);}
inlinevoidDelLock(){DeleteCriticalSection(&m_csLock);}
//Thisisforcallbackfunction.
void(*m_pNotifyPower)(PowerStatusTypepowStatus,intiBatteryPercent);
};
#endif//#ifndefPOWERTHREAD_H
//////////////////////////////////////////////////////////////////////
//PowerThread.cpp:implementationoftheCPowerThreadclass.
//
//////////////////////////////////////////////////////////////////////
#include"stdafx.h"
#include"PowerThread.h"
#include"Msgqueue.h"
//--------------------------------------------------------------------
//Macrodefine
#defineDEFAULT_TIMEOUT1000ms//1000ms
//---------------------------------------------------------------------
//Initialize
CPowerThread*CPowerThread::m_pInstance=NULL;
//----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////
//Construction/Destruction
//////////////////////////////////////////////////////////////////////
CPowerThread::CPowerThread():
m_bExitThread(TRUE),
m_ulWaitTime(DEFAULT_TIMEOUT),
m_bRunning(FALSE),
m_pNotifyPower(NULL)
{
InitLock();
}
CPowerThread::~CPowerThread()
{
if(m_pInstance!=NULL)
{
deletem_pInstance;
m_pInstance=NULL;
}
DelLock();
}
//------------------------------------------------------------------
//Description:
//GetthelevelofpowerfromthePPOWER_BROADCASTstruct
//
//Parameters:
//pPowerInfo:[in]Thestructincludesthepowerinformation
//piPercent:[out]Thebatterylifepercent.
//
//ReturnValues:
//Thepowerstatus
//----------------------------------------------------------------
PowerStatusTypeCPowerThread::GetPowerStatus(PPOWER_BROADCASTpPowerInfo,int*piPercent)
{
PowerStatusTypepowStatus=POW_UNKNOW;
if(!pPowerInfo)
{
returnPOW_UNKNOW;
}
PPOWER_BROADCAST_POWER_INFOppbpi=(PPOWER_BROADCAST_POWER_INFO)pPowerInfo->SystemPowerState;
if(!ppbpi)
{
returnPOW_UNKNOW;
}
*piPercent=ppbpi->bBatteryLifePercent;
if(ppbpi->bACLineStatus==AC_LINE_ONLINE)
{
if(ppbpi->bBatteryFlag==BATTERY_FLAG_CHARGING)
{
//Charging
powStatus=POW_CHARGING;
}
else
{
//Maybefullcharging,ormaybenobattery
powStatus=POW_CHARGEFULL;
}
}
else
{
//Usebattery
if(0<=ppbpi->bBatteryLifePercent&&ppbpi->bBatteryLifePercent<=20)
{
powStatus=POW_VLOW;
}
elseif(20<ppbpi->bBatteryLifePercent&&ppbpi->bBatteryLifePercent<=40)
{
powStatus=POW_LOW;
}
elseif(40<ppbpi->bBatteryLifePercent&&ppbpi->bBatteryLifePercent<=60)
{
powStatus=POW_NORMAL;
}
elseif(60<ppbpi->bBatteryLifePercent&&ppbpi->bBatteryLifePercent<=80)
{
powStatus=POW_HIGH;
}
elseif(80<ppbpi->bBatteryLifePercent&&ppbpi->bBatteryLifePercent<=100)
{
powStatus=POW_VHIGH;
}
else
{
powStatus=POW_UNKNOW;
}
}
returnpowStatus;
}
//------------------------------------------------------------------
//Description:
//Threadtogetthepowerstatus
//----------------------------------------------------------------
DWORDWINAPICPowerThread::PowerThread(PVOIDpArg)
{
m_pInstance->m_bRunning=TRUE;
BYTEpbMsgBuf[sizeof(POWER_BROADCAST)+sizeof(POWER_BROADCAST_POWER_INFO)];
PPOWER_BROADCASTppb=(PPOWER_BROADCAST)pbMsgBuf;
MSGQUEUEOPTIONSmsgopts;
//Createourmessagequeue
memset(&msgopts,0,sizeof(msgopts));
msgopts.dwSize=sizeof(msgopts);
msgopts.dwFlags=0;
msgopts.dwMaxMessages=0;
msgopts.cbMaxMessage=sizeof(pbMsgBuf);
msgopts.bReadAccess=TRUE;
HANDLErghWaits[1]={NULL};
rghWaits[0]=CreateMsgQueue(NULL,&msgopts);
if(!rghWaits[0])
{
//erro
return0x10;
}
HANDLEhReq=NULL;
//Requestnotifications
hReq=RequestPowerNotifications(rghWaits[0],PBT_POWERINFOCHANGE);
if(!hReq)
{
CloseHandle(rghWaits[0]);
//erro
return0x15;
}
while(m_pInstance->m_bExitThread==FALSE)
{
DWORDdwWaitCode=MsgWaitForMultipleObjectsEx(1,rghWaits,m_pInstance->m_ulWaitTime,QS_ALLINPUT,MWMO_INPUTAVAILABLE);
if(dwWaitCode==WAIT_OBJECT_0)
{
DWORDdwSize,dwFlags;
BOOLbReadResult=ReadMsgQueue(rghWaits[0],ppb,sizeof(pbMsgBuf),&dwSize,0,&dwFlags);
if(bReadResult==TRUE)
{
intiPowPercent;
PowerStatusTypepowStatus=m_pInstance->GetPowerStatus(ppb,&iPowPercent);
m_pInstance->LockThis();
if(m_pInstance->m_pNotifyPower!=NULL)
{
m_pInstance->m_pNotifyPower(powStatus,iPowPercent);
}
m_pInstance->UnLockThis();
}
else
{
//Weshouldnevergethere
break;
}
}
}
m_pInstance->m_bRunning=FALSE;
return0;
}
//------------------------------------------------------------------
//Description:
//Getinstance
//----------------------------------------------------------------
CPowerThread*CPowerThread::GetInstance()
{
if(m_pInstance==NULL)
{
m_pInstance=newCPowerThread();
}
returnm_pInstance;
}
//------------------------------------------------------------------
//Description:
//Setthetimeoutforthewaitthread.ItisonlyfortheMsgWaitForMultipleObjectsEx()
//ThedefaultvalueisDEFAULT_TIMEOUT
//----------------------------------------------------------------
voidCPowerThread::SetTimeout(ULONGulTime)
{
m_ulWaitTime=ulTime;
}
//------------------------------------------------------------------
//Description:
//Getthestatusofthread
//
//ReturnValues:
//TRUE:Thethreadisrunningforcapturingthepowerstatus.
//FALSE:Nothreadrunning.
//----------------------------------------------------------------
BOOLCPowerThread::GetRunStatus()
{
returnm_bRunning;
}
//------------------------------------------------------------------
//Description:
//startcapturingthepowerstatus.Ifthereisthreadrunning,
//itwillreturnFALSE;
//
//------------------------------------------------------------------
BOOLCPowerThread::StartCapture()
{
if(m_bRunning==TRUE)
{
returnFALSE;
}
m_bExitThread=FALSE;
//Createthethreadforbattersampled
DWORDdwPwrThdID;
HANDLEhdThrd=CreateThread(NULL,0,PowerThread,NULL,0,&dwPwrThdID);
if(hdThrd==NULL)
{
returnFALSE;
}
CloseHandle(hdThrd);
returnTRUE;
}
//-----------------------------------------------------------------------------
//Description:
//Stopcapturing.
//
//--------------------------------------------------------------------------------
voidCPowerThread::StopCapture()
{
m_bExitThread=TRUE;
}
//------------------------------------------------------------------
//Description:
//Setthecallbackfunctionforreceivethepowerstatus
//------------------------------------------------------------------
voidCPowerThread::SetCallbackFunction(void(*pCallbackFunc)(PowerStatusTypepowStatus,intiBatteryPercent))
{
LockThis();
m_pNotifyPower=pCallbackFunc;
UnLockThis();
}
//------------------------------------------------------------------
//Description:
//Getthecallbackfunction
//------------------------------------------------------------------
voidCPowerThread::GetCallbackFunction(void(**pCallbackFunc)(PowerStatusTypepowStatus,intiBatteryPercent))
{
LockThis();
*pCallbackFunc=m_pNotifyPower;
UnLockThis();
}
本文介绍了一种在Windows CE平台上实时获取电源状态的方法,通过创建并利用CPowerThread类,可以周期性地获取设备的电源状态,并通过回调函数通知应用程序。文章提供了完整的源代码和示例,展示了如何设置回调函数及调整线程的等待时间。
669

被折叠的 条评论
为什么被折叠?



