February 16, 2019
Hot Topics:

Inserting Registry Keys in a List Control

  • September 15, 2004
  • By Nancy Nicolaisen
  • Send Email »
  • More Articles »

This month, we are continuing our examination of remote manipulation of CE devices. We'll be dissecting the code that implements the "Walk Registry Tree" page of the tabbed dialog created by the RapiDemo example program. The ability to remotely manipulate Registry entries is a powerful tool for managing and maintaining remote or embedded applications. In our example, we'll limit ourselves to reading the keys. When you become adept with the basics of this operation, you may graduate to creating, writing, and deleting Registry elements using RAPI APIs.

How Key Values Are Inserted in the List Control

Registry key values are limited to a specific set of data types. For this reason, accessing the key values is a two-step process. First, we find the values by enumerating them, and then we format the raw value data to make it useful for our particular purpose. You've seen the first step in previous examples. In the InterpretKeyValue() member shown below, we handle the second step. The parameters to InterpretKeyValue(), in the order shown, are a WCHAR string containing the value's name, the address of the data buffer, the size of the data, and the Registry data type.

Just a couple of points before we push on with the job of inserting values in the listbox. First, Registry values can be unnamed, so it's possible to have data, but not have a value name. Second, we copied a maximum of 1024 bytes of data per value, but this is an artificial limit. The value could actually have more data than that. If you call CeRegEnumValue() with the data buffer address and size set to NULL, the function returns the actual size of the data, and you can allocate a buffer accordingly.

void CWalkReg::InterpretKeyValue(  wchar_t* pwszValueName,
                                   PBYTE pbValueData,
                                   DWORD dwValueDataSize,
                                   DWORD dwRegDataType)
   char  szMBCSData[1024];
   int i, iLoopLimit ;

   //insert the name of the value
   memset(szMBCSData, 0x0, sizeof(szMBCSData));
   wcstombs(&szMBCSData[0], pwszValueName, sizeof(szMBCSData));
   m_RegList.InsertString( -1, szMBCSData );

The code immediately above inserts the name of the value, and then we use a switch to appropriately handle the value data. Notice that all string data passed back from the CE registry is Unicode, and so must be translated to multibyte character format before it can be inserted in the listbox control.

   memset(szMBCSData, 0x0, sizeof(szMBCSData));
   switch (dwRegDataType)
   case REG_MULTI_SZ:
   case REG_EXPAND_SZ:
   case REG_SZ:
      wcstombs(&szMBCSData[0], (WCHAR*)pbValueData,

   case REG_DWORD:
      sprintf (&szMBCSData[0],"%x ", *(DWORD *)pbValueData);

   case REG_BINARY:
      szMBCSData[0] = '\0';
      iLoopLimit = ( (int)dwValueDataSize < sizeof(szMBCSData) - 1)?
                          dwValueDataSize : sizeof(szMBCSData) - 1;

      for ( i = 0; i < iLoopLimit; i++)
         //len = lstrlen ((LPTSTR)szData[0]);
         sprintf (&szMBCSData[i], "%02X ", pbValueData[i]);
         // if (len > dim(szData) - 6)
         //    break;

      sprintf (>szMBCSData[0],"Unknown type: %x", dwRegDataType);

   m_RegList.InsertString( -1, szMBCSData );
   m_RegList.InsertString( -1, " " );


Below is a complete list of Registry data types and their constants. Notice that the BINARY type provides a flexible format that allows you to store anything that doesn't conveniently fit into one of the other types. It can be a useful strategy to use the REG_BINARY type to organize and store app-specific hierarchical data. Keeping the CE Registry tree as "flat" as possible yields big performance benefits.

Table 1: CE Registry Data Types and Their Uses

Registry Data Type Name Meaning
REG_BINARY Byte stream; good for application defined/interpreted complex types.
REG_DWORD A 32-bit number.
REG_DWORD_LITTLE_ENDIAN A 32-bit number in little-endian format. Windows CE is designed to run on little-endian computer architectures. Some UNIX systems are big endian.
REG_DWORD_BIG_ENDIAN A 32-bit number in big-endian format.
REG_EXPAND_SZ A null-terminated string that contains unexpanded references to environment variables (for example, "%PATH%").
REG_MULTI_SZ An array of null-terminated strings, terminated by two null characters.
REG_NONE No defined value type.
REG_RESOURCE_LIST A device driver resource list.
REG_SZ A null-terminated string. It will be a Unicode or ANSI string, depending on whether you use the Unicode or ANSI functions.

Click here for a larger image.

Figure 1: The Walk Registry Tree Page of The RapiDemo App

In the next installment, we are going to use a classic programming technique to find and navigate the entire membership of the Registry tree. We'll preview that technique here so we can go straight to work on the code that implements it in the next lesson.

Page 1 of 2

Comment and Contribute


(Maximum characters: 1200). You have characters left.



Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date