Fixed Issue #395: [BUG] Infomation error when "Switch the comparison"
[TortoiseGit.git] / src / Utils / registry.h
blob3349e5299f1c0de0ce2f176a8461c62bb6ae005a
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"
23 #include "tstring.h"
25 #ifndef ASSERT
26 #define ASSERT(x)
27 #endif
29 /**
30 * \ingroup Utils
31 * Base class for the registry classes.
33 * \par requirements
34 * - win98 or later, win2k or later, win95 with IE4 or later, winNT4 with IE4 or later
35 * - import library Shlwapi.lib
38 template<class S>
39 class CRegBaseCommon
41 protected:
43 /**
44 * String type specific operations.
47 virtual LPCTSTR GetPlainString (const S& s) const = 0;
48 virtual DWORD GetLength (const S& s) const = 0;
50 public: //methods
52 /** Default constructor.
54 CRegBaseCommon();
55 /**
56 * Constructor.
57 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
58 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
59 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
61 CRegBaseCommon(const S& key, bool force, HKEY base = HKEY_CURRENT_USER);
63 /**
64 * Removes the whole registry key including all values. So if you set the registry
65 * entry to be HKCU\Software\Company\Product\key\value there will only be
66 * HKCU\Software\Company\Product key in the registry.
67 * \return ERROR_SUCCESS or an nonzero error code. Use FormatMessage() to get an error description.
69 DWORD removeKey();
70 /**
71 * Removes the value of the registry object. If you set the registry entry to
72 * be HKCU\Software\Company\Product\key\value there will only be
73 * HKCU\Software\Company\Product\key\ in the registry.
74 * \return ERROR_SUCCESS or an nonzero error code. Use FormatMessage() to get an error description.
76 LONG removeValue();
78 /**
79 * Returns the string of the last error occurred.
81 virtual S getErrorString()
83 LPVOID lpMsgBuf;
85 FormatMessage(
86 FORMAT_MESSAGE_ALLOCATE_BUFFER |
87 FORMAT_MESSAGE_FROM_SYSTEM |
88 FORMAT_MESSAGE_IGNORE_INSERTS,
89 NULL,
90 LastError,
91 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
92 (LPTSTR) &lpMsgBuf,
93 0, NULL );
95 return (LPCTSTR)lpMsgBuf;
98 public:
100 typedef S StringT; ///< used in subclass templates to specify the correct string type
102 //members
103 HKEY m_base; ///< handle to the registry base
104 S m_key; ///< the name of the value
105 S m_path; ///< the path to the key
106 LONG LastError; ///< the value of the last error occurred
108 bool m_read; ///< indicates if the value has already been read from the registry
109 bool m_force; ///< indicates if no cache should be used, i.e. always read and write directly from registry
110 bool m_exists; ///< true, if the registry actually exists
113 // implement CRegBaseCommon<> members
115 template<class S>
116 CRegBaseCommon<S>::CRegBaseCommon()
117 : m_base (HKEY_CURRENT_USER)
118 , m_key()
119 , m_path()
120 , LastError (ERROR_SUCCESS)
121 , m_read (false)
122 , m_force (false)
123 , m_exists (false)
127 template<class S>
128 CRegBaseCommon<S>::CRegBaseCommon (const S& key, bool force, HKEY base)
129 : m_base (base)
130 , m_key (key)
131 , m_path()
132 , LastError (ERROR_SUCCESS)
133 , m_read (false)
134 , m_force (force)
135 , m_exists (false)
139 template<class S>
140 DWORD CRegBaseCommon<S>::removeKey()
142 m_exists = false;
143 m_read = true;
145 HKEY hKey = NULL;
146 RegOpenKeyEx (m_base, GetPlainString (m_path), 0, KEY_WRITE, &hKey);
147 return SHDeleteKey(m_base, GetPlainString (m_path));
150 template<class S>
151 LONG CRegBaseCommon<S>::removeValue()
153 m_exists = false;
154 m_read = true;
156 HKEY hKey = NULL;
157 RegOpenKeyEx(m_base, GetPlainString (m_path), 0, KEY_WRITE, &hKey);
158 return RegDeleteValue(hKey, GetPlainString (m_key));
162 * \ingroup Utils
163 * Base class for MFC type registry classes.
166 #ifdef __CSTRINGT_H__
167 class CRegBase : public CRegBaseCommon<CString>
169 protected:
172 * String type specific operations.
175 virtual LPCTSTR GetPlainString (const CString& s) const {return (LPCTSTR)s;}
176 virtual DWORD GetLength (const CString& s) const {return s.GetLength();}
178 public: //methods
180 /** Default constructor.
182 CRegBase();
184 * Constructor.
185 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
186 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
187 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
189 CRegBase(const CString& key, bool force, HKEY base = HKEY_CURRENT_USER);
192 * Returns the string of the last error occurred.
194 CString getErrorString()
196 CString error = CRegBaseCommon<CString>::getErrorString();
197 #if defined IDS_REG_ERROR
198 CString sTemp;
199 sTemp.Format(IDS_REG_ERROR, (LPCTSTR)m_key, (LPCTSTR)error);
200 return sTemp;
201 #else
202 return error;
203 #endif
206 #endif
208 typedef std::wstring wide_string;
209 #ifndef stdstring
210 # ifdef UNICODE
211 # define stdstring wide_string
212 # else
213 # define stdstring std::string
214 # endif
215 #endif
218 * \ingroup Utils
219 * Base class for STL string type registry classes.
222 class CRegStdBase : public CRegBaseCommon<stdstring>
224 protected:
227 * String type specific operations.
230 virtual LPCTSTR GetPlainString (const stdstring& s) const {return s.c_str();}
231 virtual DWORD GetLength (const stdstring& s) const {return static_cast<DWORD>(s.size());}
233 public: //methods
235 /** Default constructor.
237 CRegStdBase();
239 * Constructor.
240 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
241 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
242 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
244 CRegStdBase(const stdstring& key, bool force, HKEY base = HKEY_CURRENT_USER);
248 * \ingroup Utils
249 * DWORD value in registry. with this class you can use DWORD values in registry
250 * like normal DWORD variables in your program.
251 * Usage:
252 * in your header file, declare your registry DWORD variable:
253 * \code
254 * CRegDWORD regvalue;
255 * \endcode
256 * next initialize the variable e.g. in the constructor of your class:
257 * \code
258 * regvalue = CRegDWORD("Software\\Company\\SubKey\\MyValue", 100);
259 * \endcode
260 * this will set the registry value "MyValue" under HKEY_CURRENT_USER with path
261 * "Software\Company\SubKey" to the variable. If the key does not yet exist or
262 * an error occurred during read from the registry, a default
263 * value of 100 is used when accessing the variable.
264 * now the variable can be used like any other DWORD variable:
265 * \code
266 * regvalue = 200; //stores the value 200 in the registry
267 * int temp = regvalue + 300; //temp has value 500 now
268 * regvalue += 300; //now the registry has the value 500 too
269 * \endcode
270 * to avoid too much access to the registry the value is cached inside the object.
271 * once the value is read, no more read accesses to the registry will be made.
272 * this means the variable will contain a wrong value if the corresponding registry
273 * entry is changed by anything else than this variable! If you think that could happen
274 * then use
275 * \code
276 * regvalue.read();
277 * \endcode
278 * to force a refresh of the variable with the registry.
279 * a write to the registry is only made if the new value assigned with the variable
280 * is different than the last assigned value.
281 * to force a write use the method write();
282 * another option to force reads and writes to the registry is to specify TRUE as the
283 * third parameter in the constructor.
285 template<class T, class Base>
286 class CRegTypedBase : public Base
288 private:
290 T m_value; ///< the cached value of the registry
291 T m_defaultvalue; ///< the default value to use
294 * sub-classes must provide type-specific code to extract data from
295 * and write data to an open registry key.
298 virtual void InternalRead (HKEY hKey, T& value) = 0;
299 virtual void InternalWrite (HKEY hKey, const T& value) = 0;
301 public:
304 * We use this instead of a default constructor because not all
305 * data types may provide an adequate default constructor.
307 CRegTypedBase(const T& def);
310 * Constructor.
311 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
312 * \param def the default value used when the key does not exist or a read error occurred
313 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
314 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
316 CRegTypedBase(const typename Base::StringT& key, const T& def, bool force = FALSE, HKEY base = HKEY_CURRENT_USER);
319 * reads the assigned value from the registry. Use this method only if you think the registry
320 * value could have been altered without using the CRegDWORD object.
321 * \return the read value
323 void read(); ///< reads the value from the registry
324 void write(); ///< writes the value to the registry
327 * Data access.
330 operator const T&();
331 CRegTypedBase<T,Base>& operator=(const T& rhs);
334 // implement CRegTypedBase<> members
336 template<class T, class Base>
337 CRegTypedBase<T, Base>::CRegTypedBase (const T& def)
338 : m_value (def)
339 , m_defaultvalue (def)
343 template<class T, class Base>
344 CRegTypedBase<T, Base>::CRegTypedBase (const typename Base::StringT& key, const T& def, bool force, HKEY base)
345 : Base (key, force, base)
346 , m_value (def)
347 , m_defaultvalue (def)
351 template<class T, class Base>
352 void CRegTypedBase<T, Base>::read()
354 m_value = m_defaultvalue;
355 m_exists = false;
357 HKEY hKey = NULL;
358 if ((LastError = RegOpenKeyEx (m_base, GetPlainString (m_path), 0, KEY_EXECUTE, &hKey))==ERROR_SUCCESS)
360 m_read = true;
362 T value = m_defaultvalue;
363 InternalRead (hKey, value);
365 if (LastError ==ERROR_SUCCESS)
367 m_exists = true;
368 m_value = value;
371 LastError = RegCloseKey(hKey);
375 template<class T, class Base>
376 void CRegTypedBase<T, Base>::write()
378 HKEY hKey = NULL;
380 DWORD disp = 0;
381 if ((LastError = RegCreateKeyEx(m_base, GetPlainString (m_path), 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &disp))!=ERROR_SUCCESS)
383 return;
386 InternalWrite (hKey, m_value);
387 if (LastError ==ERROR_SUCCESS)
389 m_read = true;
390 m_exists = true;
392 LastError = RegCloseKey(hKey);
396 template<class T, class Base>
397 CRegTypedBase<T, Base>::operator const T&()
399 if ((m_read)&&(!m_force))
401 LastError = 0;
403 else
405 read();
408 return m_value;
411 template<class T, class Base>
412 CRegTypedBase<T, Base>& CRegTypedBase<T, Base>::operator =(const T& d)
414 if ((d==m_value)&&(!m_force))
416 //no write to the registry required, its the same value
417 LastError = 0;
418 return *this;
420 m_value = d;
421 write();
422 return *this;
426 * \ingroup Utils
427 * DWORD value in registry. with this class you can use DWORD values in registry
428 * like normal DWORD variables in your program.
429 * Usage:
430 * in your header file, declare your registry DWORD variable:
431 * \code
432 * CRegDWORD regvalue;
433 * \endcode
434 * next initialize the variable e.g. in the constructor of your class:
435 * \code
436 * regvalue = CRegDWORD("Software\\Company\\SubKey\\MyValue", 100);
437 * \endcode
438 * this will set the registry value "MyValue" under HKEY_CURRENT_USER with path
439 * "Software\Company\SubKey" to the variable. If the key does not yet exist or
440 * an error occurred during read from the registry, a default
441 * value of 100 is used when accessing the variable.
442 * now the variable can be used like any other DWORD variable:
443 * \code
444 * regvalue = 200; //stores the value 200 in the registry
445 * int temp = regvalue + 300; //temp has value 500 now
446 * regvalue += 300; //now the registry has the value 500 too
447 * \endcode
448 * to avoid too much access to the registry the value is cached inside the object.
449 * once the value is read, no more read accesses to the registry will be made.
450 * this means the variable will contain a wrong value if the corresponding registry
451 * entry is changed by anything else than this variable! If you think that could happen
452 * then use
453 * \code
454 * regvalue.read();
455 * \endcode
456 * to force a refresh of the variable with the registry.
457 * a write to the registry is only made if the new value assigned with the variable
458 * is different than the last assigned value.
459 * to force a write use the method write();
460 * another option to force reads and writes to the registry is to specify TRUE as the
461 * third parameter in the constructor.
463 template<class Base>
464 class CRegDWORDCommon : public CRegTypedBase<DWORD,Base>
466 private:
469 * provide type-specific code to extract data from and write data to an open registry key.
472 virtual void InternalRead (HKEY hKey, DWORD& value);
473 virtual void InternalWrite (HKEY hKey, const DWORD& value);
475 public:
477 CRegDWORDCommon(void);
479 * Constructor.
480 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
481 * \param def the default value used when the key does not exist or a read error occurred
482 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
483 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
485 CRegDWORDCommon(const typename Base::StringT& key, DWORD def = 0, bool force = false, HKEY base = HKEY_CURRENT_USER);
487 CRegDWORDCommon& operator=(DWORD rhs) {CRegTypedBase<DWORD, Base>::operator =(rhs); return *this;}
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;}
497 CRegDWORDCommon& operator^=(DWORD d) { return *this = *this ^ d;}
500 // implement CRegDWORDCommon<> methods
502 template<class Base>
503 CRegDWORDCommon<Base>::CRegDWORDCommon(void)
504 : CRegTypedBase<DWORD, Base>(0)
508 template<class Base>
509 CRegDWORDCommon<Base>::CRegDWORDCommon(const typename Base::StringT& key, DWORD def, bool force, HKEY base)
510 : CRegTypedBase<DWORD, Base> (key, def, force, base)
512 read();
515 template<class Base>
516 void CRegDWORDCommon<Base>::InternalRead (HKEY hKey, DWORD& value)
518 DWORD size = sizeof(value);
519 DWORD type = 0;
520 if ((LastError = RegQueryValueEx(hKey, GetPlainString (m_key), NULL, &type, (BYTE*) &value, &size))==ERROR_SUCCESS)
522 ASSERT(type==REG_DWORD);
526 template<class Base>
527 void CRegDWORDCommon<Base>::InternalWrite (HKEY hKey, const DWORD& value)
529 LastError = RegSetValueEx (hKey, GetPlainString (m_key), 0, REG_DWORD,(const BYTE*) &value, sizeof(value));
533 * \ingroup Utils
534 * CString value in registry. with this class you can use CString values in registry
535 * almost like normal CString variables in your program.
536 * Usage:
537 * in your header file, declare your registry CString variable:
538 * \code
539 * CRegString regvalue;
540 * \endcode
541 * next initialize the variable e.g. in the constructor of your class:
542 * \code
543 * regvalue = CRegString("Software\\Company\\SubKey\\MyValue", "default");
544 * \endcode
545 * this will set the registry value "MyValue" under HKEY_CURRENT_USER with path
546 * "Software\Company\SubKey" to the variable. If the key does not yet exist or
547 * an error occurred during read from the registry, a default
548 * value of "default" is used when accessing the variable.
549 * now the variable can be used like any other CString variable:
550 * \code
551 * regvalue = "some string"; //stores the value "some string" in the registry
552 * CString temp = regvalue + "!!"; //temp has value "some string!!" now
553 * \endcode
554 * to use the normal methods of the CString class, just typecast the CRegString to a CString
555 * and do whatever you want with the string:
556 * \code
557 * ((CString)regvalue).GetLength();
558 * ((CString)regvalue).Trim();
559 * \endcode
560 * please be aware that in the second line the change in the string won't be written
561 * to the registry! To force a write use the write() method. A write() is only needed
562 * if you change the String with Methods not overloaded by CRegString.
563 * to avoid too much access to the registry the value is cached inside the object.
564 * once the value is read, no more read accesses to the registry will be made.
565 * this means the variable will contain a wrong value if the corresponding registry
566 * entry is changed by anything else than this variable! If you think that could happen
567 * then use
568 * \code
569 * regvalue.read();
570 * \endcode
571 * to force a refresh of the variable with the registry.
572 * a write to the registry is only made if the new value assigned with the variable
573 * is different than the last assigned value.
574 * to force a write use the method write();
575 * another option to force reads and writes to the registry is to specify TRUE as the
576 * third parameter in the constructor.
578 template<class Base>
579 class CRegStringCommon : public CRegTypedBase<typename Base::StringT, Base>
581 private:
584 * provide type-specific code to extract data from and write data to an open registry key.
587 virtual void InternalRead (HKEY hKey, typename Base::StringT& value);
588 virtual void InternalWrite (HKEY hKey, const typename Base::StringT& value);
590 public:
591 CRegStringCommon();
593 * Constructor.
594 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
595 * \param def the default value used when the key does not exist or a read error occurred
596 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
597 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
599 CRegStringCommon(const typename Base::StringT& key, const typename Base::StringT& def = _T(""), bool force = false, HKEY base = HKEY_CURRENT_USER);
601 CRegStringCommon& operator=(const typename Base::StringT& rhs) {CRegTypedBase<StringT, Base>::operator =(rhs); return *this;}
602 CRegStringCommon& operator+=(const typename Base::StringT& s) { return *this = (typename Base::StringT)*this + s; }
605 // implement CRegDWORD<> methods
607 template<class Base>
608 CRegStringCommon<Base>::CRegStringCommon(void)
609 : CRegTypedBase<typename Base::StringT, Base>(typename Base::StringT())
613 template<class Base>
614 CRegStringCommon<Base>::CRegStringCommon(const typename Base::StringT& key, const typename Base::StringT& def, bool force, HKEY base)
615 : CRegTypedBase<typename Base::StringT, Base> (key, def, force, base)
617 read();
620 template<class Base>
621 void CRegStringCommon<Base>::InternalRead (HKEY hKey, typename Base::StringT& value)
623 DWORD size = 0;
624 DWORD type = 0;
625 LastError = RegQueryValueEx(hKey, GetPlainString (m_key), NULL, &type, NULL, &size);
627 std::auto_ptr<TCHAR> pStr (new TCHAR[size]);
628 if ((LastError = RegQueryValueEx(hKey, GetPlainString (m_key), NULL, &type, (BYTE*) pStr.get(), &size))==ERROR_SUCCESS)
630 ASSERT(type==REG_SZ || type==REG_EXPAND_SZ);
631 value = StringT (pStr.get());
635 template<class Base>
636 void CRegStringCommon<Base>::InternalWrite (HKEY hKey, const typename Base::StringT& value)
638 LastError = RegSetValueEx(hKey, GetPlainString (m_key), 0, REG_SZ, (BYTE *)GetPlainString (value), (GetLength(value)+1)*sizeof (TCHAR));
642 * \ingroup Utils
643 * CRect value in registry. with this class you can use CRect values in registry
644 * almost like normal CRect variables in your program.
645 * Usage:
646 * in your header file, declare your registry CString variable:
647 * \code
648 * CRegRect regvalue;
649 * \endcode
650 * next initialize the variable e.g. in the constructor of your class:
651 * \code
652 * regvalue = CRegRect("Software\\Company\\SubKey\\MyValue", CRect(100,100,200,200));
653 * \endcode
654 * this will set the registry value "MyValue" under HKEY_CURRENT_USER with path
655 * "Software\Company\SubKey" to the variable. If the key does not yet exist or
656 * an error occurred during read from the registry, a default
657 * value of 100,100,200,200 is used when accessing the variable.
658 * now the variable can be used like any other CRect variable:
659 * \code
660 * regvalue = CRect(40,20,300,500); //stores the value in the registry
661 * CRect temp = regvalue + CPoint(1,1);
662 * temp |= CSize(5,5);
663 * \endcode
664 * to use the normal methods of the CRect class, just typecast the CRegRect to a CRect
665 * and do whatever you want with the rect:
666 * \code
667 * ((CRect)regvalue).MoveToX(100);
668 * ((CRect)regvalue).DeflateRect(10,10);
669 * \endcode
670 * please be aware that in the second line the change in the CRect won't be written
671 * to the registry! To force a write use the write() method. A write() is only needed
672 * if you change the CRect with Methods not overloaded by CRegRect.
673 * to avoid too much access to the registry the value is cached inside the object.
674 * once the value is read, no more read accesses to the registry will be made.
675 * this means the variable will contain a wrong value if the corresponding registry
676 * entry is changed by anything else than this variable! If you think that could happen
677 * then use
678 * \code
679 * regvalue.read();
680 * \endcode
681 * to force a refresh of the variable with the registry.
682 * a write to the registry is only made if the new value assigned with the variable
683 * is different than the last assigned value.
684 * to force a write use the method write();
685 * another option to force reads and writes to the registry is to specify TRUE as the
686 * third parameter in the constructor.
689 #ifdef __ATLTYPES_H__ // defines CRect
690 class CRegRect : public CRegTypedBase<CRect, CRegBase>
692 private:
695 * provide type-specific code to extract data from and write data to an open registry key.
698 virtual void InternalRead (HKEY hKey, CRect& value);
699 virtual void InternalWrite (HKEY hKey, const CRect& value);
701 public:
702 CRegRect();
704 * Constructor.
705 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
706 * \param def the default value used when the key does not exist or a read error occurred
707 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
708 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
710 CRegRect(const CString& key, const CRect& def = CRect(), bool force = false, HKEY base = HKEY_CURRENT_USER);
711 ~CRegRect(void);
713 CRegRect& operator=(const CRect& rhs) {CRegTypedBase<CRect, CRegBase>::operator =(rhs); return *this;}
714 operator LPCRECT() { return (LPCRECT)(CRect)*this; }
715 operator LPRECT() { return (LPRECT)(CRect)*this; }
716 CRegRect& operator+=(POINT r) { return *this = (CRect)*this + r;}
717 CRegRect& operator+=(SIZE r) { return *this = (CRect)*this + r;}
718 CRegRect& operator+=(LPCRECT r) { return *this = (CRect)*this + r;}
719 CRegRect& operator-=(POINT r) { return *this = (CRect)*this - r;}
720 CRegRect& operator-=(SIZE r) { return *this = (CRect)*this - r;}
721 CRegRect& operator-=(LPCRECT r) { return *this = (CRect)*this - r;}
723 CRegRect& operator&=(CRect r) { return *this = r & *this;}
724 CRegRect& operator|=(CRect r) { return *this = r | *this;}
726 #endif
729 * \ingroup Utils
730 * CPoint value in registry. with this class you can use CPoint values in registry
731 * almost like normal CPoint variables in your program.
732 * Usage:
733 * in your header file, declare your registry CPoint variable:
734 * \code
735 * CRegPoint regvalue;
736 * \endcode
737 * next initialize the variable e.g. in the constructor of your class:
738 * \code
739 * regvalue = CRegPoint("Software\\Company\\SubKey\\MyValue", CPoint(100,100));
740 * \endcode
741 * this will set the registry value "MyValue" under HKEY_CURRENT_USER with path
742 * "Software\Company\SubKey" to the variable. If the key does not yet exist or
743 * an error occurred during read from the registry, a default
744 * value of 100,100 is used when accessing the variable.
745 * now the variable can be used like any other CPoint variable:
746 * \code
747 * regvalue = CPoint(40,20); //stores the value in the registry
748 * CPoint temp = regvalue + CPoint(1,1);
749 * temp += CSize(5,5);
750 * \endcode
751 * to use the normal methods of the CPoint class, just typecast the CRegPoint to a CPoint
752 * and do whatever you want with the point:
753 * \code
754 * ((CRect)regvalue).Offset(100,10);
755 * \endcode
756 * please be aware that in the above example the change in the CPoint won't be written
757 * to the registry! To force a write use the write() method. A write() is only needed
758 * if you change the CPoint with Methods not overloaded by CRegPoint.
759 * to avoid too much access to the registry the value is cached inside the object.
760 * once the value is read, no more read accesses to the registry will be made.
761 * this means the variable will contain a wrong value if the corresponding registry
762 * entry is changed by anything else than this variable! If you think that could happen
763 * then use
764 * \code
765 * regvalue.read();
766 * \endcode
767 * to force a refresh of the variable with the registry.
768 * a write to the registry is only made if the new value assigned with the variable
769 * is different than the last assigned value.
770 * to force a write use the method write();
771 * another option to force reads and writes to the registry is to specify TRUE as the
772 * third parameter in the constructor.
775 #ifdef __ATLTYPES_H__ // defines CPoint
776 class CRegPoint : public CRegTypedBase<CPoint, CRegBase>
778 private:
781 * provide type-specific code to extract data from and write data to an open registry key.
784 virtual void InternalRead (HKEY hKey, CPoint& value);
785 virtual void InternalWrite (HKEY hKey, const CPoint& value);
787 public:
788 CRegPoint();
790 * Constructor.
791 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
792 * \param def the default value used when the key does not exist or a read error occurred
793 * \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
794 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
796 CRegPoint(const CString& key, const CPoint& def = CPoint(), bool force = false, HKEY base = HKEY_CURRENT_USER);
797 ~CRegPoint(void);
799 CRegPoint& operator=(const CPoint& rhs) {CRegTypedBase<CPoint, CRegBase>::operator =(rhs); return *this;}
800 CRegPoint& operator+=(CPoint p) { return *this = p + *this; }
801 CRegPoint& operator-=(CPoint p) { return *this = p - *this; }
803 #endif
806 * \ingroup Utils
807 * Manages a registry key (not a value). Provides methods to create and remove the
808 * key and to query the list of values and sub keys.
811 #ifdef __AFXCOLL_H__ // defines CStringList
812 class CRegistryKey
814 public: //methods
816 * Constructor.
817 * \param key the path to the key, including the key. example: "Software\\Company\\SubKey"
818 * \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
820 CRegistryKey(const CString& key, HKEY base = HKEY_CURRENT_USER);
821 ~CRegistryKey();
824 * Creates the registry key if it does not already exist.
825 * \return ERROR_SUCCESS or an nonzero error code. Use FormatMessage() to get an error description.
827 DWORD createKey();
829 * Removes the whole registry key including all values. So if you set the registry
830 * entry to be HKCU\Software\Company\Product\key there will only be
831 * HKCU\Software\Company\Product key in the registry.
832 * \return ERROR_SUCCESS or an nonzero error code. Use FormatMessage() to get an error description.
834 DWORD removeKey();
836 bool getValues(CStringList& values); ///< returns the list of values
837 bool getSubKeys(CStringList& subkeys); ///< returns the list of sub keys
839 public: //members
840 HKEY m_base; ///< handle to the registry base
841 HKEY m_hKey; ///< handle to the open registry key
842 CString m_path; ///< the path to the key
844 #endif
847 * Instantiate templates for common (data type, string type) combinations.
850 #ifdef __CSTRINGT_H__
851 CRegDWORDCommon<CRegBase>;
852 typedef CRegDWORDCommon<CRegBase> CRegDWORD;
853 CRegStringCommon<CRegBase>;
854 typedef CRegStringCommon<CRegBase> CRegString;
855 #endif
857 CRegDWORDCommon<CRegStdBase>;
858 typedef CRegDWORDCommon<CRegStdBase> CRegStdWORD;
859 typedef CRegDWORDCommon<CRegStdBase> CRegStdDWORD;
860 CRegStringCommon<CRegStdBase>;
861 typedef CRegStringCommon<CRegStdBase> CRegStdString;