#include <stdlib.h> // for _MAX_PATH
#ifndef _MAX_PATH
-#define _MAX_PATH 256
+ #define _MAX_PATH 512
#endif
// our header
{ HKEY_CURRENT_CONFIG, "HKEY_CURRENT_CONFIG", "HKCC" },
#ifndef __GNUWIN32__
{ HKEY_DYN_DATA, "HKEY_DYN_DATA", "HKDD" }, // short name?
-#endif //_GNUWIN32__
+#endif //GNUWIN32
#endif //WINVER >= 4.0
#endif //WIN32
};
// non member functions
// ----------------------------------------------------------------------------
+// removes the trailing backslash from the string if it has one
+static inline void RemoveTrailingSeparator(wxString& str);
+
// returns TRUE if given registry key exists
static bool KeyExists(HKEY hRootKey, const char *szKey);
const char *wxRegKey::GetStdKeyName(uint key)
{
// return empty string if key is invalid
- wxCHECK_RET( key < nStdKeys, "" );
+ wxCHECK_MSG( key < nStdKeys, "", "invalid key in wxRegKey::GetStdKeyName" );
return aStdKeys[key].szName;
}
const char *wxRegKey::GetStdKeyShortName(uint key)
{
// return empty string if key is invalid
- wxCHECK_RET( key < nStdKeys, "" );
+ wxCHECK( key < nStdKeys, "" );
return aStdKeys[key].szShortName;
}
// parent is a predefined (and preopened) key
wxRegKey::wxRegKey(StdKey keyParent, const wxString& strKey) : m_strKey(strKey)
{
- if ( !m_strKey.IsEmpty() && m_strKey.Last() == REG_SEPARATOR )
- m_strKey.Truncate(m_strKey.Len() - 1);
-
+ RemoveTrailingSeparator(m_strKey);
m_hRootKey = aStdKeys[keyParent].hkey;
m_hKey = NULL;
m_dwLastError = 0;
: m_strKey(keyParent.m_strKey)
{
// combine our name with parent's to get the full name
- if ( !m_strKey.IsEmpty() )
+ if ( !strKey.IsEmpty() && strKey[0] != REG_SEPARATOR )
m_strKey += REG_SEPARATOR;
m_strKey += strKey;
- if ( !m_strKey.IsEmpty() && m_strKey.Last() == REG_SEPARATOR )
- m_strKey.Truncate(m_strKey.Len() - 1);
+ RemoveTrailingSeparator(m_strKey);
m_hRootKey = keyParent.m_hRootKey;
m_hKey = NULL;
Close();
}
+// ----------------------------------------------------------------------------
+// change the key name/hkey
+// ----------------------------------------------------------------------------
+
+// set the full key name
+void wxRegKey::SetName(const wxString& strKey)
+{
+ Close();
+
+ m_strKey = strKey;
+ m_hRootKey = aStdKeys[ExtractKeyName(m_strKey)].hkey;
+}
+
+// the name is relative to the parent key
+void wxRegKey::SetName(StdKey keyParent, const wxString& strKey)
+{
+ Close();
+
+ m_strKey = strKey;
+ RemoveTrailingSeparator(m_strKey);
+ m_hRootKey = aStdKeys[keyParent].hkey;
+}
+
+// the name is relative to the parent key
+void wxRegKey::SetName(const wxRegKey& keyParent, const wxString& strKey)
+{
+ Close();
+
+ // combine our name with parent's to get the full name
+ m_strKey = strKey;
+ if ( !strKey.IsEmpty() && strKey[0] != REG_SEPARATOR )
+ m_strKey += REG_SEPARATOR;
+
+ RemoveTrailingSeparator(m_strKey);
+
+ m_hRootKey = keyParent.m_hRootKey;
+}
+
+// hKey should be opened and will be closed in wxRegKey dtor
+void wxRegKey::SetHkey(HKEY hKey)
+{
+ Close();
+
+ m_hKey = hKey;
+}
+
// ----------------------------------------------------------------------------
// info about the key
// ----------------------------------------------------------------------------
return TRUE;
}
+// close the key, it's not an error to call it when not opened
+bool wxRegKey::Close()
+{
+ if ( IsOpened() ) {
+ m_dwLastError = RegCloseKey(m_hKey);
+ if ( m_dwLastError != ERROR_SUCCESS ) {
+ wxLogSysError(m_dwLastError, "can't close registry key '%s'",
+ GetName().c_str());
+
+ m_hKey = 0;
+ return FALSE;
+ }
+ else {
+ m_hKey = 0;
+ }
+ }
+
+ return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+// delete keys/values
+// ----------------------------------------------------------------------------
bool wxRegKey::DeleteSelf()
{
- if ( !Open() )
- return FALSE;
+ {
+ wxLogNull nolog;
+ if ( !Open() ) {
+ // it already doesn't exist - ok!
+ return TRUE;
+ }
+ }
+
+ // we can't delete keys while enumerating because it confuses GetNextKey, so
+ // we first save the key names and then delete them all
+ wxArrayString astrSubkeys;
wxString strKey;
long lIndex;
bool bCont = GetFirstKey(strKey, lIndex);
while ( bCont ) {
- wxRegKey key(*this, strKey);
- if ( !key.DeleteSelf() )
- return FALSE;
+ astrSubkeys.Add(strKey);
bCont = GetNextKey(strKey, lIndex);
}
+ uint nKeyCount = astrSubkeys.Count();
+ for ( uint nKey = 0; nKey < nKeyCount; nKey++ ) {
+ wxRegKey key(*this, astrSubkeys[nKey]);
+ if ( !key.DeleteSelf() )
+ return FALSE;
+ }
+
+ // now delete this key itself
Close();
m_dwLastError = RegDeleteKey(m_hRootKey, m_strKey);
return TRUE;
}
-// close the key, it's not an error to call it when not opened
-bool wxRegKey::Close()
-{
- if ( IsOpened() ) {
- m_dwLastError = RegCloseKey(m_hKey);
- if ( m_dwLastError != ERROR_SUCCESS ) {
- wxLogSysError(m_dwLastError, "can't close registry key '%s'",
- GetName().c_str());
-
- m_hKey = 0;
- return FALSE;
- }
- else {
- m_hKey = 0;
- }
- }
-
- return TRUE;
-}
-
// ----------------------------------------------------------------------------
// access to values and subkeys
// ----------------------------------------------------------------------------
+// return TRUE if value exists
+bool wxRegKey::HasValue(const char *szValue) const
+{
+ #ifdef __WIN32__
+ if ( CONST_CAST Open() ) {
+ return RegQueryValueEx(m_hKey, szValue, RESERVED,
+ NULL, NULL, NULL) == ERROR_SUCCESS;
+ }
+ else
+ return FALSE;
+ #else // WIN16
+ // only unnamed value exists
+ return IsEmpty(szValue);
+ #endif // WIN16/32
+}
+
// returns TRUE if this key has any subkeys
bool wxRegKey::HasSubkeys() const
{
// several concurrently running indexations on the same key
// ----------------------------------------------------------------------------
-#ifdef __WIN32__
bool wxRegKey::GetFirstValue(wxString& strValueName, long& lIndex)
{
if ( !Open() )
return FALSE;
- char szValueName[1024]; // @@ use RegQueryInfoKey...
- DWORD dwValueLen = WXSIZEOF(szValueName);
-
lIndex = 0;
- m_dwLastError = RegEnumValue(m_hKey, lIndex,
- szValueName, &dwValueLen,
- RESERVED,
- NULL, // [out] type
- NULL, // [out] buffer for value
- NULL); // [i/o] it's length
-
- if ( m_dwLastError != ERROR_SUCCESS ) {
- if ( m_dwLastError == ERROR_NO_MORE_ITEMS )
- lIndex = -1;
- else {
- wxLogSysError(m_dwLastError, "can't enumerate values of key '%s'",
- GetName().c_str());
- }
-
- return FALSE;
- }
-
- strValueName = szValueName;
- return TRUE;
+ return GetNextValue(strValueName, lIndex);
}
bool wxRegKey::GetNextValue(wxString& strValueName, long& lIndex) const
{
wxASSERT( IsOpened() );
- wxASSERT( lIndex != -1 );
- char szValueName[1024]; // @@ use RegQueryInfoKey...
- DWORD dwValueLen = WXSIZEOF(szValueName);
+ // are we already at the end of enumeration?
+ if ( lIndex == -1 )
+ return FALSE;
- lIndex++;
- m_dwLastError = RegEnumValue(m_hKey, lIndex,
- szValueName, &dwValueLen,
- RESERVED,
- NULL, // buffer for type
- NULL, NULL); // buffer for value and length
+ #ifdef __WIN32__
+ char szValueName[1024]; // @@ use RegQueryInfoKey...
+ DWORD dwValueLen = WXSIZEOF(szValueName);
- if ( m_dwLastError != ERROR_SUCCESS ) {
- if ( m_dwLastError == ERROR_NO_MORE_ITEMS ) {
- m_dwLastError = ERROR_SUCCESS;
- lIndex = -1;
- }
- else {
- wxLogSysError(m_dwLastError, "can't enumerate values of key '%s'",
- GetName().c_str());
+ lIndex++;
+ m_dwLastError = RegEnumValue(m_hKey, lIndex,
+ szValueName, &dwValueLen,
+ RESERVED,
+ NULL, // [out] type
+ NULL, // [out] buffer for value
+ NULL); // [i/o] it's length
+
+ if ( m_dwLastError != ERROR_SUCCESS ) {
+ if ( m_dwLastError == ERROR_NO_MORE_ITEMS ) {
+ m_dwLastError = ERROR_SUCCESS;
+ lIndex = -1;
+ }
+ else {
+ wxLogSysError(m_dwLastError, "can't enumerate values of key '%s'",
+ GetName().c_str());
+ }
+
+ return FALSE;
}
- return FALSE;
- }
+ strValueName = szValueName;
+ #else //WIN16
+ // only one unnamed value
+ wxASSERT( lIndex == 0 );
+
+ lIndex = -1;
+ strValueName.Empty();
+ #endif
- strValueName = szValueName;
return TRUE;
}
-#endif //Win32
bool wxRegKey::GetFirstKey(wxString& strKeyName, long& lIndex)
{
if ( !Open() )
return FALSE;
- char szKeyName[_MAX_PATH + 1];
lIndex = 0;
- m_dwLastError = RegEnumKey(m_hKey, lIndex, szKeyName, WXSIZEOF(szKeyName));
-
- if ( m_dwLastError != ERROR_SUCCESS ) {
- if ( m_dwLastError == ERROR_NO_MORE_ITEMS ) {
- m_dwLastError = ERROR_SUCCESS;
- lIndex = -1;
- }
- else {
- wxLogSysError(m_dwLastError, "can't enumerate subkeys of key '%s'",
- GetName().c_str());
- }
-
- return FALSE;
- }
-
- strKeyName = szKeyName;
- return TRUE;
+ return GetNextKey(strKeyName, lIndex);
}
bool wxRegKey::GetNextKey(wxString& strKeyName, long& lIndex) const
{
wxASSERT( IsOpened() );
- wxASSERT( lIndex != -1 );
+
+ // are we already at the end of enumeration?
+ if ( lIndex == -1 )
+ return FALSE;
char szKeyName[_MAX_PATH + 1];
- lIndex++;
- m_dwLastError = RegEnumKey(m_hKey, lIndex, szKeyName, WXSIZEOF(szKeyName));
+ m_dwLastError = RegEnumKey(m_hKey, lIndex++, szKeyName, WXSIZEOF(szKeyName));
if ( m_dwLastError != ERROR_SUCCESS ) {
if ( m_dwLastError == ERROR_NO_MORE_ITEMS ) {
s_str << "\\" << szValue;
return s_str.c_str();
-}
\ No newline at end of file
+}
+
+void RemoveTrailingSeparator(wxString& str)
+{
+ if ( !str.IsEmpty() && str.Last() == REG_SEPARATOR )
+ str.Truncate(str.Len() - 1);
+}