首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > WinCE >

wince6.0+S3C6410关机处理,该怎么处理

2013-01-25 
wince6.0+S3C6410关机处理wince6.0+S3C6410关机处理通过以下方法实现:关机中断触发,判断为有效键时,发消息

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);
    }}
}
 
[解决办法]
现在方法二还不能正常实现功能,现象为:
第一次按关机键,正常实现功能;
第二次按关机键,会弹出关机界面,但是改变注册表后不能实现功能。

看你这种情况,你把注册表的那个改一下吧。例如关机的就弄成两个,一个是请求关机,另一个是关机状态。
在一次请求关机的时候,先更改请求关机的注册表,然后处理一些东西后,更改关机状态,并清除请求关机的注册表信息,这样就可以在下次来请求的时候,认清处理

热点排行