wince6.0+S3C6410关机处理
wince6.0+S3C6410关机处理通过以下方法实现:
关机中断触发,判断为有效键时,发消息给应用弹出关机界面,此时通过改变注册表值选择执行以下4个选择之一:
TURNOFFLCD: dwVal=1;关屏
TURNOFFPOWER:dwVal=2;关机
CANCLE:dwVal=3;取消
LOGOUT;dwVal=4;注销用户
现在的问题是:之前使用方法一:一直循环读注册表的方式等注册表值改变,一旦改变即跳出循环,执行相应的操作。但这种方法因为一直在循环执行浪费系统资源,所以想使用方法二:使用CeFindFirstRegChange函数等待注册表改变,只有在注册表改变的情况下才去读注册表(此部分已标红),现在方法二还不能正常实现功能,现象为:
第一次按关机键,正常实现功能;
第二次按关机键,会弹出关机界面,但是改变注册表后不能实现功能,串口输出调试信息显示此次中断在注册表没改变前已经执行完毕,也就是说第二次中断执行过程中,hEventPowerControlRegistryChange在注册表改变前一直是激活状态,所以压根就没等注册表改变就往下执行了。
第三次再按关机键时则识别到了注册表第二次改变的值,直接执行了第二次注册表改变时选择的功能。
请问:怎样操作才能用方法二正确实现关机界面的4个功能?每次关机中断执行过程中hEventPowerControlRegistryChange都能在等到注册表改变后才被激活?
完整代码附上如下:
static DWORD PowerButtonThread(void)
{
DWORD i,count;
DWORD dwVal=0;
BOOL flag,ret=FALSE;
DWORD dwResult;
HKEY hKey = NULL;
BOOL b;
HANDLE hEventPowerControlRegistryChange = NULL;
RETAILMSG(PWR_ZONE_ENTER, (_T("[PWR:INF] ++%s()\r\n"), _T(__FUNCTION__)));
dwResult = RegOpenKeyEx(HKEY_CURRENT_USER, POWERCONTROL_REGKEY, 0, KEY_NOTIFY, &hKey);
if(ERROR_SUCCESS != dwResult)
{
goto exit;
}
RETAILMSG(1, (TEXT("powerbutton hKey=%s\r\n"),hKey));
// Request notification of powercontrol registry changes:
hEventPowerControlRegistryChange = CeFindFirstRegChange(hKey, TRUE, REG_NOTIFY_CHANGE_LAST_SET);
if(INVALID_HANDLE_VALUE == hEventPowerControlRegistryChange)
{
RETAILMSG(ZONE_ERROR, (TEXT("BKL: CeFindFirstRegChange failed\r\n")));
goto exit;
}
RegCloseKey(hKey);
hKey=NULL;
while (1)
{
__try
{
WaitForSingleObject(g_hEventPowerBtn, INFINITE);
if(WaitForAPIReady(SH_SHELL,INFINITE) == WAIT_OBJECT_0)
{
RETAILMSG(1,(TEXT(" PowerButtonThread\r\n")));
//for(i=0; ; i++)
//{
RETAILMSG(1, (TEXT("ControlPower Interrup occur\r\n")));
flag = Button_pwrbtn_is_pushed();
Sleep(100);
if(Button_pwrbtn_is_pushed()&&flag)
{
count=20;
for(i=0; ; i++)
{
if(!(Button_pwrbtn_is_pushed()))
{
if(LcdSwitchCount)
{
LcdSwitch(TRUE);
KeyLedSwitch(TRUE);
break;
}
else
{
#if (PROJECT_NAME == PROJECT1603)
//PowerButtonProcessExec(_T("\\PocketMory\\PowerControl"));
PowerButtonProcessExec(_T("\\windows\\PowerControl"));
#elif(PROJECT_NAME == PROJECT1303)
//PowerButtonProcessExec(_T("\\windows\\PowerControl"));
keybd_event(VK_POWERBUTTON,0,0,0);
Sleep(100);
keybd_event(VK_POWERBUTTON,0,KEYEVENTF_KEYUP,0);
#endif
break;
}
}
else
{
Sleep(100);
--count;
if(count==0)
{
RETAILMSG(1, (TEXT(" compel poweroff\r\n")));
LcdSwitch(FALSE);
PowerDownSystem();
}
}
}
}
if(LcdSwitchCount)
{
dwVal=0;
LcdSwitchCount=FALSE;
g_pVIC1Reg->VICINTENABLE = (0x1<<30);
RETAILMSG(1, (TEXT(" LcdSwitchCount\r\n")));
}
else
{
//方法一:注册表初始值为0,循环等待注册表值发生改变,一旦判断dwVal不为0,则跳出循环执行相应的操作
do {
//RegFlushKey(HKEY_CURRENT_USER);
dwVal = ReadPowerBtnReg();
if (dwVal != 0 )
{
RETAILMSG(1, (TEXT(" test do while dwval=%d\r\n"),dwVal));
break;
}
Sleep(5);
}while(1);
/*
方法二:等待注册表改变的句柄激活,一旦激活,读注册表值
ret=WaitForSingleObject(hEventPowerControlRegistryChange, INFINITE);
if(ret==WAIT_OBJECT_0)
{
RETAILMSG(1, (TEXT("hEventPowerControlRegistryChange\r\n")));
dwVal = ReadPowerBtnReg();
RETAILMSG(1, (TEXT("Registry change dwVal=%d\r\n",dwVal)));
SetPowerBtnReg(0);
}
CeFindNextRegChange(hEventPowerControlRegistryChange);
ret=WaitForSingleObject(hEventPowerControlRegistryChange, INFINITE);
if(ret==WAIT_OBJECT_0)
{
RETAILMSG(1, (TEXT("hEventPowerControlRegistryChange22\r\n")));
}*/
}
SetPowerBtnReg(0);
//RegFlushKey(HKEY_CURRENT_USER);
if (dwVal == TURNOFFLCD)
{ //turn off lcd
RETAILMSG(1, (TEXT("turn off lcd,dwVal=%d\r\n",dwVal)));
LcdSwitchCount=TRUE;
LcdSwitch(FALSE);
#if (PROJECT_NAME == PROJECT1603)
KeyLedSwitch(FALSE);
g_pGPIOReg->GPNDAT |= (1<<10); //output hight level to turn off LED
RETAILMSG(1,(TEXT(" disable touch\r\n")));
g_pVIC1Reg->VICINTENCLEAR = (0x1<<30);
#endif
//g_pVIC0Reg->VICINTENCLEAR = (0x1<<22); //LILI add for disable keybd Interrupt
}
else if(dwVal == TURNOFFPOWER)
{ //powerdown
RETAILMSG(1, (TEXT("::: button down go to powerdown,dwVal=%d\r\n",dwVal)));
#if (PROJECT_NAME == PROJECT1603)
g_pVIC1Reg->VICINTENCLEAR = (0x1<<30);
memcpy((void *)IMAGE_FRAMEBUFFER_UA_START, gImage_powerdown2, LCD_WIDTH*LCD_HEIGHT*2);
Sleep(2000);
#elif(PROJECT_NAME == PROJECT1303)
//g_pGPIOReg->EINT0MASK |= (0x1<<18); // Mask EINT18
//g_pVIC0Reg->VICINTENCLEAR |= (0x1<<22);
LcdSwitch(FALSE);
#endif
//memcpy((void *)IMAGE_FRAMEBUFFER_UA_START, gImage_powerdown2, LCD_WIDTH*LCD_HEIGHT*2);
PowerDownSystem();
KeyLedSwitch(FALSE);
}
else if (dwVal == CANCLE)
{//cancel
RETAILMSG(1, (TEXT("::: button down go to cancel,dwVal=%d\r\n",dwVal)));
}
else if(dwVal==LOGOUT)
{
//logout(注销)
RETAILMSG(1,(TEXT("logout current user,dwVal=%d\r\n",dwVal)));
}
}
InitInterrupt();
InterruptDone(g_dwSysIntrPowerBtn);
RETAILMSG(1,(TEXT(" PWR InterruptDone\r\n")));
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
RETAILMSG(1, (_T("kandi enter into PowerButtonThread 33333333\r\n")));
}
exit:
if(hEventPowerControlRegistryChange)
{
CeFindCloseRegChange( hEventPowerControlRegistryChange);
}
if(hKey)
{
RegCloseKey(hKey);
}}
}
[最优解释]
现在方法二还不能正常实现功能,现象为:
第一次按关机键,正常实现功能;
第二次按关机键,会弹出关机界面,但是改变注册表后不能实现功能。
看你这种情况,你把注册表的那个改一下吧。例如关机的就弄成两个,一个是请求关机,另一个是关机状态。
在一次请求关机的时候,先更改请求关机的注册表,然后处理一些东西后,更改关机状态,并清除请求关机的注册表信息,这样就可以在下次来请求的时候,认清处理
[其他解释]