00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #pragma once
00013
00015 #include "nvsg/nvsgapi.h"
00016
00017 #if defined(_WIN32)
00018 # include "nvsgwindefs.h"
00019 # ifndef NOMINMAX
00020 # define NOMINMAX // avoid problems with Microsoft definitions in windef.h and min/max from stl
00021 # include <windows.h>
00022 # include <winbase.h>
00023 # undef NOMINMAX
00024 # else
00025 # include <windows.h>
00026 # include <winbase.h>
00027 # endif
00028 #endif
00029
00030 #include "nvutil/Assert.h"
00031 #include <string>
00032
00033
00034 namespace nvutil {
00035
00036 typedef std::basic_string <TCHAR> tstring;
00037
00038
00040
00041 {
00042 public:
00043 enum
00044 {
00045 DIRTY = 1
00046 };
00047
00049 RegVal( const TCHAR * value_name , const TCHAR * subkey, DWORD type, HKEY root=HKEY_LOCAL_MACHINE
00050 , const T& def=T() );
00052 ~RegVal() {}
00054 RegVal<T>& operator=(const T& rhs);
00056 operator const T&();
00057
00058 private:
00059
00060 RegVal(const RegVal<T>&) {}
00061 RegVal<T>& operator=(const RegVal<T>&) {}
00062
00063 DWORD create();
00064 DWORD read(T& out, DWORD nbytes);
00065 DWORD write(const T& in, DWORD nbytes);
00066
00067 private:
00068 tstring m_name;
00069 tstring m_subkey;
00070 DWORD m_type;
00071 HKEY m_root;
00072 HKEY m_hkey;
00073 DWORD m_flags;
00074 T m_default;
00075 T m_data;
00076 };
00077
00078
00079 template <class T>
00080 inline RegVal<T>::RegVal( const TCHAR * value_name
00081 , const TCHAR * subkey
00082 , DWORD type
00083 , HKEY root=HKEY_LOCAL_MACHINE
00084 , const T& def=T() )
00085 : m_name(value_name)
00086 , m_subkey(subkey)
00087 , m_type(type)
00088 , m_root(root)
00089 , m_flags(DIRTY)
00090 , m_default(def)
00091 {
00092 if ( ERROR_SUCCESS==create() )
00093 {
00094 if ( ERROR_FILE_NOT_FOUND==read(m_data, sizeof(T)) )
00095 {
00096 if ( ERROR_SUCCESS==write(m_default, sizeof(T)) )
00097 {
00098 m_data = m_default;
00099 m_flags &= ~DIRTY;
00100 }
00101 }
00102 }
00103 }
00104
00105
00106 template <class T>
00107 inline RegVal<T>& RegVal<T>::operator=(const T& rhs)
00108 {
00109 write(rhs, sizeof(T));
00110 m_data = rhs;
00111 m_flags &= ~DIRTY;
00112 return *this;
00113 }
00114
00115
00116 template <class T>
00117 inline RegVal<T>::operator const T&()
00118 {
00119 if ( m_flags & DIRTY ) {
00120
00121 if ( !(ERROR_SUCCESS==read(m_data, sizeof(T))) )
00122 {
00123
00124 m_data = m_default;
00125 }
00126 m_flags &= ~DIRTY;
00127
00128 }
00129 return m_data;
00130 }
00131
00132
00133 template <class T>
00134 inline DWORD RegVal<T>::create()
00135 {
00136 DWORD err;
00137 DWORD dwDisposition;
00138
00139
00140 if ( ERROR_SUCCESS == (err = RegCreateKeyEx( m_root
00141 , m_subkey.c_str()
00142 , 0
00143 , NULL
00144 , REG_OPTION_NON_VOLATILE
00145 , KEY_ALL_ACCESS
00146 , NULL
00147 , &m_hkey
00148 , &dwDisposition ))
00149 )
00150 {
00151
00152 RegCloseKey(m_hkey);
00153 }
00154
00155 return err;
00156 }
00157
00158
00159 template <class T>
00160 inline DWORD RegVal<T>::read(T& out, DWORD nbytes)
00161 {
00162 DWORD err;
00163 DWORD type;
00164
00165 if ( ERROR_SUCCESS == (err = RegOpenKeyEx(m_root, m_subkey.c_str(), NULL, KEY_READ, &m_hkey)) ) {
00166 err = RegQueryValueEx(m_hkey, m_name.c_str(), NULL, &type, (LPBYTE)&out, &nbytes);
00167 __ASSERT((err==ERROR_SUCCESS)==(m_type==type));
00168 RegCloseKey(m_hkey);
00169 }
00170 return err;
00171 }
00172
00173
00174 template<class T>
00175 inline DWORD RegVal<T>::write(const T& in, DWORD nbytes)
00176 {
00177 DWORD err;
00178
00179 if ( ERROR_SUCCESS == (err = RegOpenKeyEx(m_root, m_subkey.c_str(), NULL, KEY_ALL_ACCESS, &m_hkey)) ) {
00180 err = RegSetValueEx(m_hkey, m_name.c_str(), NULL, m_type, (const LPBYTE)&in, nbytes);
00181 RegCloseKey(m_hkey);
00182 }
00183 return err;
00184 }
00185
00186
00187 #if ! defined( DOXYGEN_IGNORE )
00188
00189
00190 template<>
00191 inline DWORD RegVal<tstring>::read(tstring& out, DWORD nbytes)
00192 {
00193 DWORD err;
00194 DWORD type;
00195
00196 if ( ERROR_SUCCESS == (err = RegOpenKeyEx(m_root, m_subkey.c_str(), NULL, KEY_READ, &m_hkey)) ) {
00197
00198 if ( ERROR_SUCCESS == (err = RegQueryValueEx(m_hkey, m_name.c_str(), NULL, &type, NULL, &nbytes)) ) {
00199
00200
00201 tstring tmp;
00202 tmp.resize(nbytes);
00203
00204 if ( ERROR_SUCCESS == (err = RegQueryValueEx(m_hkey, m_name.c_str(), NULL, &type, (LPBYTE)tmp.data(), &nbytes)) ) {
00205 __ASSERT((err==ERROR_SUCCESS)==(m_type==type));
00206
00207
00208
00209 out = tmp.c_str();
00210 }
00211 }
00212 RegCloseKey(m_hkey);
00213 }
00214 return err;
00215 }
00216
00217
00218 template<>
00219 inline DWORD RegVal<tstring>::write(const tstring& in, DWORD nbytes)
00220 {
00221 DWORD err;
00222
00223 if ( ERROR_SUCCESS == (err = RegOpenKeyEx(m_root, m_subkey.c_str(), NULL, KEY_ALL_ACCESS, &m_hkey)) ) {
00224 err = RegSetValueEx(m_hkey, m_name.c_str(), NULL, m_type, (const LPBYTE)in.c_str(), nbytes);
00225 RegCloseKey(m_hkey);
00226 }
00227 return err;
00228 }
00229
00230
00231 template<>
00232 inline RegVal<tstring>& RegVal<tstring>::operator=(const tstring& rhs)
00233 {
00234
00235 DWORD nbytes = (DWORD)rhs.length()+1;
00236 nbytes *= sizeof(TCHAR);
00237
00238
00239 write(rhs, nbytes);
00240
00241 m_data = rhs;
00242 m_flags &= ~DIRTY;
00243
00244 return *this;
00245 }
00246 #endif // DOXYGEN_IGNORE
00247
00248 }
00249
00250
00251
00252
00253