Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Putting CString into Registry

547 views
Skip to first unread message

A. J. Hunyady

unread,
Oct 1, 1998, 3:00:00 AM10/1/98
to
Maybe this will help:

BOOL CRegItem::CreateRegKeyValueString(CString regKeyPath, CString keyName,
CString keyValue)
{
HKEY hKeyOpened;
DWORD stringSize = keyValue.GetLength();
DWORD ret;

//Opens the registry key in the regKeyPath and returns its handle.
ret = RegOpenKeyEx(
m_KeyRoot, // handle of an open key
regKeyPath, // address of name of subkey to open
(DWORD)0, // reserved
KEY_ALL_ACCESS, // security access mask
&hKeyOpened // address of handle of open key
);

if (ret != ERROR_SUCCESS)
return FALSE;

//Creates a registry key and assigns a value to it.
ret = RegSetValueEx(
hKeyOpened, // handle of key to set value for
keyName, // address of value to set
(DWORD)0, // reserved
REG_SZ, // flag for value type
(unsigned char*) keyValue.GetBuffer(MAX_PATH), // address of value data
stringSize // size of value data
);

keyValue.ReleaseBuffer();
ret = RegCloseKey(hKeyOpened);
if (ret != ERROR_SUCCESS)
return FALSE;
else
return TRUE;
}


Al Blake wrote in message <3614f...@home.spc.org.nc>...
>I want to put a CString value into the registry. I am trying to use
>RegSetValueEx but I cannot get it to work correctly.
>My CString value is in m_FAXSERVER and contains the text "FRED"
>
>if I use the following syntax:
>
>RegSetValueEx(happ,"FaxServer",0,REG_SZ,&m_FAXSERVER,sizeof(m_FAXSERVER));
>
>I get a compiler error
>C:\ValidateFAX\Code\VFCpl\ConfigDlg.cpp(145) : error C2664:
'RegSetValueExA'
>: cannot convert parameter 5 from 'class CString *' to 'const unsigned char
>*'
>
>If I try to force the type using a cast as follows:
>
>RegSetValueEx(happ,"FaxServer",0,REG_SZ,(const unsigned char*)
>&m_FAXSERVER,sizeof(m_FAXSERVER));
>
>everything compiles correctly and program appears to work BUT the value
that
>is written to the registry is NOT the text string "FRED" but some binary
>junk I can't read (an address perhaps?).
>
>What Am I doing wrong?
>What is the simplest way to write a CString to the registry in C++ ?
>
>--
>Al Blake
>Information Technology Manager
>Secretariat of the Pacific Community
>Noumea, New Caledonia
>
>

Joku

unread,
Oct 1, 1998, 3:00:00 AM10/1/98
to
Use this function call instead(variables taken from your previous posting):
 
RegSetValueEx( happ, "FaxServer", 0, REG_SZ, (BYTE*)( LPCTSTR )m_FAXSERVER, m_FAXSERVER.GetLength()+1 );
 
... that should do the trick.
 
John

Tomas Restrepo

unread,
Oct 1, 1998, 3:00:00 AM10/1/98
to
Actually, what you're doing is unnecessary. The easiest way to call
RegSetValueEx() is :


RegSetValueEx(happ,"FaxServer",0,REG_SZ, (LPBYTE)(LPCTSTR)m_FAXSERVER,
m_FAXSERVER.GetLength());

Tomas Restrepo
win...@bigfoot.com
http://www.geocities.com/SiliconValley/Heights/3401

A. J. Hunyady <a...@netscreen.com> wrote in message
OxT1fhY...@uppssnewspub04.moswest.msn.net...
>Maybe this will help:
[Code Snipped]

ScottMcP

unread,
Oct 1, 1998, 3:00:00 AM10/1/98
to
Al Blake wrote:
>
> I want to put a CString value into the registry. I am trying to use
> RegSetValueEx but I cannot get it to work correctly.
> My CString value is in m_FAXSERVER and contains the text "FRED"
>
> if I use the following syntax:
>
> RegSetValueEx(happ,"FaxServer",0,REG_SZ,&m_FAXSERVER,sizeof(m_FAXSERVER));
>
> I get a compiler error
> C:\ValidateFAX\Code\VFCpl\ConfigDlg.cpp(145) : error C2664: 'RegSetValueExA'
> : cannot convert parameter 5 from 'class CString *' to 'const unsigned char
> *'
>
> If I try to force the type using a cast as follows:
>
> RegSetValueEx(happ,"FaxServer",0,REG_SZ,(const unsigned char*)
> &m_FAXSERVER,sizeof(m_FAXSERVER));
>
> everything compiles correctly and program appears to work BUT the value that
> is written to the registry is NOT the text string "FRED" but some binary
> junk I can't read (an address perhaps?).
>
> What Am I doing wrong?
> What is the simplest way to write a CString to the registry in C++ ?
>
> --
> Al Blake
> Information Technology Manager
> Secretariat of the Pacific Community
> Noumea, New Caledonia

Try
RegSetValueEx(happ,"FaxServer",0,REG_SZ,m_FAXSERVER.GetBuffer(),m_FAXSERVER.GetLength());

&m_FAXSERVER is the address of the CString object, which is not at all
the same thing as the address of the text string.

Most functions want a (const char*) and will take a CString (not
&CString) because of a nice overloaded operator built into CString. But
in this case, where you need PUCHAR, the GetBuffer function returns a
char*, which I suppose is close enough for the compiler.

Tom Porterfield

unread,
Oct 1, 1998, 3:00:00 AM10/1/98
to
I would think you could simply use the LPCTSTR cast on your CString.

--
Tom Porterfield - t...@m9.sprynet.com


Al Blake <a...@spc.org.nc> wrote in message news:3614f...@home.spc.org.nc...

Al Blake

unread,
Oct 2, 1998, 3:00:00 AM10/2/98
to

James Curran

unread,
Oct 2, 1998, 3:00:00 AM10/2/98
to
Tomas Restrepo wrote in message ...

>Actually, what you're doing is unnecessary. The easiest way to call
>RegSetValueEx() is :


>RegSetValueEx(happ,"FaxServer",0,REG_SZ, (LPBYTE)(LPCTSTR)m_FAXSERVER,
> m_FAXSERVER.GetLength());
>

How 'bout we actually use C++ to our advantage.....

inline RegSetValue(happ, CString Key, CString Value)
{ RegSetValueEx(happ,
(LPBYTE)(LPCTSTR)Key,
0,REG_SZ,
(LPBYTE)(LPCTSTR)Value,
Value.GetLength());
}

then

RegSetValue("FaxSever", m_FAXSERVER);

--
Truth,
James [MVP]
http://www.NJTheater.Com -and-
http://www.NJTheater.Com/JamesCurran


James M. Curran.vcf

Tomas Restrepo

unread,
Oct 2, 1998, 3:00:00 AM10/2/98
to
You're right, James. It's a pretty fine idea.

Only a couple of things.......

--

James Curran <James...@CompuServe.Com> wrote in message
##ODIZi7...@uppssnewspub05.moswest.msn.net...


>Tomas Restrepo wrote in message ...
>>Actually, what you're doing is unnecessary. The easiest way to call
>>RegSetValueEx() is :
>
>
>>RegSetValueEx(happ,"FaxServer",0,REG_SZ, (LPBYTE)(LPCTSTR)m_FAXSERVER,
>> m_FAXSERVER.GetLength());
>>
> How 'bout we actually use C++ to our advantage.....
>
>inline RegSetValue(happ, CString Key, CString Value)
>{ RegSetValueEx(happ,
> (LPBYTE)(LPCTSTR)Key,

Why cast it to a (LPBYTE) if the second parameter to RegSetValueEx() is
already a LPCTSTR? I don't see that's necessary.

> 0,REG_SZ,
> (LPBYTE)(LPCTSTR)Value,
> Value.GetLength());
>}
>
> then
>
> RegSetValue("FaxSever", m_FAXSERVER);

should be
RegSetValue(happ, "FaxSever", m_FAXSERVER);
(you're missing a param <G>).

James Curran

unread,
Oct 2, 1998, 3:00:00 AM10/2/98
to
Tomas Restrepo wrote in message ...
>You're right, James. It's a pretty fine idea.
>
>Only a couple of things.......
>
>>>
>> How 'bout we actually use C++ to our advantage.....
>>
>>inline RegSetValue(happ, CString Key, CString Value)
>>{ RegSetValueEx(happ,
>> (LPBYTE)(LPCTSTR)Key,
>
>Why cast it to a (LPBYTE) if the second parameter to RegSetValueEx() is
>already a LPCTSTR? I don't see that's necessary.


I didn't have the function specification in front of me, so I had to
guess at the parameters, I just copied the casts from the other one.
(You'll note that it also doesn't deal with the return value, which it
should; nor does it specify a type for "happ")

>
>> 0,REG_SZ,
>> (LPBYTE)(LPCTSTR)Value,
>> Value.GetLength());
>>}
>>
>> then
>>
>> RegSetValue("FaxSever", m_FAXSERVER);
>
>should be
> RegSetValue(happ, "FaxSever", m_FAXSERVER);
>(you're missing a param <G>).
>>


Oooops .... (that was simple bone-headedness on my part....)

James M. Curran.vcf

Seth Jones

unread,
Oct 2, 1998, 3:00:00 AM10/2/98
to
Tomas Restrepo wrote:
>
> James Curran <James...@CompuServe.Com> wrote in message
> >
> >inline RegSetValue(happ, CString Key, CString Value)
> >{ RegSetValueEx(happ,
> > (LPBYTE)(LPCTSTR)Key,
>
> Why cast it to a (LPBYTE) if the second parameter to RegSetValueEx()
> is
> already a LPCTSTR? I don't see that's necessary.
>
> > 0,REG_SZ,
> > (LPBYTE)(LPCTSTR)Value,
> > Value.GetLength());
> >}

Yes, it is necessary. BYTE in win32 is actually unsigned char, which may
not be the same thing as char (not to mention TCHAR).
It should actually be (CONST BYTE *), though.

Seth Jones

Aaron J Margosis

unread,
Oct 2, 1998, 3:00:00 AM10/2/98
to
Or better, use references instead of objects to avoid unnecessary
construction/destruction. (Yes, I know CString is reference counted, but
still...)


inline RegSetValue(happ, const CString & Key, const CString & Value)


{ RegSetValueEx(happ,
(LPBYTE)(LPCTSTR)Key,
0,REG_SZ,
(LPBYTE)(LPCTSTR)Value,
Value.GetLength());
}


Passing a const char * still works -- a temporary will get created for the
duration of the statement. However, passing a CString will not incur the
overhead of a construction/destruction.

Also, I'd like to clarify one thing for readers: casting a CString to a LPCTSTR
works only because CString provides a conversion operator for const char *. The
cast actually calls a CString method which returns a pointer to the CString's
character buffer. Casts can be dangerous; personally I prefer to call explicit
functions rather than use casts in situations like this.

HTH

James Curran wrote:
>
> Tomas Restrepo wrote in message ...

> >Actually, what you're doing is unnecessary. The easiest way to call
> >RegSetValueEx() is :
>
> >RegSetValueEx(happ,"FaxServer",0,REG_SZ, (LPBYTE)(LPCTSTR)m_FAXSERVER,
> > m_FAXSERVER.GetLength());
> >

> How 'bout we actually use C++ to our advantage.....
>

> inline RegSetValue(happ, CString Key, CString Value)
> { RegSetValueEx(happ,
> (LPBYTE)(LPCTSTR)Key,

> 0,REG_SZ,
> (LPBYTE)(LPCTSTR)Value,
> Value.GetLength());
> }
>
> then
>
> RegSetValue("FaxSever", m_FAXSERVER);
>

> --
> Truth,
> James [MVP]


-- Aaron [MVP]
---------------------
Aaron J Margosis
aaro...@erols.com
Fortress-NT - NT Workstation/Server Security Utility:
http://www.sunbelt-software.com/fortress.htm
ScrnSaveSwitch/Plus - Screen Saver Control Utility:
http://www.ssswitch.com

Tomas Restrepo

unread,
Oct 2, 1998, 3:00:00 AM10/2/98
to
If you look carefully at my post, I was refering to the first (LPBYTE) cast,
which *is* unnecessary, since the function is define to accept a LPCTSTR as
this parameter (second one). The other one (where the data goes) *is*
necessary, because the function can accept different kinds of data here.

If in doubt, look at the definition:

LONG RegSetValueEx (
HKEY hKey, // handle of key to set value for
LPCTSTR lpValueName, // address of value to set
DWORD Reserved, // reserved
DWORD dwType, // flag for value type
CONST BYTE *lpData, // address of value data
DWORD cbData // size of value data
);


Seth Jones <se...@kansmen.com> wrote in message
36156331...@kansmen.com...

piyush

unread,
Oct 2, 1998, 3:00:00 AM10/2/98
to
The problem here is that you are not converting the CString properly to a
char *
When you cast the address of CString to char *, you are not actually
pointing
to the char * that CString is pointing to, instead you are forcing the
compiler to
interpret the data at the start of Cstring as char * ( which is off course
binary junk)

ONE BASIC RULE OF THUMB FOR C++
Never cast addresses of objects to something else.

Now for your problem
You can get the char * contained in the string by calling CSTring's
getBuffer
function.
Alternatively you can cast the CString to LPCSTR ( note that you cast the
CString object,
not it's address). CString defines a cast operator to convert itself to
LPCSTR.

So you call can look like this
RegSetValueEx (happ,"FaxServer",0,REG_SZ,
m_FAXSERVER.GetBuffer(0),
m_FAXSERVER.GetLength());

OR alternatively

RegSetValueEx (happ,"FaxServer",0,REG_SZ,
(LPCSTR)m_FAXSERVER,
strlen((LPCSTR)m_FAXSERVER));

i would recommend the first approach.

Al Blake wrote in message <3614f...@home.spc.org.nc>...

Martin Wawrusch

unread,
Oct 3, 1998, 3:00:00 AM10/3/98
to


Aaron J Margosis schrieb in Nachricht <3615878F...@erols.com>...


>Or better, use references instead of objects to avoid unnecessary
>construction/destruction. (Yes, I know CString is reference counted, but
>still...)
>
>
>inline RegSetValue(happ, const CString & Key, const CString & Value)
>{ RegSetValueEx(happ,
> (LPBYTE)(LPCTSTR)Key,
> 0,REG_SZ,
> (LPBYTE)(LPCTSTR)Value,
> Value.GetLength());
>}
>
>
>Passing a const char * still works -- a temporary will get created for the
>duration of the statement. However, passing a CString will not incur the
>overhead of a construction/destruction.
>
>Also, I'd like to clarify one thing for readers: casting a CString to a
LPCTSTR
>works only because CString provides a conversion operator for const char *.
The
>cast actually calls a CString method which returns a pointer to the
CString's
>character buffer. Casts can be dangerous; personally I prefer to call
explicit
>functions rather than use casts in situations like this.

Well said. And when you cast please do so using static_cast, const_cast and
reinterpret_cast as appropriate (and avoid dynamic_cast:-). The () syntax is
c heritage that should not be used. For a complete discussion take a look at
Scott Meyers books.

Martin


Al Blake

unread,
Oct 5, 1998, 3:00:00 AM10/5/98
to
Thanks to all of you for your input. The code is working well now and I
learnt a little bit more about casts!

s...@quango.force9.co.uk

unread,
Oct 5, 1998, 3:00:00 AM10/5/98
to
"James Curran" <James...@CompuServe.Com> writes:
> Tomas Restrepo wrote in message ...
> > RegSetValueEx(happ,"FaxServer",0,REG_SZ, (LPBYTE)(LPCTSTR)m_FAXSERVER,

> How 'bout we actually use C++ to our advantage.....
>
> inline RegSetValue(happ, CString Key, CString Value)
> [...]

I've found that the best way to access the registry from C++ is to
write a class which represents a registry key and whose methods
perform operations such as reading or writing an entry to that key.

For example, if I wanted to write the entry/value pairs:

"England", "London"
"France", "Paris",
"Italy", "Rome"

to the key HKEY_LOCAL_MACHINE\Software\Test\CapitalCities, I
would write code like this:

MyRegKey regKey( "HKEY_LOCAL_MACHINE\Software\Test\CapitalCities" );
regKey.writeValue( "England", "London" );
regKey.writeValue( "France", "Paris" );
regKey.writeValue( "Italy", "Rome" );
regKey.close();

And if I wanted to find the capital of the USA, I'd do something like this:

MyRegKey regKey( "HKEY_LOCAL_MACHINE\Software\Test\CapitalCities" );
CString capitalOfUSA = regKey.readString( "USA" );
regKey.close();

The MyRegKey class would look something like this:

class MyRegKey
{
private:
HKEY m_key;

public:
MyRegKey( const CString &keyname );
void close();
DWORD readDword( const CString &entry ) const;
CString readString( const CString &entry ) const;
void writeValue( const CString &entry, DWORD value ) const;
void writeValue( const CString &entry, const CString &value );
};

Note that you never have to call any Reg* Win32 functions directly.
Only the class should do that. In addition, the HKEY handle to the
registry key is never exposed (it is private to the class). So, I
have proper data hiding.

I highly recommend this kind of solution to anyone wanting to write
C++ "front-ends" to a group of Win32 functions. It's amazing how much
shorter (and clearer) your code is if you use classes like this. I
recently replaced a 100 line program (consisting mainly of calls to
Win32 functions) with 10 lines of code which did the same thing using
my classes. It is now much easier to see what's going on and
therefore to maintain.

Geoff

John Smith

unread,
Oct 7, 1998, 3:00:00 AM10/7/98
to
You can find a registry class on www.codeguru.com


0 new messages