mirror of
https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git
synced 2026-06-14 03:16:38 +10:00
Update Settings Page.
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
#include "mpstr.h"
|
||||
#include "nstring.h"
|
||||
using namespace System;
|
||||
using namespace System::Runtime::InteropServices;
|
||||
|
||||
std::wstring HResultToMessage (HRESULT hr)
|
||||
{
|
||||
_com_error err (hr);
|
||||
auto msgptr = err.ErrorMessage ();
|
||||
return msgptr ? msgptr : L"";
|
||||
}
|
||||
[ComVisible (true)]
|
||||
public ref class _I_HResult
|
||||
{
|
||||
private:
|
||||
HRESULT hr = S_OK;
|
||||
String ^errorcode = "";
|
||||
String ^detailmsg = "";
|
||||
public:
|
||||
_I_HResult (HRESULT hres)
|
||||
{
|
||||
hr = hres;
|
||||
detailmsg = CStringToMPString (HResultToMessage (hres));
|
||||
}
|
||||
_I_HResult (HRESULT hres, String ^error, String ^message)
|
||||
{
|
||||
hr = hres;
|
||||
errorcode = error;
|
||||
detailmsg = message;
|
||||
}
|
||||
property HRESULT HResult { HRESULT get () { return hr; }}
|
||||
property String ^ErrorCode { String ^get () { return errorcode; }}
|
||||
property String ^Message { String ^get () { return detailmsg; }}
|
||||
property bool Succeeded { bool get () { return SUCCEEDED (hr); }}
|
||||
property bool Failed { bool get () { return FAILED (hr); }}
|
||||
};
|
||||
System::String ^FormatString (System::String ^fmt, ... array <Object ^> ^args) { return System::String::Format (fmt, args); }
|
||||
|
||||
String ^ EscapeToInnerXml (String ^str)
|
||||
{
|
||||
using namespace System::Xml;
|
||||
auto doc = gcnew System::Xml::XmlDocument ();
|
||||
doc->LoadXml ("<body></body>");
|
||||
auto root = doc->FirstChild;
|
||||
root->InnerText = str;
|
||||
return root->InnerXml;
|
||||
}
|
||||
std::wstring EscapeToInnerXml (const std::wstring &str) { return MPStringToStdW (EscapeToInnerXml (CStringToMPString (str))); }
|
||||
[ComVisible (true)]
|
||||
public ref class _I_String
|
||||
{
|
||||
public:
|
||||
ref class _I_NString
|
||||
{
|
||||
public:
|
||||
bool NEquals (String ^l, String ^r) { return IsNormalizeStringEquals (MPStringToPtrW (l), MPStringToPtrW (r)); }
|
||||
bool Empty (String ^l) { return IsNormalizeStringEmpty (MPStringToStdW (l)); }
|
||||
int Compare (String ^l, String ^r) { return NormalizeStringCompare (MPStringToPtrW (l), MPStringToPtrW (r)); }
|
||||
int Length (String ^l) { return GetNormalizeStringLength (MPStringToStdW (l)); }
|
||||
};
|
||||
private:
|
||||
_I_NString ^nstr = gcnew _I_NString ();
|
||||
public:
|
||||
property _I_NString ^NString { _I_NString ^get () { return nstr; }}
|
||||
String ^Trim (String ^src)
|
||||
{
|
||||
std::wstring csrc = MPStringToStdW (src);
|
||||
return CStringToMPString (::StringTrim (csrc));
|
||||
}
|
||||
String ^ToLower (String ^src) { return CStringToMPString (StringToLower (MPStringToStdW (src))); }
|
||||
String ^ToUpper (String ^src) { return CStringToMPString (StringToUpper (MPStringToStdW (src))); }
|
||||
String ^Format (String ^fmt, ... array <Object ^> ^args) { return FormatString (fmt, args); }
|
||||
String ^FormatInnerHTML (String ^fmt, ... array <Object ^> ^args)
|
||||
{
|
||||
std::wstring ihtml = EscapeToInnerXml (MPStringToStdW (fmt));
|
||||
auto pih = CStringToMPString (ihtml);
|
||||
auto newargs = gcnew array <Object ^> (args->Length);
|
||||
for (size_t i = 0; i < args->Length; i ++)
|
||||
{
|
||||
auto %p = newargs [i];
|
||||
p = Format ("<span>{0}</span>", EscapeToInnerXml (Format ("{0}", args [i])));
|
||||
}
|
||||
return Format (pih, newargs);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
template <class T> bool compare_default (const T &l, const T &r) { return l == r; }
|
||||
template <class T> bool find_vec (std::vector <T> &vec, const T &value, const std::function <void (size_t)> &callback, std::function<bool (const T &, const T &)> compare = compare_default <T>, bool sorted = false)
|
||||
{
|
||||
const size_t n = vec.size ();
|
||||
if (!compare) compare = compare_default<T>;
|
||||
if (sorted)
|
||||
{
|
||||
size_t left = 0, right = n;
|
||||
while (left < right)
|
||||
{
|
||||
size_t mid = left + (right - left) / 2;
|
||||
if (compare (vec [mid], value))
|
||||
{
|
||||
callback (mid);
|
||||
return true;
|
||||
}
|
||||
if (vec [mid] < value) left = mid + 1;
|
||||
else right = mid;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (n < 64)
|
||||
{
|
||||
for (size_t i = 0; i < n; i++)
|
||||
{
|
||||
if (compare (vec [i], value))
|
||||
{
|
||||
callback (i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
const size_t blockSize = 8;
|
||||
size_t i = 0;
|
||||
for (; i + blockSize <= n; i += blockSize)
|
||||
{
|
||||
for (size_t j = 0; j < blockSize; j ++)
|
||||
{
|
||||
if (compare (vec [i + j], value))
|
||||
{
|
||||
callback (i + j);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (; i < n; i ++)
|
||||
{
|
||||
if (compare (vec [i], value))
|
||||
{
|
||||
callback (i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
template <class T> void push_unique (std::vector <T> &vec, const T &value, std::function <bool (const T &, const T &)> compare = compare_default <T>)
|
||||
{
|
||||
bool found = find_vec <T> (
|
||||
vec, value,
|
||||
[] (size_t) {},
|
||||
compare);
|
||||
if (!found) vec.push_back (value);
|
||||
}
|
||||
template <class T> void push_normal (std::vector <T> &vec, const T &value)
|
||||
{
|
||||
vec.push_back (value);
|
||||
}
|
||||
template <class T> void push_normal (std::vector <T> &target, const std::vector <T> &another)
|
||||
{
|
||||
target.insert (target.end (), another.begin (), another.end ());
|
||||
}
|
||||
+1173
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include "filepath.h"
|
||||
void SetWebBrowserEmulation ()
|
||||
{
|
||||
std::wstring instname = GetCurrentProgramNameW ();
|
||||
BOOL isWow64 = FALSE;
|
||||
IsWow64Process (GetCurrentProcess (), &isWow64);
|
||||
HKEY hKey;
|
||||
LPCWSTR keyPath = isWow64
|
||||
? L"SOFTWARE\\WOW6432Node\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION"
|
||||
: L"SOFTWARE\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION";
|
||||
LONG result = RegOpenKeyExW (HKEY_CURRENT_USER, keyPath, 0, KEY_WRITE, &hKey);
|
||||
if (result == ERROR_SUCCESS)
|
||||
{
|
||||
DWORD value = 11001;
|
||||
RegSetValueExW (hKey, instname.c_str (), 0, REG_DWORD, reinterpret_cast <const BYTE*> (&value), sizeof (value));
|
||||
RegCloseKey (hKey);
|
||||
}
|
||||
}
|
||||
// 返回系统安装的 Internet Explorer 主版本号(如 8、9、10、11)
|
||||
int GetInternetExplorerVersionMajor ()
|
||||
{
|
||||
HKEY hKey;
|
||||
LPCWSTR IEKeyPath = L"SOFTWARE\\Microsoft\\Internet Explorer";
|
||||
if (RegOpenKeyExW (HKEY_LOCAL_MACHINE, IEKeyPath, 0, KEY_READ, &hKey) != ERROR_SUCCESS) return 0;
|
||||
WCHAR buffer [128] = {0};
|
||||
DWORD bufferSize = sizeof (buffer);
|
||||
DWORD type = 0;
|
||||
std::wstring versionStr;
|
||||
if (RegQueryValueExW (hKey, L"svcVersion", NULL, &type, (LPBYTE)buffer, &bufferSize) == ERROR_SUCCESS) versionStr = buffer;
|
||||
else
|
||||
{
|
||||
bufferSize = sizeof (buffer);
|
||||
if (RegQueryValueExW (hKey, L"Version", NULL, &type, (LPBYTE)buffer, &bufferSize) == ERROR_SUCCESS) versionStr = buffer;
|
||||
}
|
||||
RegCloseKey (hKey);
|
||||
if (versionStr.empty ()) return 0;
|
||||
int major = 0;
|
||||
swscanf_s (versionStr.c_str (), L"%d", &major);
|
||||
return major;
|
||||
}
|
||||
bool IsInternetExplorer10 () { return GetInternetExplorerVersionMajor () == 10; }
|
||||
bool IsInternetExplorer11AndLater () { return GetInternetExplorerVersionMajor () >= 11; }
|
||||
@@ -0,0 +1,599 @@
|
||||
#pragma once
|
||||
#ifndef _CRT_NON_CONFORMING_SWPRINTFS
|
||||
#define _CRT_NON_CONFORMING_SWPRINTFS
|
||||
#endif
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <cstdint>
|
||||
#include <cwchar>
|
||||
#include <type_traits>
|
||||
#include "strcode.h"
|
||||
#include "nstring.h"
|
||||
#include "typestrans.h"
|
||||
#include "mpstr.h"
|
||||
|
||||
template <typename T> std::wstring TypeToString (T value, const std::wstring &reserve = L"") { return std::to_wstring (value); }
|
||||
template <typename T> std::string TypeToString (T value, const std::string &reserve = "") { return std::to_string (value); }
|
||||
|
||||
std::string GetPrivateProfileStringA (const std::string &filePath, const std::string §ion, const std::string &key, LPCSTR defaultValue = "")
|
||||
{
|
||||
char buf [32768] = {0};
|
||||
GetPrivateProfileStringA (section.c_str (), key.c_str (), defaultValue, buf, 32767, filePath.c_str ());
|
||||
return buf;
|
||||
}
|
||||
std::wstring GetPrivateProfileStringW (const std::wstring &filePath, const std::wstring §ion, const std::wstring &key, LPCWSTR defaultValue = L"")
|
||||
{
|
||||
WCHAR buf [32768] = {0};
|
||||
GetPrivateProfileStringW (section.c_str (), key.c_str (), defaultValue, buf, 32767, filePath.c_str ());
|
||||
return buf;
|
||||
}
|
||||
UINT GetPrivateProfileIntA (const std::string &filePath, const std::string §ion, const std::string &key, INT defaultValue = 0)
|
||||
{
|
||||
return GetPrivateProfileIntA (section.c_str (), key.c_str (), defaultValue, filePath.c_str ());
|
||||
}
|
||||
UINT GetPrivateProfileIntW (const std::wstring &filePath, const std::wstring §ion, const std::wstring &key, INT defaultValue = 0)
|
||||
{
|
||||
return GetPrivateProfileIntW (section.c_str (), key.c_str (), defaultValue, filePath.c_str ());
|
||||
}
|
||||
BOOL WritePrivateProfileStringA (const std::string &filePath, const std::string §ion, const std::string &key, const std::string &value)
|
||||
{
|
||||
return WritePrivateProfileStringA (section.c_str (), key.c_str (), value.c_str (), filePath.c_str ());
|
||||
}
|
||||
BOOL WritePrivateProfileStringW (const std::wstring &filePath, const std::wstring §ion, const std::wstring &key, const std::wstring &value)
|
||||
{
|
||||
return WritePrivateProfileStringW (section.c_str (), key.c_str (), value.c_str (), filePath.c_str ());
|
||||
}
|
||||
size_t GetPrivateProfileSectionA (const std::string &filePath, const std::string §ion, std::vector <std::string> &output)
|
||||
{
|
||||
char buf [32768] = {0};
|
||||
DWORD len = GetPrivateProfileSectionA (section.c_str (), buf, sizeof (buf), filePath.c_str ());
|
||||
output.clear ();
|
||||
if (len == 0) return 0;
|
||||
char *ptr = buf;
|
||||
while (*ptr)
|
||||
{
|
||||
output.emplace_back (ptr);
|
||||
ptr += strlen (ptr) + 1;
|
||||
}
|
||||
return output.size ();
|
||||
}
|
||||
size_t GetPrivateProfileSectionW (const std::wstring &filePath, const std::wstring §ion, std::vector <std::wstring> &output)
|
||||
{
|
||||
WCHAR buf [32768] = {0};
|
||||
DWORD len = GetPrivateProfileSectionW (section.c_str (), buf, sizeof (buf) / sizeof (WCHAR), filePath.c_str ());
|
||||
output.clear ();
|
||||
if (len == 0) return 0;
|
||||
WCHAR *ptr = buf;
|
||||
while (*ptr)
|
||||
{
|
||||
output.emplace_back (ptr);
|
||||
ptr += wcslen (ptr) + 1;
|
||||
}
|
||||
return output.size ();
|
||||
}
|
||||
size_t GetPrivateProfileSectionNamesA (const std::string &filePath, std::vector <std::string> &output)
|
||||
{
|
||||
char buf [32768] = {0};
|
||||
DWORD len = GetPrivateProfileSectionNamesA (buf, sizeof (buf), filePath.c_str ());
|
||||
output.clear ();
|
||||
if (len == 0) return 0;
|
||||
char *ptr = buf;
|
||||
while (*ptr)
|
||||
{
|
||||
output.emplace_back (ptr);
|
||||
ptr += strlen (ptr) + 1;
|
||||
}
|
||||
return output.size ();
|
||||
}
|
||||
size_t GetPrivateProfileSectionNamesW (const std::wstring &filePath, std::vector <std::wstring> &output)
|
||||
{
|
||||
WCHAR buf [32768] = {0};
|
||||
DWORD len = GetPrivateProfileSectionNamesW (buf, sizeof (buf) / sizeof (WCHAR), filePath.c_str ());
|
||||
output.clear ();
|
||||
if (len == 0) return 0;
|
||||
WCHAR *ptr = buf;
|
||||
while (*ptr)
|
||||
{
|
||||
output.emplace_back (ptr);
|
||||
ptr += wcslen (ptr) + 1;
|
||||
}
|
||||
return output.size ();
|
||||
}
|
||||
bool WritePrivateProfileSectionA (const std::string &filePath, const std::string §ion, const std::vector <std::string> &lines)
|
||||
{
|
||||
std::string buf;
|
||||
for (const auto &line : lines) buf.append (line).push_back ('\0');
|
||||
buf.push_back ('\0');
|
||||
return WritePrivateProfileSectionA (section.c_str (), buf.c_str (), filePath.c_str ()) != 0;
|
||||
}
|
||||
bool WritePrivateProfileSectionW (const std::wstring &filePath, const std::wstring §ion, const std::vector <std::wstring> &lines)
|
||||
{
|
||||
std::wstring buf;
|
||||
for (const auto &line : lines) buf.append (line).push_back (L'\0');
|
||||
buf.push_back (L'\0'); // Ë« \0 ½áβ
|
||||
return WritePrivateProfileSectionW (section.c_str (), buf.c_str (), filePath.c_str ()) != 0;
|
||||
}
|
||||
bool GetPrivateProfileStructA (const std::string &filePath, const std::string §ion, const std::string &key, void *output, UINT size)
|
||||
{
|
||||
return GetPrivateProfileStructA (section.c_str (), key.c_str (), output, size, filePath.c_str ()) != 0;
|
||||
}
|
||||
bool WritePrivateProfileStructA (const std::string &filePath, const std::string §ion, const std::string &key, void *data, UINT size)
|
||||
{
|
||||
return WritePrivateProfileStructA (section.c_str (), key.c_str (), data, size, filePath.c_str ()) != 0;
|
||||
}
|
||||
bool GetPrivateProfileStructW (const std::wstring &filePath, const std::wstring §ion, const std::wstring &key, void *output, UINT size)
|
||||
{
|
||||
return GetPrivateProfileStructW (section.c_str (), key.c_str (), output, size, filePath.c_str ()) != 0;
|
||||
}
|
||||
bool WritePrivateProfileStructW (const std::wstring &filePath, const std::wstring §ion, const std::wstring &key, void *data, UINT size)
|
||||
{
|
||||
return WritePrivateProfileStructW (section.c_str (), key.c_str (), data, size, filePath.c_str ()) != 0;
|
||||
}
|
||||
size_t GetPrivateProfileKeysW (const std::wstring &filePath, const std::wstring §ion, std::vector <std::wstring> &keys)
|
||||
{
|
||||
WCHAR buf [32768] = {0};
|
||||
DWORD len = GetPrivateProfileSectionW (section.c_str (), buf, sizeof (buf) / sizeof (WCHAR), filePath.c_str ());
|
||||
keys.clear ();
|
||||
if (len == 0) return 0;
|
||||
WCHAR* ptr = buf;
|
||||
while (*ptr)
|
||||
{
|
||||
std::wstring line = ptr;
|
||||
size_t pos = line.find (L'=');
|
||||
if (pos != std::wstring::npos) keys.push_back (line.substr (0, pos));
|
||||
ptr += wcslen (ptr) + 1;
|
||||
}
|
||||
return keys.size ();
|
||||
}
|
||||
size_t GetPrivateProfileKeysA (const std::string &filePath, const std::string §ion, std::vector <std::string> &keys)
|
||||
{
|
||||
char buf [32768] = {0};
|
||||
DWORD len = GetPrivateProfileSectionA (section.c_str (), buf, sizeof (buf), filePath.c_str ());
|
||||
keys.clear ();
|
||||
if (len == 0)
|
||||
return 0;
|
||||
char *ptr = buf;
|
||||
while (*ptr)
|
||||
{
|
||||
std::string line = ptr;
|
||||
size_t pos = line.find ('=');
|
||||
if (pos != std::string::npos) keys.push_back (line.substr (0, pos));
|
||||
ptr += strlen (ptr) + 1;
|
||||
}
|
||||
return keys.size ();
|
||||
}
|
||||
bool DeletePrivateProfileKeyA (const std::string &filePath, const std::string §ion, const std::string &key)
|
||||
{
|
||||
return WritePrivateProfileStringA (section.c_str (), key.c_str (), NULL, filePath.c_str ()) != FALSE;
|
||||
}
|
||||
bool DeletePrivateProfileKeyW (const std::wstring &filePath, const std::wstring §ion, const std::wstring &key)
|
||||
{
|
||||
return WritePrivateProfileStringW (section.c_str (), key.c_str (), NULL, filePath.c_str ()) != FALSE;
|
||||
}
|
||||
bool DeletePrivateProfileSectionA (const std::string &filePath, const std::string §ion)
|
||||
{
|
||||
return WritePrivateProfileStringA (section.c_str (), NULL, NULL, filePath.c_str ()) != FALSE;
|
||||
}
|
||||
bool DeletePrivateProfileSectionW (const std::wstring &filePath, const std::wstring §ion)
|
||||
{
|
||||
return WritePrivateProfileStringW (section.c_str (), NULL, NULL, filePath.c_str ()) != FALSE;
|
||||
}
|
||||
|
||||
class initkey
|
||||
{
|
||||
public:
|
||||
using pstring = std::string &;
|
||||
using pwstring = std::wstring &;
|
||||
using pcstring = const std::string &;
|
||||
using pcwstring = const std::wstring &;
|
||||
private:
|
||||
pcwstring filepath;
|
||||
pcwstring section;
|
||||
template <typename T, typename Trans = T, typename Func> T read_t (T defaultvalue, Func process) const
|
||||
{
|
||||
auto res = read_wstring (std::to_wstring ((Trans)defaultvalue));
|
||||
if (IsNormalizeStringEmpty (res)) return defaultvalue;
|
||||
return (T)process (res.c_str ());
|
||||
}
|
||||
template <typename T> bool write_t (T value) { return write_string (std::to_wstring (value)); }
|
||||
public:
|
||||
std::wstring key;
|
||||
initkey (pcwstring path, pcwstring sect, pcwstring k): filepath (path), section (sect), key (k) {}
|
||||
std::wstring read_wstring (pcwstring defaultvalue = L"") const { return GetPrivateProfileStringW (filepath, section, key, defaultvalue.c_str ()); }
|
||||
std::string read_string (pcstring defaultvalue = "") const { return WStringToString (read_wstring (StringToWString (defaultvalue))); }
|
||||
short read_short (short defaultvalue = 0) const { return read_t (defaultvalue, _wtoi16); }
|
||||
unsigned short read_ushort (unsigned short defaultvalue = 0) const { return read_t (defaultvalue, _wtoui16); }
|
||||
int read_int (int defaultvalue = 0) const { return read_t (defaultvalue, _wtoi); }
|
||||
unsigned int read_uint (unsigned int defaultvalue = 0) const { return read_t (defaultvalue, _wtou); }
|
||||
long read_long (long defaultvalue = 0) const { return read_t (defaultvalue, _wtol); }
|
||||
unsigned long read_ulong (unsigned long defaultvalue = 0) const { return read_t (defaultvalue, _wtoul); }
|
||||
long long read_llong (long long defaultvalue = 0) const { return read_t (defaultvalue, _wtoll); }
|
||||
unsigned long long read_ullong (unsigned long long defaultvalue = 0) const { return read_t (defaultvalue, _wtou64); }
|
||||
float read_float (float defaultvalue = 0) const { return read_t (defaultvalue, _wtof); }
|
||||
double read_double (double defaultvalue = 0) const { return read_t (defaultvalue, _wtod); }
|
||||
bool read_bool (bool defaultvalue = false) const
|
||||
{
|
||||
std::wnstring res = read_wstring (defaultvalue ? L"true" : L"false");
|
||||
if (res.empty ()) return defaultvalue;
|
||||
if (res.equals (L"true") || res.equals (L"yes") || res.equals (L"zhen") || res.equals (L"Õæ") || res.equals (L"1") || _wtoi (res.c_str ()) != 0) return true;
|
||||
else if (res.equals (L"false") || res.equals (L"no") || res.equals (L"jia") || res.equals (L"¼Ù") || res.equals (L"0")) return false;
|
||||
else return defaultvalue;
|
||||
}
|
||||
int8_t read_i8 (int8_t defaultvalue = 0) const { return read_t <int8_t, int16_t> (defaultvalue, _wtoi8); }
|
||||
uint8_t read_u8 (uint8_t defaultvalue = 0) const { return read_t <uint8_t, uint16_t> (defaultvalue, _wtoui8); }
|
||||
int16_t read_i16 (int16_t defaultvalue = 0) const { return read_t (defaultvalue, _wtoi16); }
|
||||
uint16_t read_u16 (uint16_t defaultvalue = 0) const { return read_t (defaultvalue, _wtoui16); }
|
||||
int32_t read_i32 (int32_t defaultvalue = 0) const { return read_t (defaultvalue, _wtoi32); }
|
||||
uint32_t read_u32 (uint32_t defaultvalue = 0) const { return read_t (defaultvalue, _wtoui32); }
|
||||
int64_t read_i64 (int64_t defaultvalue = 0) const { return read_t (defaultvalue, _wtoi64); }
|
||||
uint64_t read_u64 (uint64_t defaultvalue = 0) const { return read_t (defaultvalue, _wtou64); }
|
||||
bool read_struct (void *output, size_t size) const { return GetPrivateProfileStructW (filepath, section, key, output, size); }
|
||||
template <typename T> bool read_struct (T &structinst) const { return read_struct (&structinst, sizeof (structinst)); }
|
||||
bool write_string (pcwstring value) { return write (value); }
|
||||
bool write_string (pcstring value) { return write (value); }
|
||||
bool write (pcwstring value) { return WritePrivateProfileStringW (filepath, section, key, value); }
|
||||
bool write (pcstring value) { return write (StringToWString (value)); }
|
||||
bool write (int value) { return write_t (value); }
|
||||
bool write (unsigned int value) { return write_t (value); }
|
||||
bool write (short value) { return write_t (value); }
|
||||
bool write (unsigned short value) { return write_t (value); }
|
||||
bool write (long value) { return write_t (value); }
|
||||
bool write (unsigned long value) { return write_t (value); }
|
||||
bool write (long long value) { return write_t (value); }
|
||||
bool write (unsigned long long value) { return write_t (value); }
|
||||
bool write (int8_t value) { return write_t ((int16_t)value); }
|
||||
bool write (uint8_t value) { return write_t ((uint16_t)value); }
|
||||
bool write (float value) { return write_t (value); }
|
||||
bool write (double value) { return write_t (value); }
|
||||
bool write (bool value) { return write (value ? L"true" : L"false"); }
|
||||
bool write (void *buf, size_t bufsize) { return WritePrivateProfileStructW (filepath, section, key, buf, bufsize); }
|
||||
operator std::wstring () { return read_wstring (); }
|
||||
operator std::string () { return read_string (); }
|
||||
template <typename T> initkey &operator = (T value) { write (value); return *this; }
|
||||
initkey &operator = (const initkey &) = delete;
|
||||
// ɾ³ýÏî
|
||||
bool clear () { return DeletePrivateProfileKeyW (filepath, section, key); }
|
||||
bool empty () const { return read_wstring ().empty (); }
|
||||
#define OPERATOR_TYPE_READ(_type_, _method_) \
|
||||
operator _type_ () { return _method_ (); }
|
||||
OPERATOR_TYPE_READ (int, read_int)
|
||||
OPERATOR_TYPE_READ (unsigned int, read_uint)
|
||||
OPERATOR_TYPE_READ (long, read_long)
|
||||
OPERATOR_TYPE_READ (unsigned long, read_ulong)
|
||||
OPERATOR_TYPE_READ (long long, read_llong)
|
||||
OPERATOR_TYPE_READ (unsigned long long, read_ullong)
|
||||
OPERATOR_TYPE_READ (short, read_short)
|
||||
OPERATOR_TYPE_READ (unsigned short, read_ushort)
|
||||
OPERATOR_TYPE_READ (float, read_float)
|
||||
OPERATOR_TYPE_READ (double, read_double)
|
||||
OPERATOR_TYPE_READ (bool, read_bool)
|
||||
#ifdef OPERATOR_TYPE_READ
|
||||
#undef OPERATOR_TYPE_READ
|
||||
#endif
|
||||
};
|
||||
class initsection
|
||||
{
|
||||
private:
|
||||
const std::wstring &filepath;
|
||||
template <typename T, typename Trans = T, typename CT, typename Func> T read_t (const std::basic_string <CT> &key, T defaultvalue, Func process) const
|
||||
{
|
||||
std::basic_string <CT> temp;
|
||||
auto res = read_string (key, TypeToString ((Trans)defaultvalue, temp));
|
||||
if (IsNormalizeStringEmpty (res)) return defaultvalue;
|
||||
return (T)process (res.c_str ());
|
||||
}
|
||||
template <typename T, typename CT> bool write_t (const std::basic_string <CT> &key, T value)
|
||||
{
|
||||
std::basic_string <CT> temp;
|
||||
return write_string (key, TypeToString (value, temp));
|
||||
}
|
||||
public:
|
||||
using pcstring = const std::string &;
|
||||
using pcwstring = const std::wstring &;
|
||||
std::wstring section;
|
||||
initsection (const std::wstring &path, const std::wstring §): filepath (path), section (sect) {}
|
||||
size_t keys (std::vector <std::wstring> &output) const { return GetPrivateProfileKeysW (filepath, section, output); }
|
||||
size_t keys (std::vector <std::string> &output) const { return GetPrivateProfileKeysA (WStringToString (filepath), WStringToString (section), output); }
|
||||
bool key_values (const std::vector <std::wstring> &lines) { return WritePrivateProfileSectionW (filepath, section, lines); }
|
||||
bool key_values (const std::vector <std::string> &lines) { return WritePrivateProfileSectionA (WStringToString (filepath), WStringToString (section), lines); }
|
||||
size_t key_values (std::vector <std::wstring> &output) const { return GetPrivateProfileSectionW (filepath, section, output); }
|
||||
size_t key_values (std::vector <std::string> &output) const { return GetPrivateProfileSectionA (WStringToString (filepath), WStringToString (section), output); }
|
||||
std::wstring read_string (const std::wstring &key, const std::wstring &defaultvalue = L"") const { return GetPrivateProfileStringW (filepath, section, key, defaultvalue.c_str ()); }
|
||||
std::string read_string (const std::string &key, const std::string &defaultvalue = "") const { return WStringToString (read_string (StringToWString (key), StringToWString (defaultvalue))); }
|
||||
std::wstring read_wstring (const std::wstring &key, const std::wstring &defaultvalue = L"") const { return read_string (key, defaultvalue); }
|
||||
int read_int (const std::wstring &key, int defaultvalue = 0) const { return read_t (key, defaultvalue, _wtoi); }
|
||||
int read_int (const std::string &key, int defaultvalue = 0) const { return read_t (key, defaultvalue, atoi); }
|
||||
unsigned int read_uint (const std::wstring &key, unsigned int defaultvalue = 0) const { return read_t (key, defaultvalue, _wtou); }
|
||||
unsigned int read_uint (const std::string &key, unsigned int defaultvalue = 0) const { return read_t (key, defaultvalue, atou); }
|
||||
long read_long (const std::wstring &key, long defaultvalue = 0) const { return read_t (key, defaultvalue, _wtol); }
|
||||
long read_long (const std::string &key, long defaultvalue = 0) const { return read_t (key, defaultvalue, atol); }
|
||||
unsigned long read_ulong (const std::wstring &key, unsigned long defaultvalue = 0) const { return read_t (key, defaultvalue, _wtoul); }
|
||||
unsigned long read_ulong (const std::string &key, unsigned long defaultvalue = 0) const { return read_t (key, defaultvalue, atoul); }
|
||||
long long read_llong (const std::wstring &key, long long defaultvalue = 0) const { return read_t (key, defaultvalue, _wtoll); }
|
||||
long long read_llong (const std::string &key, long long defaultvalue = 0) const { return read_t (key, defaultvalue, atoll); }
|
||||
unsigned long long read_ullong (const std::wstring &key, unsigned long long defaultvalue = 0) const { return read_t (key, defaultvalue, _wtou64); }
|
||||
unsigned long long read_ullong (const std::string &key, unsigned long long defaultvalue = 0) const { return read_t (key, defaultvalue, atou64); }
|
||||
int8_t read_i8 (const std::wstring &key, int8_t defaultvalue = 0) const { return read_t <int8_t, int16_t> (key, defaultvalue, _wtoi8); }
|
||||
int8_t read_i8 (const std::string &key, int8_t defaultvalue = 0) const { return read_t <int8_t, int16_t> (key, defaultvalue, atoi8); }
|
||||
uint8_t read_u8 (const std::wstring &key, uint8_t defaultvalue = 0) const { return read_t <uint8_t, uint16_t> (key, defaultvalue, _wtoui8); }
|
||||
uint8_t read_u8 (const std::string &key, uint8_t defaultvalue = 0) const { return read_t <uint8_t, uint16_t> (key, defaultvalue, atoui8); }
|
||||
int16_t read_i16 (const std::wstring &key, int16_t defaultvalue = 0) const { return read_t (key, defaultvalue, _wtoi16); }
|
||||
int16_t read_i16 (const std::string &key, int16_t defaultvalue = 0) const { return read_t (key, defaultvalue, atoi16); }
|
||||
short read_short (pcwstring key, short defaultvalue = 0) const { return read_i16 (key, defaultvalue); }
|
||||
short read_short (pcstring key, short defaultvalue = 0) const { return read_i16 (key, defaultvalue); }
|
||||
unsigned short read_ushort (pcwstring key, unsigned short defaultvalue = 0) const { return read_u16 (key, defaultvalue); }
|
||||
unsigned short read_ushort (pcstring key, unsigned short defaultvalue = 0) const { return read_u16 (key, defaultvalue); }
|
||||
uint16_t read_u16 (const std::wstring &key, uint16_t defaultvalue = 0) const { return read_t (key, defaultvalue, _wtoui16); }
|
||||
uint16_t read_u16 (const std::string &key, uint16_t defaultvalue = 0) const { return read_t (key, defaultvalue, atoui16); }
|
||||
int32_t read_i32 (const std::wstring &key, int32_t defaultvalue = 0) const { return read_t (key, defaultvalue, _wtoi32); }
|
||||
int32_t read_i32 (const std::string &key, int32_t defaultvalue = 0) const { return read_t (key, defaultvalue, atoi32); }
|
||||
uint32_t read_u32 (const std::wstring &key, uint32_t defaultvalue = 0) const { return read_t (key, defaultvalue, _wtoui32); }
|
||||
uint32_t read_u32 (const std::string &key, uint32_t defaultvalue = 0) const { return read_t (key, defaultvalue, atoui32); }
|
||||
int64_t read_i64 (const std::wstring &key, int64_t defaultvalue = 0) const { return read_t (key, defaultvalue, _wtoi64); }
|
||||
int64_t read_i64 (const std::string &key, int64_t defaultvalue = 0) const { return read_t (key, defaultvalue, atoi64); }
|
||||
uint64_t read_u64 (const std::wstring &key, uint64_t defaultvalue = 0) const { return read_ullong (key, defaultvalue); }
|
||||
uint64_t read_u64 (const std::string &key, uint64_t defaultvalue = 0) const { return read_ullong (key, defaultvalue); }
|
||||
float read_float (const std::wstring &key, float defaultvalue = 0) const { return read_t (key, defaultvalue, _wtof); }
|
||||
double read_double (const std::wstring &key, double defaultvalue = 0) const { return read_t (key, defaultvalue, _wtod); }
|
||||
bool read_bool (const std::wstring &key, bool defaultvalue = false) const
|
||||
{
|
||||
std::wnstring res = read_string (key, defaultvalue ? L"true" : L"false");
|
||||
if (res.empty ()) return defaultvalue;
|
||||
if (res.equals (L"true") || res.equals (L"yes") || res.equals (L"zhen") || res.equals (L"Õæ") || res.equals (L"1") || _wtoi (res.c_str ()) != 0) return true;
|
||||
else if (res.equals (L"false") || res.equals (L"no") || res.equals (L"jia") || res.equals (L"¼Ù") || res.equals (L"0")) return false;
|
||||
else return defaultvalue;
|
||||
}
|
||||
bool read_bool (const std::string &key, bool defaultvalue = false) const { return read_bool (StringToWString (key), defaultvalue); }
|
||||
bool read_struct (const std::wstring &key, void *output, size_t size) const { return GetPrivateProfileStructW (filepath, section, key, output, size); }
|
||||
template <typename T> bool read_struct (const std::wstring &key, T &structinst) const { return read_struct (key, &structinst, sizeof (structinst)); }
|
||||
bool write_string (const std::wstring &key, const std::wstring &value) { return WritePrivateProfileStringW (filepath, section, key, value); }
|
||||
bool write_string (const std::string &key, const std::string &value) { return write_string (StringToWString (key), StringToWString (value)); }
|
||||
bool write (const std::wstring &key, const std::wstring &value) { return write_string (key, value); }
|
||||
bool write (const std::string &key, const std::string &value) { return write_string (key, value); }
|
||||
bool write (pcwstring key, short value) { return write_t (key, value); }
|
||||
bool write (pcwstring key, unsigned short value) { return write_t (key, value); }
|
||||
bool write (pcwstring key, int value) { return write_t (key, value); }
|
||||
bool write (pcwstring key, unsigned int value) { return write_t (key, value); }
|
||||
bool write (pcwstring key, long value) { return write_t (key, value); }
|
||||
bool write (pcwstring key, unsigned long value) { return write_t (key, value); }
|
||||
bool write (pcwstring key, long long value) { return write_t (key, value); }
|
||||
bool write (pcwstring key, unsigned long long value) { return write_t (key, value); }
|
||||
bool write (pcwstring key, int8_t value) { return write_t (key, (int16_t)value); }
|
||||
bool write (pcwstring key, uint8_t value) { return write_t (key, (uint16_t)value); }
|
||||
bool write (pcwstring key, bool value) { return write (key, value ? L"true" : L"false"); }
|
||||
bool write (pcstring key, short value) { return write_t (key, value); }
|
||||
bool write (pcstring key, unsigned short value) { return write_t (key, value); }
|
||||
bool write (pcstring key, int value) { return write_t (key, value); }
|
||||
bool write (pcstring key, unsigned int value) { return write_t (key, value); }
|
||||
bool write (pcstring key, long value) { return write_t (key, value); }
|
||||
bool write (pcstring key, unsigned long value) { return write_t (key, value); }
|
||||
bool write (pcstring key, long long value) { return write_t (key, value); }
|
||||
bool write (pcstring key, unsigned long long value) { return write_t (key, value); }
|
||||
bool write (pcstring key, int8_t value) { return write_t (key, (int16_t)value); }
|
||||
bool write (pcstring key, uint8_t value) { return write_t (key, (uint16_t)value); }
|
||||
bool write (pcstring key, bool value) { return write (StringToWString (key), value ? L"true" : L"false"); }
|
||||
bool write (pcwstring key, void *buf, size_t bufsize) { return WritePrivateProfileStructW (filepath, section, key, buf, bufsize); }
|
||||
bool write (pcstring key, void *buf, size_t bufsize) { return write (StringToWString (key), buf, bufsize); }
|
||||
initkey operator [] (pcwstring key) { return initkey (filepath, section, key); }
|
||||
initkey operator [] (pcstring key) { return initkey (filepath, section, StringToWString (key)); }
|
||||
std::wstring operator [] (pcwstring key) const { return read_string (key); }
|
||||
std::wstring operator [] (pcstring key) const { return read_string (StringToWString (key)); }
|
||||
bool delete_key (pcwstring key) { return DeletePrivateProfileKeyW (filepath, section, key); }
|
||||
bool delete_key (pcstring key) { return delete_key (StringToWString (key)); }
|
||||
bool clear () { return DeletePrivateProfileSectionW (filepath, section); }
|
||||
initkey get_key (pcwstring key) const { return initkey (filepath, section, key); }
|
||||
initkey get_key (pcwstring key) { return initkey (filepath, section, key); }
|
||||
initkey get_key (pcstring key) const { return initkey (filepath, section, StringToWString (key)); }
|
||||
initkey get_key (pcstring key) { return initkey (filepath, section, StringToWString (key)); }
|
||||
initsection &operator = (const initsection &) = delete;
|
||||
};
|
||||
class initfile
|
||||
{
|
||||
public:
|
||||
using pstring = std::string &;
|
||||
using pwstring = std::wstring &;
|
||||
using pcstring = const std::string &;
|
||||
using pcwstring = const std::wstring &;
|
||||
std::wstring filepath;
|
||||
private:
|
||||
template <typename T, typename TRANS = T, typename FN> T read_t (pcwstring section, pcwstring key, T defaultvalue, FN process) const
|
||||
{
|
||||
auto res = read_wstring (section, key, std::to_wstring ((TRANS)defaultvalue));
|
||||
if (IsNormalizeStringEmpty (res)) return defaultvalue;
|
||||
return (T)process (res.c_str ());
|
||||
}
|
||||
template <typename T> bool write_t (pcwstring section, pcwstring key, T value) { return write (section, key, std::to_wstring (value)); }
|
||||
public:
|
||||
initfile (const std::wstring &initpath): filepath (initpath) {}
|
||||
size_t sections (std::vector <std::wstring> §) const { return GetPrivateProfileSectionNamesW (filepath, sect); }
|
||||
size_t sections (std::vector <std::string> §) const { return GetPrivateProfileSectionNamesA (WStringToString (filepath), sect); }
|
||||
bool delete_section (pcwstring section) { return DeletePrivateProfileSectionW (filepath, section); }
|
||||
bool delete_section (pcstring section) { return delete_section (StringToWString (section)); }
|
||||
size_t key_values (pcwstring section, std::vector <std::wstring> &keyvalues) const { return GetPrivateProfileSectionW (filepath, section, keyvalues); }
|
||||
size_t key_values (pcstring section, std::vector <std::string> &keyvalues) const { return GetPrivateProfileSectionA (WStringToString (filepath), section, keyvalues); }
|
||||
size_t keys (pcwstring section, std::vector <std::wstring> &keyvalues) const { return GetPrivateProfileKeysW (filepath, section, keyvalues); }
|
||||
size_t keys (pcstring section, std::vector <std::string> &keyvalues) const { return GetPrivateProfileKeysA (WStringToString (filepath), section, keyvalues); }
|
||||
initsection get_section (pcwstring section) { return initsection (filepath, section); }
|
||||
initsection get_section (pcwstring section) const { return initsection (filepath, section); }
|
||||
std::wstring read_wstring (pcwstring section, pcwstring key, pcwstring dflt = L"") const { return GetPrivateProfileStringW (filepath, section, key, dflt.c_str ()); }
|
||||
std::string read_string (pcwstring section, pcwstring key, pcstring dflt = "") const { return WStringToString (read_wstring (section, key, StringToWString (dflt))); }
|
||||
#define INIT_READ_WARGS(_type_, _dfltvalue_) pcwstring section, pcwstring key, _type_ dflt = _dfltvalue_
|
||||
#define METHOD_INIT_READ(_type_, _typename_, _dfltvalue_, _process_) \
|
||||
_type_ read_##_typename_ (INIT_READ_WARGS (_type_, _dfltvalue_)) const { return read_t (section, key, dflt, _process_); }
|
||||
METHOD_INIT_READ (int, int, 0, _wtoi)
|
||||
METHOD_INIT_READ (unsigned int, uint, 0, _wtou)
|
||||
METHOD_INIT_READ (long, long, 0, _wtol)
|
||||
METHOD_INIT_READ (unsigned long, ulong, 0, _wtoul)
|
||||
METHOD_INIT_READ (long long, llong, 0, _wtoll)
|
||||
METHOD_INIT_READ (unsigned long, ullong, 0, _wtou64)
|
||||
METHOD_INIT_READ (short, short, 0, _wtoi16)
|
||||
METHOD_INIT_READ (unsigned short, ushort, 0, _wtoui16)
|
||||
METHOD_INIT_READ (int16_t, i16, 0, _wtoi16)
|
||||
METHOD_INIT_READ (uint16_t, u16, 0, _wtoui16)
|
||||
METHOD_INIT_READ (int32_t, i32, 0, _wtoi32)
|
||||
METHOD_INIT_READ (uint32_t, u32, 0, _wtoui32)
|
||||
METHOD_INIT_READ (int64_t, i64, 0, _wtoi64)
|
||||
METHOD_INIT_READ (uint64_t, u64, 0, _wtou64)
|
||||
METHOD_INIT_READ (float, float, 0, _wtof)
|
||||
METHOD_INIT_READ (double, double, 0, _wtod)
|
||||
int8_t read_i8 (INIT_READ_WARGS (int8_t, 0)) const { return read_t <int8_t, int16_t> (section, key, dflt, _wtoi8); }
|
||||
uint8_t read_u8 (INIT_READ_WARGS (uint8_t, 0)) const { return read_t <uint8_t, uint16_t> (section, key, dflt, _wtoui8); }
|
||||
bool read_bool (INIT_READ_WARGS (bool, false)) const
|
||||
{
|
||||
std::wnstring res = read_wstring (section, key, dflt ? L"true" : L"false");
|
||||
if (res.empty ()) return dflt;
|
||||
if (res.equals (L"true") || res.equals (L"yes") || res.equals (L"zhen") || res.equals (L"Õæ") || res.equals (L"1") || _wtoi (res.c_str ()) != 0) return true;
|
||||
else if (res.equals (L"false") || res.equals (L"no") || res.equals (L"jia") || res.equals (L"¼Ù") || res.equals (L"0")) return false;
|
||||
else return dflt;
|
||||
}
|
||||
bool read_struct (pcwstring section, pcwstring key, void *output, size_t size) const { return GetPrivateProfileStructW (filepath, section, key, output, size); }
|
||||
template <typename T> bool read_struct (pcwstring section, pcwstring key, T &structinst) const { return read_struct (key, &structinst, sizeof (structinst)); }
|
||||
#ifdef INIT_READ_WARGS
|
||||
#undef INIT_READ_WARGS
|
||||
#endif
|
||||
#ifdef METHOD_INIT_READ
|
||||
#undef METHOD_INIT_READ
|
||||
#endif
|
||||
#define INIT_WRITE_WARGS(_type_) pcwstring section, pcwstring key, _type_ value
|
||||
bool write (INIT_WRITE_WARGS (pcwstring)) { return WritePrivateProfileStringW (filepath, section, key, value); }
|
||||
#define METHOD_INIT_WRITE(_type_) \
|
||||
bool write (INIT_WRITE_WARGS (_type_)) { return write_t (section, key, value); }
|
||||
METHOD_INIT_WRITE (short)
|
||||
METHOD_INIT_WRITE (unsigned short)
|
||||
METHOD_INIT_WRITE (int)
|
||||
METHOD_INIT_WRITE (unsigned int)
|
||||
METHOD_INIT_WRITE (long)
|
||||
METHOD_INIT_WRITE (unsigned long)
|
||||
METHOD_INIT_WRITE (long long)
|
||||
METHOD_INIT_WRITE (unsigned long long)
|
||||
METHOD_INIT_WRITE (float)
|
||||
METHOD_INIT_WRITE (double)
|
||||
bool write (INIT_WRITE_WARGS (bool)) { return write (section, key, value ? L"true" : L"false"); }
|
||||
bool write (INIT_WRITE_WARGS (int8_t)) { return write_t (section, key, (int16_t)value); }
|
||||
bool write (INIT_WRITE_WARGS (uint8_t)) { return write_t (section, key, (uint16_t)value); }
|
||||
bool write (pcwstring section, pcwstring key, void *buf, size_t bufsize) { return WritePrivateProfileStructW (filepath, section, key, buf, bufsize); }
|
||||
initsection operator [] (pcwstring section) { return initsection (filepath, section); }
|
||||
initsection operator [] (pcstring section) { return initsection (filepath, StringToWString (section)); }
|
||||
initsection operator [] (pcwstring section) const { return initsection (filepath, section); }
|
||||
initsection operator [] (pcstring section) const { return initsection (filepath, StringToWString (section)); }
|
||||
#ifdef METHOD_INIT_WRITE
|
||||
#undef METHOD_INIT_WRITE
|
||||
#endif
|
||||
#ifdef INIT_WRITE_WARGS
|
||||
#undef INIT_WRITE_WARGS
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef __cplusplus_cli
|
||||
namespace Win32
|
||||
{
|
||||
using namespace System;
|
||||
using namespace System::Runtime::InteropServices;
|
||||
[ComVisible (true)]
|
||||
public ref class Key
|
||||
{
|
||||
private:
|
||||
String ^filepath = "";
|
||||
String ^section = "";
|
||||
String ^key = "";
|
||||
public:
|
||||
property String ^FilePath { String ^get () { return filepath; }}
|
||||
property String ^Section { String ^get () { return section; }}
|
||||
property String ^KeyName { String ^get () { return key; }}
|
||||
Key (String ^file, String ^sect, String ^k): filepath (file), section (sect), key (k) {}
|
||||
Object ^Get (Object ^dflt)
|
||||
{
|
||||
auto res = GetPrivateProfileStringW (
|
||||
MPStringToStdW (filepath),
|
||||
MPStringToStdW (section),
|
||||
MPStringToStdW (key),
|
||||
dflt ? MPStringToStdW (dflt->ToString ()).c_str () : L""
|
||||
);
|
||||
return CStringToMPString (res);
|
||||
}
|
||||
Object ^Get ()
|
||||
{
|
||||
auto res = GetPrivateProfileStringW (
|
||||
MPStringToStdW (filepath),
|
||||
MPStringToStdW (section),
|
||||
MPStringToStdW (key)
|
||||
);
|
||||
return CStringToMPString (res);
|
||||
}
|
||||
bool Set (Object ^value)
|
||||
{
|
||||
return WritePrivateProfileStringW (
|
||||
MPStringToStdW (filepath),
|
||||
MPStringToStdW (section),
|
||||
MPStringToStdW (key),
|
||||
MPStringToStdW (value ? value->ToString () : L"")
|
||||
);
|
||||
}
|
||||
property Object ^Value { Object ^get () { return Get (); } void set (Object ^value) { Set (value); } }
|
||||
Key %operator = (Object ^value) { Value = value; return *this; }
|
||||
operator String ^ () { return Value->ToString (); }
|
||||
explicit operator bool ()
|
||||
{
|
||||
auto boolstr = Value->ToString ()->Trim ()->ToLower ();
|
||||
if (boolstr == "true" || boolstr == "zhen" || boolstr == "yes" || boolstr == "Õæ") return true;
|
||||
else if (boolstr == "false" || boolstr == "jia" || boolstr == "no" || boolstr == "¼Ù") return false;
|
||||
else return false;
|
||||
}
|
||||
#define OPERATOR_TRANSITION_DEFINE(type, transfunc, defaultret) \
|
||||
operator type () { try { transfunc (Value->ToString ()); } catch (...) { return defaultret; }}
|
||||
OPERATOR_TRANSITION_DEFINE (int8_t, Convert::ToSByte, 0)
|
||||
OPERATOR_TRANSITION_DEFINE (uint8_t, Convert::ToByte, 0)
|
||||
OPERATOR_TRANSITION_DEFINE (int16_t, Convert::ToInt16, 0)
|
||||
OPERATOR_TRANSITION_DEFINE (uint16_t, Convert::ToUInt16, 0)
|
||||
OPERATOR_TRANSITION_DEFINE (int32_t, Convert::ToInt32, 0)
|
||||
OPERATOR_TRANSITION_DEFINE (uint32_t, Convert::ToUInt32, 0)
|
||||
OPERATOR_TRANSITION_DEFINE (int64_t, Convert::ToInt64, 0)
|
||||
OPERATOR_TRANSITION_DEFINE (uint64_t, Convert::ToUInt64, 0)
|
||||
OPERATOR_TRANSITION_DEFINE (float, Convert::ToSingle, 0)
|
||||
OPERATOR_TRANSITION_DEFINE (double, Convert::ToDouble, 0)
|
||||
OPERATOR_TRANSITION_DEFINE (System::Decimal, Convert::ToDecimal, 0)
|
||||
OPERATOR_TRANSITION_DEFINE (System::DateTime, Convert::ToDateTime, Convert::ToDateTime (0))
|
||||
#ifdef OPERATOR_TRANSITION_DEFINE
|
||||
#undef OPERATOR_TRANSITION_DEFINE
|
||||
#endif
|
||||
};
|
||||
[ComVisible (true)]
|
||||
public ref class Section
|
||||
{
|
||||
private:
|
||||
String ^filepath = "";
|
||||
String ^section = "";
|
||||
public:
|
||||
property String ^FilePath { String ^get () { return filepath; } }
|
||||
property String ^SectionName { String ^get () { return section; } }
|
||||
Section (String ^file, String ^sect): filepath (file), section (sect) {}
|
||||
Key ^GetKey (String ^key) { return gcnew Key (filepath, section, key); }
|
||||
Object ^Get (String ^key, Object ^dflt) { return GetKey (key)->Get (dflt); }
|
||||
Object ^Get (String ^key) { return GetKey (key)->Get (); }
|
||||
bool Set (String ^key, Object ^value) { return GetKey (key)->Set (value); }
|
||||
Key ^operator [] (String ^key) { return GetKey (key); }
|
||||
};
|
||||
[ComVisible (true)]
|
||||
public ref class InitConfig
|
||||
{
|
||||
private:
|
||||
String ^filepath = "";
|
||||
public:
|
||||
property String ^FilePath { String ^get () { return filepath; } void set (String ^path) { filepath = path; } }
|
||||
InitConfig (String ^path): filepath (path) {}
|
||||
InitConfig () {}
|
||||
Section ^GetSection (String ^section) { return gcnew Section (filepath, section); }
|
||||
Key ^GetKey (String ^section, String ^key) { return gcnew Key (filepath, section, key); }
|
||||
Object ^Get (String ^section, String ^key, String ^dflt) { return GetKey (section, key)->Get (dflt); }
|
||||
Object ^Get (String ^section, String ^key) { return GetKey (section, key)->Get (); }
|
||||
Section ^Get (String ^section) { return GetSection (section); }
|
||||
bool Set (String ^section, String ^key, String ^value) { return GetKey (section, key)->Set (value); }
|
||||
Section ^operator [] (String ^section) { return GetSection (section); }
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,249 @@
|
||||
#pragma once
|
||||
#include <WinNls.h>
|
||||
#include <string>
|
||||
#include "typestrans.h"
|
||||
#include "strcode.h"
|
||||
|
||||
#undef GetLocaleInfo
|
||||
std::string GetLocaleInfoA (LCID code, LCTYPE type)
|
||||
{
|
||||
char buf [LOCALE_NAME_MAX_LENGTH] = {0};
|
||||
GetLocaleInfoA (code, type, buf, LOCALE_NAME_MAX_LENGTH);
|
||||
return buf;
|
||||
}
|
||||
std::wstring GetLocaleInfoW (LCID code, LCTYPE type)
|
||||
{
|
||||
WCHAR buf [LOCALE_NAME_MAX_LENGTH] = {0};
|
||||
GetLocaleInfoW (code, type, buf, LOCALE_NAME_MAX_LENGTH);
|
||||
return buf;
|
||||
}
|
||||
void GetLocaleInfo (LCID code, LCTYPE type, std::wstring &output)
|
||||
{
|
||||
output = GetLocaleInfoW (code, type);
|
||||
}
|
||||
void GetLocaleInfo (LCID code, LCTYPE type, std::string &output)
|
||||
{
|
||||
output = GetLocaleInfoA (code, type);
|
||||
}
|
||||
int GetLocaleInfoEx (std::wstring lpLocaleName, LCTYPE type, std::wstring &output)
|
||||
{
|
||||
WCHAR buf [LOCALE_NAME_MAX_LENGTH] = {0};
|
||||
int res = GetLocaleInfoEx (lpLocaleName.c_str (), type, buf, LOCALE_NAME_MAX_LENGTH);
|
||||
if (&output) output = std::wstring (buf);
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef SetLocaleInfo
|
||||
BOOL SetLocaleInfoA (LCID code, LCTYPE type, const std::string &lcData)
|
||||
{
|
||||
return SetLocaleInfoA (code, type, lcData.c_str ());
|
||||
}
|
||||
BOOL SetLocaleInfoW (LCID code, LCTYPE type, const std::wstring &lcData)
|
||||
{
|
||||
return SetLocaleInfoW (code, type, lcData.c_str ());
|
||||
}
|
||||
BOOL SetLocaleInfo (LCID code, LCTYPE type, const std::wstring &lcData)
|
||||
{
|
||||
return SetLocaleInfoW (code, type, lcData);
|
||||
}
|
||||
BOOL SetLocaleInfo (LCID code, LCTYPE type, const std::string &lcData)
|
||||
{
|
||||
return SetLocaleInfoA (code, type, lcData);
|
||||
}
|
||||
|
||||
std::string GetLocaleRestrictedCodeFromLcidA (LCID lcid)
|
||||
{
|
||||
return GetLocaleInfoA (lcid, 89);
|
||||
}
|
||||
std::wstring GetLocaleRestrictedCodeFromLcidW (LCID lcid)
|
||||
{
|
||||
return GetLocaleInfoW (lcid, 89);
|
||||
}
|
||||
void GetLocaleRestrictedCodeFromLcid (LCID lcid, std::string &ret)
|
||||
{
|
||||
ret = GetLocaleRestrictedCodeFromLcidA (lcid);
|
||||
}
|
||||
void GetLocaleRestrictedCodeFromLcid (LCID lcid, std::wstring &ret)
|
||||
{
|
||||
ret = GetLocaleRestrictedCodeFromLcidW (lcid);
|
||||
}
|
||||
|
||||
std::string GetLocaleElaboratedCodeFromLcidA (LCID lcid)
|
||||
{
|
||||
return GetLocaleInfoA (lcid, 90);
|
||||
}
|
||||
std::wstring GetLocaleElaboratedCodeFromLcidW (LCID lcid)
|
||||
{
|
||||
return GetLocaleInfoW (lcid, 90);
|
||||
}
|
||||
void GetLocaleElaboratedCodeFromLcid (LCID lcid, std::wstring &ret)
|
||||
{
|
||||
ret = GetLocaleElaboratedCodeFromLcidW (lcid);
|
||||
}
|
||||
void GetLocaleElaboratedCodeFromLcid (LCID lcid, std::string &ret)
|
||||
{
|
||||
ret = GetLocaleElaboratedCodeFromLcidA (lcid);
|
||||
}
|
||||
|
||||
LCID LocaleCodeToLcidW (const std::wstring &localeCode)
|
||||
{
|
||||
#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
|
||||
try
|
||||
{
|
||||
BYTE buf [LOCALE_NAME_MAX_LENGTH * sizeof (WCHAR)] = {0};
|
||||
int res = GetLocaleInfoEx (localeCode.c_str (), LOCALE_RETURN_NUMBER | LOCALE_ILANGUAGE, (LPWSTR)buf, LOCALE_NAME_MAX_LENGTH);
|
||||
LCID lcid = *((LCID *)buf);
|
||||
return lcid;
|
||||
}
|
||||
catch (const std::exception &e) {}
|
||||
return LocaleNameToLCID (localeCode.c_str (), 0);
|
||||
#else
|
||||
return LocaleNameToLCID (localeCode.c_str (), 0);
|
||||
#endif
|
||||
}
|
||||
LCID LocaleCodeToLcidA (const std::string &localeCode)
|
||||
{
|
||||
std::wstring lcWide = StringToWString (std::string (localeCode));
|
||||
return LocaleCodeToLcidW (lcWide.c_str ());
|
||||
}
|
||||
LCID LocaleCodeToLcid (const std::wstring &loccode)
|
||||
{
|
||||
return LocaleCodeToLcidW (loccode.c_str ());
|
||||
}
|
||||
LCID LocaleCodeToLcid (const std::string &loccode)
|
||||
{
|
||||
return LocaleCodeToLcidA (loccode.c_str ());
|
||||
}
|
||||
|
||||
std::string GetLocaleRestrictedCodeA (LPCSTR lc)
|
||||
{
|
||||
return GetLocaleInfoA (LocaleCodeToLcidA (lc), 89);
|
||||
}
|
||||
std::string GetLocaleRestrictedCodeA (const std::string &lc)
|
||||
{
|
||||
return GetLocaleInfoA (LocaleCodeToLcidA (lc.c_str ()), 89);
|
||||
}
|
||||
std::wstring GetLocaleRestrictedCodeW (LPCWSTR lc)
|
||||
{
|
||||
return GetLocaleInfoW (LocaleCodeToLcidW (lc), 89);
|
||||
}
|
||||
std::wstring GetLocaleRestrictedCodeW (const std::wstring &lc)
|
||||
{
|
||||
return GetLocaleInfoW (LocaleCodeToLcidW (lc.c_str ()), 89);
|
||||
}
|
||||
std::wstring GetLocaleRestrictedCode (const std::wstring &lc) { return GetLocaleRestrictedCodeW (lc); }
|
||||
std::string GetLocaleRestrictedCode (const std::string &lc) { return GetLocaleRestrictedCodeA (lc); }
|
||||
|
||||
std::string GetLocaleElaboratedCodeA (LPCSTR lc)
|
||||
{
|
||||
return GetLocaleInfoA (LocaleCodeToLcidA (lc), 90);
|
||||
}
|
||||
std::string GetLocaleElaboratedCodeA (const std::string &lc)
|
||||
{
|
||||
return GetLocaleInfoA (LocaleCodeToLcidA (lc.c_str ()), 90);
|
||||
}
|
||||
std::wstring GetLocaleElaboratedCodeW (LPCWSTR lc)
|
||||
{
|
||||
return GetLocaleInfoW (LocaleCodeToLcidW (lc), 90);
|
||||
}
|
||||
std::wstring GetLocaleElaboratedCodeW (const std::wstring &lc)
|
||||
{
|
||||
return GetLocaleInfoW (LocaleCodeToLcidW (lc.c_str ()), 90);
|
||||
}
|
||||
std::wstring GetLocaleElaboratedCode (const std::wstring &lc) { return GetLocaleElaboratedCodeW (lc); }
|
||||
std::string GetLocaleElaboratedCode (const std::string &lc) { return GetLocaleElaboratedCodeA (lc); }
|
||||
|
||||
std::string LcidToLocaleCodeA (LCID lcid, char divide = '-')
|
||||
{
|
||||
return GetLocaleRestrictedCodeFromLcidA (lcid) + divide + GetLocaleElaboratedCodeFromLcidA (lcid);
|
||||
}
|
||||
std::wstring LcidToLocaleCodeW (LCID lcid, WCHAR divide = L'-')
|
||||
{
|
||||
#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
|
||||
try
|
||||
{
|
||||
WCHAR buf [LOCALE_NAME_MAX_LENGTH] = {0};
|
||||
LCIDToLocaleName (lcid, buf, LOCALE_NAME_MAX_LENGTH, 0);
|
||||
return buf;
|
||||
}
|
||||
catch (const std::exception &e) {}
|
||||
return GetLocaleRestrictedCodeFromLcidW (lcid) + divide + GetLocaleElaboratedCodeFromLcidW (lcid);
|
||||
#else
|
||||
return GetLocaleRestrictedCodeFromLcidW (lcid) + divide + GetLocaleElaboratedCodeFromLcidW (lcid);
|
||||
#endif
|
||||
}
|
||||
std::wstring LcidToLocaleCode (LCID lcid, WCHAR divide = L'-') { return LcidToLocaleCodeW (lcid, divide); }
|
||||
std::string LcidToLocaleCode (LCID lcid, char divide = '-') { return LcidToLocaleCodeA (lcid, divide); }
|
||||
|
||||
std::wstring GetUserDefaultLocaleName ()
|
||||
{
|
||||
#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
|
||||
try
|
||||
{
|
||||
WCHAR buf [LOCALE_NAME_MAX_LENGTH] = {0};
|
||||
GetUserDefaultLocaleName (buf, LOCALE_NAME_MAX_LENGTH);
|
||||
return buf;
|
||||
}
|
||||
catch (const std::exception &e) {}
|
||||
return LcidToLocaleCodeW (GetUserDefaultLCID ());
|
||||
#else
|
||||
return LcidToLocaleCodeW (GetUserDefaultLCID ());
|
||||
#endif
|
||||
}
|
||||
std::wstring GetSystemDefaultLocaleName ()
|
||||
{
|
||||
#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
|
||||
try
|
||||
{
|
||||
WCHAR buf [LOCALE_NAME_MAX_LENGTH] = {0};
|
||||
GetSystemDefaultLocaleName (buf, LOCALE_NAME_MAX_LENGTH);
|
||||
return buf;
|
||||
}
|
||||
catch (const std::exception &e) {}
|
||||
return LcidToLocaleCodeW (GetSystemDefaultLCID ());
|
||||
#else
|
||||
return LcidToLocaleCodeW (GetSystemDefaultLCID ());
|
||||
#endif
|
||||
}
|
||||
|
||||
std::wstring GetComputerLocaleCodeW ()
|
||||
{
|
||||
#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
|
||||
{
|
||||
try
|
||||
{
|
||||
{
|
||||
LCID lcid = GetThreadLocale ();
|
||||
std::wstring tmp = LcidToLocaleCodeW (lcid);
|
||||
if (lcid && tmp.length () > 1) return tmp;
|
||||
}
|
||||
{
|
||||
WCHAR buf [LOCALE_NAME_MAX_LENGTH] = {0};
|
||||
GetUserDefaultLocaleName (buf, LOCALE_NAME_MAX_LENGTH);
|
||||
if (lstrlenW (buf)) return buf;
|
||||
}
|
||||
{
|
||||
WCHAR buf [LOCALE_NAME_MAX_LENGTH] = {0};
|
||||
GetSystemDefaultLocaleName (buf, LOCALE_NAME_MAX_LENGTH);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e) {}
|
||||
LCID lcid = GetThreadLocale ();
|
||||
if (!lcid) lcid = GetUserDefaultLCID ();
|
||||
if (!lcid) lcid = GetSystemDefaultLCID ();
|
||||
return LcidToLocaleCodeW (lcid);
|
||||
}
|
||||
#else
|
||||
{
|
||||
LCID lcid = GetThreadLocale ();
|
||||
if (!lcid) lcid = GetUserDefaultLCID ();
|
||||
if (!lcid) lcid = GetSystemDefaultLCID ();
|
||||
return LcidToLocaleCodeW (lcid);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
bool LocaleNameCompare (const std::wstring &left, const std::wstring &right)
|
||||
{
|
||||
return std::wnstring::equals (left, right) || LocaleCodeToLcidW (left) == LocaleCodeToLcidW (right);
|
||||
}
|
||||
@@ -0,0 +1,923 @@
|
||||
#include <Windows.h>
|
||||
#include <set>
|
||||
#include <msclr/marshal_cppstd.h>
|
||||
#include <ShObjIdl.h>
|
||||
#include <MsHTML.h>
|
||||
#include <ExDisp.h>
|
||||
#include <atlbase.h>
|
||||
#include <fstream>
|
||||
#include <comdef.h>
|
||||
#include <vcclr.h>
|
||||
#include <map>
|
||||
#include <rapidjson\document.h>
|
||||
#include <rapidjson\writer.h>
|
||||
#include <rapidjson\stringbuffer.h>
|
||||
#include "module.h"
|
||||
#include "themeinfo.h"
|
||||
#include "mpstr.h"
|
||||
#include "initfile.h"
|
||||
#include "vemani.h"
|
||||
#include "ieshell.h"
|
||||
#include "localeex.h"
|
||||
#include "bridge.h"
|
||||
#include "rctools.h"
|
||||
#include "nstring.h"
|
||||
#include "resmap.h"
|
||||
#include "nstring.h"
|
||||
#include "raii.h"
|
||||
|
||||
using namespace System;
|
||||
using namespace System::Runtime::InteropServices;
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define DEBUGMODE true
|
||||
#else
|
||||
#define DEBUGMODE false
|
||||
#endif
|
||||
#define JS_SAFE [MarshalAs (UnmanagedType::SafeArray, SafeArraySubType = VarEnum::VT_VARIANT)]
|
||||
struct iconhandle
|
||||
{
|
||||
HICON hIcon = nullptr;
|
||||
iconhandle (HICON hIcon = nullptr): hIcon (hIcon) {}
|
||||
~iconhandle () { try { if (hIcon) DestroyIcon (hIcon); hIcon = nullptr; } catch (...) {} }
|
||||
};
|
||||
|
||||
LPCWSTR g_lpAppId = L"WindowsModern.PracticalToolsProject!Settings";
|
||||
LPCWSTR g_idInVe = L"Settings";
|
||||
iconhandle g_hIconMain (LoadRCIcon (IDI_ICON_MAIN));
|
||||
initfile g_initfile (CombinePath (GetProgramRootDirectoryW (), L"config.ini"));
|
||||
vemanifest g_vemani (
|
||||
IsFileExists (CombinePath (GetProgramRootDirectoryW (), L"VisualElementsManifest.xml")) ?
|
||||
CombinePath (GetProgramRootDirectoryW (), L"VisualElementsManifest.xml") :
|
||||
CombinePath (GetProgramRootDirectoryW (), L"Settings.VisualElementsManifest.xml")
|
||||
);
|
||||
resxmldoc g_scaleres (
|
||||
IsFileExists (CombinePath (GetProgramRootDirectoryW (), L"VisualElements\\scale.xml")) ?
|
||||
CombinePath (GetProgramRootDirectoryW (), L"VisualElements\\scale.xml") :
|
||||
CombinePath (GetProgramRootDirectoryW (), L"VisualElementsManifest.xml")
|
||||
);
|
||||
ref class MainHtmlWnd;
|
||||
msclr::gcroot <MainHtmlWnd ^> g_mainwnd;
|
||||
std::wstring g_lastfile;
|
||||
inline std::wstring ToStdWString (const std::wstring &str) { return str; }
|
||||
|
||||
size_t ExploreFile (HWND hParent, std::vector <std::wstring> &results, LPWSTR lpFilter = L"Windows Store App Package (*.appx; *.appxbundle)\0*.appx;*.appxbundle", DWORD dwFlags = OFN_EXPLORER | OFN_ALLOWMULTISELECT | OFN_PATHMUSTEXIST, const std::wstring &swWndTitle = std::wstring (L"Please select the file(-s): "), const std::wstring &swInitDir = GetFileDirectoryW (g_lastfile))
|
||||
{
|
||||
results.clear ();
|
||||
const DWORD BUFFER_SIZE = 65536; // 64KB
|
||||
std::vector <WCHAR> buffer (BUFFER_SIZE, 0);
|
||||
OPENFILENAME ofn;
|
||||
ZeroMemory (&ofn, sizeof (ofn));
|
||||
ofn.hwndOwner = hParent;
|
||||
ofn.lpstrFile = (LPWSTR)buffer.data ();
|
||||
ofn.nMaxFile = BUFFER_SIZE;
|
||||
ofn.lpstrFilter = lpFilter;
|
||||
ofn.nFilterIndex = 1;
|
||||
ofn.lpstrTitle = swWndTitle.c_str ();
|
||||
ofn.Flags = dwFlags;
|
||||
ofn.lpstrInitialDir = swInitDir.c_str ();
|
||||
ofn.lStructSize = sizeof (ofn);
|
||||
if (GetOpenFileNameW (&ofn))
|
||||
{
|
||||
LPCWSTR p = buffer.data ();
|
||||
std::wstring dir = p;
|
||||
p += dir.length () + 1;
|
||||
if (*p == 0) results.push_back (dir);
|
||||
else
|
||||
{
|
||||
while (*p)
|
||||
{
|
||||
std::wstring fullPath = dir + L"\\" + p;
|
||||
results.push_back (fullPath);
|
||||
p += wcslen (p) + 1;
|
||||
}
|
||||
}
|
||||
if (!results.empty ()) g_lastfile = results.back ();
|
||||
}
|
||||
return results.size ();
|
||||
}
|
||||
HRESULT GetWebBrowser2Interface (System::Windows::Forms::WebBrowser ^fwb, IWebBrowser2 **output)
|
||||
{
|
||||
if (fwb == nullptr || output == nullptr) return E_INVALIDARG;
|
||||
*output = nullptr;
|
||||
Object ^activeX = fwb->ActiveXInstance;
|
||||
if (activeX == nullptr) return E_FAIL;
|
||||
IntPtr pUnk = Marshal::GetIUnknownForObject (activeX);
|
||||
if (pUnk == IntPtr::Zero) return E_FAIL;
|
||||
HRESULT hr = ((IUnknown *)pUnk.ToPointer ())->QueryInterface (IID_IWebBrowser2, (void **)output);
|
||||
Marshal::Release (pUnk);
|
||||
return hr;
|
||||
}
|
||||
bool IsWindows10 ()
|
||||
{
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4996)
|
||||
OSVERSIONINFOEX osvi = {0};
|
||||
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
|
||||
osvi.dwMajorVersion = 10;
|
||||
DWORDLONG conditionMask = 0;
|
||||
VER_SET_CONDITION (conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||
if (VerifyVersionInfoW (&osvi, VER_MAJORVERSION, conditionMask)) return TRUE;
|
||||
DWORD error = GetLastError ();
|
||||
return (error == ERROR_OLD_WIN_VERSION) ? FALSE : FALSE;
|
||||
#pragma warning(pop)
|
||||
}
|
||||
[ComVisible (true)]
|
||||
public ref class _I_InitConfig
|
||||
{
|
||||
public:
|
||||
Win32::InitConfig ^Create (String ^filepath) { return gcnew Win32::InitConfig (filepath); }
|
||||
Win32::InitConfig ^GetConfig () { return Create (CStringToMPString (g_initfile.filepath)); }
|
||||
};
|
||||
[ComVisible (true)]
|
||||
public ref class _I_Bridge_Base
|
||||
{
|
||||
protected:
|
||||
_I_String ^str = gcnew _I_String ();
|
||||
_I_InitConfig ^initconfig = gcnew _I_InitConfig ();
|
||||
public:
|
||||
property _I_String ^String { _I_String ^get () { return str; }}
|
||||
property _I_InitConfig ^Config { _I_InitConfig ^get () { return initconfig; }}
|
||||
};
|
||||
[ComVisible (true)]
|
||||
public interface class IScriptBridge
|
||||
{
|
||||
public:
|
||||
virtual Object ^CallEvent (String ^funcName, Object ^e) = 0;
|
||||
};
|
||||
[ComVisible (true)]
|
||||
public ref class _I_Window
|
||||
{
|
||||
private:
|
||||
IScriptBridge ^wndinst = nullptr;
|
||||
public:
|
||||
_I_Window (IScriptBridge ^wnd): wndinst (wnd) {}
|
||||
Object ^CallEvent (String ^name, ... array <Object ^> ^args) { return wndinst->CallEvent (name, args [0]); }
|
||||
};
|
||||
[ComVisible (true)]
|
||||
public ref class _I_UI
|
||||
{
|
||||
private:
|
||||
System::Windows::Forms::Form ^wndinst = nullptr;
|
||||
public:
|
||||
ref struct _I_UI_Size
|
||||
{
|
||||
private:
|
||||
int m_width = 0;
|
||||
int m_height = 0;
|
||||
public:
|
||||
property int width { int get () { return m_width; } }
|
||||
property int height { int get () { return m_height; }}
|
||||
property int Width { int get () { return m_width; } }
|
||||
property int Height { int get () { return m_height; }}
|
||||
int getWidth () { return m_width; }
|
||||
int getHeight () { return m_height; }
|
||||
_I_UI_Size (int w, int h): m_width (w), m_height (h) {}
|
||||
};
|
||||
_I_UI (System::Windows::Forms::Form ^wnd): wndinst (wnd) {}
|
||||
property int DPIPercent { int get () { return GetDPI (); }}
|
||||
property double DPI { double get () { return DPIPercent * 0.01; }}
|
||||
property _I_UI_Size ^WndSize { _I_UI_Size ^get () { return gcnew _I_UI_Size (wndinst->Width, wndinst->Height); } }
|
||||
property _I_UI_Size ^ClientSize { _I_UI_Size ^get () { auto cs = wndinst->ClientSize; return gcnew _I_UI_Size (cs.Width, cs.Height); } }
|
||||
property String ^ThemeColor { String ^get () { return ColorToHtml (GetDwmThemeColor ()); } }
|
||||
property bool DarkMode { bool get () { return IsAppInDarkMode (); }}
|
||||
property String ^HighContrast
|
||||
{
|
||||
String ^get ()
|
||||
{
|
||||
auto highc = GetHighContrastTheme ();
|
||||
switch (highc)
|
||||
{
|
||||
case HighContrastTheme::None: return "none";
|
||||
break;
|
||||
case HighContrastTheme::Black: return "black";
|
||||
break;
|
||||
case HighContrastTheme::White: return "white";
|
||||
break;
|
||||
case HighContrastTheme::Other: return "high";
|
||||
break;
|
||||
default: return "none";
|
||||
break;
|
||||
}
|
||||
return "none";
|
||||
}
|
||||
}
|
||||
};
|
||||
[ComVisible (true)]
|
||||
public ref class _I_Locale
|
||||
{
|
||||
public:
|
||||
property String ^CurrentLocale { String ^get () { return CStringToMPString (GetComputerLocaleCodeW ()); } }
|
||||
property LCID CurrentLCID { LCID get () { return LocaleCodeToLcid (GetComputerLocaleCodeW ()); } }
|
||||
String ^ToLocaleName (LCID lcid) { return CStringToMPString (LcidToLocaleCodeW (lcid)); }
|
||||
LCID ToLCID (String ^localename) { return LocaleCodeToLcidW (MPStringToStdW (localename)); }
|
||||
Object ^LocaleInfo (LCID lcid, LCTYPE lctype) { return CStringToMPString (GetLocaleInfoW (lcid, lctype)); }
|
||||
Object ^LocaleInfoEx (String ^localeName, LCTYPE lctype)
|
||||
{
|
||||
std::wstring output = L"";
|
||||
int ret = GetLocaleInfoEx (MPStringToStdW (localeName), lctype, output);
|
||||
if (output.empty ()) return ret;
|
||||
else return CStringToMPString (output);
|
||||
}
|
||||
};
|
||||
[ComVisible (true)]
|
||||
public ref class _I_System
|
||||
{
|
||||
private:
|
||||
_I_Resources ^ires = gcnew _I_Resources ();
|
||||
_I_Locale ^ilocale = gcnew _I_Locale ();
|
||||
public:
|
||||
property _I_Resources ^Resources { _I_Resources ^get () { return ires; } }
|
||||
property _I_Locale ^Locale { _I_Locale ^get () { return ilocale; } }
|
||||
property bool IsWindows10
|
||||
{
|
||||
bool get ()
|
||||
{
|
||||
OSVERSIONINFOEX osvi = {0};
|
||||
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
|
||||
osvi.dwMajorVersion = 10;
|
||||
DWORDLONG conditionMask = 0;
|
||||
VER_SET_CONDITION (conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||
if (VerifyVersionInfoW (&osvi, VER_MAJORVERSION, conditionMask)) return TRUE;
|
||||
DWORD error = GetLastError ();
|
||||
return (error == ERROR_OLD_WIN_VERSION) ? FALSE : FALSE;
|
||||
}
|
||||
}
|
||||
};
|
||||
public ref class _I_System2: public _I_System
|
||||
{
|
||||
protected:
|
||||
_I_UI ^ui;
|
||||
public:
|
||||
_I_System2 (System::Windows::Forms::Form ^wnd)
|
||||
{
|
||||
ui = gcnew _I_UI (wnd);
|
||||
}
|
||||
property _I_UI ^UI { _I_UI ^get () { return ui; } }
|
||||
};
|
||||
[ComVisible (true)]
|
||||
public ref class _I_Bridge_Base2: public _I_Bridge_Base
|
||||
{
|
||||
protected:
|
||||
_I_Window ^window;
|
||||
public:
|
||||
_I_Bridge_Base2 (IScriptBridge ^iscr)
|
||||
{
|
||||
window = gcnew _I_Window (iscr);
|
||||
}
|
||||
property _I_Window ^Window { _I_Window ^get () { return window; }}
|
||||
};
|
||||
[ComVisible (true)]
|
||||
public ref class _I_Bridge_Base3: public _I_Bridge_Base2
|
||||
{
|
||||
protected:
|
||||
_I_System2 ^system;
|
||||
public:
|
||||
_I_Bridge_Base3 (IScriptBridge ^iscr, System::Windows::Forms::Form ^form): _I_Bridge_Base2 (iscr)
|
||||
{
|
||||
system = gcnew _I_System2 (form);
|
||||
}
|
||||
property _I_System2 ^System { _I_System2 ^get () { return system; }}
|
||||
};
|
||||
[ComVisible (true)]
|
||||
public ref class _I_IEFrame_Base
|
||||
{
|
||||
public:
|
||||
property int Version { int get () { return GetInternetExplorerVersionMajor (); }}
|
||||
String ^ParseHtmlColor (String ^color)
|
||||
{
|
||||
auto dcolor = Drawing::ColorTranslator::FromHtml (color);
|
||||
{
|
||||
rapidjson::Document doc;
|
||||
doc.SetObject ();
|
||||
auto &alloc = doc.GetAllocator ();
|
||||
doc.AddMember ("r", (uint16_t)dcolor.R, alloc);
|
||||
doc.AddMember ("g", (uint16_t)dcolor.G, alloc);
|
||||
doc.AddMember ("b", (uint16_t)dcolor.B, alloc);
|
||||
doc.AddMember ("a", (uint16_t)dcolor.A, alloc);
|
||||
rapidjson::StringBuffer buffer;
|
||||
rapidjson::Writer <rapidjson::StringBuffer> writer (buffer);
|
||||
doc.Accept (writer);
|
||||
std::string utf8 = buffer.GetString ();
|
||||
std::wstring_convert <std::codecvt_utf8 <wchar_t>> conv;
|
||||
return CStringToMPString (conv.from_bytes (utf8));
|
||||
}
|
||||
return "{}";
|
||||
}
|
||||
};
|
||||
|
||||
[ComVisible (true)]
|
||||
public ref class SplashForm: public System::Windows::Forms::Form
|
||||
{
|
||||
public:
|
||||
using PictureBox = System::Windows::Forms::PictureBox;
|
||||
using Timer = System::Windows::Forms::Timer;
|
||||
private:
|
||||
PictureBox ^picbox;
|
||||
Timer ^timer;
|
||||
System::Drawing::Image ^splashimg = nullptr;
|
||||
System::Drawing::Color background = System::Drawing::Color::Transparent;
|
||||
// System::Windows::Forms ^parent = nullptr;
|
||||
double opastep = 0.05;
|
||||
void InitForm ()
|
||||
{
|
||||
this->DoubleBuffered = true;
|
||||
InitializeComponent ();
|
||||
this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::None;
|
||||
this->StartPosition = System::Windows::Forms::FormStartPosition::Manual;
|
||||
this->ShowInTaskbar = false;
|
||||
this->AllowTransparency = true;
|
||||
this->Opacity = 1.0;
|
||||
}
|
||||
void InitializeComponent ()
|
||||
{
|
||||
double dDpi = GetDPI () * 0.01;
|
||||
this->picbox = gcnew System::Windows::Forms::PictureBox ();
|
||||
this->picbox->Size = System::Drawing::Size (620 * dDpi, 300 * dDpi);
|
||||
this->picbox->BackColor = System::Drawing::Color::Transparent;
|
||||
picbox->Anchor = System::Windows::Forms::AnchorStyles::None;
|
||||
picbox->SizeMode = System::Windows::Forms::PictureBoxSizeMode::Zoom;
|
||||
}
|
||||
void OnFadeTimer (Object ^sender, EventArgs ^e)
|
||||
{
|
||||
auto fadeTimer = timer;
|
||||
auto opacityStep = opastep;
|
||||
if (this->Opacity > 0)
|
||||
{
|
||||
this->Opacity -= opacityStep;
|
||||
}
|
||||
else
|
||||
{
|
||||
fadeTimer->Stop ();
|
||||
this->Close ();
|
||||
}
|
||||
}
|
||||
void OnLoad (Object ^sender, EventArgs ^e)
|
||||
{
|
||||
this->ChangePosAndSize ();
|
||||
this->Visible = true;
|
||||
}
|
||||
void OnResize (Object ^sender, EventArgs ^e)
|
||||
{
|
||||
if (IsHandleCreated && picbox->IsHandleCreated)
|
||||
{
|
||||
Drawing::Size sz = this->ClientSize;
|
||||
this->picbox->Location = Drawing::Point (
|
||||
(sz.Width - picbox->Width) * 0.5,
|
||||
(sz.Height - picbox->Height) * 0.5
|
||||
);
|
||||
}
|
||||
}
|
||||
void OnResizeOwner (Object ^sender, EventArgs ^e) { this->ChangePosAndSize (); }
|
||||
void OnLocationChangedOwner (Object ^sender, EventArgs ^e) { this->ChangePosAndSize (); }
|
||||
protected:
|
||||
virtual void OnHandleCreated (EventArgs^ e) override
|
||||
{
|
||||
Form::OnHandleCreated (e);
|
||||
if (Environment::OSVersion->Version->Major >= 6)
|
||||
{
|
||||
INT mr = 0;
|
||||
MARGINS margins = {mr, mr, mr, mr};
|
||||
HRESULT hr = DwmExtendFrameIntoClientArea ((HWND)this->Handle.ToPointer (), &margins);
|
||||
}
|
||||
}
|
||||
public:
|
||||
SplashForm (System::String ^imgpath, System::Drawing::Color backcolor, System::Windows::Forms::Form ^owner)
|
||||
{
|
||||
if (owner != nullptr) this->Owner = owner;
|
||||
InitForm ();
|
||||
std::wstring filefullpath = MPStringToStdW (imgpath);
|
||||
if (filefullpath.find (L'%') != filefullpath.npos) filefullpath = ProcessEnvVars (filefullpath);
|
||||
filefullpath = GetFullPathName (imgpath ? MPStringToStdW (imgpath) : L"");
|
||||
try
|
||||
{
|
||||
auto img = System::Drawing::Image::FromFile (gcnew System::String (filefullpath.c_str ()));
|
||||
if (img != nullptr)
|
||||
{
|
||||
splashimg = img;
|
||||
picbox->Image = img;
|
||||
}
|
||||
}
|
||||
catch (...) {}
|
||||
if (splashimg) picbox->Image = splashimg;
|
||||
try
|
||||
{
|
||||
if (backcolor != Drawing::Color::Transparent)
|
||||
{
|
||||
background = backcolor;
|
||||
picbox->BackColor = backcolor;
|
||||
this->BackColor = backcolor;
|
||||
}
|
||||
else
|
||||
{
|
||||
picbox->BackColor = background;
|
||||
this->BackColor = background;
|
||||
}
|
||||
}
|
||||
catch (...) {}
|
||||
if (this->Owner != nullptr)
|
||||
{
|
||||
this->Owner->Resize += gcnew System::EventHandler (this, &SplashForm::OnResizeOwner);
|
||||
this->Owner->LocationChanged += gcnew System::EventHandler (this, &SplashForm::OnLocationChangedOwner);
|
||||
}
|
||||
this->Controls->Add (picbox);
|
||||
this->Resize += gcnew EventHandler (this, &SplashForm::OnResize);
|
||||
timer = gcnew System::Windows::Forms::Timer ();
|
||||
timer->Interval = 15;
|
||||
timer->Tick += gcnew System::EventHandler (this, &SplashForm::OnFadeTimer);
|
||||
this->Load += gcnew EventHandler (this, &SplashForm::OnLoad);
|
||||
}
|
||||
void ReInit ()
|
||||
{
|
||||
InitForm ();
|
||||
picbox = gcnew System::Windows::Forms::PictureBox ();
|
||||
picbox->BackColor = background;
|
||||
if (splashimg) picbox->Image = splashimg;
|
||||
picbox->SizeMode = System::Windows::Forms::PictureBoxSizeMode::Zoom;
|
||||
picbox->Anchor = System::Windows::Forms::AnchorStyles::None;
|
||||
double dDpi = GetDPI () * 0.01;
|
||||
picbox->Size = Drawing::Size (620 * dDpi, 300 * dDpi);
|
||||
this->BackColor = background;
|
||||
this->Controls->Clear ();
|
||||
this->Controls->Add (picbox);
|
||||
timer = gcnew System::Windows::Forms::Timer ();
|
||||
timer->Interval = 15;
|
||||
timer->Tick += gcnew EventHandler (this, &SplashForm::OnFadeTimer);
|
||||
this->Resize += gcnew EventHandler (this, &SplashForm::OnResize);
|
||||
this->Load += gcnew EventHandler (this, &SplashForm::OnLoad);
|
||||
ChangePosAndSize ();
|
||||
this->Opacity = 1.0;
|
||||
}
|
||||
void ChangePosAndSize ()
|
||||
{
|
||||
if (this->Owner && this->Owner->IsHandleCreated)
|
||||
{
|
||||
this->Owner->Update ();
|
||||
System::Drawing::Point pt = this->Owner->PointToScreen (this->Owner->ClientRectangle.Location);
|
||||
this->Location = pt;
|
||||
this->Size = this->Owner->ClientSize;
|
||||
}
|
||||
else if (this->Parent && this->Parent->IsHandleCreated)
|
||||
{
|
||||
this->Parent->Update ();
|
||||
System::Drawing::Point pt = this->Parent->PointToScreen (this->Parent->ClientRectangle.Location);
|
||||
this->Location = pt;
|
||||
this->Size = this->Parent->ClientSize;
|
||||
}
|
||||
if (IsHandleCreated && picbox->IsHandleCreated)
|
||||
{
|
||||
Drawing::Size sz = this->ClientSize;
|
||||
this->picbox->Location = Drawing::Point (
|
||||
(sz.Width - picbox->Width) * 0.5,
|
||||
(sz.Height - picbox->Height) * 0.5
|
||||
);
|
||||
}
|
||||
}
|
||||
void SetSplashImage (System::Drawing::Image ^img) { if (picbox && picbox->IsHandleCreated) { splashimg = img; picbox->Image = splashimg; } else splashimg = img; }
|
||||
void SetSplashImage (System::String ^imgpath) { try { SetSplashImage (System::Drawing::Image::FromFile (imgpath)); } catch (...) {} }
|
||||
void SetSplashImage (const std::wstring &imgpath) { SetSplashImage (CStringToMPString (imgpath)); }
|
||||
void SetSplashBackgroundColor (System::Drawing::Color color) { background = color; picbox->BackColor = color; this->BackColor = color; }
|
||||
// 渐变消失
|
||||
void FadeOut () { timer->Start (); }
|
||||
// 立即消失
|
||||
void FadeAway () { timer->Start (); }
|
||||
~SplashForm ()
|
||||
{
|
||||
if (this->Owner != nullptr)
|
||||
{
|
||||
this->Owner->Resize -= gcnew System::EventHandler (this, &SplashForm::OnResizeOwner);
|
||||
this->Owner->LocationChanged -= gcnew System::EventHandler (this, &SplashForm::OnLocationChangedOwner);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
[ComVisible (true)]
|
||||
public ref class MainHtmlWnd: public System::Windows::Forms::Form, public IScriptBridge
|
||||
{
|
||||
public:
|
||||
using WebBrowser = System::Windows::Forms::WebBrowser;
|
||||
private:
|
||||
WebBrowser ^webui;
|
||||
SplashForm ^splash;
|
||||
ITaskbarList3 *taskbar = nullptr;
|
||||
public:
|
||||
[ComVisible (true)]
|
||||
ref class _I_UI2: public _I_UI
|
||||
{
|
||||
private:
|
||||
MainHtmlWnd ^wndinst = nullptr;
|
||||
public:
|
||||
_I_UI2 (MainHtmlWnd ^wnd): wndinst (wnd), _I_UI (wnd) {}
|
||||
property String ^SplashImage
|
||||
{
|
||||
String ^get ()
|
||||
{
|
||||
auto uri = gcnew Uri (CStringToMPString (wndinst->GetSuitSplashImage ()));
|
||||
return uri->AbsoluteUri;
|
||||
}
|
||||
}
|
||||
property String ^SplashBackgroundColor
|
||||
{
|
||||
String ^get ()
|
||||
{
|
||||
std::wnstring ret = L"";
|
||||
auto personal = g_initfile [L"Personalization"];
|
||||
auto thememode = personal [L"AppInstaller:ThemeMode"];
|
||||
auto custommode = personal [L"AppInstaller:CustomThemeMode"];
|
||||
bool nowdark =
|
||||
IsNormalizeStringEquals (thememode.read_wstring ().c_str (), L"dark") ||
|
||||
IsNormalizeStringEquals (thememode.read_wstring ().c_str (), L"auto") && IsAppInDarkMode () ||
|
||||
IsNormalizeStringEquals (thememode.read_wstring ().c_str (), L"custom") && IsNormalizeStringEquals (custommode.read_wstring ().c_str (), L"dark") ||
|
||||
IsNormalizeStringEquals (thememode.read_wstring ().c_str (), L"custom") && IsNormalizeStringEquals (custommode.read_wstring ().c_str (), L"auto") && IsAppInDarkMode ();
|
||||
if (nowdark) ret = g_vemani.splash_screen_backgroundcolor_darkmode (g_idInVe);
|
||||
else ret = g_vemani.splash_screen_backgroundcolor (g_idInVe);
|
||||
if (ret.empty ()) ret = g_vemani.splash_screen_backgroundcolor (g_idInVe);
|
||||
if (ret.empty ()) ret = g_vemani.background_color (g_idInVe);
|
||||
return CStringToMPString (ret);
|
||||
}
|
||||
}
|
||||
void ShowSplash () { if (wndinst->SplashScreen->IsHandleCreated) wndinst->SplashScreen->Show (); else wndinst->SplashScreen->ReInit (); }
|
||||
void FadeAwaySplash () { wndinst->SplashScreen->FadeAway (); }
|
||||
void FadeOutSplash () { wndinst->SplashScreen->FadeOut (); }
|
||||
};
|
||||
[ComVisible (true)]
|
||||
ref class IBridge: public _I_Bridge_Base2
|
||||
{
|
||||
private:
|
||||
MainHtmlWnd ^wndinst = nullptr;
|
||||
public:
|
||||
[ComVisible (true)]
|
||||
ref class _I_IEFrame: public _I_IEFrame_Base
|
||||
{
|
||||
private:
|
||||
MainHtmlWnd ^wndinst = nullptr;
|
||||
public:
|
||||
_I_IEFrame (MainHtmlWnd ^wnd): wndinst (wnd) {}
|
||||
property int Scale
|
||||
{
|
||||
int get () { return wndinst->PageScale; }
|
||||
void set (int value) { return wndinst->PageScale = value; }
|
||||
}
|
||||
};
|
||||
[ComVisible (true)]
|
||||
ref class _I_System3: public _I_System
|
||||
{
|
||||
protected:
|
||||
_I_UI2 ^ui2;
|
||||
public:
|
||||
_I_System3 (MainHtmlWnd ^wnd)
|
||||
{
|
||||
ui2 = gcnew _I_UI2 (wnd);
|
||||
}
|
||||
property _I_UI2 ^UI { _I_UI2 ^get () { return ui2; } }
|
||||
};
|
||||
private:
|
||||
_I_IEFrame ^ieframe;
|
||||
_I_System3 ^sys;
|
||||
_I_Storage ^storage;
|
||||
public:
|
||||
IBridge (MainHtmlWnd ^wnd): wndinst (wnd), _I_Bridge_Base2 (wnd)
|
||||
{
|
||||
ieframe = gcnew _I_IEFrame (wnd);
|
||||
sys = gcnew _I_System3 (wnd);
|
||||
storage = gcnew _I_Storage ();
|
||||
}
|
||||
property _I_IEFrame ^IEFrame { _I_IEFrame ^get () { return ieframe; }}
|
||||
property _I_System3 ^System { _I_System3 ^get () { return sys; }}
|
||||
property _I_Storage ^Storage { _I_Storage ^get () { return storage; }}
|
||||
};
|
||||
protected:
|
||||
property WebBrowser ^WebUI { WebBrowser ^get () { return this->webui; } }
|
||||
property SplashForm ^SplashScreen { SplashForm ^get () { return this->splash; } }
|
||||
property int DPIPercent { int get () { return GetDPI (); }}
|
||||
property double DPI { double get () { return DPIPercent * 0.01; }}
|
||||
void InitSize ()
|
||||
{
|
||||
unsigned ww = 0, wh = 0;
|
||||
auto &ini = g_initfile;
|
||||
auto setsect = ini ["Settings"];
|
||||
auto savepos = setsect [L"Settings:SavePosAndSizeBeforeCancel"];
|
||||
auto lastw = setsect [L"Settings:LastWidth"];
|
||||
auto lasth = setsect [L"Settings:LastHeight"];
|
||||
auto defw = setsect [L"Settings:DefaultWidth"];
|
||||
auto defh = setsect [L"Settings:DefaultHeight"];
|
||||
auto minw = setsect [L"Settings:MinimumWidth"];
|
||||
auto minh = setsect [L"Settings:MinimumHeight"];
|
||||
auto lasts = setsect [L"Settings:LastWndState"];
|
||||
if (savepos.read_bool ())
|
||||
{
|
||||
ww = lastw.read_uint (defw.read_uint (rcInt (IDS_DEFAULTWIDTH)));
|
||||
wh = lasth.read_uint (defh.read_uint (rcInt (IDS_DEFAULTHEIGHT)));
|
||||
}
|
||||
else
|
||||
{
|
||||
ww = defw.read_uint (rcInt (IDS_DEFAULTWIDTH));
|
||||
wh = defh.read_uint (rcInt (IDS_DEFAULTHEIGHT));
|
||||
}
|
||||
this->ClientSize = System::Drawing::Size (ww * DPI, wh * DPI);
|
||||
int hborder = this->Size.Width - this->ClientSize.Width,
|
||||
vborder = this->Size.Height - this->ClientSize.Height;
|
||||
this->MinimumSize = System::Drawing::Size (
|
||||
minw.read_uint (rcInt (IDS_MINWIDTH)) * DPI + hborder,
|
||||
minh.read_uint (rcInt (IDS_MINHIEHGT)) * DPI + vborder
|
||||
);
|
||||
this->WindowState = (System::Windows::Forms::FormWindowState)lasts.read_int ((int)System::Windows::Forms::FormWindowState::Normal);
|
||||
}
|
||||
void Init ()
|
||||
{
|
||||
this->Visible = false;
|
||||
this->webui = gcnew System::Windows::Forms::WebBrowser ();
|
||||
this->SuspendLayout ();
|
||||
this->webui->Dock = System::Windows::Forms::DockStyle::Fill;
|
||||
this->webui->IsWebBrowserContextMenuEnabled = DEBUGMODE;
|
||||
this->webui->AllowWebBrowserDrop = false;
|
||||
this->Controls->Add (this->webui);
|
||||
if (g_hIconMain.hIcon)
|
||||
{
|
||||
try { this->Icon = System::Drawing::Icon::FromHandle (IntPtr (g_hIconMain.hIcon)); }
|
||||
catch (...) {}
|
||||
}
|
||||
this->Text = GetRCStringCli (IDS_WINTITLE);
|
||||
this->ResumeLayout (false);
|
||||
webui->ObjectForScripting = gcnew IBridge (this);
|
||||
this->webui->DocumentCompleted += gcnew System::Windows::Forms::WebBrowserDocumentCompletedEventHandler (this, &MainHtmlWnd::OnDocumentCompleted);
|
||||
this->webui->PreviewKeyDown += gcnew System::Windows::Forms::PreviewKeyDownEventHandler (this, &MainHtmlWnd::OnPreviewKeyDown_WebBrowser);
|
||||
this->Resize += gcnew System::EventHandler (this, &MainHtmlWnd::OnResize);
|
||||
this->Load += gcnew EventHandler (this, &MainHtmlWnd::OnCreate);
|
||||
this->ResizeEnd += gcnew EventHandler (this, &MainHtmlWnd::OnResizeEnd);
|
||||
}
|
||||
void OnDocumentCompleted (Object ^sender, System::Windows::Forms::WebBrowserDocumentCompletedEventArgs ^e)
|
||||
{
|
||||
static bool issetdpi = false;
|
||||
if (!issetdpi)
|
||||
{
|
||||
issetdpi = true;
|
||||
ExecScript ("Bridge.Frame.scale = Bridge.Frame.scale * Bridge.UI.dpi");
|
||||
}
|
||||
ExecScript ("Windows.UI.DPI.mode = 1");
|
||||
if (e->Url->ToString () == webui->Url->ToString ())
|
||||
{
|
||||
auto &ini = g_initfile;
|
||||
splash->FadeAway ();
|
||||
}
|
||||
}
|
||||
void OnCreate (System::Object ^sender, System::EventArgs ^e)
|
||||
{
|
||||
splash->Owner = this;
|
||||
splash->ChangePosAndSize ();
|
||||
splash->Show ();
|
||||
splash->Update ();
|
||||
splash->SetSplashImage (GetSuitSplashImage ());
|
||||
System::Windows::Forms::Application::DoEvents ();
|
||||
auto htmlpath = CombinePath (GetProgramRootDirectoryW (), L"html\\settings.html");
|
||||
webui->Navigate (CStringToMPString (htmlpath));
|
||||
if (!IsFileExists (htmlpath))
|
||||
{
|
||||
std::wstring msg = L"Error: cannot find file \"" + htmlpath + L"\".";
|
||||
MessageBoxW (InvokeGetHWND (), msg.c_str (), GetRCStringSW (IDS_WINTITLE).c_str (), MB_ICONERROR);
|
||||
this->Close ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
void OnPreviewKeyDown_WebBrowser (System::Object ^sender, System::Windows::Forms::PreviewKeyDownEventArgs ^e)
|
||||
{
|
||||
if (e->KeyCode == System::Windows::Forms::Keys::F5 || (e->KeyCode == System::Windows::Forms::Keys::R && e->Control))
|
||||
e->IsInputKey = true;
|
||||
}
|
||||
void ResponseSplashChange ()
|
||||
{
|
||||
splash->SetSplashImage (GetSuitSplashImage ());
|
||||
//ExecScript (
|
||||
// "(function () {"
|
||||
// "var splash = Page.splash;"
|
||||
// "if (!splash) return null;"
|
||||
// "splash.imagesrc = Bridge.UI.Splash.imageurl;"
|
||||
// "splash.background = Bridge.UI.Splash.backcolor;"
|
||||
// "var progress = splash.content.querySelector (\"progress\");"
|
||||
// "if (Bridge.Frame.WindowSize.height / Bridge.UI.dpi < 500) {"
|
||||
// "if (progress.classList.contains(\"win-ring\")) progress.classList.remove(\"win-ring\");}"
|
||||
// "else { if (!progress.classList.contains(\"win-ring\")) progress.classList.add(\"win-ring\"); }"
|
||||
// "}) ();"
|
||||
//);
|
||||
}
|
||||
void OnResize (Object ^sender, EventArgs ^e) { ResizeEvent (); }
|
||||
void OnResizeEnd (Object ^sender, EventArgs ^e) {}
|
||||
std::wstring GetSuitSplashImage ()
|
||||
{
|
||||
int limitw = 800 * DPI;
|
||||
int limith = 600 * DPI;
|
||||
std::wstring tag = L"settings-splash";
|
||||
int noww = this->Width;
|
||||
int nowh = this->Height;
|
||||
if (noww >= limitw && nowh >= limith)
|
||||
tag = L"settings-splashlarge";
|
||||
std::wstring path = g_scaleres [tag];
|
||||
if (IsNormalizeStringEmpty (path))
|
||||
path = g_scaleres [L"settings-splash"];
|
||||
if (IsNormalizeStringEmpty (path))
|
||||
path = g_vemani.splash_screen_image (g_idInVe);
|
||||
return path;
|
||||
}
|
||||
void ResizeEvent ()
|
||||
{
|
||||
auto &ini = g_initfile;
|
||||
auto setsect = ini ["Settings"];
|
||||
auto lasts = setsect [L"AppInstaller:LastWndState"];
|
||||
auto savepos = setsect [L"AppInstaller:SavePosAndSizeBeforeCancel"];
|
||||
auto lastw = setsect [L"AppInstaller:LastWidth"];
|
||||
auto lasth = setsect [L"AppInstaller:LastHeight"];
|
||||
switch (this->WindowState)
|
||||
{
|
||||
case System::Windows::Forms::FormWindowState::Normal:
|
||||
case System::Windows::Forms::FormWindowState::Maximized:
|
||||
lasts = (int)this->WindowState;
|
||||
}
|
||||
if (this->WindowState == System::Windows::Forms::FormWindowState::Normal && savepos)
|
||||
{
|
||||
lastw = (int)(this->ClientSize.Width / DPI);
|
||||
lasth = (int)(this->ClientSize.Height / DPI);
|
||||
}
|
||||
ResponseSplashChange ();
|
||||
}
|
||||
void InvokeClose ()
|
||||
{
|
||||
if (this->InvokeRequired) this->Invoke (gcnew Action (this, &MainHtmlWnd::Close));
|
||||
else this->Close ();
|
||||
}
|
||||
IntPtr GetHWnd () { return this->Handle; }
|
||||
delegate IntPtr GetHwndDelegate ();
|
||||
HWND InvokeGetHWND ()
|
||||
{
|
||||
if (this->InvokeRequired)
|
||||
{
|
||||
GetHwndDelegate ^del = gcnew GetHwndDelegate (this, &MainHtmlWnd::GetHWnd);
|
||||
IntPtr result = safe_cast <IntPtr> (this->Invoke (del));
|
||||
return static_cast <HWND> (result.ToPointer ());
|
||||
}
|
||||
else return static_cast <HWND> (this->Handle.ToPointer ());
|
||||
}
|
||||
bool BackPage () { return this->webui->GoBack (); }
|
||||
bool InvokeBackPage ()
|
||||
{
|
||||
if (this->InvokeRequired) return (bool)this->Invoke (gcnew Func <bool> (this, &MainHtmlWnd::BackPage));
|
||||
else return BackPage (); // 当前线程就是 UI 线程
|
||||
}
|
||||
public:
|
||||
MainHtmlWnd ()
|
||||
{
|
||||
InitSize ();
|
||||
System::Windows::Forms::Application::DoEvents ();
|
||||
splash = gcnew SplashForm (
|
||||
CStringToMPString (GetSuitSplashImage ()),
|
||||
StringToColor (CStringToMPString (g_vemani.splash_screen_backgroundcolor (g_idInVe))),
|
||||
this
|
||||
);
|
||||
System::Windows::Forms::Application::DoEvents ();
|
||||
Init ();
|
||||
ITaskbarList3 *ptr = nullptr;
|
||||
HRESULT hr = CoCreateInstance (CLSID_TaskbarList, nullptr, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void **)&ptr);
|
||||
if (SUCCEEDED (hr))
|
||||
{
|
||||
taskbar = ptr;
|
||||
taskbar->HrInit ();
|
||||
}
|
||||
else
|
||||
{
|
||||
taskbar = nullptr;
|
||||
if (ptr) ptr->Release ();
|
||||
}
|
||||
}
|
||||
Object ^CallScriptFunction (String ^lpFuncName, ... array <Object ^> ^alpParams)
|
||||
{
|
||||
try { return this->webui->Document->InvokeScript (lpFuncName, alpParams); }
|
||||
catch (Exception ^e)
|
||||
{
|
||||
try
|
||||
{
|
||||
this->webui->Document->InvokeScript ("messageBoxAsync", gcnew array <Object ^> {
|
||||
e->Message,
|
||||
e->Source,
|
||||
0,
|
||||
CStringToMPString (g_vemani.background_color (g_idInVe))
|
||||
});
|
||||
}
|
||||
catch (Exception ^ex)
|
||||
{
|
||||
MessageBoxW (InvokeGetHWND (), MPStringToStdW (e->Message).c_str (), MPStringToStdW (e->Source).c_str (), 0);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
Object ^CallScriptFunction (String ^lpScriptName)
|
||||
{
|
||||
try { return this->webui->Document->InvokeScript (lpScriptName); }
|
||||
catch (Exception ^ex) { System::Windows::Forms::MessageBox::Show ("Error calling JavaScript function: " + ex->Message); }
|
||||
return nullptr;
|
||||
}
|
||||
Object ^InvokeCallScriptFunction (String ^lpFuncName, ... array <Object ^> ^alpParams)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this->InvokeRequired) return (Object ^)this->Invoke (gcnew Func <String ^, array <Object ^> ^, Object ^> (this, &MainHtmlWnd::CallScriptFunction), lpFuncName, alpParams);
|
||||
else return CallScriptFunction (lpFuncName, alpParams);
|
||||
}
|
||||
catch (Exception ^e) {}
|
||||
return nullptr;
|
||||
}
|
||||
Object ^InvokeCallScriptFunction (String ^lpScriptName)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this->InvokeRequired) return (Object ^)this->Invoke (gcnew Func <String ^, Object ^> (this, &MainHtmlWnd::CallScriptFunction), lpScriptName);
|
||||
else return CallScriptFunction (lpScriptName);
|
||||
}
|
||||
catch (Exception ^e) {}
|
||||
return nullptr;
|
||||
}
|
||||
Object ^ExecScript (... array <Object ^> ^alpScript) { return InvokeCallScriptFunction ("eval", alpScript); }
|
||||
Object ^CallEvent (String ^funcName, Object ^e) override
|
||||
{
|
||||
std::wstring fname = MPStringToStdW (funcName);
|
||||
if (fname == L"InvokeBackPage") InvokeBackPage ();
|
||||
return nullptr;
|
||||
}
|
||||
property int PageScale
|
||||
{
|
||||
int get ()
|
||||
{
|
||||
CComPtr <IWebBrowser2> web2;
|
||||
HRESULT hr = GetWebBrowser2Interface (webui, &web2);
|
||||
if (FAILED (hr)) return 0;
|
||||
VARIANT v;
|
||||
VariantInit (&v);
|
||||
hr = web2->ExecWB (OLECMDID_OPTICAL_ZOOM, OLECMDEXECOPT_DODEFAULT, nullptr, &v);
|
||||
if (FAILED (hr) || v.vt != VT_I4) return 0;
|
||||
int val = v.lVal;
|
||||
VariantClear (&v);
|
||||
return val;
|
||||
}
|
||||
void set (int value)
|
||||
{
|
||||
CComPtr <IWebBrowser2> web2;
|
||||
HRESULT hr = GetWebBrowser2Interface (webui, &web2);
|
||||
if (FAILED (hr)) return;
|
||||
VARIANT v;
|
||||
VariantInit (&v);
|
||||
v.vt = VT_I4;
|
||||
v.lVal = value;
|
||||
web2->ExecWB (OLECMDID_OPTICAL_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER, &v, nullptr);
|
||||
}
|
||||
}
|
||||
~MainHtmlWnd ()
|
||||
{
|
||||
if (taskbar) taskbar->Release ();
|
||||
taskbar = nullptr;
|
||||
}
|
||||
};
|
||||
using MainWnd = MainHtmlWnd;
|
||||
|
||||
HRESULT SetCurrentAppUserModelID (PCWSTR appID)
|
||||
{
|
||||
typedef HRESULT (WINAPI *SetAppUserModelIDFunc)(PCWSTR);
|
||||
HMODULE shell32 = LoadLibraryW (L"shell32.dll");
|
||||
destruct freelib ([&] () {
|
||||
if (shell32) FreeLibrary (shell32);
|
||||
});
|
||||
try
|
||||
{
|
||||
if (!shell32) return E_FAIL;
|
||||
auto SetAppUserModelID = (SetAppUserModelIDFunc)GetProcAddress (shell32, "SetCurrentProcessExplicitAppUserModelID");
|
||||
if (!SetAppUserModelID)
|
||||
{
|
||||
FreeLibrary (shell32);
|
||||
return E_FAIL;
|
||||
}
|
||||
return SetAppUserModelID (appID);
|
||||
}
|
||||
catch (...) { return E_FAIL; }
|
||||
return E_FAIL;
|
||||
}
|
||||
[STAThread]
|
||||
int APIENTRY wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
|
||||
{
|
||||
SetCurrentProcessExplicitAppUserModelID (g_lpAppId);
|
||||
SetProcessDPIAware ();
|
||||
{
|
||||
// 设置当前目录为程序所在目录
|
||||
std::wnstring currdir = GetCurrentDirectoryW ();
|
||||
std::wnstring rootdir = GetProgramRootDirectoryW ();
|
||||
if (!PathEquals (currdir, rootdir)) SetCurrentDirectoryW (rootdir.c_str ());
|
||||
}
|
||||
CoInitializeEx (NULL, COINIT_MULTITHREADED | COINIT_APARTMENTTHREADED);
|
||||
SetupInstanceEnvironment ();
|
||||
destruct relco ([] () {
|
||||
CoUninitialize ();
|
||||
});
|
||||
SetWebBrowserEmulation ();
|
||||
System::Windows::Forms::Application::EnableVisualStyles ();
|
||||
System::Windows::Forms::Application::SetCompatibleTextRenderingDefault (false);
|
||||
auto mwnd = gcnew MainHtmlWnd ();
|
||||
g_mainwnd = mwnd;
|
||||
System::Windows::Forms::Application::Run (mwnd);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
#ifdef __cplusplus
|
||||
#ifndef GetCurrentModule_bRefDefault
|
||||
// 在 C++ 中,GetCurrentModule 将会启用默认值。你可以在之前宏定义此默认值。定义宏时别忘了等号“=”
|
||||
// 用法如:HMODULE GetCurrentModule (BOOL bRef GetCurrentModule_bRefDefault)
|
||||
#define GetCurrentModule_bRefDefault = FALSE
|
||||
#endif
|
||||
#else
|
||||
#define GetCurrentModule_bRefDefault
|
||||
#endif
|
||||
HMODULE GetCurrentModule (BOOL bRef GetCurrentModule_bRefDefault)
|
||||
{
|
||||
HMODULE hModule = NULL;
|
||||
if (GetModuleHandleExW (bRef ? GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS : (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
|
||||
| GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT), (LPCWSTR)GetCurrentModule, &hModule))
|
||||
{
|
||||
return hModule;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
HMODULE GetSelfModuleHandle ()
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
return ((::VirtualQuery (GetSelfModuleHandle, &mbi, sizeof (mbi)) != 0)
|
||||
? (HMODULE)mbi.AllocationBase : NULL);
|
||||
}
|
||||
#ifndef GetModuleHandleW_lpModuleNameDefault
|
||||
#define GetModuleHandleW_lpModuleNameDefault NULL
|
||||
#endif
|
||||
#ifndef DEFAULT_HMODULE
|
||||
#ifdef HMODULE_MODE_EXE
|
||||
#define DEFAULT_HMODULE GetModuleHandleW (NULL)
|
||||
#elif defined (HMODULE_MODE_DLL1)
|
||||
#define DEFAULT_HMODULE GetCurrentModule ()
|
||||
#elif defined (HMODULE_MODE_DLL2)
|
||||
#define DEFAULT_HMODULE GetSelfModuleHandle ()
|
||||
#else
|
||||
#define DEFAULT_HMODULE GetModuleHandleW (GetModuleHandleW_lpModuleNameDefault)
|
||||
#endif
|
||||
#endif
|
||||
#undef GetModuleHandleW_lpModuleNameDefault
|
||||
#ifdef __cplusplus
|
||||
#ifndef hModule_DefaultParam
|
||||
// 在 C++ 中,你可以使用此宏“hModule_DefaultParam”来用于给一些函数的形参定义默认值。你可以在之前宏定义此默认值。定义宏时别忘了等号“=”
|
||||
// 用法如:std::wstring GetRCStringSW (UINT resID, HMODULE hModule hModule_DefaultParam)。
|
||||
#define hModule_DefaultParam = DEFAULT_HMODULE
|
||||
#endif
|
||||
#else
|
||||
#define hModule_DefaultParam
|
||||
#endif
|
||||
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
#include <windef.h>
|
||||
#include <string>
|
||||
#include <vcclr.h>
|
||||
|
||||
using namespace System;
|
||||
using namespace System::Text;
|
||||
|
||||
String ^CStringToMPString (LPCSTR lpstr) { return (lpstr ? gcnew String (lpstr) : String::Empty); }
|
||||
String ^CStringToMPString (LPCWSTR lpstr) { return (lpstr ? gcnew String (lpstr) : String::Empty); }
|
||||
String ^CStringToMPString (const std::string &objstr) { return CStringToMPString (objstr.c_str ()); }
|
||||
String ^CStringToMPString (const std::wstring &objstr) { return CStringToMPString (objstr.c_str ()); }
|
||||
// 转换为 UTF-16,指针不需要释放(本质是指针转换)
|
||||
LPCWSTR MPStringToPtrW (String ^in)
|
||||
{
|
||||
if (in == nullptr) return NULL;
|
||||
pin_ptr <const wchar_t> wch = PtrToStringChars (in);
|
||||
return wch;
|
||||
}
|
||||
// 转换为 std::wstring(UTF-16)
|
||||
std::wstring MPStringToStdW (String^ in)
|
||||
{
|
||||
if (in == nullptr) return std::wstring ();
|
||||
pin_ptr <const wchar_t> wch = PtrToStringChars (in);
|
||||
return std::wstring (wch, in->Length);
|
||||
}
|
||||
// 转换为 ANSI 编码的 std::string
|
||||
std::string MPStringToStdA (String^ in)
|
||||
{
|
||||
if (in == nullptr) return std::string ();
|
||||
array <unsigned char> ^bytes = Encoding::Default->GetBytes (in);
|
||||
pin_ptr <unsigned char> pinned = &bytes [0];
|
||||
return std::string (reinterpret_cast <const char *> (pinned), bytes->Length);
|
||||
}
|
||||
// 转换为 UTF-8 编码的 std::string
|
||||
std::string MPStringToStdU8 (String^ in)
|
||||
{
|
||||
if (in == nullptr) return std::string ();
|
||||
array <unsigned char> ^bytes = Encoding::UTF8->GetBytes (in);
|
||||
pin_ptr <unsigned char> pinned = &bytes [0];
|
||||
return std::string (reinterpret_cast <const char*> (pinned), bytes->Length);
|
||||
}
|
||||
@@ -0,0 +1,465 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <locale>
|
||||
#include <cctype>
|
||||
namespace l0km
|
||||
{
|
||||
template <typename E, typename TR = std::char_traits <E>, typename AL = std::allocator <E>> inline std::basic_string<E, TR, AL> toupper (const std::basic_string <E, TR, AL> &src)
|
||||
{
|
||||
std::basic_string <E, TR, AL> dst = src;
|
||||
static const std::locale loc;
|
||||
const std::ctype <E> &ctype = std::use_facet <std::ctype <E>> (loc);
|
||||
for (typename std::basic_string <E, TR, AL>::size_type i = 0; i < src.size (); ++ i)
|
||||
{
|
||||
dst [i] = ctype.toupper (src [i]);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
template <typename E, typename TR = std::char_traits <E>, typename AL = std::allocator <E>> inline std::basic_string <E, TR, AL> tolower (const std::basic_string <E, TR, AL> &src)
|
||||
{
|
||||
std::basic_string <E, TR, AL> dst = src;
|
||||
static const std::locale loc;
|
||||
const std::ctype <E> &ctype = std::use_facet <std::ctype <E>> (loc);
|
||||
for (typename std::basic_string <E, TR, AL>::size_type i = 0; i < src.size (); ++ i)
|
||||
{
|
||||
dst [i] = ctype.tolower (src [i]);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
inline char toupper (char ch)
|
||||
{
|
||||
if (ch < -1) return ch;
|
||||
static const std::locale loc;
|
||||
return std::use_facet <std::ctype <char>> (loc).toupper (ch);
|
||||
}
|
||||
inline char tolower (char ch)
|
||||
{
|
||||
if (ch < -1) return ch;
|
||||
static const std::locale loc;
|
||||
return std::use_facet <std::ctype <char>> (loc).tolower (ch);
|
||||
}
|
||||
inline wchar_t toupper (wchar_t ch)
|
||||
{
|
||||
if (ch < -1) return ch;
|
||||
static const std::locale loc;
|
||||
return std::use_facet <std::ctype <wchar_t>> (loc).toupper (ch);
|
||||
}
|
||||
inline wchar_t tolower (wchar_t ch)
|
||||
{
|
||||
if (ch < -1) return ch;
|
||||
static const std::locale loc;
|
||||
return std::use_facet <std::ctype <wchar_t>> (loc).tolower (ch);
|
||||
}
|
||||
inline int toupper (int ch)
|
||||
{
|
||||
if (ch < -1) return ch;
|
||||
static const std::locale loc;
|
||||
return std::use_facet <std::ctype <int>> (loc).toupper (ch);
|
||||
}
|
||||
inline int tolower (int ch)
|
||||
{
|
||||
if (ch < -1) return ch;
|
||||
static const std::locale loc;
|
||||
return std::use_facet <std::ctype <int>> (loc).tolower (ch);
|
||||
}
|
||||
}
|
||||
template <typename ct> bool is_blank (ct &ch)
|
||||
{
|
||||
return ch == ct (' ') || ch == ct ('\t') || ch == ct ('\n');
|
||||
}
|
||||
template <typename E, typename TR = std::char_traits <E>, typename AL = std::allocator <E>> std::basic_string <E, TR, AL> NormalizeString (const std::basic_string <E, TR, AL> &str, bool upper = false, bool includemidblank = false)
|
||||
{
|
||||
typedef std::basic_string <E, TR, AL> string_type;
|
||||
string_type result;
|
||||
if (str.empty ()) return result;
|
||||
auto begin_it = str.begin ();
|
||||
auto end_it = str.end ();
|
||||
while (begin_it != end_it && is_blank (*begin_it)) ++begin_it;
|
||||
while (end_it != begin_it && is_blank (*(end_it - 1))) --end_it;
|
||||
bool in_space = false;
|
||||
for (auto it = begin_it; it != end_it; ++ it)
|
||||
{
|
||||
if (is_blank (*it))
|
||||
{
|
||||
if (includemidblank)
|
||||
{
|
||||
if (!in_space)
|
||||
{
|
||||
result.push_back (E (' '));
|
||||
in_space = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back (*it);
|
||||
in_space = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back (*it);
|
||||
in_space = false;
|
||||
}
|
||||
}
|
||||
if (upper) return l0km::toupper (result);
|
||||
else return l0km::tolower (result);
|
||||
}
|
||||
template <typename E, typename TR = std::char_traits <E>, typename AL = std::allocator <E>> bool IsNormalizeStringEquals (const std::basic_string <E, TR, AL> &l, const std::basic_string <E, TR, AL> &r, bool includemidblank = false)
|
||||
{
|
||||
auto _local_strlen = [] (const E *p) -> size_t {
|
||||
size_t cnt = 0;
|
||||
while (*(p + cnt)) { cnt ++; }
|
||||
return cnt;
|
||||
};
|
||||
const E *pl = l.c_str ();
|
||||
const E *pr = r.c_str ();
|
||||
while (*pl && is_blank (*pl)) ++ pl;
|
||||
while (*pr && is_blank (*pr)) ++ pr;
|
||||
const E *el = l.c_str () + _local_strlen (l.c_str ());
|
||||
const E *er = r.c_str () + _local_strlen (r.c_str ());
|
||||
while (el > pl && is_blank (*(el - 1))) --el;
|
||||
while (er > pr && is_blank (*(er - 1))) --er;
|
||||
while (pl < el && pr < er)
|
||||
{
|
||||
if (includemidblank)
|
||||
{
|
||||
if (is_blank (*pl) && is_blank (*pr))
|
||||
{
|
||||
while (pl < el && is_blank (*pl)) ++pl;
|
||||
while (pr < er && is_blank (*pr)) ++pr;
|
||||
continue;
|
||||
}
|
||||
else if (is_blank (*pl))
|
||||
{
|
||||
while (pl < el && is_blank (*pl)) ++pl;
|
||||
continue;
|
||||
}
|
||||
else if (is_blank (*pr))
|
||||
{
|
||||
while (pr < er && is_blank (*pr)) ++pr;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (l0km::tolower (*pl) != l0km::tolower (*pr)) return false;
|
||||
++ pl;
|
||||
++ pr;
|
||||
}
|
||||
while (pl < el && is_blank (*pl)) ++ pl;
|
||||
while (pr < er && is_blank (*pr)) ++ pr;
|
||||
return pl == el && pr == er;
|
||||
}
|
||||
template <typename E, typename TR = std::char_traits <E>, typename AL = std::allocator <E>> int64_t NormalizeStringCompare (const std::basic_string <E, TR, AL> &l, const std::basic_string <E, TR, AL> &r, bool includemidblank = false)
|
||||
{
|
||||
auto _local_strlen = [] (const E *p) -> size_t {
|
||||
size_t cnt = 0;
|
||||
while (*(p + cnt)) { cnt ++; }
|
||||
return cnt;
|
||||
};
|
||||
const E *pl = l.c_str ();
|
||||
const E *pr = r.c_str ();
|
||||
while (*pl && is_blank (*pl)) ++ pl;
|
||||
while (*pr && is_blank (*pr)) ++ pr;
|
||||
const E *el = l.c_str () + _local_strlen (l.c_str ());
|
||||
const E *er = r.c_str () + _local_strlen (r.c_str ());
|
||||
while (el > pl && is_blank (*(el - 1))) -- el;
|
||||
while (er > pr && is_blank (*(er - 1))) -- er;
|
||||
while (pl < el && pr < er)
|
||||
{
|
||||
if (includemidblank)
|
||||
{
|
||||
if (is_blank (*pl) && is_blank (*pr))
|
||||
{
|
||||
while (pl < el && is_blank (*pl)) ++pl;
|
||||
while (pr < er && is_blank (*pr)) ++pr;
|
||||
continue;
|
||||
}
|
||||
else if (is_blank (*pl))
|
||||
{
|
||||
while (pl < el && is_blank (*pl)) ++pl;
|
||||
continue;
|
||||
}
|
||||
else if (is_blank (*pr))
|
||||
{
|
||||
while (pr < er && is_blank (*pr)) ++pr;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
E chl = l0km::tolower (*pl);
|
||||
E chr = l0km::tolower (*pr);
|
||||
if (chl != chr) return (int64_t)chl - (int64_t)chr;
|
||||
++ pl;
|
||||
++ pr;
|
||||
}
|
||||
while (pl < el && is_blank (*pl)) ++ pl;
|
||||
while (pr < er && is_blank (*pr)) ++ pr;
|
||||
if (pl == el && pr == er) return 0;
|
||||
if (pl == el) return -1;
|
||||
if (pr == er) return 1;
|
||||
return (int64_t)l0km::tolower (*pl) - (int64_t)l0km::tolower (*pr);
|
||||
}
|
||||
template <typename CharT> bool IsNormalizeStringEquals (const CharT *l, const CharT *r, bool includemidblank = false)
|
||||
{
|
||||
if (!l || !r) return l == r;
|
||||
auto skip_blank = [] (const CharT *&p)
|
||||
{
|
||||
while (*p && is_blank (*p)) ++ p;
|
||||
};
|
||||
const CharT *p1 = l;
|
||||
const CharT *p2 = r;
|
||||
skip_blank (p1);
|
||||
skip_blank (p2);
|
||||
while (*p1 && *p2)
|
||||
{
|
||||
CharT ch1 = l0km::tolower (*p1);
|
||||
CharT ch2 = l0km::tolower (*p2);
|
||||
if (ch1 != ch2) return false;
|
||||
++ p1;
|
||||
++ p2;
|
||||
if (includemidblank)
|
||||
{
|
||||
if (is_blank (*p1) || is_blank (*p2))
|
||||
{
|
||||
skip_blank (p1);
|
||||
skip_blank (p2);
|
||||
}
|
||||
}
|
||||
}
|
||||
skip_blank (p1);
|
||||
skip_blank (p2);
|
||||
return *p1 == 0 && *p2 == 0;
|
||||
}
|
||||
template <typename CharT> int64_t NormalizeStringCompare (const CharT *l, const CharT *r, bool includemidblank = false)
|
||||
{
|
||||
if (!l || !r) return l ? 1 : (r ? -1 : 0);
|
||||
auto skip_blank = [] (const CharT *&p)
|
||||
{
|
||||
while (*p && is_blank (*p)) ++ p;
|
||||
};
|
||||
const CharT *p1 = l;
|
||||
const CharT *p2 = r;
|
||||
skip_blank (p1);
|
||||
skip_blank (p2);
|
||||
while (*p1 && *p2)
|
||||
{
|
||||
CharT ch1 = l0km::tolower (*p1);
|
||||
CharT ch2 = l0km::tolower (*p2);
|
||||
if (ch1 != ch2) return (ch1 < ch2) ? -1 : 1;
|
||||
++ p1;
|
||||
++ p2;
|
||||
if (includemidblank)
|
||||
{
|
||||
if (is_blank (*p1) || is_blank (*p2))
|
||||
{
|
||||
skip_blank (p1);
|
||||
skip_blank (p2);
|
||||
}
|
||||
}
|
||||
}
|
||||
skip_blank (p1);
|
||||
skip_blank (p2);
|
||||
if (*p1 == 0 && *p2 == 0) return 0;
|
||||
if (*p1 == 0) return -1;
|
||||
return 1;
|
||||
}
|
||||
template <typename E, typename TR = std::char_traits <E>, typename AL = std::allocator <E>> bool IsNormalizeStringEmpty (const std::basic_string <E, TR, AL> &str)
|
||||
{
|
||||
return IsNormalizeStringEquals (str, std::basic_string <E, TR, AL> ());
|
||||
}
|
||||
template <typename E, typename TR = std::char_traits <E>, typename AL = std::allocator <E>> std::basic_string <E, TR, AL> StringTrim (const std::basic_string <E, TR, AL> &str, bool includemidblank = false)
|
||||
{
|
||||
typedef std::basic_string <E, TR, AL> string_type;
|
||||
typedef typename string_type::size_type size_type;
|
||||
if (str.empty ()) return string_type ();
|
||||
size_type first = 0;
|
||||
size_type last = str.size ();
|
||||
while (first < last && is_blank (str [first])) ++first;
|
||||
while (last > first && is_blank (str [last - 1])) --last;
|
||||
if (first == last) return string_type ();
|
||||
string_type result;
|
||||
result.reserve (last - first);
|
||||
bool in_space = false;
|
||||
for (size_type i = first; i < last; ++ i)
|
||||
{
|
||||
if (is_blank (str [i]))
|
||||
{
|
||||
if (includemidblank)
|
||||
{
|
||||
if (!in_space)
|
||||
{
|
||||
result.push_back (E (' '));
|
||||
in_space = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back (str [i]);
|
||||
in_space = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back (str [i]);
|
||||
in_space = false;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
template <typename E, typename TR = std::char_traits<E>, typename AL = std::allocator <E>> size_t GetNormalizeStringLength (const std::basic_string <E, TR, AL> &str, bool includemidblank = false)
|
||||
{
|
||||
typedef typename std::basic_string <E, TR, AL>::size_type size_type;
|
||||
if (str.empty ()) return 0;
|
||||
size_type first = 0, last = str.size ();
|
||||
while (first < last && is_blank (str [first])) ++first;
|
||||
while (last > first && is_blank (str [last - 1])) --last;
|
||||
if (first == last) return 0;
|
||||
size_t length = 0;
|
||||
bool in_space = false;
|
||||
for (size_type i = first; i < last; ++i)
|
||||
{
|
||||
if (is_blank (str [i]))
|
||||
{
|
||||
if (includemidblank)
|
||||
{
|
||||
if (!in_space)
|
||||
{
|
||||
++ length;
|
||||
in_space = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++ length;
|
||||
in_space = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++ length;
|
||||
in_space = false;
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
namespace std
|
||||
{
|
||||
|
||||
template <typename ct, typename tr = std::char_traits <ct>, typename al = std::allocator <ct>> class basic_nstring: public std::basic_string <ct, tr, al>
|
||||
{
|
||||
bool default_upper = false, default_include_blank_in_str = false;
|
||||
public:
|
||||
using base = std::basic_string <ct, tr, al>;
|
||||
using derive = std::basic_nstring <ct, tr, al>;
|
||||
using typename base::size_type;
|
||||
using typename base::value_type;
|
||||
using base::base;
|
||||
using pstr = ct *;
|
||||
using pcstr = const ct *;
|
||||
basic_nstring (): base (), default_upper (false), default_include_blank_in_str (false) {}
|
||||
basic_nstring (const ct *pStr): base (pStr), default_upper (false), default_include_blank_in_str (false) {}
|
||||
basic_nstring (const base &str): base (str) {}
|
||||
basic_nstring (base &&str): base (std::move (str)) {}
|
||||
basic_nstring (const ct *data, size_type count): base (data, count), default_upper (false), default_include_blank_in_str (false) {}
|
||||
// template <std::size_t N> basic_nstring (const ct (&arr) [N]) : base (arr, N - 1) {}
|
||||
template <typename InputIt> basic_nstring (InputIt first, InputIt last): base (first, last), default_upper (false), default_include_blank_in_str (false) {}
|
||||
bool upper_default () const { return this->default_upper; }
|
||||
bool upper_default (bool value) { return this->default_upper = value; }
|
||||
bool include_blank_in_str_middle () const { return this->default_include_blank_in_str; }
|
||||
bool include_blank_in_str_middle (bool value) { return this->default_include_blank_in_str = value; }
|
||||
base normalize (bool upper, bool includemidblank) const
|
||||
{
|
||||
return NormalizeString <ct, tr, al> (*this, upper, includemidblank);
|
||||
}
|
||||
base normalize (bool upper) const
|
||||
{
|
||||
return this->normalize (upper, default_include_blank_in_str);
|
||||
}
|
||||
base normalize () const { return this->normalize (default_upper); }
|
||||
base upper (bool includemidblank) const
|
||||
{
|
||||
return NormalizeString <ct, tr, al> (*this, true, includemidblank);
|
||||
}
|
||||
base upper () const { return this->upper (default_include_blank_in_str); }
|
||||
base lower (bool includemidblank) const
|
||||
{
|
||||
return NormalizeString <ct, tr, al> (*this, false, includemidblank);
|
||||
}
|
||||
base lower () const { return this->lower (default_include_blank_in_str); }
|
||||
base trim (bool includemidblank) const
|
||||
{
|
||||
return StringTrim <ct, tr, al> (*this, includemidblank);
|
||||
}
|
||||
base trim () const { return this->trim (default_include_blank_in_str); }
|
||||
size_t length (bool includemidblank) const { return GetNormalizeStringLength (*this, includemidblank); }
|
||||
size_t length () const { return length (default_include_blank_in_str); }
|
||||
bool empty () const
|
||||
{
|
||||
return IsNormalizeStringEmpty (*this);
|
||||
}
|
||||
bool equals (const base &another, bool includemidblank) const
|
||||
{
|
||||
return IsNormalizeStringEquals <ct, tr, al> (*this, another, includemidblank);
|
||||
}
|
||||
bool equals (const base &another) const { return equals (another, default_include_blank_in_str); }
|
||||
int64_t compare (const base &another, bool includemidblank) const
|
||||
{
|
||||
return NormalizeStringCompare <ct, tr, al> (*this, another, includemidblank);
|
||||
}
|
||||
int64_t compare (const base &another) const { return compare (another, default_include_blank_in_str); }
|
||||
base &string () { return *this; }
|
||||
base to_string (bool upper, bool includemidblank) const { return this->normalize (upper, includemidblank); }
|
||||
base to_string (bool upper) const { return this->normalize (upper, default_include_blank_in_str); }
|
||||
base to_string () const { return this->normalize (default_upper); }
|
||||
bool operator == (const base &other) const { return equals (other, false); }
|
||||
bool operator != (const base &other) const { return !equals (other, false); }
|
||||
bool operator < (const base &other) const { return compare (other, false) < 0; }
|
||||
bool operator > (const base &other) const { return compare (other, false) > 0; }
|
||||
bool operator <= (const base &other) const { return compare (other, false) <= 0; }
|
||||
bool operator >= (const base &other) const { return compare (other, false) >= 0; }
|
||||
int64_t operator - (const base &other) const { return compare (other, false); }
|
||||
bool operator == (pcstr &other) const { return equals (other, false); }
|
||||
bool operator != (pcstr &other) const { return !equals (other, false); }
|
||||
bool operator < (pcstr &other) const { return compare (other, false) < 0; }
|
||||
bool operator > (pcstr &other) const { return compare (other, false) > 0; }
|
||||
bool operator <= (pcstr &other) const { return compare (other, false) <= 0; }
|
||||
bool operator >= (pcstr &other) const { return compare (other, false) >= 0; }
|
||||
template <typename E, typename TR = std::char_traits <E>, typename AL = std::allocator <E>>
|
||||
static bool equals (const std::basic_string <E> &l, const std::basic_string <E> &r, bool remove_mid_blank = false)
|
||||
{
|
||||
return IsNormalizeStringEquals <E, TR, AL> (l, r, remove_mid_blank);
|
||||
}
|
||||
template <typename E, typename TR = std::char_traits <E>, typename AL = std::allocator <E>>
|
||||
static int64_t compare (const std::basic_string <E> &l, const std::basic_string <E> &r, bool remove_mid_blank = false)
|
||||
{
|
||||
return NormalizeStringCompare <E, TR, AL> (l, r, remove_mid_blank);
|
||||
}
|
||||
template <typename E, typename TR = std::char_traits <E>, typename AL = std::allocator <E>>
|
||||
static std::basic_string <E, TR, AL> normalize (const std::basic_string <E> &str, bool to_upper = false, bool remove_mid_blank = false)
|
||||
{
|
||||
return NormalizeString <E, TR, AL> (str, to_upper, remove_mid_blank);
|
||||
}
|
||||
template <typename E, typename TR = std::char_traits <E>, typename AL = std::allocator <E>>
|
||||
static std::basic_string <E, TR, AL> trim (const std::basic_string <E> &str, bool remove_mid_blank = false)
|
||||
{
|
||||
return StringTrim <E, TR, AL> (str, remove_mid_blank);
|
||||
}
|
||||
template <typename E, typename TR = std::char_traits <E>, typename AL = std::allocator <E>>
|
||||
static size_t length (const std::basic_string <E> &str, bool remove_mid_blank = false)
|
||||
{
|
||||
return GetNormalizeStringLength <E, TR, AL> (str, remove_mid_blank);
|
||||
}
|
||||
template <typename E, typename TR = std::char_traits <E>, typename AL = std::allocator <E>>
|
||||
static bool empty (const std::basic_string <E> &str)
|
||||
{
|
||||
return IsNormalizeStringEmpty <E, TR, AL> (str);
|
||||
}
|
||||
template <typename E, typename TR = std::char_traits <E>, typename AL = std::allocator <E>>
|
||||
static std::basic_nstring <E, TR, AL> to_nstring (std::basic_string <E> &str) { return std::basic_nstring <E> (str); }
|
||||
template <typename E, typename TR = std::char_traits <E>, typename AL = std::allocator <E>>
|
||||
static std::basic_nstring <E, TR, AL> toupper (const std::basic_nstring <E, TR, AL> &str) { return l0km::toupper (str); }
|
||||
template <typename E, typename TR = std::char_traits <E>, typename AL = std::allocator <E>>
|
||||
static std::basic_nstring <E, TR, AL> tolower (const std::basic_nstring <E, TR, AL> &str) { return l0km::tolower (str); }
|
||||
};
|
||||
|
||||
typedef basic_nstring <char> nstring;
|
||||
typedef basic_nstring <wchar_t> wnstring;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="pugixml" version="1.15.0" targetFramework="native" />
|
||||
<package id="rapidjson" version="1.0.2" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include <functional>
|
||||
typedef struct raii
|
||||
{
|
||||
std::function <void ()> endtask = nullptr;
|
||||
raii (std::function <void ()> pFunc = nullptr): endtask (pFunc) {}
|
||||
~raii () { if (endtask) endtask (); }
|
||||
raii (const raii &) = delete;
|
||||
raii (raii &&) = delete;
|
||||
} destruct;
|
||||
@@ -0,0 +1,121 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
#include <WinBase.h>
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#include "typestrans.h"
|
||||
#include "module.h"
|
||||
|
||||
// 返回的指针如果非空则一定需要用 free 释放
|
||||
LPWSTR GetRCStringW (UINT resID, HMODULE hModule hModule_DefaultParam)
|
||||
{
|
||||
std::vector <WCHAR> buf (256);
|
||||
size_t cnt = 0;
|
||||
CopyStringLoop_GetRCStringW:
|
||||
{
|
||||
size_t len = LoadStringW (hModule, resID, buf.data (), buf.size ());
|
||||
if (cnt > 1625) return _wcsdup (buf.data ());
|
||||
if (len >= buf.size () - 1)
|
||||
{
|
||||
buf.resize (buf.size () + 20);
|
||||
cnt ++;
|
||||
goto CopyStringLoop_GetRCStringW;
|
||||
}
|
||||
else return _wcsdup (buf.data ());
|
||||
}
|
||||
}
|
||||
// 返回的指针如果非空则一定需要用 free 释放
|
||||
LPSTR GetRCStringA (UINT resID, HMODULE hModule hModule_DefaultParam)
|
||||
{
|
||||
std::vector <CHAR> buf (256);
|
||||
size_t cnt = 0;
|
||||
CopyStringLoop_GetRCStringA:
|
||||
{
|
||||
size_t len = LoadStringA (hModule, resID, buf.data (), buf.size ());
|
||||
if (cnt > 1625) return _strdup (buf.data ());
|
||||
if (len >= buf.size () - 1)
|
||||
{
|
||||
buf.resize (buf.size () + 20);
|
||||
cnt ++;
|
||||
goto CopyStringLoop_GetRCStringA;
|
||||
}
|
||||
else return _strdup (buf.data ());
|
||||
}
|
||||
}
|
||||
|
||||
HICON LoadRCIcon (UINT resID, HMODULE hModule hModule_DefaultParam)
|
||||
{
|
||||
return (HICON)LoadImageW (hModule, MAKEINTRESOURCEW (resID), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
|
||||
}
|
||||
HRSRC FindResourceByName (LPCWSTR resourceName, LPCWSTR resourceType, HMODULE hModule hModule_DefaultParam)
|
||||
{
|
||||
return FindResourceW (hModule, resourceName, resourceType);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
#include <string>
|
||||
std::wstring GetRCStringSW (UINT resID, HMODULE hModule hModule_DefaultParam)
|
||||
{
|
||||
std::vector <WCHAR> buf (256);
|
||||
size_t cnt = 0;
|
||||
CopyStringLoop_GetRCStringSW:
|
||||
{
|
||||
size_t len = LoadStringW (hModule, resID, buf.data (), buf.size ());
|
||||
if (cnt > 1625) return buf.data ();
|
||||
if (len >= buf.size () - 1)
|
||||
{
|
||||
buf.resize (buf.size () + 20);
|
||||
cnt ++;
|
||||
goto CopyStringLoop_GetRCStringSW;
|
||||
}
|
||||
else return buf.data ();
|
||||
}
|
||||
}
|
||||
std::string GetRCStringSA (UINT resID, HMODULE hModule hModule_DefaultParam)
|
||||
{
|
||||
std::vector <CHAR> buf (256);
|
||||
size_t cnt = 0;
|
||||
CopyStringLoop_GetRCStringSA:
|
||||
{
|
||||
size_t len = LoadStringA (hModule, resID, buf.data (), buf.size ());
|
||||
if (cnt > 1625) return buf.data ();
|
||||
if (len >= buf.size () - 1)
|
||||
{
|
||||
buf.resize (buf.size () + 20);
|
||||
cnt ++;
|
||||
goto CopyStringLoop_GetRCStringSA;
|
||||
}
|
||||
else return buf.data ();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined (__cplusplus) && defined (__cplusplus_cli)
|
||||
using namespace System;
|
||||
String ^GetRCStringCli (UINT resID, HMODULE hModule hModule_DefaultParam)
|
||||
{
|
||||
std::vector <WCHAR> buf (256);
|
||||
size_t cnt = 0;
|
||||
CopyStringLoop_GetRCStringCli:
|
||||
{
|
||||
size_t len = LoadStringW (hModule, resID, buf.data (), buf.size ());
|
||||
if (cnt > 1625) return gcnew String (buf.data ());
|
||||
if (len >= buf.size () - 1)
|
||||
{
|
||||
buf.resize (buf.size () + 20);
|
||||
cnt ++;
|
||||
goto CopyStringLoop_GetRCStringCli;
|
||||
}
|
||||
else return gcnew String (buf.data ());
|
||||
}
|
||||
}
|
||||
#define GetRCIntValue(_UINT__resID_) toInt (GetRCStringCli (_UINT__resID_))
|
||||
#define GetRCDoubleValue(_UINT__resID_) toDouble (GetRCStringCli (_UINT__resID_))
|
||||
#define GetRCBoolValue(_UINT__resID_) toBool (GetRCStringCli (_UINT__resID_))
|
||||
#define GetRCDateTimeValue(_UINT__resID_) toDateTime (GetRCStringCli (_UINT__resID_))
|
||||
#define rcString(resID) GetRCStringCli (resID)
|
||||
#define rcInt(resID) GetRCIntValue (resID)
|
||||
#define rcDouble(resID) GetRCDoubleValue (resID)
|
||||
#define rcBool(resID) GetRCBoolValue (resID)
|
||||
#define rcDTime(resID) GetRCDateTimeValue (resID)
|
||||
#define rcIcon(resID) LoadRCIcon (resID)
|
||||
#endif
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 220 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 252 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 195 KiB |
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "rctools.h"
|
||||
#include "resource.h"
|
||||
#define MAKENAMEIDMAP(_Res_Name_) {#_Res_Name_, _Res_Name_}
|
||||
std::map <std::string, unsigned> g_nameToId = {
|
||||
MAKENAMEIDMAP (IDS_WINTITLE),
|
||||
MAKENAMEIDMAP (IDS_DEFAULTWIDTH),
|
||||
MAKENAMEIDMAP (IDS_DEFAULTHEIGHT),
|
||||
MAKENAMEIDMAP (IDS_MINWIDTH),
|
||||
MAKENAMEIDMAP (IDS_MINHIEHGT)
|
||||
};
|
||||
|
||||
#ifdef MAKENAMEIDMAP
|
||||
#undef MAKENAMEIDMAP
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus_cli
|
||||
using namespace System;
|
||||
using namespace System::Runtime::InteropServices;
|
||||
[ComVisible (true)]
|
||||
public ref class _I_Resources
|
||||
{
|
||||
public:
|
||||
String ^GetById (unsigned int uiResId) { return GetRCStringCli (uiResId); }
|
||||
unsigned ToId (String ^lpResName)
|
||||
{
|
||||
auto it = g_nameToId.find (MPStringToStdA (lpResName));
|
||||
return (it != g_nameToId.end ()) ? it->second : 0;
|
||||
}
|
||||
String ^ToName (unsigned int ulResId)
|
||||
{
|
||||
for (auto &it : g_nameToId) { if (it.second == ulResId) return CStringToMPString (it.first); }
|
||||
return "";
|
||||
}
|
||||
String ^GetByName (String ^lpResId) { return GetById (ToId (lpResId)); }
|
||||
String ^operator [] (unsigned int uiResId) { return GetRCStringCli (uiResId); }
|
||||
String ^GetFromOthers (String ^filepath, unsigned int resid)
|
||||
{
|
||||
HMODULE module = nullptr;
|
||||
if (filepath && !IsNormalizeStringEmpty (MPStringToStdW (filepath))) module = GetModuleHandleW (MPStringToStdW (filepath).c_str ());
|
||||
else module = GetModuleHandleW (NULL);
|
||||
return GetRCStringCli (resid, module);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,213 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>settings</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;HMODULE_MODE_EXE;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>shlwapi.lib;version.lib;dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;HMODULE_MODE_EXE;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>shlwapi.lib;version.lib;dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System">
|
||||
<HintPath>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing">
|
||||
<HintPath>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Drawing.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Windows.Forms">
|
||||
<HintPath>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Windows.Forms.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\appinstaller\bridge.h" />
|
||||
<ClInclude Include="..\appinstaller\dynarr.h" />
|
||||
<ClInclude Include="..\appinstaller\filepath.h" />
|
||||
<ClInclude Include="..\appinstaller\ieshell.h" />
|
||||
<ClInclude Include="..\appinstaller\initfile.h" />
|
||||
<ClInclude Include="..\appinstaller\localeex.h" />
|
||||
<ClInclude Include="..\appinstaller\module.h" />
|
||||
<ClInclude Include="..\appinstaller\mpstr.h" />
|
||||
<ClInclude Include="..\appinstaller\nstring.h" />
|
||||
<ClInclude Include="..\appinstaller\raii.h" />
|
||||
<ClInclude Include="..\appinstaller\rctools.h" />
|
||||
<ClInclude Include="..\appinstaller\strcmp.h" />
|
||||
<ClInclude Include="..\appinstaller\strcode.h" />
|
||||
<ClInclude Include="..\appinstaller\themeinfo.h" />
|
||||
<ClInclude Include="..\appinstaller\typestrans.h" />
|
||||
<ClInclude Include="..\appinstaller\vemani.h" />
|
||||
<ClInclude Include="..\appinstaller\version.h" />
|
||||
<ClInclude Include="resmap.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="settings.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="res\icons\color.ico" />
|
||||
<Image Include="res\icons\main.ico" />
|
||||
<Image Include="res\icons\white.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\packages\rapidjson.1.0.2\build\native\rapidjson.targets" Condition="Exists('..\packages\rapidjson.1.0.2\build\native\rapidjson.targets')" />
|
||||
<Import Project="..\packages\pugixml.1.15.0\build\native\pugixml.targets" Condition="Exists('..\packages\pugixml.1.15.0\build\native\pugixml.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\rapidjson.1.0.2\build\native\rapidjson.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\rapidjson.1.0.2\build\native\rapidjson.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\pugixml.1.15.0\build\native\pugixml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\pugixml.1.15.0\build\native\pugixml.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -0,0 +1,100 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="源文件">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="头文件">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="资源文件">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\appinstaller\bridge.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\appinstaller\dynarr.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\appinstaller\filepath.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\appinstaller\ieshell.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\appinstaller\initfile.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\appinstaller\localeex.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\appinstaller\module.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\appinstaller\mpstr.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\appinstaller\nstring.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\appinstaller\raii.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\appinstaller\rctools.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\appinstaller\strcmp.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\appinstaller\strcode.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\appinstaller\themeinfo.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\appinstaller\typestrans.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\appinstaller\vemani.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\appinstaller\version.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resmap.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="settings.rc">
|
||||
<Filter>资源文件</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="res\icons\main.ico">
|
||||
<Filter>资源文件</Filter>
|
||||
</Image>
|
||||
<Image Include="res\icons\white.ico">
|
||||
<Filter>资源文件</Filter>
|
||||
</Image>
|
||||
<Image Include="res\icons\color.ico">
|
||||
<Filter>资源文件</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,154 @@
|
||||
#pragma once
|
||||
#include <Shlwapi.h>
|
||||
#include "nstring.h"
|
||||
#ifdef __cplusplus
|
||||
#define ptrnull(ptr) (!(ptr))
|
||||
#else
|
||||
#define ptrnull(ptr) ((ptr) == NULL)
|
||||
#endif
|
||||
#define ptrvalid(ptr) (!ptrnull (ptr))
|
||||
// 用于 char * 或 WCHAR * 字符串(结尾为 NULL),判断是否为非空字符串:指针有效且长度大于 0。千万不能是野指针,否则一定会崩溃!
|
||||
#define strvalid(strptr) (ptrvalid (strptr) && *(strptr))
|
||||
// 用于 char * 或 WCHAR * 字符串(结尾为 NULL),判断是否为空字符串:指针为 NULL 或长度为 0。千万不能是野指针,否则一定会崩溃!
|
||||
#define strnull(strptr) (ptrnull (strptr) || !*(strptr))
|
||||
typedef std::wnstring strlabel, StringLabel;
|
||||
std::wstring StringTrim (const std::wstring &str) { return std::wnstring::trim (str); }
|
||||
std::string StringTrim (const std::string &str) { return std::nstring::trim (str); }
|
||||
#define StringToUpper l0km::toupper
|
||||
#define StringToLower l0km::tolower
|
||||
int LabelCompare (const std::wstring &l1, const std::wstring &l2)
|
||||
{
|
||||
return std::wnstring::compare (l1, l2);
|
||||
}
|
||||
int LabelCompare (const std::string &l1, const std::string &l2)
|
||||
{
|
||||
return std::nstring::compare (l1, l2);
|
||||
}
|
||||
bool LabelEqual (const std::wstring &l1, const std::wstring &l2)
|
||||
{
|
||||
return std::wnstring::equals (l1, l2);
|
||||
}
|
||||
bool LabelEqual (const std::string &l1, const std::string &l2)
|
||||
{
|
||||
return std::wnstring::equals (l1, l2);
|
||||
}
|
||||
bool LabelEmpty (const std::wstring &str) { return std::wnstring::empty (str); }
|
||||
bool LabelEmpty (const std::string &str) { return std::nstring::empty (str); }
|
||||
#define LabelNoEmpty(_str_) (!LabelEmpty (_str_))
|
||||
int InStr (const std::string &text, const std::string &keyword, bool ignoreCase = false)
|
||||
{
|
||||
std::string s1, s2;
|
||||
if (ignoreCase)
|
||||
{
|
||||
s1 = StringToUpper (text);
|
||||
s2 = StringToUpper (keyword);
|
||||
}
|
||||
else
|
||||
{
|
||||
s1 = text;
|
||||
s2 = keyword;
|
||||
}
|
||||
const char *found = StrStrIA (s1.c_str (), s2.c_str ());
|
||||
if (!found)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return found - text.c_str ();
|
||||
}
|
||||
int InStr (const std::wstring &text, const std::wstring &keyword, bool ignoreCase = false)
|
||||
{
|
||||
std::wstring s1, s2;
|
||||
if (ignoreCase)
|
||||
{
|
||||
s1 = StringToUpper (text);
|
||||
s2 = StringToUpper (keyword);
|
||||
}
|
||||
else
|
||||
{
|
||||
s1 = text;
|
||||
s2 = keyword;
|
||||
}
|
||||
const WCHAR *found = StrStrIW (s1.c_str (), s2.c_str ());
|
||||
if (!found)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return found - text.c_str ();
|
||||
}
|
||||
bool StrInclude (const std::string &text, const std::string &keyword, bool ignoreCase = false)
|
||||
{
|
||||
std::string s1, s2;
|
||||
if (ignoreCase)
|
||||
{
|
||||
s1 = StringToUpper (text);
|
||||
s2 = StringToUpper (keyword);
|
||||
}
|
||||
else
|
||||
{
|
||||
s1 = text;
|
||||
s2 = keyword;
|
||||
}
|
||||
const char *found = StrStrIA (s1.c_str (), s2.c_str ());
|
||||
if (!found) return false;
|
||||
return true;
|
||||
}
|
||||
bool StrInclude (const std::wstring &text, const std::wstring &keyword, bool ignoreCase = false)
|
||||
{
|
||||
std::wstring s1, s2;
|
||||
if (ignoreCase)
|
||||
{
|
||||
s1 = StringToUpper (text);
|
||||
s2 = StringToUpper (keyword);
|
||||
}
|
||||
else
|
||||
{
|
||||
s1 = text;
|
||||
s2 = keyword;
|
||||
}
|
||||
const WCHAR *found = StrStrIW (s1.c_str (), s2.c_str ());
|
||||
if (!found) return false;
|
||||
return true;
|
||||
}
|
||||
// 该函数帮助构成 "<str1>\0<str2>\0" 这种字符串,用于通用对话框中的文件框
|
||||
LPCWSTR strcpynull (LPWSTR dest, LPCWSTR endwith, size_t bufsize)
|
||||
{
|
||||
if (!dest || !endwith || bufsize == 0)
|
||||
return dest;
|
||||
if (dest [0] == L'\0' && bufsize > 1)
|
||||
{
|
||||
dest [1] = L'\0';
|
||||
}
|
||||
size_t pos = 0;
|
||||
while (pos < bufsize - 1)
|
||||
{
|
||||
if (dest [pos] == L'\0' && dest [pos + 1] == L'\0')
|
||||
{
|
||||
if (dest [0]) pos ++;
|
||||
break;
|
||||
}
|
||||
pos ++;
|
||||
}
|
||||
size_t i = 0;
|
||||
while (pos < bufsize - 1 && endwith [i] != L'\0')
|
||||
{
|
||||
dest [pos ++] = endwith [i ++];
|
||||
}
|
||||
if (pos < bufsize)
|
||||
{
|
||||
dest [pos] = L'\0';
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
// 取文本左边,注意:长度指的是文本字符数,比如“ch”的长度为2
|
||||
std::wstring GetStringLeft (const std::wstring &str, size_t length)
|
||||
{
|
||||
std::vector <WCHAR> buf (length + 1);
|
||||
lstrcpynW (buf.data (), str.c_str (), length + 1);
|
||||
return buf.data ();
|
||||
}
|
||||
// 取文本右边
|
||||
std::wstring GetStringRight (const std::wstring &str, size_t length)
|
||||
{
|
||||
if (length >= str.length ()) return str;
|
||||
return str.substr (str.length () - length, length).c_str ();
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <Windows.h>
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
std::wstring StringToWString (const std::string &str, UINT codePage = CP_ACP)
|
||||
{
|
||||
if (str.empty ()) return std::wstring ();
|
||||
int len = MultiByteToWideChar (codePage, 0, str.c_str (), -1, nullptr, 0);
|
||||
if (len == 0) return std::wstring ();
|
||||
std::wstring wstr (len - 1, L'\0');
|
||||
MultiByteToWideChar (codePage, 0, str.c_str (), -1, &wstr [0], len);
|
||||
return wstr;
|
||||
}
|
||||
std::string WStringToString (const std::wstring &wstr, UINT codePage = CP_ACP)
|
||||
{
|
||||
if (wstr.empty ()) return std::string ();
|
||||
int len = WideCharToMultiByte (codePage, 0, wstr.c_str (), -1, nullptr, 0, nullptr, nullptr);
|
||||
if (len == 0) return std::string ();
|
||||
std::string str (len - 1, '\0');
|
||||
WideCharToMultiByte (codePage, 0, wstr.c_str (), -1, &str [0], len, nullptr, nullptr);
|
||||
return str;
|
||||
}
|
||||
std::string WStringToUtf8 (const std::wstring& ws)
|
||||
{
|
||||
static std::wstring_convert <std::codecvt_utf8_utf16 <wchar_t>> conv;
|
||||
return conv.to_bytes (ws);
|
||||
}
|
||||
std::wstring Utf8ToWString (const std::string& s)
|
||||
{
|
||||
static std::wstring_convert <std::codecvt_utf8_utf16 <wchar_t>> conv;
|
||||
return conv.from_bytes (s);
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
#include <dwmapi.h>
|
||||
using namespace System;
|
||||
|
||||
bool IsHighContrastEnabled ()
|
||||
{
|
||||
HIGHCONTRAST hc = {sizeof (HIGHCONTRAST)};
|
||||
if (SystemParametersInfo (SPI_GETHIGHCONTRAST, sizeof (hc), &hc, 0)) return (hc.dwFlags & HCF_HIGHCONTRASTON) != 0;
|
||||
return false;
|
||||
}
|
||||
enum class HighContrastTheme
|
||||
{
|
||||
None,
|
||||
Black,
|
||||
White,
|
||||
Other
|
||||
};
|
||||
HighContrastTheme GetHighContrastTheme ()
|
||||
{
|
||||
HIGHCONTRAST hc = {sizeof (HIGHCONTRAST)};
|
||||
if (!SystemParametersInfo (SPI_GETHIGHCONTRAST, sizeof (hc), &hc, 0)) return HighContrastTheme::None;
|
||||
if (!(hc.dwFlags & HCF_HIGHCONTRASTON)) return HighContrastTheme::None;
|
||||
COLORREF bgColor = GetSysColor (COLOR_WINDOW);
|
||||
COLORREF textColor = GetSysColor (COLOR_WINDOWTEXT);
|
||||
int brightnessBg = (GetRValue (bgColor) + GetGValue (bgColor) + GetBValue (bgColor)) / 3;
|
||||
int brightnessText = (GetRValue (textColor) + GetGValue (textColor) + GetBValue (textColor)) / 3;
|
||||
if (brightnessBg < brightnessText) return HighContrastTheme::Black;
|
||||
else if (brightnessBg > brightnessText) return HighContrastTheme::White;
|
||||
else return HighContrastTheme::Other;
|
||||
}
|
||||
int GetDPI ()
|
||||
{
|
||||
HDC hDC = GetDC (NULL);
|
||||
int DPI_A = (int)(((double)GetDeviceCaps (hDC, 118) / (double)GetDeviceCaps (hDC, 8)) * 100);
|
||||
int DPI_B = (int)(((double)GetDeviceCaps (hDC, 88) / 96) * 100);
|
||||
ReleaseDC (NULL, hDC);
|
||||
if (DPI_A == 100) return DPI_B;
|
||||
else if (DPI_B == 100) return DPI_A;
|
||||
else if (DPI_A == DPI_B) return DPI_A;
|
||||
else return 0;
|
||||
}
|
||||
int GetScreenWidth () { return GetSystemMetrics (SM_CXSCREEN); }
|
||||
int GetScreenHeight () { return GetSystemMetrics (SM_CYSCREEN); }
|
||||
System::Drawing::Color GetDwmThemeColor ()
|
||||
{
|
||||
DWORD color = 0;
|
||||
BOOL opaqueBlend = FALSE;
|
||||
// 调用 DwmGetColorizationColor 获取 Aero 颜色
|
||||
HRESULT hr = DwmGetColorizationColor (&color, &opaqueBlend);
|
||||
if (SUCCEEDED (hr))
|
||||
{
|
||||
BYTE r = (BYTE)((color & 0x00FF0000) >> 16);
|
||||
BYTE g = (BYTE)((color & 0x0000FF00) >> 8);
|
||||
BYTE b = (BYTE)(color & 0x000000FF);
|
||||
return System::Drawing::Color::FromArgb (r, g, b);
|
||||
}
|
||||
else return System::Drawing::Color::FromArgb (0, 120, 215); // 如果获取失败,返回默认颜色
|
||||
}
|
||||
String ^ColorToHtml (System::Drawing::Color color)
|
||||
{
|
||||
return String::Format ("#{0:X2}{1:X2}{2:X2}", color.R, color.G, color.B);
|
||||
}
|
||||
System::Drawing::Color StringToColor (String ^colorStr)
|
||||
{
|
||||
using Color = System::Drawing::Color;
|
||||
using Regex = System::Text::RegularExpressions::Regex;
|
||||
auto Clamp = [] (int value, int min, int max)
|
||||
{
|
||||
return (value < min) ? min : (value > max) ? max : value;
|
||||
};
|
||||
String ^normalized = colorStr->Trim ()->ToLower ();
|
||||
if (normalized == "transparent") return Color::Transparent;
|
||||
if (Color::FromName (normalized).IsKnownColor)
|
||||
{
|
||||
return Color::FromName (normalized);
|
||||
}
|
||||
if (normalized->StartsWith ("#"))
|
||||
{
|
||||
String^ hex = normalized->Substring (1);
|
||||
if (hex->Length == 3 || hex->Length == 4)
|
||||
{
|
||||
hex = String::Concat (
|
||||
hex [0].ToString () + hex [0],
|
||||
hex [1].ToString () + hex [1],
|
||||
hex [2].ToString () + hex [2],
|
||||
(hex->Length == 4) ? (hex [3].ToString () + hex [3]) : ""
|
||||
);
|
||||
}
|
||||
uint32_t argb = Convert::ToUInt32 (hex, 16);
|
||||
switch (hex->Length)
|
||||
{
|
||||
case 6: return Color::FromArgb (
|
||||
0xFF,
|
||||
(argb >> 16) & 0xFF,
|
||||
(argb >> 8) & 0xFF,
|
||||
argb & 0xFF
|
||||
);
|
||||
case 8: return Color::FromArgb (
|
||||
(argb >> 24) & 0xFF,
|
||||
(argb >> 16) & 0xFF,
|
||||
(argb >> 8) & 0xFF,
|
||||
argb & 0xFF
|
||||
);
|
||||
default: throw gcnew ArgumentException ("Invalid hex color format");
|
||||
}
|
||||
}
|
||||
System::Text::RegularExpressions::Match ^match = Regex::Match (normalized,
|
||||
"^(rgba?)\\s*\\(\\s*(\\d+%?)\\s*,\\s*(\\d+%?)\\s*,\\s*(\\d+%?)\\s*,?\\s*([\\d.]+%?)?\\s*\\)$");
|
||||
if (match->Success)
|
||||
{
|
||||
auto GetComponent = [&] (String^ val) -> int
|
||||
{
|
||||
if (val->EndsWith ("%"))
|
||||
{
|
||||
float percent = float::Parse (val->TrimEnd ('%')) / 100.0f;
|
||||
return Clamp ((int)Math::Round (percent * 255), 0, 255);
|
||||
}
|
||||
return Clamp (int::Parse (val), 0, 255);
|
||||
};
|
||||
int r = GetComponent (match->Groups [2]->Value);
|
||||
int g = GetComponent (match->Groups [3]->Value);
|
||||
int b = GetComponent (match->Groups [4]->Value);
|
||||
if (match->Groups [1]->Value == "rgba")
|
||||
{
|
||||
String^ alphaVal = match->Groups [5]->Value;
|
||||
int a = 255;
|
||||
if (alphaVal->EndsWith ("%"))
|
||||
{
|
||||
float percent = float::Parse (alphaVal->TrimEnd ('%')) / 100.0f;
|
||||
a = Clamp ((int)Math::Round (percent * 255), 0, 255);
|
||||
}
|
||||
else if (!String::IsNullOrEmpty (alphaVal))
|
||||
{
|
||||
a = Clamp ((int)Math::Round (float::Parse (alphaVal) * 255), 0, 255);
|
||||
}
|
||||
return Color::FromArgb (a, r, g, b);
|
||||
}
|
||||
return Color::FromArgb (r, g, b);
|
||||
}
|
||||
//throw gcnew ArgumentException ("Unsupported color format: " + colorStr);
|
||||
return Color::Transparent;
|
||||
}
|
||||
bool IsAppInDarkMode ()
|
||||
{
|
||||
HKEY hKey;
|
||||
DWORD dwValue;
|
||||
if (RegOpenKeyEx (HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
|
||||
{
|
||||
DWORD dwSize = sizeof (dwValue);
|
||||
if (RegQueryValueEx (hKey, L"AppsUseLightTheme", NULL, NULL, (LPBYTE)&dwValue, &dwSize) == ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey (hKey);
|
||||
return dwValue == 0;
|
||||
}
|
||||
RegCloseKey (hKey);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
#pragma once
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#include <Windows.h>
|
||||
#ifdef __cplusplus
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstdbool>
|
||||
#include <cstring>
|
||||
#include <cstdint>
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <cstdint>
|
||||
#endif
|
||||
unsigned _wtou (const wchar_t *str)
|
||||
{
|
||||
unsigned value = 0;
|
||||
if (str)
|
||||
{
|
||||
swscanf (str, L"%u", &value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
unsigned long _wtoul (const wchar_t *str)
|
||||
{
|
||||
unsigned value = 0;
|
||||
if (str)
|
||||
{
|
||||
swscanf (str, L"%lu", &value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
unsigned long long _wtou64 (const wchar_t *str)
|
||||
{
|
||||
unsigned long long value = 0;
|
||||
if (str)
|
||||
{
|
||||
swscanf (str, L"%llu", &value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
double _wtod (const wchar_t *str)
|
||||
{
|
||||
if (!str || !*str) return 0.0; // 避免空指针或空字符串
|
||||
double value = 0.0;
|
||||
if (swscanf (str, L"%lg", &value) == 1)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
return 0.0; // 解析失败时返回 0.0
|
||||
}
|
||||
unsigned atou (const char *str)
|
||||
{
|
||||
unsigned value = 0;
|
||||
if (str)
|
||||
{
|
||||
sscanf (str, "%u", &value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
unsigned long atoul (const char *str)
|
||||
{
|
||||
unsigned value = 0;
|
||||
if (str)
|
||||
{
|
||||
sscanf (str, "%lu", &value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
unsigned long long atou64 (const char *str)
|
||||
{
|
||||
unsigned long long value = 0;
|
||||
if (str)
|
||||
{
|
||||
sscanf (str, "%llu", &value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
double atod (const char *str)
|
||||
{
|
||||
if (!str || !*str) return 0.0; // 避免空指针或空字符串
|
||||
double value = 0.0;
|
||||
if (sscanf (str, "%lg", &value) == 1)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
return 0.0; // 解析失败时返回 0.0
|
||||
}
|
||||
int8_t atoi8 (const char *str)
|
||||
{
|
||||
int value = 0;
|
||||
if (str) sscanf (str, "%d", &value);
|
||||
return (int8_t)value;
|
||||
}
|
||||
int16_t atoi16 (const char *str)
|
||||
{
|
||||
int value = 0;
|
||||
if (str) sscanf (str, "%d", &value);
|
||||
return (int16_t)value;
|
||||
}
|
||||
int32_t atoi32 (const char *str)
|
||||
{
|
||||
int32_t value = 0;
|
||||
if (str) sscanf (str, "%d", &value);
|
||||
return value;
|
||||
}
|
||||
uint8_t atoui8 (const char *str)
|
||||
{
|
||||
unsigned value = 0;
|
||||
if (str) sscanf (str, "%u", &value);
|
||||
return (uint8_t)value;
|
||||
}
|
||||
uint16_t atoui16 (const char *str)
|
||||
{
|
||||
unsigned value = 0;
|
||||
if (str) sscanf (str, "%u", &value);
|
||||
return (uint16_t)value;
|
||||
}
|
||||
uint32_t atoui32 (const char *str)
|
||||
{
|
||||
uint32_t value = 0;
|
||||
if (str) sscanf (str, "%u", &value);
|
||||
return value;
|
||||
}
|
||||
int8_t _wtoi8 (const wchar_t *str)
|
||||
{
|
||||
int value = 0;
|
||||
if (str) swscanf (str, L"%d", &value);
|
||||
return (int8_t)value;
|
||||
}
|
||||
int16_t _wtoi16 (const wchar_t *str)
|
||||
{
|
||||
int value = 0;
|
||||
if (str) swscanf (str, L"%d", &value);
|
||||
return (int16_t)value;
|
||||
}
|
||||
int32_t _wtoi32 (const wchar_t *str)
|
||||
{
|
||||
int32_t value = 0;
|
||||
if (str) swscanf (str, L"%d", &value);
|
||||
return value;
|
||||
}
|
||||
uint8_t _wtoui8 (const wchar_t *str)
|
||||
{
|
||||
unsigned value = 0;
|
||||
if (str) swscanf (str, L"%u", &value);
|
||||
return (uint8_t)value;
|
||||
}
|
||||
uint16_t _wtoui16 (const wchar_t *str)
|
||||
{
|
||||
unsigned value = 0;
|
||||
if (str) swscanf (str, L"%u", &value);
|
||||
return (uint16_t)value;
|
||||
}
|
||||
uint32_t _wtoui32 (const wchar_t *str)
|
||||
{
|
||||
uint32_t value = 0;
|
||||
if (str) swscanf (str, L"%u", &value);
|
||||
return value;
|
||||
}
|
||||
int64_t atoi64 (const char *str)
|
||||
{
|
||||
int64_t value = 0;
|
||||
if (str) sscanf (str, "%lld", &value);
|
||||
return value;
|
||||
}
|
||||
|
||||
EXTERN_C int StringToIntA (const char *str) { return atoi (str); }
|
||||
EXTERN_C int StringToIntW (const WCHAR *str) { return _wtoi (str); }
|
||||
EXTERN_C unsigned StringToUnsignedA (const char *str) { return atou (str); }
|
||||
EXTERN_C unsigned StringToUnsignedW (const WCHAR *str) { return _wtou (str); }
|
||||
EXTERN_C bool StringToBoolA (const char *str)
|
||||
{
|
||||
char buf [32] = {0};
|
||||
strcpy (buf, str);
|
||||
for (int cnt = 0; buf [cnt]; cnt ++) buf [cnt] = tolower (buf [cnt]);
|
||||
return !strcmp (buf, "true") ||
|
||||
!strcmp (buf, "yes") ||
|
||||
!strcmp (buf, "ok") ||
|
||||
!strcmp (buf, "sure") ||
|
||||
!strcmp (buf, "okay") ||
|
||||
!strcmp (buf, "zhen") ||
|
||||
!strcmp (buf, "真");
|
||||
}
|
||||
EXTERN_C bool StringToBoolW (const WCHAR *str)
|
||||
{
|
||||
WCHAR buf [32] = {0};
|
||||
lstrcpyW (buf, str);
|
||||
for (int cnt = 0; buf [cnt]; cnt ++) buf [cnt] = tolower (buf [cnt]);
|
||||
return !lstrcmpW (buf, L"true") ||
|
||||
!lstrcmpW (buf, L"yes") ||
|
||||
!lstrcmpW (buf, L"ok") ||
|
||||
!lstrcmpW (buf, L"sure") ||
|
||||
!lstrcmpW (buf, L"okay") ||
|
||||
!lstrcmpW (buf, L"zhen") ||
|
||||
!lstrcmpW (buf, L"真");
|
||||
}
|
||||
EXTERN_C long StringToLongA (const char *str) { return atol (str); }
|
||||
EXTERN_C long StringToLongW (const WCHAR *str) { return _wtol (str); }
|
||||
EXTERN_C unsigned long StringToULongA (const char *str) { return atoul (str); }
|
||||
EXTERN_C unsigned long StringToULongW (const WCHAR *str) { return _wtoul (str); }
|
||||
EXTERN_C long long StringToLongLongA (const char *str) { return atoll (str); }
|
||||
EXTERN_C long long StringToLongLongW (const WCHAR *str) { return _wtoll (str); }
|
||||
EXTERN_C unsigned long long StringToULongLongA (const char *str) { return atou64 (str); }
|
||||
EXTERN_C unsigned long long StringToULongLongW (const WCHAR *str) { return _wtou64 (str); }
|
||||
EXTERN_C float StringToFloatA (const char *str) { return atof (str); }
|
||||
EXTERN_C float StringToFloatW (const WCHAR *str) { return _wtof (str); }
|
||||
EXTERN_C double StringToDoubleA (const char *str) { return atod (str); }
|
||||
EXTERN_C double StringToDoubleW (const WCHAR *str) { return _wtod (str); }
|
||||
|
||||
#ifdef __cplusplus
|
||||
int StringToInt (LPCSTR str) { return StringToIntA (str); }
|
||||
int StringToInt (LPCWSTR str) { return StringToIntW (str); }
|
||||
unsigned StringToUnsigned (LPCSTR str) { return StringToUnsignedA (str); }
|
||||
unsigned StringToUnsigned (LPCWSTR str) { return StringToUnsignedW (str); }
|
||||
bool StringToBool (LPCSTR str) { return StringToBoolA (str); }
|
||||
bool StringToBool (LPCWSTR str) { return StringToBoolW (str); }
|
||||
long StringToLong (LPCSTR str) { return StringToLongA (str); }
|
||||
long StringToLong (LPCWSTR str) { return StringToLongW (str); }
|
||||
unsigned long StringToULong (LPCSTR str) { return StringToULongA (str); }
|
||||
unsigned long StringToULong (LPCWSTR str) { return StringToULongW (str); }
|
||||
long long StringToLongLong (LPCSTR str) { return StringToLongLongA (str); }
|
||||
long long StringToLongLong (LPCWSTR str) { return StringToLongLongW (str); }
|
||||
unsigned long long StringToULongLong (LPCSTR str) { return StringToULongLongA (str); }
|
||||
unsigned long long StringToULongLong (LPCWSTR str) { return StringToULongLongW (str); }
|
||||
float StringToFloat (LPCSTR str) { return StringToFloatA (str); }
|
||||
float StringToFloat (LPCWSTR str) { return StringToFloatW (str); }
|
||||
double StringToDouble (LPCSTR str) { return StringToDoubleA (str); }
|
||||
double StringToDouble (LPCWSTR str) { return StringToDoubleW (str); }
|
||||
#endif
|
||||
|
||||
#if defined (__cplusplus) && defined (__cplusplus_cli)
|
||||
using namespace System;
|
||||
#define toInt(_String_Managed_Object_) Int32::Parse (_String_Managed_Object_)
|
||||
#define objToInt(_Object_Managed_) Convert::ToInt32 (_Object_Managed_)
|
||||
#define toDouble(_String_Managed_Object_) Double::Parse (_String_Managed_Object_)
|
||||
#define objToDouble(_Object_Managed_) Convert::ToDouble (_Object_Managed_)
|
||||
#define toBool(_String_Managed_Object_) Boolean::Parse (_String_Managed_Object_)
|
||||
bool objToBool (Object ^result)
|
||||
{
|
||||
if (!result) return false;
|
||||
try
|
||||
{
|
||||
String ^strValue = safe_cast <String ^> (result);
|
||||
return (strValue->ToLower () == "on");
|
||||
}
|
||||
catch (InvalidCastException ^)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Convert::ToBoolean (result);
|
||||
}
|
||||
catch (InvalidCastException ^)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#define toDateTime(_String_Managed_Object_) DateTime::Parse (_String_Managed_Object_)
|
||||
#define toDateTimeObj(_Object_Managed_) Convert::ToDateTime (_Object_Managed_)
|
||||
#define objectToType(_Object_Managed_, _Type_Name_) Convert::To##_Type_Name_ (_Object_Managed_)
|
||||
#endif
|
||||
@@ -0,0 +1,348 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
#include <pugiconfig.hpp>
|
||||
#include <pugixml.hpp>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <codecvt>
|
||||
#include <locale>
|
||||
#include <cstdio>
|
||||
#include "strcmp.h"
|
||||
#include "dynarr.h"
|
||||
#include "themeinfo.h"
|
||||
#include "nstring.h"
|
||||
#include "filepath.h"
|
||||
|
||||
class vemanifest
|
||||
{
|
||||
public:
|
||||
enum class TextColor { dark = 0x000000, light = 0xFFFFFF };
|
||||
vemanifest (): available (false) {}
|
||||
vemanifest (LPCSTR filename): available (false) { create (filename); }
|
||||
vemanifest (const std::string &filename): available (false) { create (filename); }
|
||||
vemanifest (LPCWSTR filename): available (false) { create (filename); }
|
||||
vemanifest (const std::wstring &filename): available (false) { create (filename); }
|
||||
vemanifest (std::ifstream &stream): available (false) { create (stream); }
|
||||
vemanifest (std::fstream &stream): available (false) { create (stream); }
|
||||
vemanifest (FILE *file): available (false) { create (file); }
|
||||
~vemanifest () { destroy (); }
|
||||
bool create (LPCSTR filename)
|
||||
{
|
||||
destroy ();
|
||||
pugi::xml_parse_result result = doc.load_file (filename);
|
||||
available = result; return available;
|
||||
}
|
||||
bool create (const std::string &filename) { return create (filename.c_str ()); }
|
||||
bool create (LPCWSTR filename)
|
||||
{
|
||||
destroy ();
|
||||
std::wstring ws (filename);
|
||||
std::string s = to_utf8 (ws);
|
||||
pugi::xml_parse_result result = doc.load_file (s.c_str ());
|
||||
available = result; return available;
|
||||
}
|
||||
bool create (const std::wstring &filename) { return create (filename.c_str ()); }
|
||||
bool create (std::ifstream &stream)
|
||||
{
|
||||
destroy ();
|
||||
std::stringstream buffer; buffer << stream.rdbuf ();
|
||||
std::string content = buffer.str ();
|
||||
pugi::xml_parse_result result = doc.load_string (content.c_str ());
|
||||
available = result; return available;
|
||||
}
|
||||
bool create (std::fstream &stream)
|
||||
{
|
||||
destroy ();
|
||||
std::stringstream buffer; buffer << stream.rdbuf ();
|
||||
std::string content = buffer.str ();
|
||||
pugi::xml_parse_result result = doc.load_string (content.c_str ());
|
||||
available = result; return available;
|
||||
}
|
||||
bool create (FILE *file)
|
||||
{
|
||||
destroy ();
|
||||
if (!file) { return false; }
|
||||
fseek (file, 0, SEEK_END);
|
||||
long length = ftell (file);
|
||||
fseek (file, 0, SEEK_SET);
|
||||
std::string content (length, '\0');
|
||||
fread (&content [0], 1, length, file);
|
||||
pugi::xml_parse_result result = doc.load_string (content.c_str ());
|
||||
available = result; return available;
|
||||
}
|
||||
void destroy () { if (!available) return; doc.reset (); available = false; }
|
||||
bool valid () const { return available; }
|
||||
std::string display_name (const std::string &id = "App") const
|
||||
{
|
||||
pugi::xml_node visual = visual_element_node (id);
|
||||
return visual ? visual.attribute ("DisplayName").as_string () : "";
|
||||
}
|
||||
std::wstring display_name (const std::wstring &id = L"App") const { return pugi::as_wide (this->display_name (pugi::as_utf8 (id))); }
|
||||
std::string logo (const std::string &id = "App") const
|
||||
{
|
||||
pugi::xml_node visual = visual_element_node (id);
|
||||
if (!visual) return "";
|
||||
std::string logo = visual.attribute ("Logo").as_string ();
|
||||
return !logo.empty () ? logo : visual.attribute ("Square150x150Logo").as_string ();
|
||||
}
|
||||
std::wstring logo (const std::wstring &id = L"App") const { return pugi::as_wide (this->logo (pugi::as_utf8 (id))); }
|
||||
std::string small_logo (const std::string &id = "App") const
|
||||
{
|
||||
pugi::xml_node visual = visual_element_node (id);
|
||||
if (!visual) return "";
|
||||
std::string smallLogo = visual.attribute ("SmallLogo").as_string ();
|
||||
return !smallLogo.empty () ? smallLogo : visual.attribute ("Square70x70Logo").as_string ();
|
||||
}
|
||||
std::wstring small_logo (const std::wstring &id = L"App") const { return pugi::as_wide (this->small_logo (pugi::as_utf8 (id))); }
|
||||
TextColor foreground_text (const std::string &id = "App") const
|
||||
{
|
||||
pugi::xml_node visual = visual_element_node (id);
|
||||
if (!visual) return TextColor::dark;
|
||||
std::string fg = visual.attribute ("ForegroundText").as_string ();
|
||||
return (fg == "light") ? TextColor::light : TextColor::dark;
|
||||
}
|
||||
TextColor foreground_text (const std::wstring &id = L"App") const { return (this->foreground_text (pugi::as_utf8 (id))); }
|
||||
std::string lnk_32x32_logo (const std::string &id = "App") const
|
||||
{
|
||||
pugi::xml_node visual = visual_element_node (id);
|
||||
return visual ? visual.attribute ("Lnk32x32Logo").as_string () : "";
|
||||
}
|
||||
std::wstring lnk_32x32_logo (const std::wstring &id = L"App") const { return pugi::as_wide (this->lnk_32x32_logo (pugi::as_utf8 (id))); }
|
||||
std::string item_display_logo (const std::string &id = "App") const
|
||||
{
|
||||
pugi::xml_node visual = visual_element_node (id);
|
||||
if (!visual) return "";
|
||||
std::string itemLogo = visual.attribute ("ItemDisplayLogo").as_string ();
|
||||
if (!itemLogo.empty ()) return itemLogo;
|
||||
itemLogo = visual.attribute ("Lnk32x32Logo").as_string ();
|
||||
return !itemLogo.empty () ? itemLogo : visual.attribute ("Square44x44Logo").as_string ();
|
||||
}
|
||||
std::wstring item_display_logo (const std::wstring &id = L"App") const { return pugi::as_wide (this->item_display_logo (pugi::as_utf8 (id))); }
|
||||
bool show_name_on_tile (const std::string &id = "App") const
|
||||
{
|
||||
pugi::xml_node visual = visual_element_node (id);
|
||||
return visual ? (std::string (visual.attribute ("ShowNameOnSquare150x150Logo").as_string ()) == "on") : false;
|
||||
}
|
||||
bool show_name_on_tile (const std::wstring &id = L"App") const { return (this->show_name_on_tile (pugi::as_utf8 (id))); }
|
||||
std::string background_color (const std::string &id = "App") const
|
||||
{
|
||||
pugi::xml_node visual = visual_element_node (id);
|
||||
return visual ? visual.attribute ("BackgroundColor").as_string () : "";
|
||||
}
|
||||
std::wstring background_color (const std::wstring &id = L"App") const { return pugi::as_wide (this->background_color (pugi::as_utf8 (id))); }
|
||||
std::string splash_screen_image (const std::string &id = "App") const
|
||||
{
|
||||
pugi::xml_node visual = visual_element_node (id);
|
||||
if (!visual) return "";
|
||||
pugi::xml_node splash = visual.child ("SplashScreen");
|
||||
return splash ? splash.attribute ("Image").as_string () : "";
|
||||
}
|
||||
std::wstring splash_screen_image (const std::wstring &id = L"App") const { return pugi::as_wide (this->splash_screen_image (pugi::as_utf8 (id))); }
|
||||
std::string splash_screen_backgroundcolor (const std::string &id = "App") const
|
||||
{
|
||||
pugi::xml_node visual = visual_element_node (id);
|
||||
if (!visual) return "";
|
||||
pugi::xml_node splash = visual.child ("SplashScreen");
|
||||
std::string bg = splash ? splash.attribute ("BackgroundColor").as_string () : "";
|
||||
return !bg.empty () ? bg : visual.attribute ("BackgroundColor").as_string ();
|
||||
}
|
||||
std::wstring splash_screen_backgroundcolor (const std::wstring &id = L"App") const { return pugi::as_wide (this->splash_screen_backgroundcolor (pugi::as_utf8 (id))); }
|
||||
std::string splash_screen_backgroundcolor_darkmode (const std::string &id = "App") const
|
||||
{
|
||||
pugi::xml_node visual = visual_element_node (id);
|
||||
if (!visual) return "";
|
||||
pugi::xml_node splash = visual.child ("SplashScreen");
|
||||
std::string bg = splash ? splash.attribute ("DarkModeBackgroundColor").as_string () : "";
|
||||
return !bg.empty () ? bg : visual.attribute ("DarkModeBackgroundColor").as_string ();
|
||||
}
|
||||
std::wstring splash_screen_backgroundcolor_darkmode (const std::wstring &id = L"App") const { return pugi::as_wide (this->splash_screen_backgroundcolor_darkmode (pugi::as_utf8 (id))); }
|
||||
bool is_appid_exists (const std::string &id) const
|
||||
{
|
||||
pugi::xml_node root = doc.document_element ();
|
||||
std::string rootName = root.name ();
|
||||
if (rootName == "Applications")
|
||||
{
|
||||
for (pugi::xml_node app : root.children ("Application"))
|
||||
{
|
||||
pugi::xml_attribute attr = app.attribute ("Id");
|
||||
if (attr && LabelEqual (std::string (attr.value ()), id)) return true;
|
||||
}
|
||||
return pugi::xml_node ();
|
||||
}
|
||||
else if (rootName == "Application")
|
||||
{
|
||||
pugi::xml_attribute attr = root.attribute ("Id");
|
||||
if (attr && LabelEqual (std::string (attr.value ()), id)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool is_appid_exists (const std::wstring &id) const { return this->is_appid_exists (pugi::as_utf8 (id)); }
|
||||
size_t app_ids (std::vector <std::string> &output) const
|
||||
{
|
||||
if (!&output) return 0;
|
||||
output.clear ();
|
||||
pugi::xml_node root = doc.document_element ();
|
||||
std::string rootName = root.name ();
|
||||
if (rootName == "Applications")
|
||||
{
|
||||
for (pugi::xml_node app : root.children ("Application"))
|
||||
{
|
||||
pugi::xml_attribute attr = app.attribute ("Id");
|
||||
if (attr)
|
||||
{
|
||||
LPCSTR lp = attr.value ();
|
||||
if (lp) push_unique (output, std::string (lp));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (rootName == "Application")
|
||||
{
|
||||
pugi::xml_attribute attr = root.attribute ("Id");
|
||||
if (attr)
|
||||
{
|
||||
if (attr)
|
||||
{
|
||||
LPCSTR lp = attr.value ();
|
||||
if (lp) push_unique (output, std::string (lp));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!output.size ()) push_unique (output, std::string ("App"));
|
||||
return output.size ();
|
||||
}
|
||||
size_t app_ids (std::vector <std::wstring> &output) const
|
||||
{
|
||||
if (!&output) return 0;
|
||||
output.clear ();
|
||||
pugi::xml_node root = doc.document_element ();
|
||||
std::string rootName = root.name ();
|
||||
if (rootName == "Applications")
|
||||
{
|
||||
for (pugi::xml_node app : root.children ("Application"))
|
||||
{
|
||||
pugi::xml_attribute attr = app.attribute ("Id");
|
||||
if (attr)
|
||||
{
|
||||
LPCSTR lp = attr.value ();
|
||||
if (lp) push_unique (output, pugi::as_wide (lp));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (rootName == "Application")
|
||||
{
|
||||
pugi::xml_attribute attr = root.attribute ("Id");
|
||||
if (attr)
|
||||
{
|
||||
if (attr)
|
||||
{
|
||||
LPCSTR lp = attr.value ();
|
||||
if (lp) push_unique (output, pugi::as_wide (lp));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!output.size ()) push_unique (output, std::wstring (L"App"));
|
||||
return output.size ();
|
||||
}
|
||||
private:
|
||||
pugi::xml_document doc;
|
||||
bool available;
|
||||
// 根据 id 查找 VisualElements 节点:若根节点为 <Applications>,遍历所有 <Application> 查找其 <VisualElements> 节点中属性 Id 等于 id;若根节点为 <Application>,直接返回其 <VisualElements>
|
||||
pugi::xml_node visual_element_node (const std::string &id) const
|
||||
{
|
||||
pugi::xml_node root = doc.document_element ();
|
||||
std::string rootName = root.name ();
|
||||
if (rootName == "Applications")
|
||||
{
|
||||
for (pugi::xml_node app : root.children ("Application"))
|
||||
{
|
||||
pugi::xml_attribute attr = app.attribute ("Id");
|
||||
if (attr && LabelEqual (std::string (attr.value ()), id))
|
||||
{
|
||||
pugi::xml_node visual = app.child ("VisualElements");
|
||||
if (visual) return visual;
|
||||
}
|
||||
}
|
||||
return pugi::xml_node ();
|
||||
}
|
||||
else if (rootName == "Application") return root.child ("VisualElements");
|
||||
return pugi::xml_node ();
|
||||
}
|
||||
std::string to_utf8 (const std::wstring &wstr) const
|
||||
{
|
||||
std::wstring_convert <std::codecvt_utf8 <wchar_t>> conv;
|
||||
return conv.to_bytes (wstr);
|
||||
}
|
||||
};
|
||||
|
||||
class resxmldoc
|
||||
{
|
||||
private:
|
||||
std::wstring filepath;
|
||||
pugi::xml_document doc;
|
||||
bool available = false;
|
||||
std::string to_utf8 (const std::wstring &wstr) const
|
||||
{
|
||||
std::wstring_convert <std::codecvt_utf8 <wchar_t>> conv;
|
||||
return conv.to_bytes (wstr);
|
||||
}
|
||||
public:
|
||||
resxmldoc (const std::wstring &xmlpath) { create (xmlpath); }
|
||||
void destroy () { if (!available) return; doc.reset (); available = false; }
|
||||
~resxmldoc () { destroy (); }
|
||||
bool create (const std::wstring &xmlpath)
|
||||
{
|
||||
destroy ();
|
||||
std::wstring ws (filepath = xmlpath);
|
||||
std::string s = to_utf8 (ws);
|
||||
pugi::xml_parse_result result = doc.load_file (s.c_str ());
|
||||
available = result; return available;
|
||||
}
|
||||
std::string get (const std::string &id) const
|
||||
{
|
||||
auto root = doc.first_child ();
|
||||
auto nodes = root.children ();
|
||||
for (auto it : nodes)
|
||||
{
|
||||
if (IsNormalizeStringEquals (std::string (it.attribute ("id").as_string ()), id))
|
||||
{
|
||||
auto scales = it.children ();
|
||||
std::map <int, std::string> s_v;
|
||||
for (auto it_s : scales)
|
||||
{
|
||||
std::string dpi = it_s.attribute ("dpi").as_string ();
|
||||
if (IsNormalizeStringEquals (dpi.c_str (), "default")) { s_v [0] = it_s.text ().get (); }
|
||||
else
|
||||
{
|
||||
try { s_v [it_s.attribute ("dpi").as_int ()] = it_s.text ().get (); }
|
||||
catch (...) {}
|
||||
}
|
||||
}
|
||||
std::vector <std::pair <int, std::string>> existfilepath;
|
||||
{
|
||||
std::vector <std::pair <int, std::string>> vec (s_v.begin (), s_v.end ());
|
||||
std::sort (vec.begin (), vec.end (), [] (auto &a, auto &b) { return a.second < b.second; });
|
||||
for (auto &it_ss : vec)
|
||||
{
|
||||
it_ss.second = pugi::as_utf8 (CombinePath (GetFileDirectoryW (filepath), pugi::as_wide (it_ss.second)));
|
||||
if (IsFileExists (pugi::as_wide (it_ss.second))) existfilepath.push_back (it_ss);
|
||||
}
|
||||
}
|
||||
int dpipercent = GetDPI ();
|
||||
for (auto &it_path : existfilepath)
|
||||
{
|
||||
if (it_path.first >= dpipercent) return it_path.second;
|
||||
}
|
||||
if (!existfilepath.empty ()) return existfilepath.at (0).second;
|
||||
return "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
std::wstring get (const std::wstring &id) const { return pugi::as_wide (get (WStringToString (id))); }
|
||||
std::wstring operator [] (const std::wstring &id) const { return get (id); }
|
||||
std::wstring operator [] (const std::wstring &id) { return get (id); }
|
||||
std::string operator [] (const std::string &id) const { return get (id); }
|
||||
std::string operator [] (const std::string &id) { return get (id); }
|
||||
};
|
||||
@@ -0,0 +1,193 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
typedef uint64_t UINT64;
|
||||
typedef int64_t INT64;
|
||||
typedef uint16_t UINT16;
|
||||
typedef struct version
|
||||
{
|
||||
UINT16 major = 0, minor = 0, build = 0, revision = 0;
|
||||
version (UINT64 value):
|
||||
major ((value >> 0x30) & 0xFFFF), minor ((value >> 0x20) & 0xFFFF),
|
||||
build ((value >> 0x10) & 0xFFFF), revision ((value) & 0xFFFF) {}
|
||||
version (UINT16 major, UINT16 minor, UINT16 build, UINT16 revision):
|
||||
major (major), minor (minor), build (build), revision (revision) {}
|
||||
version (const std::wstring &verstr) { this->interpret (verstr); }
|
||||
version (const std::string &verstr) { this->interpret (verstr); }
|
||||
version () {}
|
||||
version (const version &other): major (other.major), minor (other.minor), build (other.build), revision (other.revision) {}
|
||||
version (version &&other) noexcept: major (other.major), minor (other.minor), build (other.build), revision (other.revision) {}
|
||||
version &operator = (const version &other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
major = other.major;
|
||||
minor = other.minor;
|
||||
build = other.build;
|
||||
revision = other.revision;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
version &operator = (version &&other) noexcept
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
major = other.major;
|
||||
minor = other.minor;
|
||||
build = other.build;
|
||||
revision = other.revision;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
version &operator = (UINT64 value) { this->data (value); return *this; }
|
||||
UINT64 data () const { return (((UINT64)major) << 48) | (((UINT64)minor) << 32) | (((UINT64)build) << 16) | ((UINT64)revision); }
|
||||
UINT64 data (UINT64 value)
|
||||
{
|
||||
major = (value >> 48) & 0xFFFF;
|
||||
minor = (value >> 32) & 0xFFFF;
|
||||
build = (value >> 16) & 0xFFFF;
|
||||
revision = value & 0xFFFF;
|
||||
return value;
|
||||
}
|
||||
std::wstring stringifyw () const
|
||||
{
|
||||
std::wstringstream ss;
|
||||
ss << major << L'.' << minor << L'.' << build << L'.' << revision;
|
||||
return ss.str ();
|
||||
}
|
||||
std::string stringify () const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << major << '.' << minor << '.' << build << '.' << revision;
|
||||
return ss.str ();
|
||||
}
|
||||
version &interpret (const std::wstring &verstr)
|
||||
{
|
||||
auto result = split (verstr);
|
||||
if (result.size () > 0) this->major = _wtoi (result [0].c_str ());
|
||||
if (result.size () > 1) this->minor = _wtoi (result [1].c_str ());
|
||||
if (result.size () > 2) this->build = _wtoi (result [2].c_str ());
|
||||
if (result.size () > 3) this->revision = _wtoi (result [3].c_str ());
|
||||
return *this;
|
||||
}
|
||||
version &interpret (const std::string &verstr)
|
||||
{
|
||||
auto result = split (verstr);
|
||||
if (result.size () > 0) this->major = atoi (result [0].c_str ());
|
||||
if (result.size () > 1) this->minor = atoi (result [1].c_str ());
|
||||
if (result.size () > 2) this->build = atoi (result [2].c_str ());
|
||||
if (result.size () > 3) this->revision = atoi (result [3].c_str ());
|
||||
return *this;
|
||||
}
|
||||
bool empty () const { return *(UINT64 *)this == 0; }
|
||||
friend bool operator == (const version &l, const version &r) { return *(UINT64 *)&l == *(UINT64 *)&r; }
|
||||
friend bool operator == (const version &l, const UINT64 &r) { return l.data () == r; }
|
||||
friend bool operator == (const UINT64 &r, const version &l) { return l.data () == r; }
|
||||
friend bool operator < (const version &l, const version &r) { return l.data () < r.data (); }
|
||||
friend bool operator > (const version &l, const version &r) { return l.data () > r.data (); }
|
||||
friend bool operator <= (const version &l, const version &r) { return l.data () <= r.data (); }
|
||||
friend bool operator >= (const version &l, const version &r) { return l.data () >= r.data (); }
|
||||
friend bool operator != (const version &l, const version &r) { return *(UINT64 *)&l != *(UINT64 *)&r; }
|
||||
explicit operator bool () const { return !this->empty (); }
|
||||
bool operator ! () { return this->empty (); }
|
||||
friend std::ostream &operator << (std::ostream &o, const version &v) { return o << v.major << '.' << v.minor << '.' << v.build << '.' << v.revision; }
|
||||
friend std::wostream &operator << (std::wostream &o, const version &v) { return o << v.major << '.' << v.minor << '.' << v.build << '.' << v.revision; }
|
||||
bool equals (const version &r) const { return *this == r; }
|
||||
INT64 compare (const version &r) const { return this->data () - r.data (); }
|
||||
static version parse (const std::wstring &value) { return version (value); }
|
||||
static version parse (const std::string &value) { return version (value); }
|
||||
static std::wstring stringifyw (const version &v) { return v.stringifyw (); }
|
||||
static std::string stringify (const version &v) { return v.stringify (); }
|
||||
static bool equals (const version &l, const version &r) { return l == r; }
|
||||
static INT64 compare (const version &l, const version &r) { return l.data () - r.data (); }
|
||||
static version decode (UINT64 value) { return version (value); }
|
||||
static UINT64 encode (const version &v) { return v.data (); }
|
||||
protected:
|
||||
template <typename StringType> std::vector <StringType> split (const StringType &str, typename StringType::value_type delimiter1 = '.', typename StringType::value_type delimiter2 = ',')
|
||||
{
|
||||
std::vector <StringType> result;
|
||||
std::basic_stringstream<typename StringType::value_type> ss (str);
|
||||
StringType segment;
|
||||
while (std::getline (ss, segment, delimiter1))
|
||||
{
|
||||
size_t pos = 0;
|
||||
while ((pos = segment.find (delimiter2)) != StringType::npos)
|
||||
{
|
||||
result.push_back (segment.substr (0, pos));
|
||||
segment.erase (0, pos + 1);
|
||||
}
|
||||
if (!segment.empty ()) result.push_back (segment);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} Version;
|
||||
|
||||
#ifdef __cplusplus_cli
|
||||
using namespace System;
|
||||
using namespace System::Runtime::InteropServices;
|
||||
[ComVisible (true)]
|
||||
public ref class _I_Version
|
||||
{
|
||||
private:
|
||||
UINT16 major = 0, minor = 0, build = 0, revision = 0;
|
||||
public:
|
||||
property UINT16 Major { UINT16 get () { return major; } void set (UINT16 value) { major = value; } }
|
||||
property UINT16 Minor { UINT16 get () { return minor; } void set (UINT16 value) { minor = value; } }
|
||||
property UINT16 Build { UINT16 get () { return build; } void set (UINT16 value) { build = value; } }
|
||||
property UINT16 Revision { UINT16 get () { return revision; } void set (UINT16 value) { revision = value; } }
|
||||
property array <UINT16> ^Data
|
||||
{
|
||||
array <UINT16> ^get ()
|
||||
{
|
||||
return gcnew array <UINT16> {
|
||||
major, minor, build, revision
|
||||
};
|
||||
}
|
||||
void set (array <UINT16> ^arr)
|
||||
{
|
||||
major = minor = build = revision = 0;
|
||||
for (size_t i = 0; i < arr->Length; i ++)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: major = arr [i]; break;
|
||||
case 1: minor = arr [i]; break;
|
||||
case 2: build = arr [i]; break;
|
||||
case 3: revision = arr [i]; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
property String ^DataStr
|
||||
{
|
||||
String ^get () { return Stringify (); }
|
||||
void set (String ^str) { Parse (str); }
|
||||
}
|
||||
_I_Version (UINT16 p_ma, UINT16 p_mi, UINT16 p_b, UINT16 p_r):
|
||||
major (p_ma), minor (p_mi), build (p_b), revision (p_r) {}
|
||||
_I_Version (UINT16 p_ma, UINT16 p_mi, UINT16 p_b):
|
||||
major (p_ma), minor (p_mi), build (p_b), revision (0) {}
|
||||
_I_Version (UINT16 p_ma, UINT16 p_mi):
|
||||
major (p_ma), minor (p_mi), build (0), revision (0) {}
|
||||
_I_Version (UINT16 p_ma):
|
||||
major (p_ma), minor (0), build (0), revision (0) {}
|
||||
_I_Version () {}
|
||||
_I_Version %Parse (String ^ver)
|
||||
{
|
||||
auto strarr = ver->Split ('.');
|
||||
auto arr = gcnew array <UINT16> (4);
|
||||
for (size_t i = 0; i < strarr->Length; i ++)
|
||||
{
|
||||
try { arr [i] = Convert::ToUInt16 (strarr [i]); }
|
||||
catch (...) {}
|
||||
}
|
||||
Data = arr;
|
||||
return *this;
|
||||
}
|
||||
String ^Stringify () { return major + "." + minor + "." + build + "." + revision; }
|
||||
String ^ToString () override { return Stringify (); }
|
||||
bool Valid () { return Major != 0 && Minor != 0 && Build != 0 && Revision != 0; }
|
||||
};
|
||||
#endif
|
||||
Reference in New Issue
Block a user