1 // TortoiseSVN - a Windows shell extension for easy version control
\r
3 // Copyright (C) 2003-2008 - TortoiseSVN
\r
5 // This program is free software; you can redistribute it and/or
\r
6 // modify it under the terms of the GNU General Public License
\r
7 // as published by the Free Software Foundation; either version 2
\r
8 // of the License, or (at your option) any later version.
\r
10 // This program is distributed in the hope that it will be useful,
\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 // GNU General Public License for more details.
\r
15 // You should have received a copy of the GNU General Public License
\r
16 // along with this program; if not, write to the Free Software Foundation,
\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\r
22 #include "shlwapi.h"
\r
30 * Base class for the registry classes.
\r
32 * \par requirements
\r
33 * - win98 or later, win2k or later, win95 with IE4 or later, winNT4 with IE4 or later
\r
34 * - import library Shlwapi.lib
\r
38 class CRegBaseCommon
\r
43 * String type specific operations.
\r
46 virtual LPCTSTR GetPlainString (const S& s) const = 0;
\r
47 virtual DWORD GetLength (const S& s) const = 0;
\r
51 /** Default constructor.
\r
56 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
\r
57 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
\r
58 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
\r
60 CRegBaseCommon(const S& key, bool force, HKEY base = HKEY_CURRENT_USER);
\r
63 * Removes the whole registry key including all values. So if you set the registry
\r
64 * entry to be HKCU\Software\Company\Product\key\value there will only be
\r
65 * HKCU\Software\Company\Product key in the registry.
\r
66 * \return ERROR_SUCCESS or an nonzero error code. Use FormatMessage() to get an error description.
\r
70 * Removes the value of the registry object. If you set the registry entry to
\r
71 * be HKCU\Software\Company\Product\key\value there will only be
\r
72 * HKCU\Software\Company\Product\key\ in the registry.
\r
73 * \return ERROR_SUCCESS or an nonzero error code. Use FormatMessage() to get an error description.
\r
78 * Returns the string of the last error occurred.
\r
80 virtual S getErrorString()
\r
85 FORMAT_MESSAGE_ALLOCATE_BUFFER |
\r
86 FORMAT_MESSAGE_FROM_SYSTEM |
\r
87 FORMAT_MESSAGE_IGNORE_INSERTS,
\r
90 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
\r
94 return (LPCTSTR)lpMsgBuf;
\r
99 typedef S StringT; ///< used in subclass templates to specify the correct string type
\r
102 HKEY m_base; ///< handle to the registry base
\r
103 S m_key; ///< the name of the value
\r
104 S m_path; ///< the path to the key
\r
105 LONG LastError; ///< the value of the last error occurred
\r
107 bool m_read; ///< indicates if the value has already been read from the registry
\r
108 bool m_force; ///< indicates if no cache should be used, i.e. always read and write directly from registry
\r
109 bool m_exists; ///< true, if the registry actually exists
\r
112 // implement CRegBaseCommon<> members
\r
115 CRegBaseCommon<S>::CRegBaseCommon()
\r
116 : m_base (HKEY_CURRENT_USER)
\r
119 , LastError (ERROR_SUCCESS)
\r
127 CRegBaseCommon<S>::CRegBaseCommon (const S& key, bool force, HKEY base)
\r
131 , LastError (ERROR_SUCCESS)
\r
139 DWORD CRegBaseCommon<S>::removeKey()
\r
145 RegOpenKeyEx (m_base, GetPlainString (m_path), 0, KEY_WRITE, &hKey);
\r
146 return SHDeleteKey(m_base, GetPlainString (m_path));
\r
150 LONG CRegBaseCommon<S>::removeValue()
\r
156 RegOpenKeyEx(m_base, GetPlainString (m_path), 0, KEY_WRITE, &hKey);
\r
157 return RegDeleteValue(hKey, GetPlainString (m_key));
\r
162 * Base class for MFC type registry classes.
\r
165 #ifdef __CSTRINGT_H__
\r
166 class CRegBase : public CRegBaseCommon<CString>
\r
171 * String type specific operations.
\r
174 virtual LPCTSTR GetPlainString (const CString& s) const {return (LPCTSTR)s;}
\r
175 virtual DWORD GetLength (const CString& s) const {return s.GetLength();}
\r
179 /** Default constructor.
\r
184 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
\r
185 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
\r
186 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
\r
188 CRegBase(const CString& key, bool force, HKEY base = HKEY_CURRENT_USER);
\r
191 * Returns the string of the last error occurred.
\r
193 CString getErrorString()
\r
195 CString error = CRegBaseCommon<CString>::getErrorString();
\r
196 #if defined IDS_REG_ERROR
\r
198 sTemp.Format(IDS_REG_ERROR, (LPCTSTR)m_key, (LPCTSTR)error);
\r
207 typedef std::wstring wide_string;
\r
210 # define stdstring wide_string
\r
212 # define stdstring std::string
\r
218 * Base class for STL string type registry classes.
\r
221 class CRegStdBase : public CRegBaseCommon<stdstring>
\r
226 * String type specific operations.
\r
229 virtual LPCTSTR GetPlainString (const stdstring& s) const {return s.c_str();}
\r
230 virtual DWORD GetLength (const stdstring& s) const {return static_cast<DWORD>(s.size());}
\r
234 /** Default constructor.
\r
239 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
\r
240 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
\r
241 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
\r
243 CRegStdBase(const stdstring& key, bool force, HKEY base = HKEY_CURRENT_USER);
\r
248 * DWORD value in registry. with this class you can use DWORD values in registry
\r
249 * like normal DWORD variables in your program.
\r
251 * in your header file, declare your registry DWORD variable:
\r
253 * CRegDWORD regvalue;
\r
255 * next initialize the variable e.g. in the constructor of your class:
\r
257 * regvalue = CRegDWORD("Software\\Company\\SubKey\\MyValue", 100);
\r
259 * this will set the registry value "MyValue" under HKEY_CURRENT_USER with path
\r
260 * "Software\Company\SubKey" to the variable. If the key does not yet exist or
\r
261 * an error occurred during read from the registry, a default
\r
262 * value of 100 is used when accessing the variable.
\r
263 * now the variable can be used like any other DWORD variable:
\r
265 * regvalue = 200; //stores the value 200 in the registry
\r
266 * int temp = regvalue + 300; //temp has value 500 now
\r
267 * regvalue += 300; //now the registry has the value 500 too
\r
269 * to avoid too much access to the registry the value is cached inside the object.
\r
270 * once the value is read, no more read accesses to the registry will be made.
\r
271 * this means the variable will contain a wrong value if the corresponding registry
\r
272 * entry is changed by anything else than this variable! If you think that could happen
\r
277 * to force a refresh of the variable with the registry.
\r
278 * a write to the registry is only made if the new value assigned with the variable
\r
279 * is different than the last assigned value.
\r
280 * to force a write use the method write();
\r
281 * another option to force reads and writes to the registry is to specify TRUE as the
\r
282 * third parameter in the constructor.
\r
284 template<class T, class Base>
\r
285 class CRegTypedBase : public Base
\r
289 T m_value; ///< the cached value of the registry
\r
290 T m_defaultvalue; ///< the default value to use
\r
293 * sub-classes must provide type-specific code to extract data from
\r
294 * and write data to an open registry key.
\r
297 virtual void InternalRead (HKEY hKey, T& value) = 0;
\r
298 virtual void InternalWrite (HKEY hKey, const T& value) = 0;
\r
303 * We use this instead of a default constructor because not all
\r
304 * data types may provide an adequate default constructor.
\r
306 CRegTypedBase(const T& def);
\r
310 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
\r
311 * \param def the default value used when the key does not exist or a read error occurred
\r
312 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
\r
313 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
\r
315 CRegTypedBase(const typename Base::StringT& key, const T& def, bool force = FALSE, HKEY base = HKEY_CURRENT_USER);
\r
318 * reads the assigned value from the registry. Use this method only if you think the registry
\r
319 * value could have been altered without using the CRegDWORD object.
\r
320 * \return the read value
\r
322 void read(); ///< reads the value from the registry
\r
323 void write(); ///< writes the value to the registry
\r
329 operator const T&();
\r
330 CRegTypedBase<T,Base>& operator=(const T& rhs);
\r
333 // implement CRegTypedBase<> members
\r
335 template<class T, class Base>
\r
336 CRegTypedBase<T, Base>::CRegTypedBase (const T& def)
\r
338 , m_defaultvalue (def)
\r
342 template<class T, class Base>
\r
343 CRegTypedBase<T, Base>::CRegTypedBase (const typename Base::StringT& key, const T& def, bool force, HKEY base)
\r
344 : Base (key, force, base)
\r
346 , m_defaultvalue (def)
\r
350 template<class T, class Base>
\r
351 void CRegTypedBase<T, Base>::read()
\r
353 m_value = m_defaultvalue;
\r
357 if ((LastError = RegOpenKeyEx (m_base, GetPlainString (m_path), 0, KEY_EXECUTE, &hKey))==ERROR_SUCCESS)
\r
361 T value = m_defaultvalue;
\r
362 InternalRead (hKey, value);
\r
364 if (LastError ==ERROR_SUCCESS)
\r
370 LastError = RegCloseKey(hKey);
\r
374 template<class T, class Base>
\r
375 void CRegTypedBase<T, Base>::write()
\r
380 if ((LastError = RegCreateKeyEx(m_base, GetPlainString (m_path), 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &disp))!=ERROR_SUCCESS)
\r
385 InternalWrite (hKey, m_value);
\r
386 if (LastError ==ERROR_SUCCESS)
\r
391 LastError = RegCloseKey(hKey);
\r
395 template<class T, class Base>
\r
396 CRegTypedBase<T, Base>::operator const T&()
\r
398 if ((m_read)&&(!m_force))
\r
410 template<class T, class Base>
\r
411 CRegTypedBase<T, Base>& CRegTypedBase<T, Base>::operator =(const T& d)
\r
413 if ((d==m_value)&&(!m_force))
\r
415 //no write to the registry required, its the same value
\r
426 * DWORD value in registry. with this class you can use DWORD values in registry
\r
427 * like normal DWORD variables in your program.
\r
429 * in your header file, declare your registry DWORD variable:
\r
431 * CRegDWORD regvalue;
\r
433 * next initialize the variable e.g. in the constructor of your class:
\r
435 * regvalue = CRegDWORD("Software\\Company\\SubKey\\MyValue", 100);
\r
437 * this will set the registry value "MyValue" under HKEY_CURRENT_USER with path
\r
438 * "Software\Company\SubKey" to the variable. If the key does not yet exist or
\r
439 * an error occurred during read from the registry, a default
\r
440 * value of 100 is used when accessing the variable.
\r
441 * now the variable can be used like any other DWORD variable:
\r
443 * regvalue = 200; //stores the value 200 in the registry
\r
444 * int temp = regvalue + 300; //temp has value 500 now
\r
445 * regvalue += 300; //now the registry has the value 500 too
\r
447 * to avoid too much access to the registry the value is cached inside the object.
\r
448 * once the value is read, no more read accesses to the registry will be made.
\r
449 * this means the variable will contain a wrong value if the corresponding registry
\r
450 * entry is changed by anything else than this variable! If you think that could happen
\r
455 * to force a refresh of the variable with the registry.
\r
456 * a write to the registry is only made if the new value assigned with the variable
\r
457 * is different than the last assigned value.
\r
458 * to force a write use the method write();
\r
459 * another option to force reads and writes to the registry is to specify TRUE as the
\r
460 * third parameter in the constructor.
\r
462 template<class Base>
\r
463 class CRegDWORDCommon : public CRegTypedBase<DWORD,Base>
\r
468 * provide type-specific code to extract data from and write data to an open registry key.
\r
471 virtual void InternalRead (HKEY hKey, DWORD& value);
\r
472 virtual void InternalWrite (HKEY hKey, const DWORD& value);
\r
476 CRegDWORDCommon(void);
\r
479 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
\r
480 * \param def the default value used when the key does not exist or a read error occurred
\r
481 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
\r
482 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
\r
484 CRegDWORDCommon(const typename Base::StringT& key, DWORD def = 0, bool force = false, HKEY base = HKEY_CURRENT_USER);
\r
486 CRegDWORDCommon& operator=(DWORD rhs) {CRegTypedBase<DWORD, Base>::operator =(rhs); return *this;}
\r
487 CRegDWORDCommon& operator+=(DWORD d) { return *this = *this + d;}
\r
488 CRegDWORDCommon& operator-=(DWORD d) { return *this = *this - d;}
\r
489 CRegDWORDCommon& operator*=(DWORD d) { return *this = *this * d;}
\r
490 CRegDWORDCommon& operator/=(DWORD d) { return *this = *this / d;}
\r
491 CRegDWORDCommon& operator%=(DWORD d) { return *this = *this % d;}
\r
492 CRegDWORDCommon& operator<<=(DWORD d) { return *this = *this << d;}
\r
493 CRegDWORDCommon& operator>>=(DWORD d) { return *this = *this >> d;}
\r
494 CRegDWORDCommon& operator&=(DWORD d) { return *this = *this & d;}
\r
495 CRegDWORDCommon& operator|=(DWORD d) { return *this = *this | d;}
\r
496 CRegDWORDCommon& operator^=(DWORD d) { return *this = *this ^ d;}
\r
499 // implement CRegDWORDCommon<> methods
\r
501 template<class Base>
\r
502 CRegDWORDCommon<Base>::CRegDWORDCommon(void)
\r
503 : CRegTypedBase<DWORD, Base>(0)
\r
507 template<class Base>
\r
508 CRegDWORDCommon<Base>::CRegDWORDCommon(const typename Base::StringT& key, DWORD def, bool force, HKEY base)
\r
509 : CRegTypedBase<DWORD, Base> (key, def, force, base)
\r
514 template<class Base>
\r
515 void CRegDWORDCommon<Base>::InternalRead (HKEY hKey, DWORD& value)
\r
517 DWORD size = sizeof(value);
\r
519 if ((LastError = RegQueryValueEx(hKey, GetPlainString (m_key), NULL, &type, (BYTE*) &value, &size))==ERROR_SUCCESS)
\r
521 ASSERT(type==REG_DWORD);
\r
525 template<class Base>
\r
526 void CRegDWORDCommon<Base>::InternalWrite (HKEY hKey, const DWORD& value)
\r
528 LastError = RegSetValueEx (hKey, GetPlainString (m_key), 0, REG_DWORD,(const BYTE*) &value, sizeof(value));
\r
533 * CString value in registry. with this class you can use CString values in registry
\r
534 * almost like normal CString variables in your program.
\r
536 * in your header file, declare your registry CString variable:
\r
538 * CRegString regvalue;
\r
540 * next initialize the variable e.g. in the constructor of your class:
\r
542 * regvalue = CRegString("Software\\Company\\SubKey\\MyValue", "default");
\r
544 * this will set the registry value "MyValue" under HKEY_CURRENT_USER with path
\r
545 * "Software\Company\SubKey" to the variable. If the key does not yet exist or
\r
546 * an error occurred during read from the registry, a default
\r
547 * value of "default" is used when accessing the variable.
\r
548 * now the variable can be used like any other CString variable:
\r
550 * regvalue = "some string"; //stores the value "some string" in the registry
\r
551 * CString temp = regvalue + "!!"; //temp has value "some string!!" now
\r
553 * to use the normal methods of the CString class, just typecast the CRegString to a CString
\r
554 * and do whatever you want with the string:
\r
556 * ((CString)regvalue).GetLength();
\r
557 * ((CString)regvalue).Trim();
\r
559 * please be aware that in the second line the change in the string won't be written
\r
560 * to the registry! To force a write use the write() method. A write() is only needed
\r
561 * if you change the String with Methods not overloaded by CRegString.
\r
562 * to avoid too much access to the registry the value is cached inside the object.
\r
563 * once the value is read, no more read accesses to the registry will be made.
\r
564 * this means the variable will contain a wrong value if the corresponding registry
\r
565 * entry is changed by anything else than this variable! If you think that could happen
\r
570 * to force a refresh of the variable with the registry.
\r
571 * a write to the registry is only made if the new value assigned with the variable
\r
572 * is different than the last assigned value.
\r
573 * to force a write use the method write();
\r
574 * another option to force reads and writes to the registry is to specify TRUE as the
\r
575 * third parameter in the constructor.
\r
577 template<class Base>
\r
578 class CRegStringCommon : public CRegTypedBase<typename Base::StringT, Base>
\r
583 * provide type-specific code to extract data from and write data to an open registry key.
\r
586 virtual void InternalRead (HKEY hKey, typename Base::StringT& value);
\r
587 virtual void InternalWrite (HKEY hKey, const typename Base::StringT& value);
\r
590 CRegStringCommon();
\r
593 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
\r
594 * \param def the default value used when the key does not exist or a read error occurred
\r
595 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
\r
596 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
\r
598 CRegStringCommon(const typename Base::StringT& key, const typename Base::StringT& def = _T(""), bool force = false, HKEY base = HKEY_CURRENT_USER);
\r
600 CRegStringCommon& operator=(const typename Base::StringT& rhs) {CRegTypedBase<StringT, Base>::operator =(rhs); return *this;}
\r
601 CRegStringCommon& operator+=(const typename Base::StringT& s) { return *this = (typename Base::StringT)*this + s; }
\r
604 // implement CRegDWORD<> methods
\r
606 template<class Base>
\r
607 CRegStringCommon<Base>::CRegStringCommon(void)
\r
608 : CRegTypedBase<typename Base::StringT, Base>(typename Base::StringT())
\r
612 template<class Base>
\r
613 CRegStringCommon<Base>::CRegStringCommon(const typename Base::StringT& key, const typename Base::StringT& def, bool force, HKEY base)
\r
614 : CRegTypedBase<typename Base::StringT, Base> (key, def, force, base)
\r
619 template<class Base>
\r
620 void CRegStringCommon<Base>::InternalRead (HKEY hKey, typename Base::StringT& value)
\r
624 LastError = RegQueryValueEx(hKey, GetPlainString (m_key), NULL, &type, NULL, &size);
\r
626 std::auto_ptr<TCHAR> pStr (new TCHAR[size]);
\r
627 if ((LastError = RegQueryValueEx(hKey, GetPlainString (m_key), NULL, &type, (BYTE*) pStr.get(), &size))==ERROR_SUCCESS)
\r
629 ASSERT(type==REG_SZ || type==REG_EXPAND_SZ);
\r
630 value = StringT (pStr.get());
\r
634 template<class Base>
\r
635 void CRegStringCommon<Base>::InternalWrite (HKEY hKey, const typename Base::StringT& value)
\r
637 LastError = RegSetValueEx(hKey, GetPlainString (m_key), 0, REG_SZ, (BYTE *)GetPlainString (value), (GetLength(value)+1)*sizeof (TCHAR));
\r
642 * CRect value in registry. with this class you can use CRect values in registry
\r
643 * almost like normal CRect variables in your program.
\r
645 * in your header file, declare your registry CString variable:
\r
647 * CRegRect regvalue;
\r
649 * next initialize the variable e.g. in the constructor of your class:
\r
651 * regvalue = CRegRect("Software\\Company\\SubKey\\MyValue", CRect(100,100,200,200));
\r
653 * this will set the registry value "MyValue" under HKEY_CURRENT_USER with path
\r
654 * "Software\Company\SubKey" to the variable. If the key does not yet exist or
\r
655 * an error occurred during read from the registry, a default
\r
656 * value of 100,100,200,200 is used when accessing the variable.
\r
657 * now the variable can be used like any other CRect variable:
\r
659 * regvalue = CRect(40,20,300,500); //stores the value in the registry
\r
660 * CRect temp = regvalue + CPoint(1,1);
\r
661 * temp |= CSize(5,5);
\r
663 * to use the normal methods of the CRect class, just typecast the CRegRect to a CRect
\r
664 * and do whatever you want with the rect:
\r
666 * ((CRect)regvalue).MoveToX(100);
\r
667 * ((CRect)regvalue).DeflateRect(10,10);
\r
669 * please be aware that in the second line the change in the CRect won't be written
\r
670 * to the registry! To force a write use the write() method. A write() is only needed
\r
671 * if you change the CRect with Methods not overloaded by CRegRect.
\r
672 * to avoid too much access to the registry the value is cached inside the object.
\r
673 * once the value is read, no more read accesses to the registry will be made.
\r
674 * this means the variable will contain a wrong value if the corresponding registry
\r
675 * entry is changed by anything else than this variable! If you think that could happen
\r
680 * to force a refresh of the variable with the registry.
\r
681 * a write to the registry is only made if the new value assigned with the variable
\r
682 * is different than the last assigned value.
\r
683 * to force a write use the method write();
\r
684 * another option to force reads and writes to the registry is to specify TRUE as the
\r
685 * third parameter in the constructor.
\r
688 #ifdef __ATLTYPES_H__ // defines CRect
\r
689 class CRegRect : public CRegTypedBase<CRect, CRegBase>
\r
694 * provide type-specific code to extract data from and write data to an open registry key.
\r
697 virtual void InternalRead (HKEY hKey, CRect& value);
\r
698 virtual void InternalWrite (HKEY hKey, const CRect& value);
\r
704 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
\r
705 * \param def the default value used when the key does not exist or a read error occurred
\r
706 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
\r
707 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
\r
709 CRegRect(const CString& key, const CRect& def = CRect(), bool force = false, HKEY base = HKEY_CURRENT_USER);
\r
712 CRegRect& operator=(const CRect& rhs) {CRegTypedBase<CRect, CRegBase>::operator =(rhs); return *this;}
\r
713 operator LPCRECT() { return (LPCRECT)(CRect)*this; }
\r
714 operator LPRECT() { return (LPRECT)(CRect)*this; }
\r
715 CRegRect& operator+=(POINT r) { return *this = (CRect)*this + r;}
\r
716 CRegRect& operator+=(SIZE r) { return *this = (CRect)*this + r;}
\r
717 CRegRect& operator+=(LPCRECT r) { return *this = (CRect)*this + r;}
\r
718 CRegRect& operator-=(POINT r) { return *this = (CRect)*this - r;}
\r
719 CRegRect& operator-=(SIZE r) { return *this = (CRect)*this - r;}
\r
720 CRegRect& operator-=(LPCRECT r) { return *this = (CRect)*this - r;}
\r
722 CRegRect& operator&=(CRect r) { return *this = r & *this;}
\r
723 CRegRect& operator|=(CRect r) { return *this = r | *this;}
\r
729 * CPoint value in registry. with this class you can use CPoint values in registry
\r
730 * almost like normal CPoint variables in your program.
\r
732 * in your header file, declare your registry CPoint variable:
\r
734 * CRegPoint regvalue;
\r
736 * next initialize the variable e.g. in the constructor of your class:
\r
738 * regvalue = CRegPoint("Software\\Company\\SubKey\\MyValue", CPoint(100,100));
\r
740 * this will set the registry value "MyValue" under HKEY_CURRENT_USER with path
\r
741 * "Software\Company\SubKey" to the variable. If the key does not yet exist or
\r
742 * an error occurred during read from the registry, a default
\r
743 * value of 100,100 is used when accessing the variable.
\r
744 * now the variable can be used like any other CPoint variable:
\r
746 * regvalue = CPoint(40,20); //stores the value in the registry
\r
747 * CPoint temp = regvalue + CPoint(1,1);
\r
748 * temp += CSize(5,5);
\r
750 * to use the normal methods of the CPoint class, just typecast the CRegPoint to a CPoint
\r
751 * and do whatever you want with the point:
\r
753 * ((CRect)regvalue).Offset(100,10);
\r
755 * please be aware that in the above example the change in the CPoint won't be written
\r
756 * to the registry! To force a write use the write() method. A write() is only needed
\r
757 * if you change the CPoint with Methods not overloaded by CRegPoint.
\r
758 * to avoid too much access to the registry the value is cached inside the object.
\r
759 * once the value is read, no more read accesses to the registry will be made.
\r
760 * this means the variable will contain a wrong value if the corresponding registry
\r
761 * entry is changed by anything else than this variable! If you think that could happen
\r
766 * to force a refresh of the variable with the registry.
\r
767 * a write to the registry is only made if the new value assigned with the variable
\r
768 * is different than the last assigned value.
\r
769 * to force a write use the method write();
\r
770 * another option to force reads and writes to the registry is to specify TRUE as the
\r
771 * third parameter in the constructor.
\r
774 #ifdef __ATLTYPES_H__ // defines CPoint
\r
775 class CRegPoint : public CRegTypedBase<CPoint, CRegBase>
\r
780 * provide type-specific code to extract data from and write data to an open registry key.
\r
783 virtual void InternalRead (HKEY hKey, CPoint& value);
\r
784 virtual void InternalWrite (HKEY hKey, const CPoint& value);
\r
790 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
\r
791 * \param def the default value used when the key does not exist or a read error occurred
\r
792 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
\r
793 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
\r
795 CRegPoint(const CString& key, const CPoint& def = CPoint(), bool force = false, HKEY base = HKEY_CURRENT_USER);
\r
798 CRegPoint& operator=(const CPoint& rhs) {CRegTypedBase<CPoint, CRegBase>::operator =(rhs); return *this;}
\r
799 CRegPoint& operator+=(CPoint p) { return *this = p + *this; }
\r
800 CRegPoint& operator-=(CPoint p) { return *this = p - *this; }
\r
806 * Manages a registry key (not a value). Provides methods to create and remove the
\r
807 * key and to query the list of values and sub keys.
\r
810 #ifdef __AFXCOLL_H__ // defines CStringList
\r
816 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey"
\r
817 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
\r
819 CRegistryKey(const CString& key, HKEY base = HKEY_CURRENT_USER);
\r
823 * Creates the registry key if it does not already exist.
\r
824 * \return ERROR_SUCCESS or an nonzero error code. Use FormatMessage() to get an error description.
\r
828 * Removes the whole registry key including all values. So if you set the registry
\r
829 * entry to be HKCU\Software\Company\Product\key there will only be
\r
830 * HKCU\Software\Company\Product key in the registry.
\r
831 * \return ERROR_SUCCESS or an nonzero error code. Use FormatMessage() to get an error description.
\r
835 bool getValues(CStringList& values); ///< returns the list of values
\r
836 bool getSubKeys(CStringList& subkeys); ///< returns the list of sub keys
\r
839 HKEY m_base; ///< handle to the registry base
\r
840 HKEY m_hKey; ///< handle to the open registry key
\r
841 CString m_path; ///< the path to the key
\r
846 * Instantiate templates for common (data type, string type) combinations.
\r
849 #ifdef __CSTRINGT_H__
\r
850 CRegDWORDCommon<CRegBase>;
\r
851 typedef CRegDWORDCommon<CRegBase> CRegDWORD;
\r
852 CRegStringCommon<CRegBase>;
\r
853 typedef CRegStringCommon<CRegBase> CRegString;
\r
856 CRegDWORDCommon<CRegStdBase>;
\r
857 typedef CRegDWORDCommon<CRegStdBase> CRegStdWORD;
\r
858 CRegStringCommon<CRegStdBase>;
\r
859 typedef CRegStringCommon<CRegStdBase> CRegStdString;
\r