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:
@@ -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;
|
||||
|
||||
|
Reference in New Issue
Block a user