Pick Ref: Browse Ref buttons added to dialogs derived from ChooseVersion.
[TortoiseGit.git] / src / Utils / registry.h
blobce4669f19a579b629d2d04ef6c0ba733d8afdfe0
1 // TortoiseSVN - a Windows shell extension for easy version control
3 // Copyright (C) 2003-2008 - TortoiseSVN
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #pragma once
20 #include <string>
21 #include <memory>
22 #include "shlwapi.h"
24 #ifndef ASSERT
25 #define ASSERT(x)
26 #endif
28 /**
29 * \ingroup Utils
30 * Base class for the registry classes.
32 * \par requirements
33 * - win98 or later, win2k or later, win95 with IE4 or later, winNT4 with IE4 or later
34 * - import library Shlwapi.lib
37 template<class S>
38 class CRegBaseCommon
40 protected:
42 /**
43 * String type specific operations.
46 virtual LPCTSTR GetPlainString (const S& s) const = 0;
47 virtual DWORD GetLength (const S& s) const = 0;
49 public: //methods
51 /** Default constructor.
53 CRegBaseCommon();
54 /**
55 * Constructor.
56 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
57 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
58 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
60 CRegBaseCommon(const S& key, bool force, HKEY base = HKEY_CURRENT_USER);
62 /**
63 * Removes the whole registry key including all values. So if you set the registry
64 * entry to be HKCU\Software\Company\Product\key\value there will only be
65 * HKCU\Software\Company\Product key in the registry.
66 * \return ERROR_SUCCESS or an nonzero error code. Use FormatMessage() to get an error description.
68 DWORD removeKey();
69 /**
70 * Removes the value of the registry object. If you set the registry entry to
71 * be HKCU\Software\Company\Product\key\value there will only be
72 * HKCU\Software\Company\Product\key\ in the registry.
73 * \return ERROR_SUCCESS or an nonzero error code. Use FormatMessage() to get an error description.
75 LONG removeValue();
77 /**
78 * Returns the string of the last error occurred.
80 virtual S getErrorString()
82 LPVOID lpMsgBuf;
84 FormatMessage(
85 FORMAT_MESSAGE_ALLOCATE_BUFFER |
86 FORMAT_MESSAGE_FROM_SYSTEM |
87 FORMAT_MESSAGE_IGNORE_INSERTS,
88 NULL,
89 LastError,
90 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
91 (LPTSTR) &lpMsgBuf,
92 0, NULL );
94 return (LPCTSTR)lpMsgBuf;
97 public:
99 typedef S StringT; ///< used in subclass templates to specify the correct string type
101 //members
102 HKEY m_base; ///< handle to the registry base
103 S m_key; ///< the name of the value
104 S m_path; ///< the path to the key
105 LONG LastError; ///< the value of the last error occurred
107 bool m_read; ///< indicates if the value has already been read from the registry
108 bool m_force; ///< indicates if no cache should be used, i.e. always read and write directly from registry
109 bool m_exists; ///< true, if the registry actually exists
112 // implement CRegBaseCommon<> members
114 template<class S>
115 CRegBaseCommon<S>::CRegBaseCommon()
116 : m_base (HKEY_CURRENT_USER)
117 , m_key()
118 , m_path()
119 , LastError (ERROR_SUCCESS)
120 , m_read (false)
121 , m_force (false)
122 , m_exists (false)
126 template<class S>
127 CRegBaseCommon<S>::CRegBaseCommon (const S& key, bool force, HKEY base)
128 : m_base (base)
129 , m_key (key)
130 , m_path()
131 , LastError (ERROR_SUCCESS)
132 , m_read (false)
133 , m_force (force)
134 , m_exists (false)
138 template<class S>
139 DWORD CRegBaseCommon<S>::removeKey()
141 m_exists = false;
142 m_read = true;
144 HKEY hKey = NULL;
145 RegOpenKeyEx (m_base, GetPlainString (m_path), 0, KEY_WRITE, &hKey);
146 return SHDeleteKey(m_base, GetPlainString (m_path));
149 template<class S>
150 LONG CRegBaseCommon<S>::removeValue()
152 m_exists = false;
153 m_read = true;
155 HKEY hKey = NULL;
156 RegOpenKeyEx(m_base, GetPlainString (m_path), 0, KEY_WRITE, &hKey);
157 return RegDeleteValue(hKey, GetPlainString (m_key));
161 * \ingroup Utils
162 * Base class for MFC type registry classes.
165 #ifdef __CSTRINGT_H__
166 class CRegBase : public CRegBaseCommon<CString>
168 protected:
171 * String type specific operations.
174 virtual LPCTSTR GetPlainString (const CString& s) const {return (LPCTSTR)s;}
175 virtual DWORD GetLength (const CString& s) const {return s.GetLength();}
177 public: //methods
179 /** Default constructor.
181 CRegBase();
183 * Constructor.
184 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
185 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
186 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
188 CRegBase(const CString& key, bool force, HKEY base = HKEY_CURRENT_USER);
191 * Returns the string of the last error occurred.
193 CString getErrorString()
195 CString error = CRegBaseCommon<CString>::getErrorString();
196 #if defined IDS_REG_ERROR
197 CString sTemp;
198 sTemp.Format(IDS_REG_ERROR, (LPCTSTR)m_key, (LPCTSTR)error);
199 return sTemp;
200 #else
201 return error;
202 #endif
205 #endif
207 typedef std::wstring wide_string;
208 #ifndef stdstring
209 # ifdef UNICODE
210 # define stdstring wide_string
211 # else
212 # define stdstring std::string
213 # endif
214 #endif
217 * \ingroup Utils
218 * Base class for STL string type registry classes.
221 class CRegStdBase : public CRegBaseCommon<stdstring>
223 protected:
226 * String type specific operations.
229 virtual LPCTSTR GetPlainString (const stdstring& s) const {return s.c_str();}
230 virtual DWORD GetLength (const stdstring& s) const {return static_cast<DWORD>(s.size());}
232 public: //methods
234 /** Default constructor.
236 CRegStdBase();
238 * Constructor.
239 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
240 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
241 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
243 CRegStdBase(const stdstring& key, bool force, HKEY base = HKEY_CURRENT_USER);
247 * \ingroup Utils
248 * DWORD value in registry. with this class you can use DWORD values in registry
249 * like normal DWORD variables in your program.
250 * Usage:
251 * in your header file, declare your registry DWORD variable:
252 * \code
253 * CRegDWORD regvalue;
254 * \endcode
255 * next initialize the variable e.g. in the constructor of your class:
256 * \code
257 * regvalue = CRegDWORD("Software\\Company\\SubKey\\MyValue", 100);
258 * \endcode
259 * this will set the registry value "MyValue" under HKEY_CURRENT_USER with path
260 * "Software\Company\SubKey" to the variable. If the key does not yet exist or
261 * an error occurred during read from the registry, a default
262 * value of 100 is used when accessing the variable.
263 * now the variable can be used like any other DWORD variable:
264 * \code
265 * regvalue = 200; //stores the value 200 in the registry
266 * int temp = regvalue + 300; //temp has value 500 now
267 * regvalue += 300; //now the registry has the value 500 too
268 * \endcode
269 * to avoid too much access to the registry the value is cached inside the object.
270 * once the value is read, no more read accesses to the registry will be made.
271 * this means the variable will contain a wrong value if the corresponding registry
272 * entry is changed by anything else than this variable! If you think that could happen
273 * then use
274 * \code
275 * regvalue.read();
276 * \endcode
277 * to force a refresh of the variable with the registry.
278 * a write to the registry is only made if the new value assigned with the variable
279 * is different than the last assigned value.
280 * to force a write use the method write();
281 * another option to force reads and writes to the registry is to specify TRUE as the
282 * third parameter in the constructor.
284 template<class T, class Base>
285 class CRegTypedBase : public Base
287 private:
289 T m_value; ///< the cached value of the registry
290 T m_defaultvalue; ///< the default value to use
293 * sub-classes must provide type-specific code to extract data from
294 * and write data to an open registry key.
297 virtual void InternalRead (HKEY hKey, T& value) = 0;
298 virtual void InternalWrite (HKEY hKey, const T& value) = 0;
300 public:
303 * We use this instead of a default constructor because not all
304 * data types may provide an adequate default constructor.
306 CRegTypedBase(const T& def);
309 * Constructor.
310 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
311 * \param def the default value used when the key does not exist or a read error occurred
312 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
313 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
315 CRegTypedBase(const typename Base::StringT& key, const T& def, bool force = FALSE, HKEY base = HKEY_CURRENT_USER);
318 * reads the assigned value from the registry. Use this method only if you think the registry
319 * value could have been altered without using the CRegDWORD object.
320 * \return the read value
322 void read(); ///< reads the value from the registry
323 void write(); ///< writes the value to the registry
326 * Data access.
329 operator const T&();
330 CRegTypedBase<T,Base>& operator=(const T& rhs);
333 // implement CRegTypedBase<> members
335 template<class T, class Base>
336 CRegTypedBase<T, Base>::CRegTypedBase (const T& def)
337 : m_value (def)
338 , m_defaultvalue (def)
342 template<class T, class Base>
343 CRegTypedBase<T, Base>::CRegTypedBase (const typename Base::StringT& key, const T& def, bool force, HKEY base)
344 : Base (key, force, base)
345 , m_value (def)
346 , m_defaultvalue (def)
350 template<class T, class Base>
351 void CRegTypedBase<T, Base>::read()
353 m_value = m_defaultvalue;
354 m_exists = false;
356 HKEY hKey = NULL;
357 if ((LastError = RegOpenKeyEx (m_base, GetPlainString (m_path), 0, KEY_EXECUTE, &hKey))==ERROR_SUCCESS)
359 m_read = true;
361 T value = m_defaultvalue;
362 InternalRead (hKey, value);
364 if (LastError ==ERROR_SUCCESS)
366 m_exists = true;
367 m_value = value;
370 LastError = RegCloseKey(hKey);
374 template<class T, class Base>
375 void CRegTypedBase<T, Base>::write()
377 HKEY hKey = NULL;
379 DWORD disp = 0;
380 if ((LastError = RegCreateKeyEx(m_base, GetPlainString (m_path), 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &disp))!=ERROR_SUCCESS)
382 return;
385 InternalWrite (hKey, m_value);
386 if (LastError ==ERROR_SUCCESS)
388 m_read = true;
389 m_exists = true;
391 LastError = RegCloseKey(hKey);
395 template<class T, class Base>
396 CRegTypedBase<T, Base>::operator const T&()
398 if ((m_read)&&(!m_force))
400 LastError = 0;
402 else
404 read();
407 return m_value;
410 template<class T, class Base>
411 CRegTypedBase<T, Base>& CRegTypedBase<T, Base>::operator =(const T& d)
413 if ((d==m_value)&&(!m_force))
415 //no write to the registry required, its the same value
416 LastError = 0;
417 return *this;
419 m_value = d;
420 write();
421 return *this;
425 * \ingroup Utils
426 * DWORD value in registry. with this class you can use DWORD values in registry
427 * like normal DWORD variables in your program.
428 * Usage:
429 * in your header file, declare your registry DWORD variable:
430 * \code
431 * CRegDWORD regvalue;
432 * \endcode
433 * next initialize the variable e.g. in the constructor of your class:
434 * \code
435 * regvalue = CRegDWORD("Software\\Company\\SubKey\\MyValue", 100);
436 * \endcode
437 * this will set the registry value "MyValue" under HKEY_CURRENT_USER with path
438 * "Software\Company\SubKey" to the variable. If the key does not yet exist or
439 * an error occurred during read from the registry, a default
440 * value of 100 is used when accessing the variable.
441 * now the variable can be used like any other DWORD variable:
442 * \code
443 * regvalue = 200; //stores the value 200 in the registry
444 * int temp = regvalue + 300; //temp has value 500 now
445 * regvalue += 300; //now the registry has the value 500 too
446 * \endcode
447 * to avoid too much access to the registry the value is cached inside the object.
448 * once the value is read, no more read accesses to the registry will be made.
449 * this means the variable will contain a wrong value if the corresponding registry
450 * entry is changed by anything else than this variable! If you think that could happen
451 * then use
452 * \code
453 * regvalue.read();
454 * \endcode
455 * to force a refresh of the variable with the registry.
456 * a write to the registry is only made if the new value assigned with the variable
457 * is different than the last assigned value.
458 * to force a write use the method write();
459 * another option to force reads and writes to the registry is to specify TRUE as the
460 * third parameter in the constructor.
462 template<class Base>
463 class CRegDWORDCommon : public CRegTypedBase<DWORD,Base>
465 private:
468 * provide type-specific code to extract data from and write data to an open registry key.
471 virtual void InternalRead (HKEY hKey, DWORD& value);
472 virtual void InternalWrite (HKEY hKey, const DWORD& value);
474 public:
476 CRegDWORDCommon(void);
478 * Constructor.
479 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
480 * \param def the default value used when the key does not exist or a read error occurred
481 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
482 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
484 CRegDWORDCommon(const typename Base::StringT& key, DWORD def = 0, bool force = false, HKEY base = HKEY_CURRENT_USER);
486 CRegDWORDCommon& operator=(DWORD rhs) {CRegTypedBase<DWORD, Base>::operator =(rhs); return *this;}
487 CRegDWORDCommon& operator+=(DWORD d) { return *this = *this + d;}
488 CRegDWORDCommon& operator-=(DWORD d) { return *this = *this - d;}
489 CRegDWORDCommon& operator*=(DWORD d) { return *this = *this * d;}
490 CRegDWORDCommon& operator/=(DWORD d) { return *this = *this / d;}
491 CRegDWORDCommon& operator%=(DWORD d) { return *this = *this % d;}
492 CRegDWORDCommon& operator<<=(DWORD d) { return *this = *this << d;}
493 CRegDWORDCommon& operator>>=(DWORD d) { return *this = *this >> d;}
494 CRegDWORDCommon& operator&=(DWORD d) { return *this = *this & d;}
495 CRegDWORDCommon& operator|=(DWORD d) { return *this = *this | d;}
496 CRegDWORDCommon& operator^=(DWORD d) { return *this = *this ^ d;}
499 // implement CRegDWORDCommon<> methods
501 template<class Base>
502 CRegDWORDCommon<Base>::CRegDWORDCommon(void)
503 : CRegTypedBase<DWORD, Base>(0)
507 template<class Base>
508 CRegDWORDCommon<Base>::CRegDWORDCommon(const typename Base::StringT& key, DWORD def, bool force, HKEY base)
509 : CRegTypedBase<DWORD, Base> (key, def, force, base)
511 read();
514 template<class Base>
515 void CRegDWORDCommon<Base>::InternalRead (HKEY hKey, DWORD& value)
517 DWORD size = sizeof(value);
518 DWORD type = 0;
519 if ((LastError = RegQueryValueEx(hKey, GetPlainString (m_key), NULL, &type, (BYTE*) &value, &size))==ERROR_SUCCESS)
521 ASSERT(type==REG_DWORD);
525 template<class Base>
526 void CRegDWORDCommon<Base>::InternalWrite (HKEY hKey, const DWORD& value)
528 LastError = RegSetValueEx (hKey, GetPlainString (m_key), 0, REG_DWORD,(const BYTE*) &value, sizeof(value));
532 * \ingroup Utils
533 * CString value in registry. with this class you can use CString values in registry
534 * almost like normal CString variables in your program.
535 * Usage:
536 * in your header file, declare your registry CString variable:
537 * \code
538 * CRegString regvalue;
539 * \endcode
540 * next initialize the variable e.g. in the constructor of your class:
541 * \code
542 * regvalue = CRegString("Software\\Company\\SubKey\\MyValue", "default");
543 * \endcode
544 * this will set the registry value "MyValue" under HKEY_CURRENT_USER with path
545 * "Software\Company\SubKey" to the variable. If the key does not yet exist or
546 * an error occurred during read from the registry, a default
547 * value of "default" is used when accessing the variable.
548 * now the variable can be used like any other CString variable:
549 * \code
550 * regvalue = "some string"; //stores the value "some string" in the registry
551 * CString temp = regvalue + "!!"; //temp has value "some string!!" now
552 * \endcode
553 * to use the normal methods of the CString class, just typecast the CRegString to a CString
554 * and do whatever you want with the string:
555 * \code
556 * ((CString)regvalue).GetLength();
557 * ((CString)regvalue).Trim();
558 * \endcode
559 * please be aware that in the second line the change in the string won't be written
560 * to the registry! To force a write use the write() method. A write() is only needed
561 * if you change the String with Methods not overloaded by CRegString.
562 * to avoid too much access to the registry the value is cached inside the object.
563 * once the value is read, no more read accesses to the registry will be made.
564 * this means the variable will contain a wrong value if the corresponding registry
565 * entry is changed by anything else than this variable! If you think that could happen
566 * then use
567 * \code
568 * regvalue.read();
569 * \endcode
570 * to force a refresh of the variable with the registry.
571 * a write to the registry is only made if the new value assigned with the variable
572 * is different than the last assigned value.
573 * to force a write use the method write();
574 * another option to force reads and writes to the registry is to specify TRUE as the
575 * third parameter in the constructor.
577 template<class Base>
578 class CRegStringCommon : public CRegTypedBase<typename Base::StringT, Base>
580 private:
583 * provide type-specific code to extract data from and write data to an open registry key.
586 virtual void InternalRead (HKEY hKey, typename Base::StringT& value);
587 virtual void InternalWrite (HKEY hKey, const typename Base::StringT& value);
589 public:
590 CRegStringCommon();
592 * Constructor.
593 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
594 * \param def the default value used when the key does not exist or a read error occurred
595 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
596 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
598 CRegStringCommon(const typename Base::StringT& key, const typename Base::StringT& def = _T(""), bool force = false, HKEY base = HKEY_CURRENT_USER);
600 CRegStringCommon& operator=(const typename Base::StringT& rhs) {CRegTypedBase<StringT, Base>::operator =(rhs); return *this;}
601 CRegStringCommon& operator+=(const typename Base::StringT& s) { return *this = (typename Base::StringT)*this + s; }
604 // implement CRegDWORD<> methods
606 template<class Base>
607 CRegStringCommon<Base>::CRegStringCommon(void)
608 : CRegTypedBase<typename Base::StringT, Base>(typename Base::StringT())
612 template<class Base>
613 CRegStringCommon<Base>::CRegStringCommon(const typename Base::StringT& key, const typename Base::StringT& def, bool force, HKEY base)
614 : CRegTypedBase<typename Base::StringT, Base> (key, def, force, base)
616 read();
619 template<class Base>
620 void CRegStringCommon<Base>::InternalRead (HKEY hKey, typename Base::StringT& value)
622 DWORD size = 0;
623 DWORD type = 0;
624 LastError = RegQueryValueEx(hKey, GetPlainString (m_key), NULL, &type, NULL, &size);
626 std::auto_ptr<TCHAR> pStr (new TCHAR[size]);
627 if ((LastError = RegQueryValueEx(hKey, GetPlainString (m_key), NULL, &type, (BYTE*) pStr.get(), &size))==ERROR_SUCCESS)
629 ASSERT(type==REG_SZ || type==REG_EXPAND_SZ);
630 value = StringT (pStr.get());
634 template<class Base>
635 void CRegStringCommon<Base>::InternalWrite (HKEY hKey, const typename Base::StringT& value)
637 LastError = RegSetValueEx(hKey, GetPlainString (m_key), 0, REG_SZ, (BYTE *)GetPlainString (value), (GetLength(value)+1)*sizeof (TCHAR));
641 * \ingroup Utils
642 * CRect value in registry. with this class you can use CRect values in registry
643 * almost like normal CRect variables in your program.
644 * Usage:
645 * in your header file, declare your registry CString variable:
646 * \code
647 * CRegRect regvalue;
648 * \endcode
649 * next initialize the variable e.g. in the constructor of your class:
650 * \code
651 * regvalue = CRegRect("Software\\Company\\SubKey\\MyValue", CRect(100,100,200,200));
652 * \endcode
653 * this will set the registry value "MyValue" under HKEY_CURRENT_USER with path
654 * "Software\Company\SubKey" to the variable. If the key does not yet exist or
655 * an error occurred during read from the registry, a default
656 * value of 100,100,200,200 is used when accessing the variable.
657 * now the variable can be used like any other CRect variable:
658 * \code
659 * regvalue = CRect(40,20,300,500); //stores the value in the registry
660 * CRect temp = regvalue + CPoint(1,1);
661 * temp |= CSize(5,5);
662 * \endcode
663 * to use the normal methods of the CRect class, just typecast the CRegRect to a CRect
664 * and do whatever you want with the rect:
665 * \code
666 * ((CRect)regvalue).MoveToX(100);
667 * ((CRect)regvalue).DeflateRect(10,10);
668 * \endcode
669 * please be aware that in the second line the change in the CRect won't be written
670 * to the registry! To force a write use the write() method. A write() is only needed
671 * if you change the CRect with Methods not overloaded by CRegRect.
672 * to avoid too much access to the registry the value is cached inside the object.
673 * once the value is read, no more read accesses to the registry will be made.
674 * this means the variable will contain a wrong value if the corresponding registry
675 * entry is changed by anything else than this variable! If you think that could happen
676 * then use
677 * \code
678 * regvalue.read();
679 * \endcode
680 * to force a refresh of the variable with the registry.
681 * a write to the registry is only made if the new value assigned with the variable
682 * is different than the last assigned value.
683 * to force a write use the method write();
684 * another option to force reads and writes to the registry is to specify TRUE as the
685 * third parameter in the constructor.
688 #ifdef __ATLTYPES_H__ // defines CRect
689 class CRegRect : public CRegTypedBase<CRect, CRegBase>
691 private:
694 * provide type-specific code to extract data from and write data to an open registry key.
697 virtual void InternalRead (HKEY hKey, CRect& value);
698 virtual void InternalWrite (HKEY hKey, const CRect& value);
700 public:
701 CRegRect();
703 * Constructor.
704 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
705 * \param def the default value used when the key does not exist or a read error occurred
706 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
707 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
709 CRegRect(const CString& key, const CRect& def = CRect(), bool force = false, HKEY base = HKEY_CURRENT_USER);
710 ~CRegRect(void);
712 CRegRect& operator=(const CRect& rhs) {CRegTypedBase<CRect, CRegBase>::operator =(rhs); return *this;}
713 operator LPCRECT() { return (LPCRECT)(CRect)*this; }
714 operator LPRECT() { return (LPRECT)(CRect)*this; }
715 CRegRect& operator+=(POINT r) { return *this = (CRect)*this + r;}
716 CRegRect& operator+=(SIZE r) { return *this = (CRect)*this + r;}
717 CRegRect& operator+=(LPCRECT r) { return *this = (CRect)*this + r;}
718 CRegRect& operator-=(POINT r) { return *this = (CRect)*this - r;}
719 CRegRect& operator-=(SIZE r) { return *this = (CRect)*this - r;}
720 CRegRect& operator-=(LPCRECT r) { return *this = (CRect)*this - r;}
722 CRegRect& operator&=(CRect r) { return *this = r & *this;}
723 CRegRect& operator|=(CRect r) { return *this = r | *this;}
725 #endif
728 * \ingroup Utils
729 * CPoint value in registry. with this class you can use CPoint values in registry
730 * almost like normal CPoint variables in your program.
731 * Usage:
732 * in your header file, declare your registry CPoint variable:
733 * \code
734 * CRegPoint regvalue;
735 * \endcode
736 * next initialize the variable e.g. in the constructor of your class:
737 * \code
738 * regvalue = CRegPoint("Software\\Company\\SubKey\\MyValue", CPoint(100,100));
739 * \endcode
740 * this will set the registry value "MyValue" under HKEY_CURRENT_USER with path
741 * "Software\Company\SubKey" to the variable. If the key does not yet exist or
742 * an error occurred during read from the registry, a default
743 * value of 100,100 is used when accessing the variable.
744 * now the variable can be used like any other CPoint variable:
745 * \code
746 * regvalue = CPoint(40,20); //stores the value in the registry
747 * CPoint temp = regvalue + CPoint(1,1);
748 * temp += CSize(5,5);
749 * \endcode
750 * to use the normal methods of the CPoint class, just typecast the CRegPoint to a CPoint
751 * and do whatever you want with the point:
752 * \code
753 * ((CRect)regvalue).Offset(100,10);
754 * \endcode
755 * please be aware that in the above example the change in the CPoint won't be written
756 * to the registry! To force a write use the write() method. A write() is only needed
757 * if you change the CPoint with Methods not overloaded by CRegPoint.
758 * to avoid too much access to the registry the value is cached inside the object.
759 * once the value is read, no more read accesses to the registry will be made.
760 * this means the variable will contain a wrong value if the corresponding registry
761 * entry is changed by anything else than this variable! If you think that could happen
762 * then use
763 * \code
764 * regvalue.read();
765 * \endcode
766 * to force a refresh of the variable with the registry.
767 * a write to the registry is only made if the new value assigned with the variable
768 * is different than the last assigned value.
769 * to force a write use the method write();
770 * another option to force reads and writes to the registry is to specify TRUE as the
771 * third parameter in the constructor.
774 #ifdef __ATLTYPES_H__ // defines CPoint
775 class CRegPoint : public CRegTypedBase<CPoint, CRegBase>
777 private:
780 * provide type-specific code to extract data from and write data to an open registry key.
783 virtual void InternalRead (HKEY hKey, CPoint& value);
784 virtual void InternalWrite (HKEY hKey, const CPoint& value);
786 public:
787 CRegPoint();
789 * Constructor.
790 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
791 * \param def the default value used when the key does not exist or a read error occurred
792 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
793 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
795 CRegPoint(const CString& key, const CPoint& def = CPoint(), bool force = false, HKEY base = HKEY_CURRENT_USER);
796 ~CRegPoint(void);
798 CRegPoint& operator=(const CPoint& rhs) {CRegTypedBase<CPoint, CRegBase>::operator =(rhs); return *this;}
799 CRegPoint& operator+=(CPoint p) { return *this = p + *this; }
800 CRegPoint& operator-=(CPoint p) { return *this = p - *this; }
802 #endif
805 * \ingroup Utils
806 * Manages a registry key (not a value). Provides methods to create and remove the
807 * key and to query the list of values and sub keys.
810 #ifdef __AFXCOLL_H__ // defines CStringList
811 class CRegistryKey
813 public: //methods
815 * Constructor.
816 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey"
817 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
819 CRegistryKey(const CString& key, HKEY base = HKEY_CURRENT_USER);
820 ~CRegistryKey();
823 * Creates the registry key if it does not already exist.
824 * \return ERROR_SUCCESS or an nonzero error code. Use FormatMessage() to get an error description.
826 DWORD createKey();
828 * Removes the whole registry key including all values. So if you set the registry
829 * entry to be HKCU\Software\Company\Product\key there will only be
830 * HKCU\Software\Company\Product key in the registry.
831 * \return ERROR_SUCCESS or an nonzero error code. Use FormatMessage() to get an error description.
833 DWORD removeKey();
835 bool getValues(CStringList& values); ///< returns the list of values
836 bool getSubKeys(CStringList& subkeys); ///< returns the list of sub keys
838 public: //members
839 HKEY m_base; ///< handle to the registry base
840 HKEY m_hKey; ///< handle to the open registry key
841 CString m_path; ///< the path to the key
843 #endif
846 * Instantiate templates for common (data type, string type) combinations.
849 #ifdef __CSTRINGT_H__
850 CRegDWORDCommon<CRegBase>;
851 typedef CRegDWORDCommon<CRegBase> CRegDWORD;
852 CRegStringCommon<CRegBase>;
853 typedef CRegStringCommon<CRegBase> CRegString;
854 #endif
856 CRegDWORDCommon<CRegStdBase>;
857 typedef CRegDWORDCommon<CRegStdBase> CRegStdWORD;
858 typedef CRegDWORDCommon<CRegStdBase> CRegStdDWORD;
859 CRegStringCommon<CRegStdBase>;
860 typedef CRegStringCommon<CRegStdBase> CRegStdString;