Windows CE 6.0注册表示例,及注册表监控函数

 Windows CE 6.0有4个基本的注册表键值, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS,其它的都是这4个注册表的子键。我们以一个内建的串口驱动为例,它在注册表文件Platform.reg中的描述如下:
[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/Serial]               
"Prefix"="COM"               
"Dll"="$(_TGTPLAT_PFX)_serial.dll"                
"Flags"=dword:0               
"Index"=dword:1
      其中Prefix 和 Dll项是必不可少的,Index为设备序号,Prefix代表设备文件名前缀,与Index合用表示该设备的名称,该注册表子键的设备名称就是"COM1:",该名称可以用于CreateFile调用。Dll则是动态链接库名称。Flags为1表示系统启动时不加载,需要应用程序自己加载,为0表示该驱动在系统启动时加载。
      有两种方法操作注册表。第一种方法,在%WinCE Dir%Public%Common%OAK%INC%目录下,文件Cregedit.h中,定义了一个类CRegistryEdit来封装了注册表的操作。还有一种方法是利用windows CE提供的API进行注册表项的操作。分述如下:
(1)利用系统提供的注册表类CRegistryEdit
      类的定义在文件regedit.h中。在构建函数中,会取得当前注册表子键的HANDLE句柄。有3个构造函数,第一个是用全路径,调用hKey = OpenDeviceKey(TEXT("HKEY_LOCAL_MACHINE//Drivers//BuiltIn//Serial"))构造;第二个是如果已知其父注册表子键,调用RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("Drivers//BuiltIn//Serial"), 0,0,&hKey)。第三种方法是用RegCreateKeyEx()。
       析构函数中,调用RegCloseKey(hKey)关闭掉对注册表子键的引用。读取注册表项可以使用GetRegValue方法,写入注册表项使用RegSetValueEx方法。其方法的实现也是通过windows CE API,具体可以参照下一个Section。
(2)利用windows CE API
      RegCreateKeyEx是新建一个注册表项,如果该项已经存在,就直接打开获取句柄。正常使用时,为了获取一个注册表键值,先要调用RegOpenKeyEx。以上面内建串口驱动为例,RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("Drivers//BuiltIn//Serial"), 0, 0, &hKey ),其中hKey就是我们获取的该注册表子键的HANDLE句柄。接下来对注册表子键的操作就是通过hKey来实现。
      有了hKey, 就可以对注册表子键的各个内容进行读写操作。如果要读出子键的Prefix,调用函数RegQueryValueEx(hKey, TEXT("Prefix"), NULL, &lpType, &lpData, &lpcbData), lpType, lpData为Prefix返回类型和值,该例中,lpType = REG_SZ,lpData = TEXT("COM")。相对应读操作,写操作是一个相反的过程,RegSetValueEx(hKey, TEXT("Prefix"), NULL, REG_SZ, PBYTE(TEXT("TST")), wcslen(TEXT("TST"))*2),其中要写入的项为Prefix项,类型为REG_SZ,值为TEXT("TST"),最后一个参数为写入值得SIZE in bytes。注意第二个参数,如果注册表中存在该项,则改写它的值。如果没有,则新建一个注册表项。
      某些情况下,我们需要删除一个注册表项,只需调用RegDeleteKey(hKey, TEXT("Index"))就可以删除Index注册表项。要关闭一个注册表子键,只需要调用RegCloseKey(hKey)就可以完成。

(3)实例

      在HKEY_CURRENT_USER根键下,创建MySoftWare//RegTest键,并在此键下写入某人的姓名跟作者年龄信息,数据类型分别为字符串类型和整数类型。

HKEY hOpenKey;

DWORD dwOpenStyle;

long lResult = 0;

LPCTSTR  keyName = L"MySoftWare//RegTest";   //定义键名

lResult = RegCreateKeyEx(HKEY_CURRENT_USER,keyName,0,L"",

                   0,0,NULL,&hOpenKey,&dwOpenStyle);   //打开或者新建指定的键

ASSERT(lResult == ERROR_SRCCESS);

 

LPCTSTR strKeyName = L"作者";                        //写入键值,字符串类型

LPCTSTR strKeyValue = L"王二";

lResult = RegSetValueEx(hOpenKey,strKeyName,0,REG_SZ,(BYTE*)strKeyValue,wcslen(strKeyValue)*2);

ASSERT(lResult == ERROR_SRCCESS);

 

LPCTSTR dwKeyName = L"年龄";                        //写入键值,整数类型

DWORD dwKeyValue = 25;

lResult = RegSetValueEx(hOpenKey,dwKeyName ,0,REG_SZ,(BYTE*)dwKeyValue,wcslen(dwKeyValue)*2);

ASSERT(lResult == ERROR_SRCCESS);

 

RegCloseKey(hOpenKey);

      对应的如果要读取上述写进去的值,方式如下:

DWORD dwKeyValueType = 0;

TCHAR  strKeyValue[500];

zeroMemory(strKeyValue,500*2);

dwKeyValueLength = 500*2;

lResult = RegQueryValueEx(hOpenKey,strKeyName,0,&dwKeyValueType ,(BYTE*)strKeyValue,&dwKeyValueLength );

(4)注册表监控函数RegistryNotifyCallback用来对注册表项进行监控,一旦发生变化就执行回调函数。比如我们在操作上层应用界面的控件时,它会直接反映到注册表上,那么底层的注册表监控回调函数就执行,从而控制到驱动做对应的动作。以下通过一个振动器马达的动态链接库来举例说明。

#define DEVICE_MIS_FILE_NAME    L"MIS1:" //马达设备
HANDLE hMisc=NULL;       //马达句柄

bool  g_bScreenTapsEnable=false;   //马达震动的使能和禁止

bool  g_bExited=false;    //控制线程退出
void StartVibrator()     //开始震动
{
        if(hMisc == NULL)
        {
                hMisc = CreateFile(DEVICE_MIS_FILE_NAME, 0, 0, NULL, 0, 0, NULL);
        } 
        if(hMisc) 
        {
                int   iSetValue = 0;
                DWORD dwBufSize = sizeof(int);
                DWORD dwRetSize = 0;     
                iSetValue = 1;   //震动,通过IOCTL来实现
                if(DeviceIoControl(hMisc, IOCTL_MIS_IT_VIBRATOR,&iSetValue,dwBufSize, NULL,0, &dwRetSize,NULL))
                {
                       RETAILMSG (0,(TEXT( "miccco_touch IOCTL_MIS_IT_VIBRATOR() success /r/n"));   
                }
                else 

                {
                       RETAILMSG (0,(TEXT( "miccco_touch IOCTL_MIS_IT_VIBRATOR() failure/r/n")));   
                }
        }
}

void StopVibrator()    //停止震动
{
        if(hMisc == NULL)
        {
                 hMisc = CreateFile(DEVICE_MIS_FILE_NAME, 0, 0, NULL, 0, 0, NULL);
        }
        if(hMisc) 
        {
                 int   iSetValue = 0;
                 DWORD dwBufSize = sizeof(int);
                 DWORD dwRetSize = 0;    
                 iSetValue = 0;    //关闭震动
                 if(DeviceIoControl(hMisc, IOCTL_MIS_IT_VIBRATOR,&iSetValue,dwBufSize, NULL,0, &dwRetSize,NULL))
                 {
                         RETAILMSG (1,(TEXT( "miccco_touch IOCTL_MIS_IT_VIBRATOR() success dwRetSize/r/n"));   
                 }
                 else

                 {
                         RETAILMSG (1,(TEXT( "miccco_touch IOCTL_MIS_IT_VIBRATOR() failure/r/n")));   
                 }
        }
}

DWORD WINAPI DoTouchVibrateThreadPrc(LPVOID lpParameter)   //DLLMain中创建的线程函数
{
         CeSetThreadPriority(GetCurrentThread(),100);   //设置线程优先级
         while(1)
         {
                WaitForSingleObject(g_hVibratorEvent, INFINITE);   //等待点击事件发生
                if(g_bExited)     //检测到DLL被挂起,则退出循环

                       break;
                StartVibrator();
                Sleep(g_dwTime);   //马达震动时间
                StopVibrator();
         }
         return 0;
}

static void ScreenTapsCallbackFunc(HREGNOTIFY hNotify, DWORD dwUserData, const PBYTE pData, const UINT cbData)    //注册表监控函数的回调函数,用来对注册表的改变做相应处理
{
         if(*pData==1)
         {
                 g_bScreenTapsEnable=TRUE;    //使能马达
         }
         else
         {
                 g_bScreenTapsEnable=false;     //禁止马达
         }
}

BOOL DllMain(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)  //DLL主函数
{
         if ( dwReason == DLL_PROCESS_ATTACH )
         {
                HKEY hKey=NULL;
                DWORD dwDisposition=0,dwValue;
                DWORD dwSize=sizeof(DWORD); 
                if ((ERROR_SUCCESS==RegCreateKeyEx(HKEY_CURRENT_USER, _T("ControlPanel//TouchVibration"),0,NULL,0,0,NULL,&hKey,&dwDisposition))) //创建键值
               { 
                      if((dwDisposition==REG_CREATED_NEW_KEY))   //判断是新建的键值
                      {
                            dwValue=0;
                            g_bScreenTapsEnable=false;      //初始化禁止马达
                            RegSetValueEx(hKey,_T("ScreenTaps"),0,REG_DWORD,(BYTE *)&dwValue,sizeof(DWORD));
                       }

                       else    //如果是打开的已存在的键值
                       {
                             if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("ScreenTaps"),0,0,(UCHAR*)&(dwValue),&dwSize)&&dwValue==1)   //根据注册表的值来使能或者禁止马达
                             {
                                    g_bScreenTapsEnable=TRUE;
                             }

                             else
                             {
                                    g_bScreenTapsEnable=false;
                             }
                       }
                       RegCloseKey(hKey);
                }

 

                if ((ERROR_SUCCESS==RegCreateKeyEx(HKEY_CURRENT_USER, _T("ControlPanel"),0,NULL,0,0,NULL,&hKey,&dwDisposition)))
                {
                        RegistryNotifyCallback(hKey, _T("TouchVibration"),_T("ScreenTaps"),ScreenTapsCallbackFunc,0,
NULL,&g_hRegNotify_ScreenTaps);   //注册对某些键值进行监控的函数
                        RegCloseKey(hKey);
                 }
                 g_bExited=false;  //初始化退出标志
                 g_hVibratorEvent=CreateEvent(NULL, FALSE, FALSE, NULL);
                 if(g_hVibratorEvent)
                 {
                        CreateThread(NULL, 0, DoTouchVibrateThreadPrc, NULL, 0, NULL);  //创建触发标志及线程
                 }
                 DisableThreadLibraryCalls((HMODULE) hInstDll);   //禁止再加载DLL
        }

        if ( dwReason == DLL_PROCESS_DETACH )

        {
                 if(g_hRegNotify_ScreenTaps)

                 {       

                          RegistryCloseNotification(g_hRegNotify_ScreenTaps);  //取消注册表监控
                          g_hRegNotify_ScreenTaps=NULL;

                 }
                 if(g_hVibratorEvent)
                 {
                        g_bExited=true;    //使线程退出
                        CloseHandle(g_hVibratorEvent);
                 }
         }
         return(TRUE);

}

BOOL DoTouchVibrate(DWORD dwLength)     //DLL的暴露函数
{
         if(g_bScreenTapsEnable)     //从注册表获得的消息来判断是否动作
         {
                ResetEvent(g_hVibratorEvent);    //防止连续震动,在每次震动事件之前,清除掉之前的事件
                dwLength>200?g_dwTime=200:g_dwTime=dwLength;
                SetEvent(g_hVibratorEvent);
         }
         return(TRUE);
}

 

参考原文:http://developer.51cto.com/art/200907/133698.htm

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值