[dasher: 138/217] XML settings implementation for Windows with '/Config file.xml' command line option.
- From: Patrick Welche <pwelche src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dasher: 138/217] XML settings implementation for Windows with '/Config file.xml' command line option.
- Date: Sat, 27 Feb 2016 12:11:55 +0000 (UTC)
commit cd31d2d696aa3c04b4ddc364ec903dab504c1dac
Author: unknown <lbaudoin google com>
Date: Tue Dec 8 20:57:16 2015 -0700
XML settings implementation for Windows with '/Config file.xml' command line option.
Src/DasherCore/DasherCore_vc2013.vcxproj | 2 +
Src/DasherCore/XmlSettingsStore.cpp | 14 ++-
Src/Win32/AppSettings.cpp | 312 +++---------------------------
Src/Win32/AppSettings.h | 57 +-----
Src/Win32/Common/WinOptions.cpp | 46 -----
Src/Win32/Common/WinOptions.h | 5 -
Src/Win32/Common/WinUTF8.cpp | 28 ++-
Src/Win32/Common/WinUTF8.h | 4 +
Src/Win32/Dasher.cpp | 4 +-
Src/Win32/Dasher.h | 2 +-
Src/Win32/DasherWindow.cpp | 38 +++-
Src/Win32/DasherWindow.h | 7 +-
Src/Win32/WinMain.cpp | 18 ++-
13 files changed, 125 insertions(+), 412 deletions(-)
---
diff --git a/Src/DasherCore/DasherCore_vc2013.vcxproj b/Src/DasherCore/DasherCore_vc2013.vcxproj
index 9a38ee8..eaa6149 100644
--- a/Src/DasherCore/DasherCore_vc2013.vcxproj
+++ b/Src/DasherCore/DasherCore_vc2013.vcxproj
@@ -284,6 +284,7 @@
<ClCompile Include="UserLogParam.cpp" />
<ClCompile Include="UserLogTrial.cpp" />
<ClCompile Include="WordGeneratorBase.cpp" />
+ <ClCompile Include="XmlSettingsStore.cpp" />
<ClCompile Include="XMLUtil.cpp" />
</ItemGroup>
<ItemGroup>
@@ -367,6 +368,7 @@
<ClInclude Include="UserLogParam.h" />
<ClInclude Include="UserLogTrial.h" />
<ClInclude Include="WordGeneratorBase.h" />
+ <ClInclude Include="XmlSettingsStore.h" />
<ClInclude Include="XMLUtil.h" />
</ItemGroup>
<ItemGroup>
diff --git a/Src/DasherCore/XmlSettingsStore.cpp b/Src/DasherCore/XmlSettingsStore.cpp
index f9a6914..02c212a 100644
--- a/Src/DasherCore/XmlSettingsStore.cpp
+++ b/Src/DasherCore/XmlSettingsStore.cpp
@@ -4,6 +4,16 @@
#include <fstream>
#include <string.h>
#include <algorithm>
+#include <locale>
+#include <codecvt>
+
+#if defined(_WIN32) || defined(_WIN64)
+#include "WinUTF8.h"
+#define strcasecmp _stricmp
+#define widen(a) WinUTF8::widen(a)
+#else
+#define widen((a)) (a)
+#endif
namespace Dasher {
namespace {
@@ -27,7 +37,7 @@ XmlSettingsStore::XmlSettingsStore(const std::string& filename,
bool XmlSettingsStore::Load() {
bool result = true;
- std::ifstream f(filename_);
+ std::ifstream f(widen(filename_));
if (f.good()) {
f.close();
if (!ParseFile(filename_, true /* user */)) {
@@ -88,7 +98,7 @@ bool XmlSettingsStore::Save() {
try {
modified_ = false;
std::ofstream out;
- out.open(filename_, std::ios::out | std::ios::trunc);
+ out.open(widen(filename_), std::ios::out | std::ios::trunc);
out << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
out << "<settings>\n";
for (const auto& p : long_settings_) {
diff --git a/Src/Win32/AppSettings.cpp b/Src/Win32/AppSettings.cpp
index 420ae24..a8f01b4 100644
--- a/Src/Win32/AppSettings.cpp
+++ b/Src/Win32/AppSettings.cpp
@@ -1,5 +1,7 @@
#include "WinCommon.h"
+#include <stdio.h>
+
#include ".\AppSettings.h"
#include "../Common/AppSettingsData.h"
#include ".\Dasher.h"
@@ -8,147 +10,49 @@
using namespace WinUTF8;
using namespace std;
-CAppSettings::CAppSettings(Dasher::CDasher *pDasher, HWND hWnd)
+CAppSettings::CAppSettings(Dasher::CDasher *pDasher, HWND hWnd, Dasher::CSettingsStore* settings_store) :
settings_store_(settings_store)
{
m_hWnd = hWnd;
m_pDasher = pDasher;
- // Initialise registry stuff
-
- // Windows requires strings as Tstring
- Tstring TGroup, TProduct;
- UTF8string_to_wstring("Inference Group", TGroup);
- UTF8string_to_wstring("Dasher3", TProduct);
-
- // Get hold of HKEY_CURRENT_USER\Software
- HKEY SoftwareKey;
- if(GetOrCreate(HKEY_CURRENT_USER, TEXT("Software"), KEY_WRITE, &SoftwareKey) != 0) {
- // Can't open or create key - do something...
- // Probably flag registry as failed and just return default options
- exit(1); // give up for now.
- }
-
- // Then HKEY_CURRENT_USER\Software\<Group>
- HKEY GroupKey;
- if(GetOrCreate(SoftwareKey, TGroup.c_str(), KEY_WRITE, &GroupKey) != 0) {
- exit(1);
- }
- RegCloseKey(SoftwareKey);
-
- // Then HKEY_CURRENT_USER\Software\<Group>\<Product>
- if(GetOrCreate(GroupKey, TProduct.c_str(), KEY_ALL_ACCESS, &ProductKey) != 0) {
- exit(1);
- }
- RegCloseKey(GroupKey);
-
- // ---
-
-
- m_pBoolTable = new bp_info[NUM_OF_APP_BPS];
- m_pLongTable = new lp_info[NUM_OF_APP_LPS];
- m_pStringTable = new sp_info[NUM_OF_APP_SPS];
-
- for(int ii = 0; ii < NUM_OF_APP_BPS; ii++) {
- m_pBoolTable[ii].key = app_boolparamtable[ii].key;
- if(!LoadSetting(app_boolparamtable[ii].regName, &m_pBoolTable[ii].value))
- m_pBoolTable[ii].value = app_boolparamtable[ii].defaultValue;
- m_pBoolTable[ii].defaultVal = app_boolparamtable[ii].defaultValue;
- m_pBoolTable[ii].humanReadable = app_boolparamtable[ii].humanReadable;
- m_pBoolTable[ii].persistent = app_boolparamtable[ii].persistent == Persistence::PERSISTENT;
- m_pBoolTable[ii].regName = app_boolparamtable[ii].regName;
- }
-
- for(int ii = 0; ii < NUM_OF_APP_LPS; ii++) {
- m_pLongTable[ii].key = app_longparamtable[ii].key;
- if(!LoadSetting(app_longparamtable[ii].regName, &m_pLongTable[ii].value))
- m_pLongTable[ii].value = app_longparamtable[ii].defaultValue;
- m_pLongTable[ii].defaultVal = app_longparamtable[ii].defaultValue;
- m_pLongTable[ii].humanReadable = app_longparamtable[ii].humanReadable;
- m_pLongTable[ii].persistent = app_longparamtable[ii].persistent == Persistence::PERSISTENT;
- m_pLongTable[ii].regName = app_longparamtable[ii].regName;
- }
-
- for(int ii = 0; ii < NUM_OF_APP_SPS; ii++) {
- m_pStringTable[ii].key = app_stringparamtable[ii].key;
- if(!LoadSetting(app_stringparamtable[ii].regName, &m_pStringTable[ii].value))
- m_pStringTable[ii].value = app_stringparamtable[ii].defaultValue;
- m_pStringTable[ii].defaultVal = app_stringparamtable[ii].defaultValue;
- m_pStringTable[ii].humanReadable = app_stringparamtable[ii].humanReadable;
- m_pStringTable[ii].persistent = app_stringparamtable[ii].persistent == Persistence::PERSISTENT;
- m_pStringTable[ii].regName = app_stringparamtable[ii].regName;
- }
+ settings_store_->AddParameters(app_boolparamtable, NUM_OF_APP_BPS);
+ settings_store_->AddParameters(app_longparamtable, NUM_OF_APP_LPS);
+ settings_store_->AddParameters(app_stringparamtable, NUM_OF_APP_SPS);
}
CAppSettings::~CAppSettings(void)
{
- RegCloseKey(ProductKey);
-
- delete[] m_pBoolTable;
- delete[] m_pLongTable;
- delete[] m_pStringTable;
}
bool CAppSettings::GetBoolParameter(int iParameter) {
- if( iParameter < END_OF_BPS )
- return m_pDasher->GetBoolParameter(iParameter);
- else
- return m_pBoolTable[iParameter - FIRST_APP_BP].value;
+ return settings_store_->GetBoolParameter(iParameter);
}
void CAppSettings::SetBoolParameter(int iParameter, bool bValue) {
- if( iParameter < END_OF_BPS )
- m_pDasher->SetBoolParameter(iParameter , bValue);
- else {
- m_pBoolTable[iParameter - FIRST_APP_BP].value = bValue;
- SaveSetting(m_pBoolTable[iParameter - FIRST_APP_BP].regName, bValue);
-
- m_pDasher->HandleEvent(iParameter);
- }
+ settings_store_->SetBoolParameter(iParameter, bValue);
+ m_pDasher->HandleEvent(iParameter);
}
long CAppSettings::GetLongParameter(int iParameter) {
- if( iParameter < END_OF_LPS)
- return m_pDasher->GetLongParameter(iParameter);
- else
- return m_pLongTable[iParameter - FIRST_APP_LP].value;
+ return settings_store_->GetLongParameter(iParameter);
}
void CAppSettings::SetLongParameter(int iParameter, long iValue) {
- if( iParameter < END_OF_LPS )
- m_pDasher->SetLongParameter(iParameter, iValue);
- else {
- m_pLongTable[iParameter - FIRST_APP_LP].value = iValue;
- SaveSetting(m_pLongTable[iParameter - FIRST_APP_LP].regName, iValue);
- m_pDasher->HandleEvent(iParameter);
- }
+ settings_store_->SetLongParameter(iParameter, iValue);
+ m_pDasher->HandleEvent(iParameter);
}
std::string CAppSettings::GetStringParameter(int iParameter) {
- if(iParameter < END_OF_SPS)
- return m_pDasher->GetStringParameter(iParameter);
- else
- return m_pStringTable[iParameter - FIRST_APP_SP].value;
+ return settings_store_->GetStringParameter(iParameter);
}
void CAppSettings::SetStringParameter(int iParameter, const std::string &strValue) {
- if(iParameter < END_OF_SPS)
- m_pDasher->SetStringParameter(iParameter, strValue);
- else {
- m_pStringTable[iParameter - FIRST_APP_SP].value = strValue;
- SaveSetting(m_pStringTable[iParameter - FIRST_APP_SP].regName, strValue);
- m_pDasher->HandleEvent(iParameter);
- }
+ settings_store_->SetStringParameter(iParameter, strValue);
+ m_pDasher->HandleEvent(iParameter);
}
void CAppSettings::ResetParamater(int iParameter) {
- if(iParameter < END_OF_SPS)
- m_pDasher->ResetParameter(iParameter);
- else if(iParameter < END_OF_APP_BPS)
- SetBoolParameter(iParameter, app_boolparamtable[iParameter - FIRST_APP_BP].defaultValue);
- else if(iParameter < END_OF_APP_LPS)
- SetLongParameter(iParameter, app_longparamtable[iParameter - FIRST_APP_LP].defaultValue);
- else
- SetStringParameter(iParameter, app_stringparamtable[iParameter - FIRST_APP_SP].defaultValue);
+ settings_store_->ResetParameter(iParameter);
}
void CAppSettings::GetPermittedValues(int iParameter, vector<string> &vList) {
@@ -158,205 +62,41 @@ void CAppSettings::GetPermittedValues(int iParameter, vector<string> &vList) {
m_pDasher->GetPermittedValues(iParameter,vList);
}
-// Functions for accessing persistent storage (stolen from WinOptions)
-
-bool CAppSettings::LoadSetting(const std::string &Key, bool *Value) {
- Tstring TKey;
- UTF8string_to_wstring(Key, TKey);
- BYTE *Data = 0;
-
- if(!GetlpByte(TKey, &Data)) {
- delete[]Data;
- return false;
- }
-
- if((DWORD) * Data == 0)
- *Value = false;
- else
- *Value = true;
-
- delete[]Data;
- return true;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-
-bool CAppSettings::LoadSetting(const std::string &Key, long *Value) {
- Tstring TKey;
- UTF8string_to_wstring(Key, TKey);
- BYTE *Data = 0;
-
- if(!GetlpByte(TKey, &Data)) {
- delete[]Data;
- return false;
- }
-
- // Evil casting to make sure I can retrieve signed longs, even
- // though windows registry only stores +ve values.
- *Value = *((long *)Data);
- delete[]Data;
- return true;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-
-bool CAppSettings::LoadSettingT(const std::string &Key, Tstring *TValue) {
- Tstring TKey;
- UTF8string_to_wstring(Key, TKey);
- BYTE *Data = 0;
-
- if(!GetlpByte(TKey, &Data)) {
- delete[]Data;
- return false;
- }
-
- *TValue = (TCHAR *) Data;
- delete[]Data;
-
- return true;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-
-bool CAppSettings::LoadSetting(const std::string &Key, std::string *Value) {
-
- Tstring str;
- if(LoadSettingT(Key, &str)) {
- wstring_to_UTF8string(str, *Value);
- return true;
-
- }
- return false;
-
-}
-
-/////////////////////////////////////////////////////////////////////////////
-
-static TCHAR FormatWindowPlacement[] = TEXT("%u,%u,%d,%d,%d,%d,%d,%d,%d,%d,%d");
+static const char FormatWindowPlacement[] = "%u,%u,%d,%d,%d,%d,%d,%d,%d,%d,%d";
/////////////////////////////////////////////////////////////////////////////
#ifndef _WIN32_WCE
-void CAppSettings::SaveSetting(const std::string &Key, const LPWINDOWPLACEMENT pwp, int sp) {
+void CAppSettings::SaveWindowPlacement(int iParameter, const LPWINDOWPLACEMENT pwp, int sp) {
DASHER_ASSERT(pwp != NULL);
- TCHAR t[200];
- _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,sp);
-
- Tstring ts(t);
- SaveSettingT(Key, ts);
-
+ char t[200];
+ sprintf_s(t, sizeof(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,sp);
+ SetStringParameter(iParameter, t);
}
/////////////////////////////////////////////////////////////////////////////
-bool CAppSettings::LoadSetting(const std::string &Key, LPWINDOWPLACEMENT pwp, int* psp) {
+bool CAppSettings::LoadWindowPlacement(int iParameter, LPWINDOWPLACEMENT pwp, int* psp) {
DASHER_ASSERT(pwp != NULL);
- Tstring str;
-
- if(!LoadSettingT(Key, &str))
+ auto str = GetStringParameter(iParameter);
+ if (str.empty())
return false;
WINDOWPLACEMENT wp;
- int nRead = _stscanf(str.c_str(), FormatWindowPlacement,
+ int nRead = sscanf_s(str.c_str(), FormatWindowPlacement,
&wp.flags, &wp.showCmd,
&wp.ptMinPosition.x, &wp.ptMinPosition.y,
&wp.ptMaxPosition.x, &wp.ptMaxPosition.y,
&wp.rcNormalPosition.left, &wp.rcNormalPosition.top,
&wp.rcNormalPosition.right, &wp.rcNormalPosition.bottom, psp);
- if(nRead < 10)
+ if(nRead != 11)
return false;
wp.length = sizeof(wp);
-
*pwp = wp;
return true;
-
}
#endif
-/////////////////////////////////////////////////////////////////////////////
-
-void CAppSettings::SaveSetting(const std::string &Key, bool Value) {
- if(Value)
- SaveSetting(Key, 1l);
- else
- SaveSetting(Key, 0l);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-
-void CAppSettings::SaveSetting(const std::string &Key, long Value) {
- Tstring TKey;
- UTF8string_to_wstring(Key, TKey);
- // Evil casting. Registry stores DWORD's (unsigned longs)
- // I'm forcing in signed longs and if I force them out again in the same
- // way I should get a sensible result.
- DWORD *RegValue = (DWORD *) & Value;
- DWORD MemAllow = sizeof(DWORD);
- LONG ErrVal = RegSetValueEx(ProductKey, TKey.c_str(), 0,
- REG_DWORD, (const unsigned char *)RegValue, MemAllow);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-
-void CAppSettings::SaveSettingT(const std::string &Key, const Tstring &TValue) {
- Tstring TKey;
- UTF8string_to_wstring(Key, TKey);
-
- DWORD MemAllow = (TValue.size() + 1) * sizeof(TCHAR);
-
- //const unsigned char* StrInput = (const unsigned char*) Value.c_str();
- //LONG ErrVal = RegSetValueEx(ProductKey, TKey.c_str(), 0,
- // REG_SZ, StrInput, MemAllow);
-
- LONG ErrVal = RegSetValueEx(ProductKey, TKey.c_str(), 0,
- REG_SZ, (CONST BYTE *) TValue.c_str(), MemAllow);
-
-}
-
-/////////////////////////////////////////////////////////////////////////////
-
-void CAppSettings::SaveSetting(const std::string &Key, const std::string &Value) {
-
- // DJW20031107 - i think Values should also be converted to Tstring
- Tstring TValue;
- UTF8string_to_wstring(Value, TValue);
-
- SaveSettingT(Key, TValue);
-}
-
-// Used for getting a handle on the Dasher key in the constructor.
-int CAppSettings::GetOrCreate(HKEY hKey, LPCTSTR lpSubKey, REGSAM samDesired, HKEY *lpNewKey) {
- if(!(RegOpenKeyEx(hKey, lpSubKey, 0, samDesired, lpNewKey) == ERROR_SUCCESS)) {
-
- if(!(RegCreateKeyEx(hKey, lpSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, samDesired, NULL, lpNewKey, NULL)
== ERROR_SUCCESS)) {
-
- return (1);
- }
- }
- return 0;
-}
-
-bool CAppSettings::GetlpByte(const Tstring &Key, BYTE **Data) const {
- *Data = new BYTE[1];
- unsigned long datasize = sizeof(BYTE[1]);
- DWORD Type;
-
- LONG ErrVal = RegQueryValueEx(ProductKey, Key.c_str(), 0, &Type, *Data, &datasize);
- while(ErrVal == ERROR_MORE_DATA) {
- delete[] * Data;
- *Data = new BYTE[datasize];
- ErrVal = RegQueryValueEx(ProductKey, Key.c_str(), 0, &Type, *Data, &datasize);
- }
-
- // Perhaps I should spend lots of time working out why the registry doesn't work.
- // when this fails. Would probably just confuse users though. Users with a broken
- // registry can live with defaults :)
- if((ErrVal == ERROR_SUCCESS) && (*Data != 0))
- return true;
- else
- return false;
-}
-
diff --git a/Src/Win32/AppSettings.h b/Src/Win32/AppSettings.h
index 5753a43..1d9f203 100644
--- a/Src/Win32/AppSettings.h
+++ b/Src/Win32/AppSettings.h
@@ -1,7 +1,9 @@
#pragma once
#include "../Common/AppSettingsHeader.h"
+#include "../DasherCore/SettingsStore.h"
+#include <memory>
#include <vector>
#include <string>
@@ -28,8 +30,8 @@ namespace Dasher {
class CAppSettings
{
public:
-
- CAppSettings(Dasher::CDasher *pDasher, HWND hWnd);
+ // The constructor takes ownership of the settings_store.
+ CAppSettings(Dasher::CDasher *pDasher, HWND hWnd, Dasher::CSettingsStore* settings_store);
~CAppSettings(void);
///
@@ -48,8 +50,8 @@ public:
void GetPermittedValues(int iParameter, std::vector<std::string> &vList);
#ifndef _WIN32_WCE
- bool LoadSetting(const std::string & Key, LPWINDOWPLACEMENT pwp, int* psp);
- void SaveSetting(const std::string & Key, const LPWINDOWPLACEMENT pwp, int sp);
+ bool LoadWindowPlacement(int iParameter, LPWINDOWPLACEMENT pwp, int* psp);
+ void SaveWindowPlacement(int iParameter, const LPWINDOWPLACEMENT pwp, int sp);
#endif
void SetHwnd(HWND hWnd) {
@@ -62,54 +64,9 @@ public:
};
private:
- struct bp_info {
- int key;
- std::string regName;
- bool persistent;
- bool value;
- bool defaultVal;
- std::string humanReadable;
- };
- struct lp_info {
- int key;
- std::string regName;
- bool persistent;
- long value;
- long defaultVal;
- std::string humanReadable;
- };
- struct sp_info {
- int key;
- std::string regName;
- bool persistent;
- std::string value;
- std::string defaultVal;
- std::string humanReadable;
- };
-
- bp_info *m_pBoolTable;
- lp_info *m_pLongTable;
- sp_info *m_pStringTable;
Dasher::CDasher *m_pDasher;
HWND m_hWnd;
- bool LoadSetting(const std::string & Key, bool * Value);
- bool LoadSetting(const std::string & Key, long *Value);
- bool LoadSetting(const std::string & Key, std::string * Value);
- bool LoadSettingT(const std::string & Key, Tstring * Value);
-
- void SaveSetting(const std::string & Key, bool Value);
- void SaveSetting(const std::string & Key, long Value);
- void SaveSetting(const std::string & Key, const std::string & Value);
-
- void SaveSettingT(const std::string & Key, const Tstring & TValue);
-
- // Platform Specific helpers
- HKEY ProductKey;
- int GetOrCreate(HKEY hKey, LPCTSTR lpSubKey, REGSAM samDesired, HKEY * lpNewKey);
- // CARE! Users of GetlpByte must call delete[] on *Data after use.
- bool GetlpByte(const Tstring & key, BYTE ** Data) const;
-
-
+ std::unique_ptr<Dasher::CSettingsStore> settings_store_;
};
diff --git a/Src/Win32/Common/WinOptions.cpp b/Src/Win32/Common/WinOptions.cpp
index b1a124a..3ab0f75 100644
--- a/Src/Win32/Common/WinOptions.cpp
+++ b/Src/Win32/Common/WinOptions.cpp
@@ -133,52 +133,6 @@ bool CWinOptions::LoadSetting(const std::string &Key, std::string *Value) {
/////////////////////////////////////////////////////////////////////////////
-static TCHAR FormatWindowPlacement[] = TEXT("%u,%u,%d,%d,%d,%d,%d,%d,%d,%d");
-
-/////////////////////////////////////////////////////////////////////////////
-#ifndef _WIN32_WCE
-
-void CWinOptions::SaveSetting(const std::string &Key, const LPWINDOWPLACEMENT pwp) {
- DASHER_ASSERT(pwp != NULL);
-
- TCHAR t[200];
- _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);
-
- Tstring ts(t);
- SaveSettingT(Key, ts);
-
-}
-
-/////////////////////////////////////////////////////////////////////////////
-
-bool CWinOptions::LoadSetting(const std::string &Key, LPWINDOWPLACEMENT pwp) {
- DASHER_ASSERT(pwp != NULL);
-
- Tstring str;
-
- if(!LoadSettingT(Key, &str))
- return false;
-
- WINDOWPLACEMENT wp;
- int nRead = _stscanf(str.c_str(), FormatWindowPlacement,
- &wp.flags, &wp.showCmd,
- &wp.ptMinPosition.x, &wp.ptMinPosition.y,
- &wp.ptMaxPosition.x, &wp.ptMaxPosition.y,
- &wp.rcNormalPosition.left, &wp.rcNormalPosition.top,
- &wp.rcNormalPosition.right, &wp.rcNormalPosition.bottom);
-
- if(nRead != 10)
- return false;
- wp.length = sizeof(wp);
-
- *pwp = wp;
- return true;
-
-}
-
-#endif
-/////////////////////////////////////////////////////////////////////////////
-
void CWinOptions::SaveSetting(const std::string &Key, bool Value) {
if(Value)
SaveSetting(Key, 1l);
diff --git a/Src/Win32/Common/WinOptions.h b/Src/Win32/Common/WinOptions.h
index 2aa7ca1..6a7faf6 100644
--- a/Src/Win32/Common/WinOptions.h
+++ b/Src/Win32/Common/WinOptions.h
@@ -22,11 +22,6 @@ public:
CWinOptions(const std::string & Group, const std::string & Product);
~CWinOptions();
-#ifndef _WIN32_WCE
- bool LoadSetting(const std::string & Key, LPWINDOWPLACEMENT pwp);
- void SaveSetting(const std::string & Key, const LPWINDOWPLACEMENT pwp);
-#endif
-
private:
// Platform Specific settings file management
bool LoadSetting(const std::string & Key, bool * Value);
diff --git a/Src/Win32/Common/WinUTF8.cpp b/Src/Win32/Common/WinUTF8.cpp
index 3c548da..9e5b7d8 100644
--- a/Src/Win32/Common/WinUTF8.cpp
+++ b/Src/Win32/Common/WinUTF8.cpp
@@ -6,6 +6,9 @@
//
/////////////////////////////////////////////////////////////////////////////
+#include <locale>
+#include <codecvt>
+
#include "WinCommon.h"
#include "WinUTF8.h"
@@ -75,16 +78,21 @@ string WinUTF8::wstring_to_UTF8string(const wchar_t *Input) {
}
void WinUTF8::wstring_to_UTF8string(const wchar_t *Input, string &Output) {
+ size_t len = wcslen(Input);
+ int size_needed = WideCharToMultiByte(CP_UTF8, 0, Input, len, nullptr, 0, nullptr, nullptr);
+ Output.resize(size_needed);
+ WideCharToMultiByte(CP_UTF8, 0, Input, (int)Output.size(), &Output[0], size_needed, NULL, NULL);
+ return;
+}
- const std::size_t BufferSize = wcslen(Input) + 1;
- const wchar_t *Buffer = Input;
-
- const std::size_t BufferSize2 = BufferSize * 2;
- char *Buffer2 = new char[BufferSize2];
-
- WideCharToMultiByte(CP_UTF8, 0, Buffer, -1, Buffer2, BufferSize2, NULL, NULL);
+std::wstring_convert<std::codecvt_utf8<wchar_t, 0x10ffff, std::consume_header>, wchar_t> utf16conv;
+std::wstring WinUTF8::widen(const char* utf8) {
+ return utf16conv.from_bytes(utf8);
+}
+std::wstring WinUTF8::widen(const std::string& utf8) {
+ return utf16conv.from_bytes(utf8);
+}
- Output = Buffer2;
- delete[]Buffer2;
- return;
+std::string WinUTF8::narrow(const wchar_t* wide) {
+ return utf16conv.to_bytes(wide).substr(3); // Remove the BOM.
}
diff --git a/Src/Win32/Common/WinUTF8.h b/Src/Win32/Common/WinUTF8.h
index 40c7d8f..cef6543 100644
--- a/Src/Win32/Common/WinUTF8.h
+++ b/Src/Win32/Common/WinUTF8.h
@@ -25,5 +25,9 @@ namespace WinUTF8 {
void wstring_to_UTF8string(const std::wstring & Input, std::string & Output);
void wstring_to_UTF8string(const wchar_t *Input, std::string &Output);
std::string wstring_to_UTF8string(const wchar_t* Input);
+
+ std::wstring widen(const char* utf8);
+ std::wstring widen(const std::string& utf8);
+ std::string narrow(const wchar_t* wide);
}
#endif /* #ifndef __WinUTF8_h__ */
diff --git a/Src/Win32/Dasher.cpp b/Src/Win32/Dasher.cpp
index 1769e3b..a307e2c 100644
--- a/Src/Win32/Dasher.cpp
+++ b/Src/Win32/Dasher.cpp
@@ -32,8 +32,8 @@ using namespace WinUTF8;
CONST UINT WM_DASHER_FOCUS = RegisterWindowMessage(L"WM_DASHER_FOCUS");
-CDasher::CDasher(HWND Parent, CDasherWindow *pWindow, CEdit *pEdit)
- : CDashIntfScreenMsgs(new CWinOptions( "Inference Group", "Dasher3")), m_hParent(Parent),
m_pWindow(pWindow), m_pEdit(pEdit) {
+CDasher::CDasher(HWND Parent, CDasherWindow *pWindow, CEdit *pEdit, Dasher::CSettingsStore* settings)
+ : CDashIntfScreenMsgs(settings), m_hParent(Parent), m_pWindow(pWindow), m_pEdit(pEdit) {
// This class will be a wrapper for the Dasher 'control' - think ActiveX
#ifndef _WIN32_WCE
diff --git a/Src/Win32/Dasher.h b/Src/Win32/Dasher.h
index 01a9146..ed21aa2 100644
--- a/Src/Win32/Dasher.h
+++ b/Src/Win32/Dasher.h
@@ -26,7 +26,7 @@ namespace Dasher {
class CDasher : public CDashIntfScreenMsgs
{
public:
- CDasher(HWND Parent, CDasherWindow *pWindow, CEdit *pEdit);
+ CDasher(HWND Parent, CDasherWindow *pWindow, CEdit *pEdit, Dasher::CSettingsStore* settings);
~CDasher(void);
// The following functions will not be part of the final interface
diff --git a/Src/Win32/DasherWindow.cpp b/Src/Win32/DasherWindow.cpp
index 1b47e04..4d84f83 100644
--- a/Src/Win32/DasherWindow.cpp
+++ b/Src/Win32/DasherWindow.cpp
@@ -25,6 +25,8 @@
#include "Widgets/Toolbar.h"
#include "WinCommon.h"
+#include "WinOptions.h"
+#include "../DasherCore/XmlSettingsStore.h"
#include <windows.h>
#include "resource.h"
@@ -35,11 +37,23 @@ using namespace std;
#define IDT_TIMER1 200
+namespace {
+class XmlErrorDisplay : public CMessageDisplay {
+public:
+ void Message(const std::string &strText, bool bInterrupt) override {
+ std::wstring text;
+ WinUTF8::UTF8string_to_wstring(strText, text);
+ // TODO: find a way to localize.
+ MessageBox(nullptr, text.c_str(), L"Configuration Error", MB_ICONERROR|MB_ICONSTOP);
+ }
+};
+} // namespace
+
// NOTE: There were previously various bits and pieces in this class from
// text services framework stuff, which were never really finished. If
// required, look in version control history (prior to May 2007).
-CDasherWindow::CDasherWindow() {
+CDasherWindow::CDasherWindow(const CString& xml_config_file) : xml_config_file_(xml_config_file) {
m_bFullyCreated = false;
m_pAppSettings = 0;
m_pToolbar = 0;
@@ -66,7 +80,21 @@ HWND CDasherWindow::Create() {
Tstring WindowTitle;
WinLocalisation::GetResourceString(IDS_APP_TITLE, &WindowTitle);
- m_pAppSettings = new CAppSettings(0, 0);
+ static XmlErrorDisplay display;
+ Dasher::CSettingsStore* settings;
+ if (xml_config_file_.IsEmpty()) {
+ settings = new CWinOptions("Inference Group", "Dasher3");
+ }
+ else {
+ std::string utf8_path = WinUTF8::narrow(xml_config_file_);
+ auto xml_settings = new Dasher::XmlSettingsStore(utf8_path, &display);
+ xml_settings->Load();
+ // Save the defaults if needed.
+ xml_settings->Save();
+ settings = xml_settings;
+ }
+
+ m_pAppSettings = new CAppSettings(0, 0, settings); // Takes ownership of the settings store.
int iStyle(m_pAppSettings->GetLongParameter(APP_LP_STYLE));
HWND hWnd;
@@ -85,7 +113,7 @@ HWND CDasherWindow::Create() {
m_pEdit->Create(hWnd, m_pAppSettings->GetBoolParameter(APP_BP_TIME_STAMP));
m_pEdit->SetFont(m_pAppSettings->GetStringParameter(APP_SP_EDIT_FONT),
m_pAppSettings->GetLongParameter(APP_LP_EDIT_FONT_SIZE));
- m_pDasher = new CDasher(hWnd, this, m_pEdit);
+ m_pDasher = new CDasher(hWnd, this, m_pEdit, settings);
// Create a CAppSettings
m_pAppSettings->SetHwnd(hWnd);
@@ -130,14 +158,14 @@ void CDasherWindow::SaveWindowState() const {
wp.length = sizeof(WINDOWPLACEMENT);
if (GetWindowPlacement(&wp)) {//function call succeeds
- m_pAppSettings->SaveSetting("WindowState", &wp, m_pSplitter->GetPos());
+ m_pAppSettings->SaveWindowPlacement(APP_SP_WINDOW_STATE, &wp, m_pSplitter->GetPos());
}
}
bool CDasherWindow::LoadWindowState() {
WINDOWPLACEMENT wp;
int splitterPos = -1;
- if (m_pAppSettings->LoadSetting("WindowState", &wp, &splitterPos)) {
+ if (m_pAppSettings->LoadWindowPlacement(APP_SP_WINDOW_STATE, &wp, &splitterPos)) {
if (splitterPos != -1) {
m_pSplitter->SetPos(splitterPos);
}
diff --git a/Src/Win32/DasherWindow.h b/Src/Win32/DasherWindow.h
index 9385169..dc77c19 100644
--- a/Src/Win32/DasherWindow.h
+++ b/Src/Win32/DasherWindow.h
@@ -9,6 +9,8 @@
#ifndef __DasherWindow_h__
#define __DasherWindow_h__
+#include <memory>
+
#include "Widgets/Splitter.h"
#include "Widgets/StatusControl.h"
#include "Widgets/Edit.h"
@@ -23,7 +25,7 @@ class CDasherWindow :
public CSplitterOwner
{
public:
- CDasherWindow();
+ CDasherWindow(const CString& xml_config_file);
~CDasherWindow();
DECLARE_WND_CLASS(_T("DASHER"))
@@ -88,7 +90,8 @@ private:
HICON m_hIconSm;
HMENU m_hMenu;
-
+ CString xml_config_file_;
+ std::unique_ptr<Dasher::CSettingsStore> setting_store_;
// Misc window handling
void Layout();
};
diff --git a/Src/Win32/WinMain.cpp b/Src/Win32/WinMain.cpp
index 58cc4f3..a7b9b21 100644
--- a/Src/Win32/WinMain.cpp
+++ b/Src/Win32/WinMain.cpp
@@ -7,7 +7,7 @@
/////////////////////////////////////////////////////////////////////////////
#include "WinCommon.h"
-
+#include <shellapi.h>
// Visual leak detector
// #ifdef _DEBUG
// #include "vld/vld.h"
@@ -29,7 +29,7 @@ public:
Control is passed to the main GUI loop, and only returns when the main window closes.
*/
HRESULT Run(int nShowCmd){
- m_pDasherWindow = new CDasherWindow;
+ m_pDasherWindow = new CDasherWindow(xml_config_file_);
m_pDasherWindow->Create();
m_pDasherWindow->Show(nShowCmd);
@@ -48,8 +48,20 @@ public:
return iRet;
};
- static VOID CALLBACK HandleWinEvent(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject,
LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime);
+ bool ParseCommandLine(LPCTSTR lpCmdLine, HRESULT* pnRetCode) {
+ int argc;
+ auto argv = CommandLineToArgvW(lpCmdLine, &argc);
+ for (int i = 0; i < argc; ++i) {
+ if (wcsicmp(argv[i], L"/config") == 0 && i + 1 < argc) {
+ xml_config_file_ = argv[i + 1];
+ }
+ }
+ LocalFree(argv);
+ return CAtlExeModuleT::ParseCommandLine(lpCmdLine, pnRetCode);
+ }
+ static VOID CALLBACK HandleWinEvent(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject,
LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime);
+ CString xml_config_file_;
} DasherApp;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]