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
23 #include "tstring.h"
\r
31 * Base class for the registry classes.
\r
33 * \par requirements
\r
34 * - win98 or later, win2k or later, win95 with IE4 or later, winNT4 with IE4 or later
\r
35 * - import library Shlwapi.lib
\r
39 class CRegBaseCommon
\r
44 * String type specific operations.
\r
47 virtual LPCTSTR GetPlainString (const S& s) const = 0;
\r
48 virtual DWORD GetLength (const S& s) const = 0;
\r
52 /** Default constructor.
\r
57 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
\r
58 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
\r
59 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
\r
61 CRegBaseCommon(const S& key, bool force, HKEY base = HKEY_CURRENT_USER);
\r
64 * Removes the whole registry key including all values. So if you set the registry
\r
65 * entry to be HKCU\Software\Company\Product\key\value there will only be
\r
66 * HKCU\Software\Company\Product key in the registry.
\r
67 * \return ERROR_SUCCESS or an nonzero error code. Use FormatMessage() to get an error description.
\r
71 * Removes the value of the registry object. If you set the registry entry to
\r
72 * be HKCU\Software\Company\Product\key\value there will only be
\r
73 * HKCU\Software\Company\Product\key\ in the registry.
\r
74 * \return ERROR_SUCCESS or an nonzero error code. Use FormatMessage() to get an error description.
\r
79 * Returns the string of the last error occurred.
\r
81 virtual S getErrorString()
\r
86 FORMAT_MESSAGE_ALLOCATE_BUFFER |
\r
87 FORMAT_MESSAGE_FROM_SYSTEM |
\r
88 FORMAT_MESSAGE_IGNORE_INSERTS,
\r
91 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
\r
95 return (LPCTSTR)lpMsgBuf;
\r
100 typedef S StringT; ///< used in subclass templates to specify the correct string type
\r
103 HKEY m_base; ///< handle to the registry base
\r
104 S m_key; ///< the name of the value
\r
105 S m_path; ///< the path to the key
\r
106 LONG LastError; ///< the value of the last error occurred
\r
108 bool m_read; ///< indicates if the value has already been read from the registry
\r
109 bool m_force; ///< indicates if no cache should be used, i.e. always read and write directly from registry
\r
110 bool m_exists; ///< true, if the registry actually exists
\r
113 // implement CRegBaseCommon<> members
\r
116 CRegBaseCommon<S>::CRegBaseCommon()
\r
117 : m_base (HKEY_CURRENT_USER)
\r
120 , LastError (ERROR_SUCCESS)
\r
128 CRegBaseCommon<S>::CRegBaseCommon (const S& key, bool force, HKEY base)
\r
132 , LastError (ERROR_SUCCESS)
\r
140 DWORD CRegBaseCommon<S>::removeKey()
\r
146 RegOpenKeyEx (m_base, GetPlainString (m_path), 0, KEY_WRITE, &hKey);
\r
147 return SHDeleteKey(m_base, GetPlainString (m_path));
\r
151 LONG CRegBaseCommon<S>::removeValue()
\r
157 RegOpenKeyEx(m_base, GetPlainString (m_path), 0, KEY_WRITE, &hKey);
\r
158 return RegDeleteValue(hKey, GetPlainString (m_key));
\r
163 * Base class for MFC type registry classes.
\r
166 #ifdef __CSTRINGT_H__
\r
167 class CRegBase : public CRegBaseCommon<CString>
\r
172 * String type specific operations.
\r
175 virtual LPCTSTR GetPlainString (const CString& s) const {return (LPCTSTR)s;}
\r
176 virtual DWORD GetLength (const CString& s) const {return s.GetLength();}
\r
180 /** Default constructor.
\r
185 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
\r
186 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
\r
187 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
\r
189 CRegBase(const CString& key, bool force, HKEY base = HKEY_CURRENT_USER);
\r
192 * Returns the string of the last error occurred.
\r
194 CString getErrorString()
\r
196 CString error = CRegBaseCommon<CString>::getErrorString();
\r
197 #if defined IDS_REG_ERROR
\r
199 sTemp.Format(IDS_REG_ERROR, (LPCTSTR)m_key, (LPCTSTR)error);
\r
208 typedef std::wstring wide_string;
\r
211 # define stdstring wide_string
\r
213 # define stdstring std::string
\r
219 * Base class for STL string type registry classes.
\r
222 class CRegStdBase : public CRegBaseCommon<stdstring>
\r
227 * String type specific operations.
\r
230 virtual LPCTSTR GetPlainString (const stdstring& s) const {return s.c_str();}
\r
231 virtual DWORD GetLength (const stdstring& s) const {return static_cast<DWORD>(s.size());}
\r
235 /** Default constructor.
\r
240 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
\r
241 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
\r
242 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
\r
244 CRegStdBase(const stdstring& key, bool force, HKEY base = HKEY_CURRENT_USER);
\r
249 * DWORD value in registry. with this class you can use DWORD values in registry
\r
250 * like normal DWORD variables in your program.
\r
252 * in your header file, declare your registry DWORD variable:
\r
254 * CRegDWORD regvalue;
\r
256 * next initialize the variable e.g. in the constructor of your class:
\r
258 * regvalue = CRegDWORD("Software\\Company\\SubKey\\MyValue", 100);
\r
260 * this will set the registry value "MyValue" under HKEY_CURRENT_USER with path
\r
261 * "Software\Company\SubKey" to the variable. If the key does not yet exist or
\r
262 * an error occurred during read from the registry, a default
\r
263 * value of 100 is used when accessing the variable.
\r
264 * now the variable can be used like any other DWORD variable:
\r
266 * regvalue = 200; //stores the value 200 in the registry
\r
267 * int temp = regvalue + 300; //temp has value 500 now
\r
268 * regvalue += 300; //now the registry has the value 500 too
\r
270 * to avoid too much access to the registry the value is cached inside the object.
\r
271 * once the value is read, no more read accesses to the registry will be made.
\r
272 * this means the variable will contain a wrong value if the corresponding registry
\r
273 * entry is changed by anything else than this variable! If you think that could happen
\r
278 * to force a refresh of the variable with the registry.
\r
279 * a write to the registry is only made if the new value assigned with the variable
\r
280 * is different than the last assigned value.
\r
281 * to force a write use the method write();
\r
282 * another option to force reads and writes to the registry is to specify TRUE as the
\r
283 * third parameter in the constructor.
\r
285 template<class T, class Base>
\r
286 class CRegTypedBase : public Base
\r
290 T m_value; ///< the cached value of the registry
\r
291 T m_defaultvalue; ///< the default value to use
\r
294 * sub-classes must provide type-specific code to extract data from
\r
295 * and write data to an open registry key.
\r
298 virtual void InternalRead (HKEY hKey, T& value) = 0;
\r
299 virtual void InternalWrite (HKEY hKey, const T& value) = 0;
\r
304 * We use this instead of a default constructor because not all
\r
305 * data types may provide an adequate default constructor.
\r
307 CRegTypedBase(const T& def);
\r
311 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
\r
312 * \param def the default value used when the key does not exist or a read error occurred
\r
313 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
\r
314 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
\r
316 CRegTypedBase(const typename Base::StringT& key, const T& def, bool force = FALSE, HKEY base = HKEY_CURRENT_USER);
\r
319 * reads the assigned value from the registry. Use this method only if you think the registry
\r
320 * value could have been altered without using the CRegDWORD object.
\r
321 * \return the read value
\r
323 void read(); ///< reads the value from the registry
\r
324 void write(); ///< writes the value to the registry
\r
330 operator const T&();
\r
331 CRegTypedBase<T,Base>& operator=(const T& rhs);
\r
334 // implement CRegTypedBase<> members
\r
336 template<class T, class Base>
\r
337 CRegTypedBase<T, Base>::CRegTypedBase (const T& def)
\r
339 , m_defaultvalue (def)
\r
343 template<class T, class Base>
\r
344 CRegTypedBase<T, Base>::CRegTypedBase (const typename Base::StringT& key, const T& def, bool force, HKEY base)
\r
345 : Base (key, force, base)
\r
347 , m_defaultvalue (def)
\r
351 template<class T, class Base>
\r
352 void CRegTypedBase<T, Base>::read()
\r
354 m_value = m_defaultvalue;
\r
358 if ((LastError = RegOpenKeyEx (m_base, GetPlainString (m_path), 0, KEY_EXECUTE, &hKey))==ERROR_SUCCESS)
\r
362 T value = m_defaultvalue;
\r
363 InternalRead (hKey, value);
\r
365 if (LastError ==ERROR_SUCCESS)
\r
371 LastError = RegCloseKey(hKey);
\r
375 template<class T, class Base>
\r
376 void CRegTypedBase<T, Base>::write()
\r
381 if ((LastError = RegCreateKeyEx(m_base, GetPlainString (m_path), 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &disp))!=ERROR_SUCCESS)
\r
386 InternalWrite (hKey, m_value);
\r
387 if (LastError ==ERROR_SUCCESS)
\r
392 LastError = RegCloseKey(hKey);
\r
396 template<class T, class Base>
\r
397 CRegTypedBase<T, Base>::operator const T&()
\r
399 if ((m_read)&&(!m_force))
\r
411 template<class T, class Base>
\r
412 CRegTypedBase<T, Base>& CRegTypedBase<T, Base>::operator =(const T& d)
\r
414 if ((d==m_value)&&(!m_force))
\r
416 //no write to the registry required, its the same value
\r
427 * DWORD value in registry. with this class you can use DWORD values in registry
\r
428 * like normal DWORD variables in your program.
\r
430 * in your header file, declare your registry DWORD variable:
\r
432 * CRegDWORD regvalue;
\r
434 * next initialize the variable e.g. in the constructor of your class:
\r
436 * regvalue = CRegDWORD("Software\\Company\\SubKey\\MyValue", 100);
\r
438 * this will set the registry value "MyValue" under HKEY_CURRENT_USER with path
\r
439 * "Software\Company\SubKey" to the variable. If the key does not yet exist or
\r
440 * an error occurred during read from the registry, a default
\r
441 * value of 100 is used when accessing the variable.
\r
442 * now the variable can be used like any other DWORD variable:
\r
444 * regvalue = 200; //stores the value 200 in the registry
\r
445 * int temp = regvalue + 300; //temp has value 500 now
\r
446 * regvalue += 300; //now the registry has the value 500 too
\r
448 * to avoid too much access to the registry the value is cached inside the object.
\r
449 * once the value is read, no more read accesses to the registry will be made.
\r
450 * this means the variable will contain a wrong value if the corresponding registry
\r
451 * entry is changed by anything else than this variable! If you think that could happen
\r
456 * to force a refresh of the variable with the registry.
\r
457 * a write to the registry is only made if the new value assigned with the variable
\r
458 * is different than the last assigned value.
\r
459 * to force a write use the method write();
\r
460 * another option to force reads and writes to the registry is to specify TRUE as the
\r
461 * third parameter in the constructor.
\r
463 template<class Base>
\r
464 class CRegDWORDCommon : public CRegTypedBase<DWORD,Base>
\r
469 * provide type-specific code to extract data from and write data to an open registry key.
\r
472 virtual void InternalRead (HKEY hKey, DWORD& value);
\r
473 virtual void InternalWrite (HKEY hKey, const DWORD& value);
\r
477 CRegDWORDCommon(void);
\r
480 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
\r
481 * \param def the default value used when the key does not exist or a read error occurred
\r
482 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
\r
483 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
\r
485 CRegDWORDCommon(const typename Base::StringT& key, DWORD def = 0, bool force = false, HKEY base = HKEY_CURRENT_USER);
\r
487 CRegDWORDCommon& operator=(DWORD rhs) {CRegTypedBase<DWORD, Base>::operator =(rhs); return *this;}
\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
497 CRegDWORDCommon& operator^=(DWORD d) { return *this = *this ^ d;}
\r
500 // implement CRegDWORDCommon<> methods
\r
502 template<class Base>
\r
503 CRegDWORDCommon<Base>::CRegDWORDCommon(void)
\r
504 : CRegTypedBase<DWORD, Base>(0)
\r
508 template<class Base>
\r
509 CRegDWORDCommon<Base>::CRegDWORDCommon(const typename Base::StringT& key, DWORD def, bool force, HKEY base)
\r
510 : CRegTypedBase<DWORD, Base> (key, def, force, base)
\r
515 template<class Base>
\r
516 void CRegDWORDCommon<Base>::InternalRead (HKEY hKey, DWORD& value)
\r
518 DWORD size = sizeof(value);
\r
520 if ((LastError = RegQueryValueEx(hKey, GetPlainString (m_key), NULL, &type, (BYTE*) &value, &size))==ERROR_SUCCESS)
\r
522 ASSERT(type==REG_DWORD);
\r
526 template<class Base>
\r
527 void CRegDWORDCommon<Base>::InternalWrite (HKEY hKey, const DWORD& value)
\r
529 LastError = RegSetValueEx (hKey, GetPlainString (m_key), 0, REG_DWORD,(const BYTE*) &value, sizeof(value));
\r
534 * CString value in registry. with this class you can use CString values in registry
\r
535 * almost like normal CString variables in your program.
\r
537 * in your header file, declare your registry CString variable:
\r
539 * CRegString regvalue;
\r
541 * next initialize the variable e.g. in the constructor of your class:
\r
543 * regvalue = CRegString("Software\\Company\\SubKey\\MyValue", "default");
\r
545 * this will set the registry value "MyValue" under HKEY_CURRENT_USER with path
\r
546 * "Software\Company\SubKey" to the variable. If the key does not yet exist or
\r
547 * an error occurred during read from the registry, a default
\r
548 * value of "default" is used when accessing the variable.
\r
549 * now the variable can be used like any other CString variable:
\r
551 * regvalue = "some string"; //stores the value "some string" in the registry
\r
552 * CString temp = regvalue + "!!"; //temp has value "some string!!" now
\r
554 * to use the normal methods of the CString class, just typecast the CRegString to a CString
\r
555 * and do whatever you want with the string:
\r
557 * ((CString)regvalue).GetLength();
\r
558 * ((CString)regvalue).Trim();
\r
560 * please be aware that in the second line the change in the string won't be written
\r
561 * to the registry! To force a write use the write() method. A write() is only needed
\r
562 * if you change the String with Methods not overloaded by CRegString.
\r
563 * to avoid too much access to the registry the value is cached inside the object.
\r
564 * once the value is read, no more read accesses to the registry will be made.
\r
565 * this means the variable will contain a wrong value if the corresponding registry
\r
566 * entry is changed by anything else than this variable! If you think that could happen
\r
571 * to force a refresh of the variable with the registry.
\r
572 * a write to the registry is only made if the new value assigned with the variable
\r
573 * is different than the last assigned value.
\r
574 * to force a write use the method write();
\r
575 * another option to force reads and writes to the registry is to specify TRUE as the
\r
576 * third parameter in the constructor.
\r
578 template<class Base>
\r
579 class CRegStringCommon : public CRegTypedBase<typename Base::StringT, Base>
\r
584 * provide type-specific code to extract data from and write data to an open registry key.
\r
587 virtual void InternalRead (HKEY hKey, typename Base::StringT& value);
\r
588 virtual void InternalWrite (HKEY hKey, const typename Base::StringT& value);
\r
591 CRegStringCommon();
\r
594 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
\r
595 * \param def the default value used when the key does not exist or a read error occurred
\r
596 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
\r
597 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
\r
599 CRegStringCommon(const typename Base::StringT& key, const typename Base::StringT& def = _T(""), bool force = false, HKEY base = HKEY_CURRENT_USER);
\r
601 CRegStringCommon& operator=(const typename Base::StringT& rhs) {CRegTypedBase<StringT, Base>::operator =(rhs); return *this;}
\r
602 CRegStringCommon& operator+=(const typename Base::StringT& s) { return *this = (typename Base::StringT)*this + s; }
\r
605 // implement CRegDWORD<> methods
\r
607 template<class Base>
\r
608 CRegStringCommon<Base>::CRegStringCommon(void)
\r
609 : CRegTypedBase<typename Base::StringT, Base>(typename Base::StringT())
\r
613 template<class Base>
\r
614 CRegStringCommon<Base>::CRegStringCommon(const typename Base::StringT& key, const typename Base::StringT& def, bool force, HKEY base)
\r
615 : CRegTypedBase<typename Base::StringT, Base> (key, def, force, base)
\r
620 template<class Base>
\r
621 void CRegStringCommon<Base>::InternalRead (HKEY hKey, typename Base::StringT& value)
\r
625 LastError = RegQueryValueEx(hKey, GetPlainString (m_key), NULL, &type, NULL, &size);
\r
627 std::auto_ptr<TCHAR> pStr (new TCHAR[size]);
\r
628 if ((LastError = RegQueryValueEx(hKey, GetPlainString (m_key), NULL, &type, (BYTE*) pStr.get(), &size))==ERROR_SUCCESS)
\r
630 ASSERT(type==REG_SZ || type==REG_EXPAND_SZ);
\r
631 value = StringT (pStr.get());
\r
635 template<class Base>
\r
636 void CRegStringCommon<Base>::InternalWrite (HKEY hKey, const typename Base::StringT& value)
\r
638 LastError = RegSetValueEx(hKey, GetPlainString (m_key), 0, REG_SZ, (BYTE *)GetPlainString (value), (GetLength(value)+1)*sizeof (TCHAR));
\r
643 * CRect value in registry. with this class you can use CRect values in registry
\r
644 * almost like normal CRect variables in your program.
\r
646 * in your header file, declare your registry CString variable:
\r
648 * CRegRect regvalue;
\r
650 * next initialize the variable e.g. in the constructor of your class:
\r
652 * regvalue = CRegRect("Software\\Company\\SubKey\\MyValue", CRect(100,100,200,200));
\r
654 * this will set the registry value "MyValue" under HKEY_CURRENT_USER with path
\r
655 * "Software\Company\SubKey" to the variable. If the key does not yet exist or
\r
656 * an error occurred during read from the registry, a default
\r
657 * value of 100,100,200,200 is used when accessing the variable.
\r
658 * now the variable can be used like any other CRect variable:
\r
660 * regvalue = CRect(40,20,300,500); //stores the value in the registry
\r
661 * CRect temp = regvalue + CPoint(1,1);
\r
662 * temp |= CSize(5,5);
\r
664 * to use the normal methods of the CRect class, just typecast the CRegRect to a CRect
\r
665 * and do whatever you want with the rect:
\r
667 * ((CRect)regvalue).MoveToX(100);
\r
668 * ((CRect)regvalue).DeflateRect(10,10);
\r
670 * please be aware that in the second line the change in the CRect won't be written
\r
671 * to the registry! To force a write use the write() method. A write() is only needed
\r
672 * if you change the CRect with Methods not overloaded by CRegRect.
\r
673 * to avoid too much access to the registry the value is cached inside the object.
\r
674 * once the value is read, no more read accesses to the registry will be made.
\r
675 * this means the variable will contain a wrong value if the corresponding registry
\r
676 * entry is changed by anything else than this variable! If you think that could happen
\r
681 * to force a refresh of the variable with the registry.
\r
682 * a write to the registry is only made if the new value assigned with the variable
\r
683 * is different than the last assigned value.
\r
684 * to force a write use the method write();
\r
685 * another option to force reads and writes to the registry is to specify TRUE as the
\r
686 * third parameter in the constructor.
\r
689 #ifdef __ATLTYPES_H__ // defines CRect
\r
690 class CRegRect : public CRegTypedBase<CRect, CRegBase>
\r
695 * provide type-specific code to extract data from and write data to an open registry key.
\r
698 virtual void InternalRead (HKEY hKey, CRect& value);
\r
699 virtual void InternalWrite (HKEY hKey, const CRect& value);
\r
705 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
\r
706 * \param def the default value used when the key does not exist or a read error occurred
\r
707 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
\r
708 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
\r
710 CRegRect(const CString& key, const CRect& def = CRect(), bool force = false, HKEY base = HKEY_CURRENT_USER);
\r
713 CRegRect& operator=(const CRect& rhs) {CRegTypedBase<CRect, CRegBase>::operator =(rhs); return *this;}
\r
714 operator LPCRECT() { return (LPCRECT)(CRect)*this; }
\r
715 operator LPRECT() { return (LPRECT)(CRect)*this; }
\r
716 CRegRect& operator+=(POINT r) { return *this = (CRect)*this + r;}
\r
717 CRegRect& operator+=(SIZE r) { return *this = (CRect)*this + r;}
\r
718 CRegRect& operator+=(LPCRECT r) { return *this = (CRect)*this + r;}
\r
719 CRegRect& operator-=(POINT r) { return *this = (CRect)*this - r;}
\r
720 CRegRect& operator-=(SIZE r) { return *this = (CRect)*this - r;}
\r
721 CRegRect& operator-=(LPCRECT r) { return *this = (CRect)*this - r;}
\r
723 CRegRect& operator&=(CRect r) { return *this = r & *this;}
\r
724 CRegRect& operator|=(CRect r) { return *this = r | *this;}
\r
730 * CPoint value in registry. with this class you can use CPoint values in registry
\r
731 * almost like normal CPoint variables in your program.
\r
733 * in your header file, declare your registry CPoint variable:
\r
735 * CRegPoint regvalue;
\r
737 * next initialize the variable e.g. in the constructor of your class:
\r
739 * regvalue = CRegPoint("Software\\Company\\SubKey\\MyValue", CPoint(100,100));
\r
741 * this will set the registry value "MyValue" under HKEY_CURRENT_USER with path
\r
742 * "Software\Company\SubKey" to the variable. If the key does not yet exist or
\r
743 * an error occurred during read from the registry, a default
\r
744 * value of 100,100 is used when accessing the variable.
\r
745 * now the variable can be used like any other CPoint variable:
\r
747 * regvalue = CPoint(40,20); //stores the value in the registry
\r
748 * CPoint temp = regvalue + CPoint(1,1);
\r
749 * temp += CSize(5,5);
\r
751 * to use the normal methods of the CPoint class, just typecast the CRegPoint to a CPoint
\r
752 * and do whatever you want with the point:
\r
754 * ((CRect)regvalue).Offset(100,10);
\r
756 * please be aware that in the above example the change in the CPoint won't be written
\r
757 * to the registry! To force a write use the write() method. A write() is only needed
\r
758 * if you change the CPoint with Methods not overloaded by CRegPoint.
\r
759 * to avoid too much access to the registry the value is cached inside the object.
\r
760 * once the value is read, no more read accesses to the registry will be made.
\r
761 * this means the variable will contain a wrong value if the corresponding registry
\r
762 * entry is changed by anything else than this variable! If you think that could happen
\r
767 * to force a refresh of the variable with the registry.
\r
768 * a write to the registry is only made if the new value assigned with the variable
\r
769 * is different than the last assigned value.
\r
770 * to force a write use the method write();
\r
771 * another option to force reads and writes to the registry is to specify TRUE as the
\r
772 * third parameter in the constructor.
\r
775 #ifdef __ATLTYPES_H__ // defines CPoint
\r
776 class CRegPoint : public CRegTypedBase<CPoint, CRegBase>
\r
781 * provide type-specific code to extract data from and write data to an open registry key.
\r
784 virtual void InternalRead (HKEY hKey, CPoint& value);
\r
785 virtual void InternalWrite (HKEY hKey, const CPoint& value);
\r
791 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
\r
792 * \param def the default value used when the key does not exist or a read error occurred
\r
793 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
\r
794 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
\r
796 CRegPoint(const CString& key, const CPoint& def = CPoint(), bool force = false, HKEY base = HKEY_CURRENT_USER);
\r
799 CRegPoint& operator=(const CPoint& rhs) {CRegTypedBase<CPoint, CRegBase>::operator =(rhs); return *this;}
\r
800 CRegPoint& operator+=(CPoint p) { return *this = p + *this; }
\r
801 CRegPoint& operator-=(CPoint p) { return *this = p - *this; }
\r
807 * Manages a registry key (not a value). Provides methods to create and remove the
\r
808 * key and to query the list of values and sub keys.
\r
811 #ifdef __AFXCOLL_H__ // defines CStringList
\r
817 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey"
\r
818 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
\r
820 CRegistryKey(const CString& key, HKEY base = HKEY_CURRENT_USER);
\r
824 * Creates the registry key if it does not already exist.
\r
825 * \return ERROR_SUCCESS or an nonzero error code. Use FormatMessage() to get an error description.
\r
829 * Removes the whole registry key including all values. So if you set the registry
\r
830 * entry to be HKCU\Software\Company\Product\key there will only be
\r
831 * HKCU\Software\Company\Product key in the registry.
\r
832 * \return ERROR_SUCCESS or an nonzero error code. Use FormatMessage() to get an error description.
\r
836 bool getValues(CStringList& values); ///< returns the list of values
\r
837 bool getSubKeys(CStringList& subkeys); ///< returns the list of sub keys
\r
840 HKEY m_base; ///< handle to the registry base
\r
841 HKEY m_hKey; ///< handle to the open registry key
\r
842 CString m_path; ///< the path to the key
\r
847 * Instantiate templates for common (data type, string type) combinations.
\r
850 #ifdef __CSTRINGT_H__
\r
851 CRegDWORDCommon<CRegBase>;
\r
852 typedef CRegDWORDCommon<CRegBase> CRegDWORD;
\r
853 CRegStringCommon<CRegBase>;
\r
854 typedef CRegStringCommon<CRegBase> CRegString;
\r
857 CRegDWORDCommon<CRegStdBase>;
\r
858 typedef CRegDWORDCommon<CRegStdBase> CRegStdWORD;
\r
859 typedef CRegDWORDCommon<CRegStdBase> CRegStdDWORD;
\r
860 CRegStringCommon<CRegStdBase>;
\r
861 typedef CRegStringCommon<CRegStdBase> CRegStdString;
\r