Click to See Complete Forum and Search --> : RegQueryValue & string types


felix1432
May 23rd, 2010, 01:37 AM
Hi,

Win APIs & string passed to them as arguments are driving me crazy:


char tmp[22];
::RegQueryValue(HKEY_LOCAL_MACHINE, "x", "y", tmp);

gives me:

converting 2nd parameter from 'const char [2]' to 'LPCWSTR' not possible


and


char tmp[22];
::RegQueryValueA(HKEY_LOCAL_MACHINE, "x", "y", tmp);

converting parameter 4 from 'char [22]' to 'PLONG' not possible



Is there any reference/explanation as for all those string types?
Why cant i pass a simple "text string" to an API?

thx, :)

ovidiucucu
May 23rd, 2010, 04:30 AM
First of all we have to pay more attention to SDK documentation.
Taking a look at RegQueryValue, you may notice arguments of type, HKEY, LPCTSTR, LPTSTR, and PLONG.
HKEY is a handle.
LPCTSTR is an alias for LPCWSTR if UNICODE is defined (Unicode string). Otherwise it's an alias for LPCSTR (ANSI string).
Somewhere in a SDK header (winnt.h) you can find something like
#ifdef UNICODE
//...
typedef LPCWSTR LPCTSTR;
//...
#else
//...
typedef LPCSTR LPCTSTR;
//...
#endif
Finally, LPCWSTR is an alias type for const wchar_t* while LPCSTR is an alias for const char*.
wchar_t is a standard type keeping wide characters (Unicode).

LPTSTR "expands" in a very similar way, except that it's not const.
PLONG is a pointer to LONG (long*).

Generally in Windows SDK, the functions which are dealing with strings have two versions: one for Unicode and one for ANSI (in our case RegQueryValueW and RegQueryValueA, respectively).
You cand find that RegQueryValue is just a macro defined as:
#ifdef UNICODE
#define RegQueryValue RegQueryValueW
#else
#define RegQueryValue RegQueryValueA
#endif
That's to allow using the same code in both Unicode and ANSI builds. The same purpose has types like TCHAR and the macro _T.

There are many other things to tell here but for the moment we can put these together and get rid of errors by writing something like
#define MAX_DATA_LENGTH 256
//...
HKEY hKey = HKEY_LOCAL_MACHINE;
LPCTSTR pszSubKey = _T("Software\\my_key");
TCHAR lpData[MAX_DATA_LENGTH] = {0};
LONG cbValue = MAX_DATA_LENGTH;
LONG lRet = ::RegQueryValue(hKey, pszSubKey, lpData, &cbValue);
// ...

See also:

MSDN: RegQueryValue Function (http://msdn.microsoft.com/en-us/library/ms724909(VS.85).aspx)
MSDN: Windows Data Types (http://msdn.microsoft.com/en-us/library/aa383751(VS.85).aspx)
FAQ: Which Windows API functions are faster, ANSI or UNICODE? (http://www.codeguru.com/forum/showthread.php?t=469917)
...and many more.

VictorN
May 23rd, 2010, 04:48 AM
I'd also like to add that according to MSDN (RegQueryValue Function (http://msdn.microsoft.com/en-us/library/ms724909(VS.85).aspx)):RegQueryValue Function
Retrieves the data associated with the default or unnamed value of a specified registry key. The data must be a null-terminated string.

Note This function is provided only for compatibility with 16-bit versions of Windows. Applications should use the RegQueryValueEx function.

ovidiucucu
May 23rd, 2010, 04:59 AM
Right, Victor.
Returning to...
First of all we have to pay more attention to SDK documentation. [...]
:D :D ;)

VictorN
May 23rd, 2010, 05:08 AM
Right, Victor.
Returning to...
First of all we have to pay more attention to SDK documentation.
:D :D ;)Wow!
Sorry, Ovidiu! :blush:
I had read your post "diagonally" :)
And my post was, of course, not to you but to OP! ;)

ovidiucucu
May 23rd, 2010, 05:17 AM
No problem. Anyhow, anytime, there is more and more to tell...
Thank you for completing! :)

felix1432
May 25th, 2010, 12:51 PM
Thanks guys!
Perfect! :)