3 #include ".\AppSettings.h"
4 #include "../Common/AppSettingsData.h"
6 #include "../DasherCore/Event.h"
8 using namespace WinUTF8
;
11 CAppSettings::CAppSettings(Dasher::CDasher
*pDasher
, HWND hWnd
)
16 // Initialise registry stuff
18 // Windows requires strings as Tstring
19 Tstring TGroup
, TProduct
;
20 UTF8string_to_wstring("Inference Group", TGroup
);
21 UTF8string_to_wstring("Dasher3", TProduct
);
23 // Get hold of HKEY_CURRENT_USER\Software
25 if(GetOrCreate(HKEY_CURRENT_USER
, TEXT("Software"), KEY_WRITE
, &SoftwareKey
) != 0) {
26 // Can't open or create key - do something...
27 // Probably flag registry as failed and just return default options
28 exit(1); // give up for now.
31 // Then HKEY_CURRENT_USER\Software\<Group>
33 if(GetOrCreate(SoftwareKey
, TGroup
.c_str(), KEY_WRITE
, &GroupKey
) != 0) {
36 RegCloseKey(SoftwareKey
);
38 // Then HKEY_CURRENT_USER\Software\<Group>\<Product>
39 if(GetOrCreate(GroupKey
, TProduct
.c_str(), KEY_ALL_ACCESS
, &ProductKey
) != 0) {
42 RegCloseKey(GroupKey
);
47 m_pBoolTable
= new bp_info
[NUM_OF_APP_BPS
];
48 m_pLongTable
= new lp_info
[NUM_OF_APP_LPS
];
49 m_pStringTable
= new sp_info
[NUM_OF_APP_SPS
];
51 for(int ii
= 0; ii
< NUM_OF_APP_BPS
; ii
++) {
52 m_pBoolTable
[ii
].key
= app_boolparamtable
[ii
].key
;
53 if(!LoadSetting(app_boolparamtable
[ii
].regName
, &m_pBoolTable
[ii
].value
))
54 m_pBoolTable
[ii
].value
= app_boolparamtable
[ii
].bDefaultValue
;
55 m_pBoolTable
[ii
].defaultVal
= app_boolparamtable
[ii
].bDefaultValue
;
56 m_pBoolTable
[ii
].humanReadable
= app_boolparamtable
[ii
].humanReadable
;
57 m_pBoolTable
[ii
].persistent
= app_boolparamtable
[ii
].persistent
;
58 m_pBoolTable
[ii
].regName
= app_boolparamtable
[ii
].regName
;
61 for(int ii
= 0; ii
< NUM_OF_APP_LPS
; ii
++) {
62 m_pLongTable
[ii
].key
= app_longparamtable
[ii
].key
;
63 if(!LoadSetting(app_longparamtable
[ii
].regName
, &m_pLongTable
[ii
].value
))
64 m_pLongTable
[ii
].value
= app_longparamtable
[ii
].iDefaultValue
;
65 m_pLongTable
[ii
].defaultVal
= app_longparamtable
[ii
].iDefaultValue
;
66 m_pLongTable
[ii
].humanReadable
= app_longparamtable
[ii
].humanReadable
;
67 m_pLongTable
[ii
].persistent
= app_longparamtable
[ii
].persistent
;
68 m_pLongTable
[ii
].regName
= app_longparamtable
[ii
].regName
;
71 for(int ii
= 0; ii
< NUM_OF_APP_SPS
; ii
++) {
72 m_pStringTable
[ii
].key
= app_stringparamtable
[ii
].key
;
73 if(!LoadSetting(app_stringparamtable
[ii
].regName
, &m_pStringTable
[ii
].value
))
74 m_pStringTable
[ii
].value
= app_stringparamtable
[ii
].szDefaultValue
;
75 m_pStringTable
[ii
].defaultVal
= app_stringparamtable
[ii
].szDefaultValue
;
76 m_pStringTable
[ii
].humanReadable
= app_stringparamtable
[ii
].humanReadable
;
77 m_pStringTable
[ii
].persistent
= app_stringparamtable
[ii
].persistent
;
78 m_pStringTable
[ii
].regName
= app_stringparamtable
[ii
].regName
;
82 CAppSettings::~CAppSettings(void)
84 RegCloseKey(ProductKey
);
86 delete[] m_pBoolTable
;
87 delete[] m_pLongTable
;
88 delete[] m_pStringTable
;
91 bool CAppSettings::GetBoolParameter(int iParameter
) {
92 if( iParameter
< END_OF_BPS
)
93 return m_pDasher
->GetBoolParameter(iParameter
);
95 return m_pBoolTable
[iParameter
- FIRST_APP_BP
].value
;
98 void CAppSettings::SetBoolParameter(int iParameter
, bool bValue
) {
99 if( iParameter
< END_OF_BPS
)
100 m_pDasher
->SetBoolParameter(iParameter
, bValue
);
102 m_pBoolTable
[iParameter
- FIRST_APP_BP
].value
= bValue
;
103 SaveSetting(m_pBoolTable
[iParameter
- FIRST_APP_BP
].regName
, bValue
);
105 Dasher::CParameterNotificationEvent
oEvent(iParameter
);
106 SendMessage(m_hWnd
, WM_DASHER_EVENT
, 0, (LPARAM
)&oEvent
);
110 long CAppSettings::GetLongParameter(int iParameter
) {
111 if( iParameter
< END_OF_LPS
)
112 return m_pDasher
->GetLongParameter(iParameter
);
114 return m_pLongTable
[iParameter
- FIRST_APP_LP
].value
;
117 void CAppSettings::SetLongParameter(int iParameter
, long iValue
) {
118 if( iParameter
< END_OF_LPS
)
119 m_pDasher
->SetLongParameter(iParameter
, iValue
);
121 m_pLongTable
[iParameter
- FIRST_APP_LP
].value
= iValue
;
122 SaveSetting(m_pLongTable
[iParameter
- FIRST_APP_LP
].regName
, iValue
);
123 Dasher::CParameterNotificationEvent
oEvent(iParameter
);
124 SendMessage(m_hWnd
, WM_DASHER_EVENT
, 0, (LPARAM
)&oEvent
);
128 std::string
CAppSettings::GetStringParameter(int iParameter
) {
129 if(iParameter
< END_OF_SPS
)
130 return m_pDasher
->GetStringParameter(iParameter
);
132 return m_pStringTable
[iParameter
- FIRST_APP_SP
].value
;
135 void CAppSettings::SetStringParameter(int iParameter
, const std::string
&strValue
) {
136 if(iParameter
< END_OF_SPS
)
137 m_pDasher
->SetStringParameter(iParameter
, strValue
);
139 m_pStringTable
[iParameter
- FIRST_APP_SP
].value
= strValue
;
140 SaveSetting(m_pStringTable
[iParameter
- FIRST_APP_SP
].regName
, strValue
);
141 Dasher::CParameterNotificationEvent
oEvent(iParameter
);
142 SendMessage(m_hWnd
, WM_DASHER_EVENT
, 0, (LPARAM
)&oEvent
);
146 void CAppSettings::ResetParamater(int iParameter
) {
147 if(iParameter
< END_OF_SPS
)
148 m_pDasher
->ResetParameter(iParameter
);
149 else if(iParameter
< END_OF_APP_BPS
)
150 SetBoolParameter(iParameter
, app_boolparamtable
[iParameter
- FIRST_APP_BP
].bDefaultValue
);
151 else if(iParameter
< END_OF_APP_LPS
)
152 SetLongParameter(iParameter
, app_longparamtable
[iParameter
- FIRST_APP_LP
].iDefaultValue
);
154 SetStringParameter(iParameter
, app_stringparamtable
[iParameter
- FIRST_APP_SP
].szDefaultValue
);
158 // Functions for accessing persistent storage (stolen from WinOptions)
160 bool CAppSettings::LoadSetting(const std::string
&Key
, bool *Value
) {
162 UTF8string_to_wstring(Key
, TKey
);
165 if(!GetlpByte(TKey
, &Data
)) {
170 if((DWORD
) * Data
== 0)
179 /////////////////////////////////////////////////////////////////////////////
181 bool CAppSettings::LoadSetting(const std::string
&Key
, long *Value
) {
183 UTF8string_to_wstring(Key
, TKey
);
186 if(!GetlpByte(TKey
, &Data
)) {
191 // Evil casting to make sure I can retrieve signed longs, even
192 // though windows registry only stores +ve values.
193 *Value
= *((long *)Data
);
198 /////////////////////////////////////////////////////////////////////////////
200 bool CAppSettings::LoadSettingT(const std::string
&Key
, Tstring
*TValue
) {
202 UTF8string_to_wstring(Key
, TKey
);
205 if(!GetlpByte(TKey
, &Data
)) {
210 *TValue
= (TCHAR
*) Data
;
216 /////////////////////////////////////////////////////////////////////////////
218 bool CAppSettings::LoadSetting(const std::string
&Key
, std::string
*Value
) {
221 if(LoadSettingT(Key
, &str
)) {
222 wstring_to_UTF8string(str
, *Value
);
230 /////////////////////////////////////////////////////////////////////////////
232 static TCHAR FormatWindowPlacement
[] = TEXT("%u,%u,%d,%d,%d,%d,%d,%d,%d,%d");
234 /////////////////////////////////////////////////////////////////////////////
237 void CAppSettings::SaveSetting(const std::string
&Key
, const LPWINDOWPLACEMENT pwp
) {
238 DASHER_ASSERT(pwp
!= NULL
);
241 _stprintf(t
, FormatWindowPlacement
, pwp
->flags
, pwp
->showCmd
, pwp
->ptMinPosition
.x
, pwp
->ptMinPosition
.y
, pwp
->ptMaxPosition
.x
, pwp
->ptMaxPosition
.y
, pwp
->rcNormalPosition
.left
, pwp
->rcNormalPosition
.top
, pwp
->rcNormalPosition
.right
, pwp
->rcNormalPosition
.bottom
);
244 SaveSettingT(Key
, ts
);
248 /////////////////////////////////////////////////////////////////////////////
250 bool CAppSettings::LoadSetting(const std::string
&Key
, LPWINDOWPLACEMENT pwp
) {
251 DASHER_ASSERT(pwp
!= NULL
);
255 if(!LoadSettingT(Key
, &str
))
259 int nRead
= _stscanf(str
.c_str(), FormatWindowPlacement
,
260 &wp
.flags
, &wp
.showCmd
,
261 &wp
.ptMinPosition
.x
, &wp
.ptMinPosition
.y
,
262 &wp
.ptMaxPosition
.x
, &wp
.ptMaxPosition
.y
,
263 &wp
.rcNormalPosition
.left
, &wp
.rcNormalPosition
.top
,
264 &wp
.rcNormalPosition
.right
, &wp
.rcNormalPosition
.bottom
);
268 wp
.length
= sizeof(wp
);
276 /////////////////////////////////////////////////////////////////////////////
278 void CAppSettings::SaveSetting(const std::string
&Key
, bool Value
) {
280 SaveSetting(Key
, 1l);
282 SaveSetting(Key
, 0l);
285 /////////////////////////////////////////////////////////////////////////////
287 void CAppSettings::SaveSetting(const std::string
&Key
, long Value
) {
289 UTF8string_to_wstring(Key
, TKey
);
290 // Evil casting. Registry stores DWORD's (unsigned longs)
291 // I'm forcing in signed longs and if I force them out again in the same
292 // way I should get a sensible result.
293 DWORD
*RegValue
= (DWORD
*) & Value
;
294 DWORD MemAllow
= sizeof(DWORD
);
295 LONG ErrVal
= RegSetValueEx(ProductKey
, TKey
.c_str(), 0,
296 REG_DWORD
, (const unsigned char *)RegValue
, MemAllow
);
299 /////////////////////////////////////////////////////////////////////////////
301 void CAppSettings::SaveSettingT(const std::string
&Key
, const Tstring
&TValue
) {
303 UTF8string_to_wstring(Key
, TKey
);
305 DWORD MemAllow
= (TValue
.size() + 1) * sizeof(TCHAR
);
307 //const unsigned char* StrInput = (const unsigned char*) Value.c_str();
308 //LONG ErrVal = RegSetValueEx(ProductKey, TKey.c_str(), 0,
309 // REG_SZ, StrInput, MemAllow);
311 LONG ErrVal
= RegSetValueEx(ProductKey
, TKey
.c_str(), 0,
312 REG_SZ
, (CONST BYTE
*) TValue
.c_str(), MemAllow
);
316 /////////////////////////////////////////////////////////////////////////////
318 void CAppSettings::SaveSetting(const std::string
&Key
, const std::string
&Value
) {
320 // DJW20031107 - i think Values should also be converted to Tstring
322 UTF8string_to_wstring(Value
, TValue
);
324 SaveSettingT(Key
, TValue
);
327 // Used for getting a handle on the Dasher key in the constructor.
328 int CAppSettings::GetOrCreate(HKEY hKey
, LPCTSTR lpSubKey
, REGSAM samDesired
, HKEY
*lpNewKey
) {
329 if(!(RegOpenKeyEx(hKey
, lpSubKey
, 0, samDesired
, lpNewKey
) == ERROR_SUCCESS
)) {
331 if(!(RegCreateKeyEx(hKey
, lpSubKey
, 0, NULL
, REG_OPTION_NON_VOLATILE
, samDesired
, NULL
, lpNewKey
, NULL
) == ERROR_SUCCESS
)) {
339 bool CAppSettings::GetlpByte(const Tstring
&Key
, BYTE
**Data
) const {
341 unsigned long datasize
= sizeof(BYTE
[1]);
344 LONG ErrVal
= RegQueryValueEx(ProductKey
, Key
.c_str(), 0, &Type
, *Data
, &datasize
);
345 while(ErrVal
== ERROR_MORE_DATA
) {
347 *Data
= new BYTE
[datasize
];
348 ErrVal
= RegQueryValueEx(ProductKey
, Key
.c_str(), 0, &Type
, *Data
, &datasize
);
351 // Perhaps I should spend lots of time working out why the registry doesn't work.
352 // when this fails. Would probably just confuse users though. Users with a broken
353 // registry can live with defaults :)
354 if((ErrVal
== ERROR_SUCCESS
) && (*Data
!= 0))