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
>
>
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]
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 - t...@m9.sprynet.com
Al Blake <a...@spc.org.nc> wrote in message news:3614f...@home.spc.org.nc...
>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
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>).
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....)
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
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
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...
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>...
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
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