Add 64-bit numbers support to wxRegKey

This uses the native registry support for 64-bit values available since
Windows XP.

Note that SetValue64() can't be just called SetValue() as this would
introduce ambiguities when writing an int or an enum to the registry.
This could be avoided by providing overloads for all the arithmetic
types, but it's arguably better to be more clear about what exactly is
being written to the registry in this low-level class and using a
different name is definitely simpler.
This commit is contained in:
Vadim Zeitlin
2021-03-09 21:09:42 +01:00
parent eb33447c39
commit 3f2c84d4a9
3 changed files with 76 additions and 3 deletions

View File

@@ -42,7 +42,8 @@ public:
Type_Multi_String, // Multiple Unicode strings Type_Multi_String, // Multiple Unicode strings
Type_Resource_list, // Resource list in the resource map Type_Resource_list, // Resource list in the resource map
Type_Full_resource_descriptor, // Resource list in the hardware description Type_Full_resource_descriptor, // Resource list in the hardware description
Type_Resource_requirements_list // ??? Type_Resource_requirements_list, // ???
Type_Qword // 64-bit number
}; };
// predefined registry keys // predefined registry keys
@@ -197,10 +198,14 @@ public:
// retrieve either raw or expanded string value // retrieve either raw or expanded string value
bool QueryValue(const wxString& szValue, wxString& strValue, bool raw) const; bool QueryValue(const wxString& szValue, wxString& strValue, bool raw) const;
// set the numeric value // set the 32-bit numeric value
bool SetValue(const wxString& szValue, long lValue); bool SetValue(const wxString& szValue, long lValue);
// return the numeric value // return the 32-bit numeric value
bool QueryValue(const wxString& szValue, long *plValue) const; bool QueryValue(const wxString& szValue, long *plValue) const;
// set the 64-bit numeric value
bool SetValue64(const wxString& szValue, wxLongLong_t llValue);
// return the 64-bit numeric value
bool QueryValue64(const wxString& szValue, wxLongLong_t *pllValue) const;
// set the binary value // set the binary value
bool SetValue(const wxString& szValue, const wxMemoryBuffer& buf); bool SetValue(const wxString& szValue, const wxMemoryBuffer& buf);
// return the binary value // return the binary value

View File

@@ -350,6 +350,14 @@ public:
*/ */
bool QueryValue(const wxString& szValue, long* plValue) const; bool QueryValue(const wxString& szValue, long* plValue) const;
/**
Retrieves the 64-bit value. Returns @true if successful.
An empty @a szValue queries the default/unnamed key value.
@since 3.1.5
*/
bool QueryValue64(const wxString& szValue, wxLongLong_t* plValue) const;
/** /**
Retrieves the binary structure. Returns @true if successful. Retrieves the binary structure. Returns @true if successful.
An empty @a szValue queries the default/unnamed key value. An empty @a szValue queries the default/unnamed key value.
@@ -397,6 +405,17 @@ public:
An empty @a szValue sets the default/unnamed key value. An empty @a szValue sets the default/unnamed key value.
*/ */
bool SetValue(const wxString& szValue, long lValue); bool SetValue(const wxString& szValue, long lValue);
/**
Sets a 64-bit value.
This function creates or modifies a field of @c QWORD type in the
registry.
@since 3.1.5
*/
bool SetValue64(const wxString& szValue, wxLongLong_t lValue);
/** /**
Sets the given @a szValue which must be string. If the value doesn't Sets the given @a szValue which must be string. If the value doesn't
exist, it is created. Returns @true if successful. exist, it is created. Returns @true if successful.

View File

@@ -913,6 +913,54 @@ bool wxRegKey::QueryValue(const wxString& szValue, long *plValue) const
return false; return false;
} }
bool wxRegKey::SetValue64(const wxString& szValue, wxLongLong_t llValue)
{
if ( CONST_CAST Open() ) {
m_dwLastError = RegSetValueEx((HKEY) m_hKey, RegValueStr(szValue),
wxRESERVED_PARAM, REG_QWORD,
(RegString)&llValue, sizeof(llValue));
if ( m_dwLastError == ERROR_SUCCESS )
return true;
}
wxLogSysError(m_dwLastError, _("Can't set value of '%s'"),
GetFullName(this, szValue));
return false;
}
bool wxRegKey::QueryValue64(const wxString& szValue, wxLongLong_t *pllValue) const
{
if ( CONST_CAST Open(Read) ) {
DWORD dwType, dwSize = sizeof(wxLongLong_t); // QWORD doesn't exist.
RegString pBuf = (RegString)pllValue;
m_dwLastError = RegQueryValueEx((HKEY) m_hKey, RegValueStr(szValue),
wxRESERVED_PARAM,
&dwType, pBuf, &dwSize);
if ( m_dwLastError != ERROR_SUCCESS ) {
wxLogSysError(m_dwLastError, _("Can't read value of key '%s'"),
GetName().c_str());
return false;
}
// check that we read the value of right type
switch ( dwType )
{
case REG_DWORD_LITTLE_ENDIAN:
case REG_DWORD_BIG_ENDIAN:
case REG_QWORD:
break;
default:
wxLogError(_("Registry value \"%s\" is not numeric (but of type %s)"),
GetFullName(this, szValue), GetTypeString(dwType));
return false;
}
return true;
}
else
return false;
}
bool wxRegKey::SetValue(const wxString& szValue, const wxMemoryBuffer& buffer) bool wxRegKey::SetValue(const wxString& szValue, const wxMemoryBuffer& buffer)
{ {
if ( CONST_CAST Open() ) { if ( CONST_CAST Open() ) {
@@ -1175,6 +1223,7 @@ bool wxRegKey::IsNumericValue(const wxString& szValue) const
case Type_Dword: case Type_Dword:
/* case Type_Dword_little_endian: == Type_Dword */ /* case Type_Dword_little_endian: == Type_Dword */
case Type_Dword_big_endian: case Type_Dword_big_endian:
case Type_Qword:
return true; return true;
default: default: