Visual studio 2005 thinks that long long int is 64 bit. The difference between
[dasher.git] / Src / Win32 / AppSettings.cpp
blob0b2db41b129b79c2a6ca04e657e7a15137a3133c
1 #include "WinCommon.h"
3 #include ".\AppSettings.h"
4 #include "../Common/AppSettingsData.h"
5 #include ".\Dasher.h"
6 #include "../DasherCore/Event.h"
8 using namespace WinUTF8;
9 using namespace std;
11 CAppSettings::CAppSettings(Dasher::CDasher *pDasher, HWND hWnd)
13 m_hWnd = hWnd;
14 m_pDasher = pDasher;
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
24 HKEY SoftwareKey;
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>
32 HKEY GroupKey;
33 if(GetOrCreate(SoftwareKey, TGroup.c_str(), KEY_WRITE, &GroupKey) != 0) {
34 exit(1);
36 RegCloseKey(SoftwareKey);
38 // Then HKEY_CURRENT_USER\Software\<Group>\<Product>
39 if(GetOrCreate(GroupKey, TProduct.c_str(), KEY_ALL_ACCESS, &ProductKey) != 0) {
40 exit(1);
42 RegCloseKey(GroupKey);
44 // ---
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);
94 else
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);
101 else {
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);
113 else
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);
120 else {
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);
131 else
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);
138 else {
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);
153 else
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) {
161 Tstring TKey;
162 UTF8string_to_wstring(Key, TKey);
163 BYTE *Data = 0;
165 if(!GetlpByte(TKey, &Data)) {
166 delete[]Data;
167 return false;
170 if((DWORD) * Data == 0)
171 *Value = false;
172 else
173 *Value = true;
175 delete[]Data;
176 return true;
179 /////////////////////////////////////////////////////////////////////////////
181 bool CAppSettings::LoadSetting(const std::string &Key, long *Value) {
182 Tstring TKey;
183 UTF8string_to_wstring(Key, TKey);
184 BYTE *Data = 0;
186 if(!GetlpByte(TKey, &Data)) {
187 delete[]Data;
188 return false;
191 // Evil casting to make sure I can retrieve signed longs, even
192 // though windows registry only stores +ve values.
193 *Value = *((long *)Data);
194 delete[]Data;
195 return true;
198 /////////////////////////////////////////////////////////////////////////////
200 bool CAppSettings::LoadSettingT(const std::string &Key, Tstring *TValue) {
201 Tstring TKey;
202 UTF8string_to_wstring(Key, TKey);
203 BYTE *Data = 0;
205 if(!GetlpByte(TKey, &Data)) {
206 delete[]Data;
207 return false;
210 *TValue = (TCHAR *) Data;
211 delete[]Data;
213 return true;
216 /////////////////////////////////////////////////////////////////////////////
218 bool CAppSettings::LoadSetting(const std::string &Key, std::string *Value) {
220 Tstring str;
221 if(LoadSettingT(Key, &str)) {
222 wstring_to_UTF8string(str, *Value);
223 return true;
226 return false;
230 /////////////////////////////////////////////////////////////////////////////
232 static TCHAR FormatWindowPlacement[] = TEXT("%u,%u,%d,%d,%d,%d,%d,%d,%d,%d");
234 /////////////////////////////////////////////////////////////////////////////
235 #ifndef DASHER_WINCE
237 void CAppSettings::SaveSetting(const std::string &Key, const LPWINDOWPLACEMENT pwp) {
238 DASHER_ASSERT(pwp != NULL);
240 TCHAR t[200];
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);
243 Tstring ts(t);
244 SaveSettingT(Key, ts);
248 /////////////////////////////////////////////////////////////////////////////
250 bool CAppSettings::LoadSetting(const std::string &Key, LPWINDOWPLACEMENT pwp) {
251 DASHER_ASSERT(pwp != NULL);
253 Tstring str;
255 if(!LoadSettingT(Key, &str))
256 return false;
258 WINDOWPLACEMENT wp;
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);
266 if(nRead != 10)
267 return false;
268 wp.length = sizeof(wp);
270 *pwp = wp;
271 return true;
275 #endif
276 /////////////////////////////////////////////////////////////////////////////
278 void CAppSettings::SaveSetting(const std::string &Key, bool Value) {
279 if(Value)
280 SaveSetting(Key, 1l);
281 else
282 SaveSetting(Key, 0l);
285 /////////////////////////////////////////////////////////////////////////////
287 void CAppSettings::SaveSetting(const std::string &Key, long Value) {
288 Tstring TKey;
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) {
302 Tstring TKey;
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
321 Tstring TValue;
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)) {
333 return (1);
336 return 0;
339 bool CAppSettings::GetlpByte(const Tstring &Key, BYTE **Data) const {
340 *Data = new BYTE[1];
341 unsigned long datasize = sizeof(BYTE[1]);
342 DWORD Type;
344 LONG ErrVal = RegQueryValueEx(ProductKey, Key.c_str(), 0, &Type, *Data, &datasize);
345 while(ErrVal == ERROR_MORE_DATA) {
346 delete[] * 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))
355 return true;
356 else
357 return false;