Windows CE 6.0註冊表示例,及註冊表監控函數

來源:互聯網
上載者:User

       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

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.