1. implemented wxRegKey::Copy() and CopyValue()

2. regtest sample doesn't crash any more
3. wxLogGui uses msg box for only 1 message
4. "const wxEventType" => "enum"
5. wxEVT_COMMAND_TREE_END_DRAG introduced - see sample for example
6. fixed several non fatal bugs in wxRegKey
7. many changes in regtest sample, not tested yet


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6017 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2000-02-15 00:05:36 +00:00
parent 0bddb3cc6f
commit 23f681ec48
12 changed files with 1106 additions and 1045 deletions

View File

@@ -2,7 +2,7 @@
// Name: msw/registry.cpp
// Purpose: implementation of registry classes and functions
// Author: Vadim Zeitlin
// Modified by:
// Modified by:
// Created: 03.04.98
// RCS-ID: $Id$
// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
@@ -65,8 +65,8 @@ static struct
const wxChar *szName;
const wxChar *szShortName;
}
aStdKeys[] =
{
aStdKeys[] =
{
{ HKEY_CLASSES_ROOT, wxT("HKEY_CLASSES_ROOT"), wxT("HKCR") },
#ifdef __WIN32__
{ HKEY_CURRENT_USER, wxT("HKEY_CURRENT_USER"), wxT("HKCU") },
@@ -110,7 +110,7 @@ static inline void RemoveTrailingSeparator(wxString& str);
static bool KeyExists(WXHKEY hRootKey, const wxChar *szKey);
// combines value and key name (uses static buffer!)
static const wxChar *GetFullName(const wxRegKey *pKey,
static const wxChar *GetFullName(const wxRegKey *pKey,
const wxChar *szValue = NULL);
// ============================================================================
@@ -124,7 +124,7 @@ static const wxChar *GetFullName(const wxRegKey *pKey,
const size_t wxRegKey::nStdKeys = WXSIZEOF(aStdKeys);
// @@ should take a `StdKey key', but as it's often going to be used in loops
// it would require casts in user code.
// it would require casts in user code.
const wxChar *wxRegKey::GetStdKeyName(size_t key)
{
// return empty string if key is invalid
@@ -148,7 +148,7 @@ wxRegKey::StdKey wxRegKey::ExtractKeyName(wxString& strKey)
HKEY hRootKey = 0;
size_t ui;
for ( ui = 0; ui < nStdKeys; ui++ ) {
if ( strRoot.CmpNoCase(aStdKeys[ui].szName) == 0 ||
if ( strRoot.CmpNoCase(aStdKeys[ui].szName) == 0 ||
strRoot.CmpNoCase(aStdKeys[ui].szShortName) == 0 ) {
hRootKey = aStdKeys[ui].hkey;
break;
@@ -175,7 +175,7 @@ wxRegKey::StdKey wxRegKey::GetStdKeyFromHkey(WXHKEY hkey)
if ( (int) aStdKeys[ui].hkey == (int) hkey )
return (StdKey)ui;
}
wxFAIL_MSG(wxT("non root hkey passed to wxRegKey::GetStdKeyFromHkey."));
return HKCR;
@@ -213,7 +213,7 @@ wxRegKey::wxRegKey(const wxRegKey& keyParent, const wxString& strKey)
: m_strKey(keyParent.m_strKey)
{
// combine our name with parent's to get the full name
if ( !m_strKey.IsEmpty() &&
if ( !m_strKey.IsEmpty() &&
(strKey.IsEmpty() || strKey[0] != REG_SEPARATOR) ) {
m_strKey += REG_SEPARATOR;
}
@@ -294,7 +294,7 @@ bool wxRegKey::Exists() const
wxString wxRegKey::GetName(bool bShortPrefix) const
{
StdKey key = GetStdKeyFromHkey((StdKey) m_hRootKey);
wxString str = bShortPrefix ? aStdKeys[key].szShortName
wxString str = bShortPrefix ? aStdKeys[key].szShortName
: aStdKeys[key].szName;
if ( !m_strKey.IsEmpty() )
str << "\\" << m_strKey;
@@ -302,37 +302,44 @@ wxString wxRegKey::GetName(bool bShortPrefix) const
return str;
}
#if defined( __GNUWIN32_OLD__ )
bool wxRegKey::GetKeyInfo(size_t* pnSubKeys,
size_t* pnMaxKeyLen,
size_t* pnValues,
size_t* pnMaxValueLen) const
#else
bool wxRegKey::GetKeyInfo(ulong *pnSubKeys,
ulong *pnMaxKeyLen,
ulong *pnValues,
ulong *pnMaxValueLen) const
#endif
bool wxRegKey::GetKeyInfo(size_t *pnSubKeys,
size_t *pnMaxKeyLen,
size_t *pnValues,
size_t *pnMaxValueLen) const
{
#if defined(__WIN32__) && !defined(__TWIN32__)
// old gcc headers incorrectly prototype RegQueryInfoKey()
#ifdef __GNUWIN32_OLD__
#define REG_PARAM (size_t *)
#else
#define REG_PARAM (LPDWORD)
#endif
m_dwLastError = ::RegQueryInfoKey
(
(HKEY) m_hKey,
NULL, // class name
NULL, // (ptr to) size of class name buffer
RESERVED,
REG_PARAM
pnSubKeys, // [out] number of subkeys
REG_PARAM
pnMaxKeyLen, // [out] max length of a subkey name
NULL, // longest subkey class name
REG_PARAM
pnValues, // [out] number of values
REG_PARAM
pnMaxValueLen, // [out] max length of a value name
NULL, // longest value data
NULL, // security descriptor
NULL // time of last modification
);
#undef REG_PARAM
if ( m_dwLastError != ERROR_SUCCESS ) {
wxLogSysError(m_dwLastError, _("can't get info about registry key '%s'"),
wxLogSysError(m_dwLastError, _("Can't get info about registry key '%s'"),
GetName().c_str());
return FALSE;
}
@@ -358,7 +365,7 @@ bool wxRegKey::Open()
HKEY tmpKey;
m_dwLastError = RegOpenKey((HKEY) m_hRootKey, m_strKey, &tmpKey);
if ( m_dwLastError != ERROR_SUCCESS ) {
wxLogSysError(m_dwLastError, _("can't open registry key '%s'"),
wxLogSysError(m_dwLastError, _("Can't open registry key '%s'"),
GetName().c_str());
return FALSE;
}
@@ -383,7 +390,7 @@ bool wxRegKey::Create(bool bOkIfExists)
HKEY tmpKey;
m_dwLastError = RegCreateKey((HKEY) m_hRootKey, m_strKey, &tmpKey);
if ( m_dwLastError != ERROR_SUCCESS ) {
wxLogSysError(m_dwLastError, _("can't create registry key '%s'"),
wxLogSysError(m_dwLastError, _("Can't create registry key '%s'"),
GetName().c_str());
return FALSE;
}
@@ -400,7 +407,7 @@ bool wxRegKey::Close()
if ( IsOpened() ) {
m_dwLastError = RegCloseKey((HKEY) m_hKey);
if ( m_dwLastError != ERROR_SUCCESS ) {
wxLogSysError(m_dwLastError, _("can't close registry key '%s'"),
wxLogSysError(m_dwLastError, _("Can't close registry key '%s'"),
GetName().c_str());
m_hKey = 0;
@@ -414,6 +421,126 @@ bool wxRegKey::Close()
return TRUE;
}
bool wxRegKey::RenameValue(const wxChar *szValueOld, const wxChar *szValueNew)
{
bool ok = TRUE;
if ( HasValue(szValueNew) ) {
wxLogError(_("Registry value '%s' already exists."), szValueNew);
ok = FALSE;
}
if ( !ok || !CopyValue(szValueOld, *this, szValueNew) ) {
wxLogError(_("Failed to rename registry value '%s' to '%s'."),
szValueOld, szValueNew);
return FALSE;
}
return TRUE;
}
bool wxRegKey::CopyValue(const wxChar *szValue,
wxRegKey& keyDst,
const wxChar *szValueNew)
{
switch ( GetValueType(szValue) ) {
case Type_String:
{
wxString strVal;
return QueryValue(szValue, strVal) &&
keyDst.SetValue(szValueNew, strVal);
}
case Type_Dword:
/* case Type_Dword_little_endian: == Type_Dword */
{
long dwVal;
return QueryValue(szValue, &dwVal) &&
keyDst.SetValue(szValueNew, dwVal);
}
// these types are unsupported because I am not sure about how
// exactly they should be copied and because they shouldn't
// occur among the application keys (supposedly created with
// this class)
#ifdef __WIN32__
case Type_None:
case Type_Expand_String:
case Type_Binary:
case Type_Dword_big_endian:
case Type_Link:
case Type_Multi_String:
case Type_Resource_list:
case Type_Full_resource_descriptor:
case Type_Resource_requirements_list:
#endif // Win32
default:
wxLogError(_("Can't copy values of unsupported type %d."),
GetValueType(szValue));
return FALSE;
}
}
bool wxRegKey::Copy(const wxString& strNewName)
{
// create the new key first
wxRegKey keyDst(strNewName);
bool ok = keyDst.Create(FALSE /* fail if alredy exists */);
if ( ok ) {
ok = Copy(keyDst);
// we created the dest key but copying to it failed - delete it
if ( !ok ) {
(void)keyDst.DeleteSelf();
}
}
return ok;
}
bool wxRegKey::Copy(wxRegKey& keyDst)
{
bool ok = TRUE;
// copy all sub keys to the new location
wxString strKey;
long lIndex;
bool bCont = GetFirstKey(strKey, lIndex);
while ( ok && bCont ) {
wxRegKey key(*this, strKey);
wxString keyName;
keyName << GetFullName(&keyDst) << REG_SEPARATOR << strKey;
ok = key.Copy(keyName);
if ( ok )
bCont = GetNextKey(strKey, lIndex);
}
// copy all values
wxString strVal;
bCont = GetFirstValue(strVal, lIndex);
while ( ok && bCont ) {
ok = CopyValue(strVal, keyDst);
if ( !ok ) {
wxLogSysError(m_dwLastError,
_("Failed to copy registry value '%s'"),
strVal.c_str());
}
else {
bCont = GetNextValue(strVal, lIndex);
}
}
if ( !ok ) {
wxLogError(_("Failed to copy the contents of registry key '%s' to "
"'%s'."), GetFullName(this), GetFullName(&keyDst));
}
return ok;
}
// ----------------------------------------------------------------------------
// delete keys/values
// ----------------------------------------------------------------------------
@@ -464,7 +591,7 @@ bool wxRegKey::DeleteSelf()
m_dwLastError = RegDeleteKey((HKEY) m_hRootKey, m_strKey);
if ( m_dwLastError != ERROR_SUCCESS ) {
wxLogSysError(m_dwLastError, _("can't delete key '%s'"),
wxLogSysError(m_dwLastError, _("Can't delete key '%s'"),
GetName().c_str());
return FALSE;
}
@@ -489,7 +616,7 @@ bool wxRegKey::DeleteValue(const wxChar *szValue)
#if defined(__WIN32__) && !defined(__TWIN32__)
m_dwLastError = RegDeleteValue((HKEY) m_hKey, WXSTRINGCAST szValue);
if ( m_dwLastError != ERROR_SUCCESS ) {
wxLogSysError(m_dwLastError, _("can't delete value '%s' from key '%s'"),
wxLogSysError(m_dwLastError, _("Can't delete value '%s' from key '%s'"),
szValue, GetName().c_str());
return FALSE;
}
@@ -500,7 +627,7 @@ bool wxRegKey::DeleteValue(const wxChar *szValue)
// just set the (default and unique) value of the key to ""
m_dwLastError = RegSetValue((HKEY) m_hKey, NULL, REG_SZ, "", RESERVED);
if ( m_dwLastError != ERROR_SUCCESS ) {
wxLogSysError(m_dwLastError, _("can't delete value of key '%s'"),
wxLogSysError(m_dwLastError, _("Can't delete value of key '%s'"),
GetName().c_str());
return FALSE;
}
@@ -518,7 +645,7 @@ bool wxRegKey::HasValue(const wxChar *szValue) const
{
// this function should be silent, so suppress possible messages from Open()
wxLogNull nolog;
#ifdef __WIN32__
if ( CONST_CAST Open() ) {
return RegQueryValueEx((HKEY) m_hKey, WXSTRINGCAST szValue, RESERVED,
@@ -537,7 +664,7 @@ bool wxRegKey::HasValues() const
{
// suppress possible messages from GetFirstValue()
wxLogNull nolog;
// just call GetFirstValue with dummy parameters
wxString str;
long l;
@@ -549,7 +676,7 @@ bool wxRegKey::HasSubkeys() const
{
// suppress possible messages from GetFirstKey()
wxLogNull nolog;
// just call GetFirstKey with dummy parameters
wxString str;
long l;
@@ -561,7 +688,7 @@ bool wxRegKey::HasSubKey(const wxChar *szKey) const
{
// this function should be silent, so suppress possible messages from Open()
wxLogNull nolog;
if ( CONST_CAST Open() )
return KeyExists(m_hKey, szKey);
else
@@ -578,7 +705,7 @@ wxRegKey::ValueType wxRegKey::GetValueType(const wxChar *szValue) const
m_dwLastError = RegQueryValueEx((HKEY) m_hKey, WXSTRINGCAST szValue, RESERVED,
&dwType, NULL, NULL);
if ( m_dwLastError != ERROR_SUCCESS ) {
wxLogSysError(m_dwLastError, _("can't read value of key '%s'"),
wxLogSysError(m_dwLastError, _("Can't read value of key '%s'"),
GetName().c_str());
return Type_None;
}
@@ -603,7 +730,7 @@ bool wxRegKey::SetValue(const wxChar *szValue, long lValue)
return TRUE;
}
wxLogSysError(m_dwLastError, _("can't set value of '%s'"),
wxLogSysError(m_dwLastError, _("Can't set value of '%s'"),
GetFullName(this, szValue));
return FALSE;
#endif
@@ -617,13 +744,13 @@ bool wxRegKey::QueryValue(const wxChar *szValue, long *plValue) const
m_dwLastError = RegQueryValueEx((HKEY) m_hKey, WXSTRINGCAST szValue, RESERVED,
&dwType, pBuf, &dwSize);
if ( m_dwLastError != ERROR_SUCCESS ) {
wxLogSysError(m_dwLastError, _("can't read value of key '%s'"),
wxLogSysError(m_dwLastError, _("Can't read value of key '%s'"),
GetName().c_str());
return FALSE;
}
else {
// check that we read the value of right type
wxASSERT_MSG( dwType == REG_DWORD,
wxASSERT_MSG( IsNumericValue(szValue),
wxT("Type mismatch in wxRegKey::QueryValue().") );
return TRUE;
@@ -644,13 +771,25 @@ bool wxRegKey::QueryValue(const wxChar *szValue, wxString& strValue) const
m_dwLastError = RegQueryValueEx((HKEY) m_hKey, WXSTRINGCAST szValue, RESERVED,
&dwType, NULL, &dwSize);
if ( m_dwLastError == ERROR_SUCCESS ) {
RegString pBuf = (RegString)strValue.GetWriteBuf(dwSize);
m_dwLastError = RegQueryValueEx((HKEY) m_hKey, WXSTRINGCAST szValue, RESERVED,
&dwType, pBuf, &dwSize);
strValue.UngetWriteBuf();
if ( !dwSize ) {
// must treat this case specially as GetWriteBuf() doesn't like
// being called with 0 size
strValue.Empty();
}
else {
RegString pBuf = (RegString)strValue.GetWriteBuf(dwSize);
m_dwLastError = RegQueryValueEx((HKEY) m_hKey,
WXSTRINGCAST szValue,
RESERVED,
&dwType,
pBuf,
&dwSize);
strValue.UngetWriteBuf();
}
if ( m_dwLastError == ERROR_SUCCESS ) {
// check that it was the right type
wxASSERT_MSG( dwType == REG_SZ,
wxASSERT_MSG( !IsNumericValue(szValue),
wxT("Type mismatch in wxRegKey::QueryValue().") );
return TRUE;
@@ -667,7 +806,7 @@ bool wxRegKey::QueryValue(const wxChar *szValue, wxString& strValue) const
#endif //WIN16/32
}
wxLogSysError(m_dwLastError, _("can't read value of '%s'"),
wxLogSysError(m_dwLastError, _("Can't read value of '%s'"),
GetFullName(this, szValue));
return FALSE;
}
@@ -677,7 +816,7 @@ bool wxRegKey::SetValue(const wxChar *szValue, const wxString& strValue)
if ( CONST_CAST Open() ) {
#if defined( __WIN32__) && !defined(__TWIN32__)
m_dwLastError = RegSetValueEx((HKEY) m_hKey, szValue, (DWORD) RESERVED, REG_SZ,
(RegString)strValue.c_str(),
(RegString)strValue.c_str(),
strValue.Len() + 1);
if ( m_dwLastError == ERROR_SUCCESS )
return TRUE;
@@ -691,7 +830,7 @@ bool wxRegKey::SetValue(const wxChar *szValue, const wxString& strValue)
#endif //WIN16/32
}
wxLogSysError(m_dwLastError, _("can't set value of '%s'"),
wxLogSysError(m_dwLastError, _("Can't set value of '%s'"),
GetFullName(this, szValue));
return FALSE;
}
@@ -732,8 +871,8 @@ bool wxRegKey::GetNextValue(wxString& strValueName, long& lIndex) const
m_dwLastError = RegEnumValue((HKEY) m_hKey, lIndex++,
szValueName, &dwValueLen,
RESERVED,
NULL, // [out] type
RESERVED,
NULL, // [out] type
NULL, // [out] buffer for value
NULL); // [i/o] it's length
@@ -743,7 +882,7 @@ bool wxRegKey::GetNextValue(wxString& strValueName, long& lIndex) const
lIndex = -1;
}
else {
wxLogSysError(m_dwLastError, _("can't enumerate values of key '%s'"),
wxLogSysError(m_dwLastError, _("Can't enumerate values of key '%s'"),
GetName().c_str());
}
@@ -788,7 +927,7 @@ bool wxRegKey::GetNextKey(wxString& strKeyName, long& lIndex) const
lIndex = -1;
}
else {
wxLogSysError(m_dwLastError, _("can't enumerate subkeys of key '%s'"),
wxLogSysError(m_dwLastError, _("Can't enumerate subkeys of key '%s'"),
GetName().c_str());
}
@@ -801,11 +940,11 @@ bool wxRegKey::GetNextKey(wxString& strKeyName, long& lIndex) const
// returns TRUE if the value contains a number (else it's some string)
bool wxRegKey::IsNumericValue(const wxChar *szValue) const
{
{
ValueType type = GetValueType(szValue);
switch ( type ) {
case Type_Dword:
case Type_Dword_little_endian:
/* case Type_Dword_little_endian: == Type_Dword */
case Type_Dword_big_endian:
return TRUE;