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

wince6.0+S3C6410关机处置

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

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

引用:
现在方法二还不能正常实现功能,现象为:
第一次按关机键,正常实现功能;
第二次按关机键,会弹出关机界面,但是改变注册表后不能实现功能。

看你这种情况,你把注册表的那个改一下吧。例如关机的就弄成两个,一个是请求关机,另一个是关机状态。
在一次请求关机的时候,先更改请求关机的注册表,然后处理一些东西后,更改关机状态,并清除请求关机的注册表信息,这样就可以在下次来请求的时候,认清处理
我是在执行关机之后通过SetPowerBtnReg(0)把注册表又恢复到了初始状态的,现在的问题是hEventPowerControlRegistryChange这个句柄第一次被激活之后就一直是激活状态了,怎么能让它执行一次后就回到等待状态直到下一次注册表改变时再被激活?
[其他解释]
用ResetEvent不行?
[其他解释]
关个机,也搞那么高深。

按下关机键,长按以后,弹一框出来,然后注意把注册表flush一下,再直接关闭电源不就完了
[其他解释]
该回复于2012-09-07 11:31:35被版主删除
[其他解释]
引用:
关个机,也搞那么高深。

按下关机键,长按以后,弹一框出来,然后注意把注册表flush一下,再直接关闭电源不就完了
现在也是这么做的,只是再等待修改注册表的时间里一个是直接停下等,等到改变了再读;一个是不停的循环查询,查到改变就读,现在可以用后一种实现,只是想学习一下为什么前一种方法实现不了而已
[其他解释]
引用:
用ResetEvent不行?
貌似不行,试了不行,我觉的可能是这几个函数我用的方法不对,但又不知道怎么用才是对的,想学习一下
[其他解释]
引用:
用ResetEvent不行?
貌似不行,试了不行,我觉的可能是这几个函数我用的方法不对,但又不知道怎么用才是对的,想学习一下
[其他解释]
原谅我只看了前面两段,后面的都没有看完

事件应该是可以解决问题的

关机中断触发,判断为有效键时,发消息给应用弹出关机界面,此时通过改变注册表值选择执行以下4个选择之一:
TURNOFFLCD: dwVal=1;关屏
TURNOFFPOWER:dwVal=2;关机
CANCLE:dwVal=3;取消
LOGOUT;dwVal=4;注销用户

为什么要通过改变注册表执行相应的操作,改变注册表应该是另外一个逻辑流程吧。对应用来说,收到按键事件后,应该只需要判断需要执行哪个操作就执行哪个操作就行了。
[其他解释]
引用:
原谅我只看了前面两段,后面的都没有看完

事件应该是可以解决问题的

关机中断触发,判断为有效键时,发消息给应用弹出关机界面,此时通过改变注册表值选择执行以下4个选择之一:
TURNOFFLCD: dwVal=1;关屏
TURNOFFPOWER:dwVal=2;关机
CANCLE:dwVal=3;取消
LOGOUT;dwVal=4;注销用户

为什么要通过改变注册表执行相应的操……
因为产品一开始的要求是这样的:所有功能都做到一个应用里,所以,在关机处理上,只能是驱动响应了关机的中断处理,然后把关机的请求发给应用程序,让应用程序弹出关机的界面,可是真正执行关机操作的是驱动,所以应用程序根据不同的选择改变注册表的值,驱动根据读到的注册表值执行相应的操作。这样做是有点不合理,会出现一旦应用程序卡死,关机也跟着失效了,想重新强制关机都不行。所以,现在已经改成全在驱动里做了,关机界面也是驱动响应到关机中断后直接调用的一个单独的小应用程序。

热点排行