Update Shell.
@@ -3,12 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "appinstaller", "AppInstallerReset\AppInstallerReset.vcxproj", "{C96219BE-8AFF-4914-8933-B6B7047A94D8}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{33D91B58-1981-4A3C-B4D1-86EE406CDE12} = {33D91B58-1981-4A3C-B4D1-86EE406CDE12}
|
||||
{A7753282-AA16-43D9-8ACA-7065239DD702} = {A7753282-AA16-43D9-8ACA-7065239DD702}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pkgread", "pkgread\pkgread.vcxproj", "{A7753282-AA16-43D9-8ACA-7065239DD702}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dlltest", "dlltest\dlltest.vcxproj", "{F5CCB3AB-AC43-432A-862D-4F264760B09B}"
|
||||
@@ -30,6 +24,16 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PriFile", "PriFileFormat\Pr
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "certmgr", "certmgr\certmgr.vcxproj", "{E04CCAB9-35DB-495C-A279-5B483C707CD0}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "appinstaller", "appinstaller\appinstaller.vcxproj", "{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{8EAC0230-4990-4E41-8E0F-D641D1561396} = {8EAC0230-4990-4E41-8E0F-D641D1561396}
|
||||
{33D91B58-1981-4A3C-B4D1-86EE406CDE12} = {33D91B58-1981-4A3C-B4D1-86EE406CDE12}
|
||||
{A7753282-AA16-43D9-8ACA-7065239DD702} = {A7753282-AA16-43D9-8ACA-7065239DD702}
|
||||
{798ED492-EECE-457D-8FD8-129DA93CE126} = {798ED492-EECE-457D-8FD8-129DA93CE126}
|
||||
{F5CCB3AB-AC43-432A-862D-4F264760B09B} = {F5CCB3AB-AC43-432A-862D-4F264760B09B}
|
||||
{E04CCAB9-35DB-495C-A279-5B483C707CD0} = {E04CCAB9-35DB-495C-A279-5B483C707CD0}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -40,16 +44,6 @@ Global
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C96219BE-8AFF-4914-8933-B6B7047A94D8}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{C96219BE-8AFF-4914-8933-B6B7047A94D8}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{C96219BE-8AFF-4914-8933-B6B7047A94D8}.Debug|x64.Build.0 = Debug|x64
|
||||
{C96219BE-8AFF-4914-8933-B6B7047A94D8}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{C96219BE-8AFF-4914-8933-B6B7047A94D8}.Debug|x86.Build.0 = Debug|Win32
|
||||
{C96219BE-8AFF-4914-8933-B6B7047A94D8}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{C96219BE-8AFF-4914-8933-B6B7047A94D8}.Release|x64.ActiveCfg = Release|x64
|
||||
{C96219BE-8AFF-4914-8933-B6B7047A94D8}.Release|x64.Build.0 = Release|x64
|
||||
{C96219BE-8AFF-4914-8933-B6B7047A94D8}.Release|x86.ActiveCfg = Release|Win32
|
||||
{C96219BE-8AFF-4914-8933-B6B7047A94D8}.Release|x86.Build.0 = Release|Win32
|
||||
{A7753282-AA16-43D9-8ACA-7065239DD702}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{A7753282-AA16-43D9-8ACA-7065239DD702}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A7753282-AA16-43D9-8ACA-7065239DD702}.Debug|x64.Build.0 = Debug|x64
|
||||
@@ -118,6 +112,16 @@ Global
|
||||
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Release|x64.Build.0 = Release|x64
|
||||
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Release|x86.ActiveCfg = Release|Win32
|
||||
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Release|x86.Build.0 = Release|Win32
|
||||
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Debug|x64.Build.0 = Debug|x64
|
||||
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Debug|x86.Build.0 = Debug|Win32
|
||||
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Release|x64.ActiveCfg = Release|x64
|
||||
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Release|x64.Build.0 = Release|x64
|
||||
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Release|x86.ActiveCfg = Release|Win32
|
||||
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<?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>
|
||||
</Project>
|
||||
BIN
appinstaller/appinstaller.rc
Normal file
@@ -19,11 +19,10 @@
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{C96219BE-8AFF-4914-8933-B6B7047A94D8}</ProjectGuid>
|
||||
<ProjectGuid>{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>AppInstallerReset</RootNamespace>
|
||||
<RootNamespace>appinstaller</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<ProjectName>appinstaller</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
@@ -31,6 +30,7 @@
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
@@ -38,6 +38,7 @@
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
@@ -88,12 +89,13 @@
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<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;$(OutDir)pkgread.lib;$(OutDir)pkgmgr.lib;$(OutDir)certmgr.lib;$(OutDir)priformatcli.lib;$(OutDir)notice.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
@@ -118,7 +120,7 @@
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;HMODULE_MODE_EXE;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
@@ -126,6 +128,7 @@
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>shlwapi.lib;version.lib;dwmapi.lib;$(OutDir)pkgread.lib;$(OutDir)pkgmgr.lib;$(OutDir)certmgr.lib;$(OutDir)priformatcli.lib;$(OutDir)notice.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
@@ -147,8 +150,55 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="cmdargs.h" />
|
||||
<ClInclude Include="dynarr.h" />
|
||||
<ClInclude Include="filepath.h" />
|
||||
<ClInclude Include="ieshell.h" />
|
||||
<ClInclude Include="initfile.h" />
|
||||
<ClInclude Include="module.h" />
|
||||
<ClInclude Include="mpstr.h" />
|
||||
<ClInclude Include="nstring.h" />
|
||||
<ClInclude Include="raii.h" />
|
||||
<ClInclude Include="rctools.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="strcmp.h" />
|
||||
<ClInclude Include="strcode.h" />
|
||||
<ClInclude Include="themeinfo.h" />
|
||||
<ClInclude Include="typestrans.h" />
|
||||
<ClInclude Include="vemani.h" />
|
||||
<ClInclude Include="version.h" />
|
||||
</ItemGroup>
|
||||
<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" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="appinstaller.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="res\icons\color.ico" />
|
||||
<Image Include="res\icons\file.ico" />
|
||||
<Image Include="res\icons\main.ico" />
|
||||
<Image Include="res\icons\taskbar.ico" />
|
||||
<Image Include="res\icons\white.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<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\pugixml.1.15.0\build\native\pugixml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\pugixml.1.15.0\build\native\pugixml.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
100
appinstaller/appinstaller.vcxproj.filters
Normal file
@@ -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>
|
||||
<ClInclude Include="cmdargs.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="filepath.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="initfile.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="module.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mpstr.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="nstring.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="rctools.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="strcmp.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="typestrans.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="version.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="raii.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="themeinfo.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="strcode.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="vemani.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="dynarr.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ieshell.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="appinstaller.rc">
|
||||
<Filter>资源文件</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="res\icons\color.ico">
|
||||
<Filter>资源文件</Filter>
|
||||
</Image>
|
||||
<Image Include="res\icons\file.ico">
|
||||
<Filter>资源文件</Filter>
|
||||
</Image>
|
||||
<Image Include="res\icons\taskbar.ico">
|
||||
<Filter>资源文件</Filter>
|
||||
</Image>
|
||||
<Image Include="res\icons\white.ico">
|
||||
<Filter>资源文件</Filter>
|
||||
</Image>
|
||||
<Image Include="res\icons\main.ico">
|
||||
<Filter>资源文件</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
161
appinstaller/cmdargs.h
Normal file
@@ -0,0 +1,161 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include "nstring.h"
|
||||
#include "rctools.h"
|
||||
#include "filepath.h"
|
||||
#include "raii.h"
|
||||
|
||||
// 允许忽视命令行前缀。如当命令行前缀为“-”"/"时,且开启此项,则输入“-args”与"/args"和"args" 是等效的
|
||||
#define CMDARG_IGNOREPREFIXS 0b001
|
||||
// 允许参数后跟着值,如“/args=file”,但要求必须配置后缀,且是有效的字符
|
||||
#define CMDARG_ENABLEPARAMS 0b010
|
||||
// 当 CMDARG_ENABLEPARAMS 开启时允许参数为空。如 “/args=file”和"/args"都是允许的
|
||||
#define CMDARG_IGNOREPARAMS 0b100
|
||||
// 命令行参数
|
||||
struct cmdarg
|
||||
{
|
||||
std::vector <std::wstring> prefixs; // 允许无前缀(长度为 0)
|
||||
std::vector <std::wstring> commands; // 参数(长度不能为 0,不能为空)
|
||||
std::vector <std::wstring> postfixs; // 允许无后缀(长度为 0)
|
||||
std::wstring uniquelabel; // 唯一标识,参数名
|
||||
std::wstring description; // 描述,用于生成帮助文本
|
||||
DWORD flags; // 标志
|
||||
};
|
||||
#define CMDARG_PREFIXS_DEFAULT {L"-", L"/"}
|
||||
#define CMDARG_POSTFIXS_DEFAULT {}
|
||||
std::vector <cmdarg> g_argslist = {
|
||||
{CMDARG_PREFIXS_DEFAULT, {L"silent", L"quiet", L"passive"}, CMDARG_POSTFIXS_DEFAULT, L"silent", GetRCStringSW (0), CMDARG_IGNOREPREFIXS},
|
||||
{CMDARG_PREFIXS_DEFAULT, {L"verysilent", L"veryquiet"}, CMDARG_POSTFIXS_DEFAULT, L"verysilent", GetRCStringSW (0), CMDARG_IGNOREPREFIXS},
|
||||
{CMDARG_PREFIXS_DEFAULT, {L"multiple", L"filelist"}, {L"="}, L"multiple", GetRCStringSW (0), CMDARG_IGNOREPREFIXS | CMDARG_ENABLEPARAMS}
|
||||
};
|
||||
bool IsFile (const std::wstring &path)
|
||||
{
|
||||
return IsPathExists (path);
|
||||
}
|
||||
bool IsURI (const std::wstring &str)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto uristr = gcnew System::String (str.c_str ());
|
||||
auto uri = gcnew System::Uri (uristr);
|
||||
return uri != nullptr;
|
||||
}
|
||||
catch (...) { return false; }
|
||||
}
|
||||
enum class paramtype
|
||||
{
|
||||
string,
|
||||
file,
|
||||
uri
|
||||
};
|
||||
struct cmdkey
|
||||
{
|
||||
std::wnstring key; // 键
|
||||
paramtype type; // 键类型,当传入的参数是存在的文件路径时(如“C:\1.txt”)则键的类型为文件。同理也可设置为 uri
|
||||
operator std::wnstring () { return key; }
|
||||
operator LPCWSTR () { return key.c_str (); }
|
||||
cmdkey (const std::wstring &k): key (k)
|
||||
{
|
||||
if (IsFile (k)) type = paramtype::file;
|
||||
else if (IsURI (k)) type = paramtype::uri;
|
||||
else type = paramtype::string;
|
||||
}
|
||||
cmdkey (const std::wstring &k, paramtype pt): key (k), type (pt) {}
|
||||
bool operator == (const cmdkey &r) const { return key == r.key; }
|
||||
bool operator > (const cmdkey &r) const { return key > r.key; }
|
||||
bool operator < (const cmdkey &r) const { return key < r.key; }
|
||||
};
|
||||
struct cmdvalue
|
||||
{
|
||||
std::wstring value; // 值
|
||||
paramtype type;
|
||||
bool isnull; // 当参数不支持跟着值时,或允许时值为空时设置为真。
|
||||
};
|
||||
// 对于从命令行获取到的 argv 和 argc,argc 最小为 1,argv 的第一个元素指向程序。所以 startpos 为 1。
|
||||
void ParseCmdArgs (LPWSTR *argv, DWORD argc, std::map <cmdkey, cmdvalue> &parseresult, DWORD startpos = 1)
|
||||
{
|
||||
for (size_t i = startpos; i < argc; i ++)
|
||||
{
|
||||
std::wnstring arg = argv [i];
|
||||
arg = arg.trim ();
|
||||
if (IsFile (arg)) parseresult [cmdkey (arg, paramtype::file)] = cmdvalue {L"", paramtype::file, true};
|
||||
else if (IsURI (arg)) parseresult [cmdkey (arg, paramtype::uri)] = cmdvalue {L"", paramtype::uri, true};
|
||||
else
|
||||
{
|
||||
for (auto &it : g_argslist)
|
||||
{
|
||||
std::set <std::wnstring> prefixs;
|
||||
for (auto &it_s : it.prefixs) prefixs.insert (it_s);
|
||||
int cmdhead = -1;
|
||||
for (auto &it_s : prefixs)
|
||||
{
|
||||
auto plen = GetNormalizeStringLength (it_s);
|
||||
auto parg = GetStringLeft (arg, plen);
|
||||
if (it_s == parg) { cmdhead = plen; break; }
|
||||
}
|
||||
if (((it.flags & CMDARG_IGNOREPREFIXS) || !it.prefixs.size () || !prefixs.size ()) && cmdhead < 0)
|
||||
{
|
||||
if (!arg.length ()) continue;
|
||||
cmdhead = 0;
|
||||
}
|
||||
if (cmdhead < 0) continue;
|
||||
int postfixhead = -1;
|
||||
std::set <std::wnstring> commands;
|
||||
for (auto &it_s : it.commands) if (GetNormalizeStringLength (it_s)) commands.insert (it_s);
|
||||
if (commands.empty ()) continue;
|
||||
for (auto &it_s : commands)
|
||||
{
|
||||
auto clen = it_s.length ();
|
||||
auto carg = GetStringLeft (arg.substr (cmdhead), clen);
|
||||
if (it_s == carg) { postfixhead = cmdhead + clen; }
|
||||
}
|
||||
if (postfixhead < 0) continue;
|
||||
std::set <std::wnstring> postfixs;
|
||||
for (auto &it_s : it.postfixs) if (GetNormalizeStringLength (it_s)) postfixs.insert (it_s);
|
||||
if (!(it.flags & CMDARG_ENABLEPARAMS)) it.postfixs.clear ();
|
||||
if ((it.flags & CMDARG_ENABLEPARAMS) && postfixs.size ())
|
||||
{
|
||||
int valuehead = -1;
|
||||
auto rightpart = StringTrim (GetStringRight (arg, lstrlenW (arg.c_str ()) - postfixhead));
|
||||
if (it.flags & CMDARG_IGNOREPARAMS)
|
||||
{
|
||||
if (!rightpart.length ()) { parseresult [cmdkey (it.uniquelabel, paramtype::string)] = cmdvalue {L"", paramtype::string, true}; break; }
|
||||
}
|
||||
for (auto &it_s : postfixs)
|
||||
{
|
||||
auto plen = it_s.length ();
|
||||
auto parg = GetStringLeft (rightpart, plen);
|
||||
if (it_s == parg) { valuehead = plen; break; }
|
||||
}
|
||||
if (valuehead < 0) continue;
|
||||
else
|
||||
{
|
||||
auto value = rightpart.substr (valuehead);
|
||||
paramtype ptype = paramtype::string;
|
||||
if (IsFile (value)) ptype = paramtype::file;
|
||||
else if (IsURI (StringTrim (value))) ptype = paramtype::uri;
|
||||
parseresult [cmdkey (it.uniquelabel, paramtype::string)] = cmdvalue {value, ptype, false};
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
parseresult [cmdkey (it.uniquelabel, paramtype::string)] = cmdvalue {L"", paramtype::string, true};
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void ParseCmdLine (LPCWSTR lpCommandLine, std::map <cmdkey, cmdvalue> &parseresult)
|
||||
{
|
||||
int argc = 0;
|
||||
LPWSTR *alpstr = CommandLineToArgvW (lpCommandLine, &argc);
|
||||
destruct relt ([&alpstr] () {
|
||||
if (alpstr) LocalFree (alpstr);
|
||||
});
|
||||
ParseCmdArgs (alpstr, argc, parseresult, 0);
|
||||
}
|
||||
77
appinstaller/dynarr.h
Normal file
@@ -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 ());
|
||||
}
|
||||
871
appinstaller/filepath.h
Normal file
@@ -0,0 +1,871 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <shlwapi.h>
|
||||
#include <vector>
|
||||
#include <iomanip>
|
||||
#include <functional>
|
||||
#include <sstream>
|
||||
#include "strcmp.h"
|
||||
#include "version.h"
|
||||
#include "module.h"
|
||||
typedef version VERSION;
|
||||
template <typename T> constexpr T Max (T l, T r) { return l > r ? l : r; }
|
||||
template <typename T> constexpr T Max (T l, T m, T r) { return Max (Max (l, r), m); }
|
||||
template <typename T> constexpr T Max (T l, T ml, T mr, T r) { return Max (Max (l, ml), Max (mr, r)); }
|
||||
template <typename CharT> std::basic_string <CharT> replace_substring
|
||||
(
|
||||
const std::basic_string <CharT> &str,
|
||||
const std::basic_string <CharT> &from,
|
||||
const std::basic_string <CharT> &to
|
||||
)
|
||||
{
|
||||
if (from.empty ()) return str;
|
||||
std::basic_string <CharT> result;
|
||||
size_t pos = 0;
|
||||
size_t start_pos;
|
||||
while ((start_pos = str.find (from, pos)) != std::basic_string<CharT>::npos)
|
||||
{
|
||||
result.append (str, pos, start_pos - pos);
|
||||
result.append (to);
|
||||
pos = start_pos + from.length ();
|
||||
}
|
||||
result.append (str, pos, str.length () - pos);
|
||||
return result;
|
||||
}
|
||||
std::string GetProgramRootDirectoryA (HMODULE hModule hModule_DefaultParam)
|
||||
{
|
||||
char path [MAX_PATH];
|
||||
if (GetModuleFileNameA (hModule, path, MAX_PATH))
|
||||
{
|
||||
std::string dir (path);
|
||||
size_t pos = dir.find_last_of ("\\/");
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
dir = dir.substr (0, pos);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
std::wstring GetProgramRootDirectoryW (HMODULE hModule hModule_DefaultParam)
|
||||
{
|
||||
wchar_t path [MAX_PATH];
|
||||
if (GetModuleFileNameW (hModule, path, MAX_PATH))
|
||||
{
|
||||
std::wstring dir (path);
|
||||
size_t pos = dir.find_last_of (L"\\/");
|
||||
if (pos != std::wstring::npos)
|
||||
{
|
||||
dir = dir.substr (0, pos);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
return L"";
|
||||
}
|
||||
std::string EnsureTrailingSlash (const std::string &path)
|
||||
{
|
||||
if (path.empty ()) return path; // 空路径直接返回
|
||||
|
||||
char lastChar = path.back ();
|
||||
if (lastChar == '\\' || lastChar == '/')
|
||||
return path; // 已有分隔符,直接返回
|
||||
// 根据系统或原路径格式添加适当的分隔符
|
||||
char separator = (path.find ('/') != std::string::npos) ? '/' : '\\';
|
||||
return path + separator;
|
||||
}
|
||||
std::wstring EnsureTrailingSlash (const std::wstring &path)
|
||||
{
|
||||
if (path.empty ()) return path;
|
||||
|
||||
wchar_t lastChar = path.back ();
|
||||
if (lastChar == L'\\' || lastChar == L'/')
|
||||
return path;
|
||||
|
||||
wchar_t separator = (path.find (L'/') != std::wstring::npos) ? L'/' : L'\\';
|
||||
return path + separator;
|
||||
}
|
||||
bool IsFileExistsW (LPCWSTR filename)
|
||||
{
|
||||
DWORD dwAttrib = GetFileAttributesW (filename);
|
||||
return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
|
||||
}
|
||||
bool IsFileExistsA (LPCSTR filename)
|
||||
{
|
||||
DWORD dwAttrib = GetFileAttributesA (filename);
|
||||
return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
|
||||
}
|
||||
bool IsFileExists (LPWSTR filePath) { return IsFileExistsW (filePath); }
|
||||
bool IsFileExists (LPCSTR filePath) { return IsFileExistsA (filePath); }
|
||||
bool IsFileExists (const std::string &filePath) { return IsFileExistsA (filePath.c_str ()); }
|
||||
bool IsFileExists (const std::wstring &filePath) { return IsFileExistsW (filePath.c_str ()); }
|
||||
bool IsDirectoryExistsA (LPCSTR path)
|
||||
{
|
||||
DWORD attributes = GetFileAttributesA (path);
|
||||
return (attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY));
|
||||
}
|
||||
bool IsDirectoryExistsW (LPCWSTR path)
|
||||
{
|
||||
DWORD attributes = GetFileAttributesW (path);
|
||||
return (attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY));
|
||||
}
|
||||
bool IsDirectoryExists (const std::string &path) { return IsDirectoryExistsA (path.c_str ()); }
|
||||
bool IsDirectoryExists (const std::wstring &path) { return IsDirectoryExistsW (path.c_str ()); }
|
||||
bool IsDirectoryExists (LPCSTR path) { return IsDirectoryExistsA (path); }
|
||||
bool IsDirectoryExists (LPCWSTR path) { return IsDirectoryExistsW (path); }
|
||||
bool IsPathExistsW (LPCWSTR filename)
|
||||
{
|
||||
DWORD dwAttrib = GetFileAttributesW (filename);
|
||||
return (dwAttrib != INVALID_FILE_ATTRIBUTES);
|
||||
}
|
||||
bool IsPathExistsA (LPCSTR filename)
|
||||
{
|
||||
DWORD dwAttrib = GetFileAttributesA (filename);
|
||||
return (dwAttrib != INVALID_FILE_ATTRIBUTES);
|
||||
}
|
||||
bool IsPathExists (const std::string &path) { return IsPathExistsA (path.c_str ()); }
|
||||
bool IsPathExists (const std::wstring &path) { return IsPathExistsW (path.c_str ()); }
|
||||
bool IsPathExists (LPCSTR path) { return IsPathExistsA (path); }
|
||||
bool IsPathExists (LPCWSTR path) { return IsPathExistsW (path); }
|
||||
std::string NormalizePath (const std::string &path)
|
||||
{
|
||||
if (!path.empty () && path.back () == '\\')
|
||||
return path.substr (0, path.size () - 1);
|
||||
return path.c_str ();
|
||||
}
|
||||
std::wstring NormalizePath (const std::wstring &path)
|
||||
{
|
||||
if (!path.empty () && path.back () == L'\\')
|
||||
return path.substr (0, path.size () - 1);
|
||||
return path.c_str ();
|
||||
}
|
||||
std::vector <std::string> EnumSubdirectories (const std::string &directory, bool includeParentPath)
|
||||
{
|
||||
std::vector<std::string> subdirs;
|
||||
std::string normPath = NormalizePath (directory);
|
||||
std::string searchPath = normPath + "\\*";
|
||||
WIN32_FIND_DATAA findData;
|
||||
HANDLE hFind = FindFirstFileA (searchPath.c_str (), &findData);
|
||||
if (hFind == INVALID_HANDLE_VALUE) return subdirs;
|
||||
do
|
||||
{
|
||||
// 过滤 "." 和 ".."
|
||||
if (strcmp (findData.cFileName, ".") == 0 || strcmp (findData.cFileName, "..") == 0)
|
||||
continue;
|
||||
// 判断是否为目录
|
||||
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
if (includeParentPath)
|
||||
subdirs.push_back (normPath + "\\" + findData.cFileName);
|
||||
else
|
||||
subdirs.push_back (findData.cFileName);
|
||||
}
|
||||
} while (FindNextFileA (hFind, &findData));
|
||||
FindClose (hFind);
|
||||
return subdirs;
|
||||
}
|
||||
std::vector <std::wstring> EnumSubdirectories (const std::wstring &directory, bool includeParentPath)
|
||||
{
|
||||
std::vector<std::wstring> subdirs;
|
||||
std::wstring normPath = NormalizePath (directory);
|
||||
std::wstring searchPath = normPath + L"\\*";
|
||||
WIN32_FIND_DATAW findData;
|
||||
HANDLE hFind = FindFirstFileW (searchPath.c_str (), &findData);
|
||||
if (hFind == INVALID_HANDLE_VALUE) return subdirs;
|
||||
do
|
||||
{
|
||||
if (wcscmp (findData.cFileName, L".") == 0 || wcscmp (findData.cFileName, L"..") == 0)
|
||||
continue;
|
||||
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
if (includeParentPath)
|
||||
subdirs.push_back (normPath + L"\\" + findData.cFileName);
|
||||
else
|
||||
subdirs.push_back (findData.cFileName);
|
||||
}
|
||||
} while (FindNextFileW (hFind, &findData));
|
||||
FindClose (hFind);
|
||||
return subdirs;
|
||||
}
|
||||
std::string GetCurrentProgramPathA (HMODULE hModule hModule_DefaultParam)
|
||||
{
|
||||
std::vector <CHAR> buf (Max <size_t> (MAX_PATH, GetModuleFileNameA (hModule, nullptr, 0)) + 1);
|
||||
GetModuleFileNameA (hModule, buf.data (), buf.capacity ());
|
||||
return buf.data ();
|
||||
}
|
||||
std::wstring GetCurrentProgramPathW (HMODULE hModule hModule_DefaultParam)
|
||||
{
|
||||
std::vector <WCHAR> buf (Max <size_t> (MAX_PATH, GetModuleFileNameW (hModule, nullptr, 0)) + 1);
|
||||
GetModuleFileNameW (hModule, buf.data (), buf.capacity ());
|
||||
return buf.data ();
|
||||
}
|
||||
std::string GetCurrentProgramNameA (HMODULE hModule hModule_DefaultParam) { return PathFindFileNameA (GetCurrentProgramPathA (hModule).c_str ()); }
|
||||
std::wstring GetCurrentProgramNameW (HMODULE hModule hModule_DefaultParam) { return PathFindFileNameW (GetCurrentProgramPathW (hModule).c_str ()); }
|
||||
VERSION GetExeFileVersion (LPCSTR lpszFilePath)
|
||||
{
|
||||
VERSION ver (0);
|
||||
DWORD dummy;
|
||||
DWORD size = GetFileVersionInfoSizeA (lpszFilePath, &dummy);
|
||||
std::vector <BYTE> pVersionInfo (size);
|
||||
if (!GetFileVersionInfoA (lpszFilePath, 0, size, pVersionInfo.data ()))
|
||||
{
|
||||
return ver;
|
||||
}
|
||||
VS_FIXEDFILEINFO* pFileInfo = nullptr;
|
||||
UINT len = 0;
|
||||
if (!VerQueryValueA (pVersionInfo.data (), "\\", (LPVOID *)&pFileInfo, &len))
|
||||
{
|
||||
return ver;
|
||||
}
|
||||
if (len == 0 || pFileInfo == nullptr)
|
||||
{
|
||||
return ver;
|
||||
}
|
||||
ver = VERSION (
|
||||
HIWORD (pFileInfo->dwFileVersionMS),
|
||||
LOWORD (pFileInfo->dwFileVersionMS),
|
||||
HIWORD (pFileInfo->dwFileVersionLS),
|
||||
LOWORD (pFileInfo->dwFileVersionLS)
|
||||
);
|
||||
return ver;
|
||||
}
|
||||
VERSION GetExeFileVersion (LPCWSTR lpswFilePath)
|
||||
{
|
||||
VERSION ver (0);
|
||||
DWORD dummy;
|
||||
DWORD size = GetFileVersionInfoSizeW (lpswFilePath, &dummy);
|
||||
std::vector <BYTE> pVersionInfo (size);
|
||||
if (!GetFileVersionInfoW (lpswFilePath, 0, size, pVersionInfo.data ()))
|
||||
{
|
||||
return ver;
|
||||
}
|
||||
VS_FIXEDFILEINFO* pFileInfo = nullptr;
|
||||
UINT len = 0;
|
||||
if (!VerQueryValueA (pVersionInfo.data (), "\\", (LPVOID *)&pFileInfo, &len))
|
||||
{
|
||||
return ver;
|
||||
}
|
||||
if (len == 0 || pFileInfo == nullptr)
|
||||
{
|
||||
return ver;
|
||||
}
|
||||
ver = VERSION (
|
||||
HIWORD (pFileInfo->dwFileVersionMS),
|
||||
LOWORD (pFileInfo->dwFileVersionMS),
|
||||
HIWORD (pFileInfo->dwFileVersionLS),
|
||||
LOWORD (pFileInfo->dwFileVersionLS)
|
||||
);
|
||||
return ver;
|
||||
}
|
||||
VERSION GetExeFileVersion (std::wstring objswFilePath)
|
||||
{
|
||||
return GetExeFileVersion (objswFilePath.c_str ());
|
||||
}
|
||||
VERSION GetExeFileVersion (std::string objszFilePath)
|
||||
{
|
||||
return GetExeFileVersion (objszFilePath.c_str ());
|
||||
}
|
||||
// 设置当前进程的环境变量RunPath和ProgramPath
|
||||
void SetupInstanceEnvironment (HMODULE hModule hModule_DefaultParam)
|
||||
{
|
||||
// 设置RunPath为当前工作目录(无结尾反斜杠)
|
||||
std::vector <WCHAR> currentDir (Max <size_t> (GetCurrentDirectoryW (0, nullptr), MAX_PATH) + 1);
|
||||
DWORD len = GetCurrentDirectoryW (currentDir.capacity (), currentDir.data ());
|
||||
if (len > 0)
|
||||
{
|
||||
std::wstring runPath (currentDir.data ());
|
||||
if (!runPath.empty () && (runPath.back () == L'\\' || runPath.back () == L'/'))
|
||||
{
|
||||
runPath.pop_back ();
|
||||
}
|
||||
SetEnvironmentVariableW (L"RunPath", runPath.c_str ());
|
||||
}
|
||||
// 设置ProgramPath为程序所在目录(无结尾反斜杠)
|
||||
std::vector <WCHAR> modulePath (Max <size_t> (GetModuleFileNameW (hModule, nullptr, 0), MAX_PATH) + 1);
|
||||
len = GetModuleFileNameW (hModule, modulePath.data (), MAX_PATH);
|
||||
if (len > 0 && len < MAX_PATH)
|
||||
{
|
||||
wchar_t* lastSlash = wcsrchr (modulePath.data (), L'\\');
|
||||
if (!lastSlash) lastSlash = wcsrchr (modulePath.data (), L'/');
|
||||
if (lastSlash) *lastSlash = L'\0';
|
||||
std::wstring programPath (modulePath.data ());
|
||||
if (!programPath.empty () && (programPath.back () == L'\\' || programPath.back () == L'/'))
|
||||
{
|
||||
programPath.pop_back ();
|
||||
}
|
||||
SetEnvironmentVariableW (L"ProgramPath", programPath.c_str ());
|
||||
}
|
||||
}
|
||||
// 处理宽字符串环境变量展开
|
||||
std::wstring ProcessEnvVars (const std::wstring &input)
|
||||
{
|
||||
DWORD requiredSize = ExpandEnvironmentStringsW (input.c_str (), nullptr, 0);
|
||||
if (requiredSize == 0) return input;
|
||||
std::wstring buffer (requiredSize, L'\0');
|
||||
if (!ExpandEnvironmentStringsW (input.c_str (), &buffer [0], requiredSize))
|
||||
{
|
||||
return input;
|
||||
}
|
||||
buffer.resize (requiredSize - 1); // 去除终止空字符
|
||||
return buffer.c_str ();
|
||||
}
|
||||
std::wstring ProcessEnvVars (LPCWSTR input)
|
||||
{
|
||||
return ProcessEnvVars (std::wstring (input));
|
||||
}
|
||||
// 处理ANSI字符串环境变量展开
|
||||
std::string ProcessEnvVars (const std::string &input)
|
||||
{
|
||||
DWORD requiredSize = ExpandEnvironmentStringsA (input.c_str (), nullptr, 0);
|
||||
if (requiredSize == 0) return input;
|
||||
std::string buffer (requiredSize, '\0');
|
||||
if (!ExpandEnvironmentStringsA (input.c_str (), &buffer [0], requiredSize))
|
||||
{
|
||||
return input;
|
||||
}
|
||||
buffer.resize (requiredSize - 1); // 去除终止空字符
|
||||
return buffer.c_str ();
|
||||
}
|
||||
std::string ProcessEnvVars (LPCSTR input)
|
||||
{
|
||||
return ProcessEnvVars (std::string (input));
|
||||
}
|
||||
std::string GetCurrentDirectoryA ()
|
||||
{
|
||||
std::vector <CHAR> buf (Max <size_t> (GetCurrentDirectoryA (0, nullptr), MAX_PATH) + 1);
|
||||
GetCurrentDirectoryA (buf.size (), buf.data ());
|
||||
return buf.data ();
|
||||
}
|
||||
std::wstring GetCurrentDirectoryW ()
|
||||
{
|
||||
std::vector <WCHAR> buf (Max <size_t> (GetCurrentDirectoryW (0, nullptr), MAX_PATH) + 1);
|
||||
GetCurrentDirectoryW (buf.size (), buf.data ());
|
||||
return buf.data ();
|
||||
}
|
||||
std::wstring GetFileDirectoryW (const std::wstring &filePath)
|
||||
{
|
||||
std::vector <WCHAR> buf (filePath.capacity () + 1);
|
||||
lstrcpyW (buf.data (), filePath.c_str ());
|
||||
PathRemoveFileSpecW (buf.data ());
|
||||
return buf.data ();
|
||||
}
|
||||
std::string GetFileDirectoryA (const std::string &filePath)
|
||||
{
|
||||
std::vector <CHAR> buf (filePath.capacity () + 1);
|
||||
lstrcpyA (buf.data (), filePath.c_str ());
|
||||
PathRemoveFileSpecA (buf.data ());
|
||||
return buf.data ();
|
||||
}
|
||||
size_t EnumerateFilesW (const std::wstring &directory, const std::wstring &filter,
|
||||
std::vector <std::wstring> &outFiles, bool recursive = false)
|
||||
{
|
||||
std::wstring searchPath = directory;
|
||||
if (!searchPath.empty () && searchPath.back () != L'\\')
|
||||
{
|
||||
searchPath += L'\\';
|
||||
}
|
||||
searchPath += filter;
|
||||
WIN32_FIND_DATAW findData;
|
||||
HANDLE hFind = FindFirstFileW (searchPath.c_str (), &findData);
|
||||
if (hFind != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
do {
|
||||
if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
outFiles.push_back (directory + L"\\" + findData.cFileName);
|
||||
}
|
||||
} while (FindNextFileW (hFind, &findData));
|
||||
FindClose (hFind);
|
||||
}
|
||||
if (recursive) {
|
||||
std::wstring subDirSearchPath = directory + L"\\*";
|
||||
hFind = FindFirstFileW (subDirSearchPath.c_str (), &findData);
|
||||
if (hFind != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
do {
|
||||
if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
|
||||
wcscmp (findData.cFileName, L".") != 0 && wcscmp (findData.cFileName, L"..") != 0)
|
||||
{
|
||||
EnumerateFilesW (directory + L"\\" + findData.cFileName, filter, outFiles, true);
|
||||
}
|
||||
} while (FindNextFileW (hFind, &findData));
|
||||
FindClose (hFind);
|
||||
}
|
||||
}
|
||||
return outFiles.size ();
|
||||
}
|
||||
// 检查是否为 Windows 设备名(大小写不敏感)
|
||||
bool IsReservedName (const std::wstring &name)
|
||||
{
|
||||
static const wchar_t* reserved [] = {
|
||||
L"CON", L"PRN", L"AUX", L"NUL", L"COM1", L"COM2", L"COM3", L"COM4", L"COM5", L"COM6", L"COM7", L"COM8", L"COM9",
|
||||
L"LPT1", L"LPT2", L"LPT3", L"LPT4", L"LPT5", L"LPT6", L"LPT7", L"LPT8", L"LPT9"
|
||||
};
|
||||
std::wstring upperName = StringToUpper (name);
|
||||
for (const auto& res : reserved)
|
||||
{
|
||||
if (upperName == res || (upperName.rfind (res, 0) == 0 && upperName.length () > wcslen (res) && upperName [wcslen (res)] == L'.'))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// Windows 文件命名规范检查 (Unicode)
|
||||
bool IsValidWindowsNameW (LPCWSTR name)
|
||||
{
|
||||
if (!name || !*name) return false;
|
||||
std::wstring wname (name);
|
||||
if (wname.find_first_of (L"<>:\"/\\|?*") != std::wstring::npos) return false;
|
||||
if (IsReservedName (wname)) return false;
|
||||
if (wname.back () == L' ' || wname.back () == L'.') return false;
|
||||
return true;
|
||||
}
|
||||
// Windows 文件命名规范检查 (ANSI)
|
||||
bool IsValidWindowsNameA (LPCSTR name)
|
||||
{
|
||||
if (!name || !*name) return false;
|
||||
std::string str (name);
|
||||
if (str.find_first_of ("<>:\"/\\|?*") != std::string::npos) return false;
|
||||
|
||||
// 转换 ANSI 到宽字符
|
||||
int len = MultiByteToWideChar (CP_ACP, 0, name, -1, NULL, 0);
|
||||
if (len <= 0) return false;
|
||||
std::wstring wname (len - 1, L'\0');
|
||||
MultiByteToWideChar (CP_ACP, 0, name, -1, &wname [0], len);
|
||||
if (IsReservedName (wname)) return false;
|
||||
if (str.back () == ' ' || str.back () == '.') return false;
|
||||
return true;
|
||||
}
|
||||
bool IsValidWindowsName (LPCSTR name) { return IsValidWindowsNameA (name); }
|
||||
bool IsValidWindowsName (LPCWSTR name) { return IsValidWindowsNameW (name); }
|
||||
bool IsValidWindowsName (const std::wstring &name) { return IsValidWindowsName (name.c_str ()); }
|
||||
bool IsValidWindowsName (const std::string &name) { return IsValidWindowsName (name.c_str ()); }
|
||||
std::wstring GetRootFolderNameFromFilePath (const std::wstring &lpFilePath)
|
||||
{
|
||||
std::vector <WCHAR> szPath (Max <size_t> (lpFilePath.length (), MAX_PATH) + 1);
|
||||
if (!PathCanonicalizeW (szPath.data (), lpFilePath.c_str ())) return L"";
|
||||
if (PathRemoveFileSpecW (szPath.data ()) == FALSE) return L"";
|
||||
LPCWSTR pszFolder = PathFindFileNameW (szPath.data ());
|
||||
if (*pszFolder != L'\0') return std::wstring (pszFolder);
|
||||
WCHAR rootName [3] = {szPath [0], L':', L'\0'};
|
||||
return std::wstring (rootName);
|
||||
}
|
||||
std::wstring GetSafeTimestampForFilename ()
|
||||
{
|
||||
::FILETIME ft;
|
||||
GetSystemTimeAsFileTime (&ft);
|
||||
SYSTEMTIME st;
|
||||
FileTimeToSystemTime (&ft, &st);
|
||||
std::wstringstream wss;
|
||||
wss << std::setfill (L'0')
|
||||
<< st.wYear
|
||||
<< std::setw (2) << st.wMonth
|
||||
<< std::setw (2) << st.wDay << L"_"
|
||||
<< std::setw (2) << st.wHour
|
||||
<< std::setw (2) << st.wMinute
|
||||
<< std::setw (2) << st.wSecond
|
||||
<< std::setw (3) << st.wMilliseconds;
|
||||
return wss.str ();
|
||||
}
|
||||
size_t EnumFiles (
|
||||
const std::wstring &lpDir,
|
||||
const std::wstring &lpFilter,
|
||||
std::vector <std::wstring> &aszOutput,
|
||||
bool bOutputWithPath = false,
|
||||
bool bSortByLetter = false,
|
||||
bool bIncludeSubDir = false
|
||||
) {
|
||||
if (!bIncludeSubDir) aszOutput.clear ();
|
||||
std::vector<std::wstring> filters;
|
||||
size_t start = 0;
|
||||
while (start < lpFilter.length ())
|
||||
{
|
||||
size_t pos = lpFilter.find (L'\\', start);
|
||||
if (pos == std::wstring::npos) pos = lpFilter.length ();
|
||||
filters.emplace_back (lpFilter.substr (start, pos - start));
|
||||
start = pos + 1;
|
||||
}
|
||||
|
||||
std::function <void (const std::wstring &, std::wstring)> enumDir;
|
||||
enumDir = [&] (const std::wstring &physicalPath, std::wstring relativePath)
|
||||
{
|
||||
WIN32_FIND_DATAW ffd;
|
||||
HANDLE hFind = FindFirstFileW ((physicalPath + L"\\*").c_str (), &ffd);
|
||||
if (hFind == INVALID_HANDLE_VALUE) return;
|
||||
do {
|
||||
if (wcscmp (ffd.cFileName, L".") == 0 ||
|
||||
wcscmp (ffd.cFileName, L"..") == 0) continue;
|
||||
const bool isDir = (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
|
||||
const std::wstring newPhysical = physicalPath + L"\\" + ffd.cFileName;
|
||||
std::wstring newRelative = relativePath;
|
||||
if (isDir) {
|
||||
if (bIncludeSubDir) {
|
||||
newRelative += ffd.cFileName;
|
||||
newRelative += L"\\";
|
||||
enumDir (newPhysical, newRelative);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto &filter : filters)
|
||||
{
|
||||
if (PathMatchSpecW (ffd.cFileName, filter.c_str ()))
|
||||
{
|
||||
aszOutput.push_back
|
||||
(
|
||||
bOutputWithPath ? newPhysical : (relativePath + ffd.cFileName)
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (FindNextFileW (hFind, &ffd));
|
||||
FindClose (hFind);
|
||||
};
|
||||
enumDir (lpDir, L"");
|
||||
if (bSortByLetter) std::sort (aszOutput.begin (), aszOutput.end ());
|
||||
return aszOutput.size ();
|
||||
}
|
||||
std::wstring GetRelativePath (
|
||||
const std::wstring &pszBaseDir,
|
||||
const std::wstring &pszFullPath,
|
||||
DWORD cchRelative
|
||||
) {
|
||||
std::vector <WCHAR> szBase (Max <size_t> (pszBaseDir.length (), pszFullPath.length (), MAX_PATH) + 1);
|
||||
wcscpy_s (szBase.data (), MAX_PATH, pszBaseDir.c_str ());
|
||||
if (szBase [wcslen (szBase.data ()) - 1] != L'\\')
|
||||
{
|
||||
wcscat_s (szBase.data (), MAX_PATH, L"\\");
|
||||
}
|
||||
std::vector <WCHAR> buf (Max <size_t> (MAX_PATH, szBase.size ()) + 1);
|
||||
BOOL res = PathRelativePathToW (
|
||||
buf.data (),
|
||||
szBase.data (),
|
||||
FILE_ATTRIBUTE_DIRECTORY,
|
||||
pszFullPath.c_str (),
|
||||
FILE_ATTRIBUTE_NORMAL
|
||||
);
|
||||
if (res) return buf.data ();
|
||||
else return L"";
|
||||
}
|
||||
size_t EnumDirectory (
|
||||
const std::wstring &lpDir,
|
||||
std::vector<std::wstring> &aszOutput,
|
||||
bool bOutputWithPath = false,
|
||||
bool bSortByLetter = false,
|
||||
bool bIncludeSubDir = false
|
||||
) {
|
||||
aszOutput.clear ();
|
||||
std::function <void (const std::wstring &, const std::wstring &)> enumDir;
|
||||
enumDir = [&] (const std::wstring &physicalPath, const std::wstring &relativePath) {
|
||||
WIN32_FIND_DATAW ffd;
|
||||
HANDLE hFind = FindFirstFileW ((physicalPath + L"\\*").c_str (), &ffd);
|
||||
if (hFind == INVALID_HANDLE_VALUE) return;
|
||||
do
|
||||
{
|
||||
const std::wstring name = ffd.cFileName;
|
||||
if (name == L"." || name == L"..") continue;
|
||||
const bool isDir = (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
std::wstring newPhysical = physicalPath + L"\\" + name;
|
||||
std::wstring newRelative = relativePath + name;
|
||||
if (isDir)
|
||||
{
|
||||
if (bIncludeSubDir) enumDir (newPhysical, newRelative + L"\\");
|
||||
if (bOutputWithPath) aszOutput.push_back (newPhysical);
|
||||
else aszOutput.push_back (newRelative);
|
||||
}
|
||||
} while (FindNextFileW (hFind, &ffd));
|
||||
FindClose (hFind);
|
||||
};
|
||||
enumDir (lpDir, L"");
|
||||
if (bSortByLetter) std::sort (aszOutput.begin (), aszOutput.end ());
|
||||
return aszOutput.size ();
|
||||
}
|
||||
|
||||
static DWORD CALLBACK ProgressRoutine (
|
||||
LARGE_INTEGER TotalFileSize,
|
||||
LARGE_INTEGER TotalBytesTransferred,
|
||||
LARGE_INTEGER /*StreamSize*/,
|
||||
LARGE_INTEGER /*StreamBytesTransferred*/,
|
||||
DWORD /*dwStreamNumber*/,
|
||||
DWORD /*dwCallbackReason*/,
|
||||
HANDLE /*hSourceFile*/,
|
||||
HANDLE /*hDestinationFile*/,
|
||||
LPVOID lpData
|
||||
) {
|
||||
auto *pCallback = reinterpret_cast <std::function <void (int)> *> (lpData);
|
||||
if (pCallback && *pCallback)
|
||||
{
|
||||
int progress = static_cast <int> (
|
||||
(TotalBytesTransferred.QuadPart * 100) / TotalFileSize.QuadPart
|
||||
);
|
||||
(*pCallback) (progress);
|
||||
}
|
||||
return PROGRESS_CONTINUE;
|
||||
}
|
||||
bool RenameFileW (
|
||||
const std::wstring &lpSrcPath,
|
||||
const std::wstring &lpDestPath,
|
||||
std::function <void (int)> fProgress = nullptr
|
||||
) {
|
||||
LPPROGRESS_ROUTINE pRoutine = nullptr;
|
||||
LPVOID pData = nullptr;
|
||||
if (fProgress)
|
||||
{
|
||||
pRoutine = ProgressRoutine;
|
||||
pData = &fProgress;
|
||||
}
|
||||
DWORD flags = MOVEFILE_COPY_ALLOWED;
|
||||
BOOL ok = MoveFileWithProgressW (
|
||||
lpSrcPath.c_str (),
|
||||
lpDestPath.c_str (),
|
||||
pRoutine,
|
||||
pData,
|
||||
flags
|
||||
);
|
||||
return ok != FALSE;
|
||||
}
|
||||
bool RenameFileA (
|
||||
const std::string &lpSrcPath,
|
||||
const std::string &lpDestPath,
|
||||
std::function <void (int)> fProgress = nullptr
|
||||
) {
|
||||
LPPROGRESS_ROUTINE pRoutine = nullptr;
|
||||
LPVOID pData = nullptr;
|
||||
if (fProgress)
|
||||
{
|
||||
pRoutine = ProgressRoutine;
|
||||
pData = &fProgress;
|
||||
}
|
||||
DWORD flags = MOVEFILE_COPY_ALLOWED;
|
||||
BOOL ok = MoveFileWithProgressA (
|
||||
lpSrcPath.c_str (),
|
||||
lpDestPath.c_str (),
|
||||
pRoutine,
|
||||
pData,
|
||||
flags
|
||||
);
|
||||
return ok != FALSE;
|
||||
}
|
||||
bool RenameFileW (const std::wstring &lpSrcDir, const std::wstring &lpSrcName, const std::wstring &lpDestName, std::function <void (int)> fProgress = nullptr)
|
||||
{
|
||||
struct BuildTask
|
||||
{
|
||||
LPWSTR src = nullptr, dest = nullptr;
|
||||
~BuildTask ()
|
||||
{
|
||||
if (src != nullptr)
|
||||
{
|
||||
delete [] src;
|
||||
src = nullptr;
|
||||
}
|
||||
if (dest != nullptr)
|
||||
{
|
||||
delete [] dest;
|
||||
dest = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
BuildTask bt;
|
||||
bt.src = new WCHAR [lpSrcDir.length () + lpSrcName.length () + 2];
|
||||
bt.dest = new WCHAR [lpSrcDir.length () + lpDestName.length () + 2];
|
||||
PathCombineW (bt.src, lpSrcDir.c_str (), lpSrcName.c_str ());
|
||||
PathCombineW (bt.dest, lpSrcDir.c_str (), lpDestName.c_str ());
|
||||
return RenameFileW (bt.src, bt.dest, fProgress);
|
||||
}
|
||||
bool RenameFileA (const std::string &lpSrcDir, const std::string &lpSrcName, const std::string &lpDestName, std::function <void (int)> fProgress = nullptr)
|
||||
{
|
||||
struct BuildTask
|
||||
{
|
||||
LPSTR src = nullptr, dest = nullptr;
|
||||
~BuildTask ()
|
||||
{
|
||||
if (src != nullptr)
|
||||
{
|
||||
delete [] src;
|
||||
src = nullptr;
|
||||
}
|
||||
if (dest != nullptr)
|
||||
{
|
||||
delete [] dest;
|
||||
dest = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
BuildTask bt;
|
||||
bt.src = new CHAR [lpSrcDir.length () + lpSrcName.length () + 2];
|
||||
bt.dest = new CHAR [lpSrcDir.length () + lpDestName.length () + 2];
|
||||
PathCombineA (bt.src, lpSrcDir.c_str (), lpSrcName.c_str ());
|
||||
PathCombineA (bt.dest, lpSrcDir.c_str (), lpDestName.c_str ());
|
||||
return RenameFileA (bt.src, bt.dest, fProgress);
|
||||
}
|
||||
bool RenameFile (const std::wstring &lpSrcPath, const std::wstring &lpDestPath, std::function <void (int)> fProgress = nullptr)
|
||||
{
|
||||
return RenameFileW (lpSrcPath, lpDestPath, fProgress);
|
||||
}
|
||||
bool RenameFile (const std::string &lpSrcPath, const std::string &lpDestPath, std::function <void (int)> fProgress = nullptr)
|
||||
{
|
||||
return RenameFileA (lpSrcPath, lpDestPath, fProgress);
|
||||
}
|
||||
bool RenameFile (const std::wstring &lpSrcDir, const std::wstring &lpSrcName, const std::wstring &lpDestName, std::function <void (int)> fProgress = nullptr)
|
||||
{
|
||||
return RenameFileW (lpSrcDir, lpSrcName, lpDestName, fProgress);
|
||||
}
|
||||
bool RenameFile (const std::string &lpSrcDir, const std::string &lpSrcName, const std::string &lpDestName, std::function <void (int)> fProgress = nullptr)
|
||||
{
|
||||
return RenameFileA (lpSrcDir, lpSrcName, lpDestName, fProgress);
|
||||
}
|
||||
bool RenameDirectoryW (
|
||||
const std::wstring &lpSrcPath,
|
||||
const std::wstring &lpDestPath,
|
||||
std::function <void (int)> fProgress = nullptr
|
||||
) {
|
||||
LPPROGRESS_ROUTINE pRoutine = nullptr;
|
||||
LPVOID pData = nullptr;
|
||||
if (fProgress)
|
||||
{
|
||||
pRoutine = ProgressRoutine;
|
||||
pData = &fProgress;
|
||||
}
|
||||
DWORD flags = MOVEFILE_COPY_ALLOWED;
|
||||
BOOL ok = MoveFileWithProgressW (
|
||||
lpSrcPath.c_str (),
|
||||
lpDestPath.c_str (),
|
||||
pRoutine,
|
||||
pData,
|
||||
flags
|
||||
);
|
||||
return ok != FALSE;
|
||||
}
|
||||
bool RenameDirectoryA (
|
||||
const std::string &lpSrcPath,
|
||||
const std::string &lpDestPath,
|
||||
std::function <void (int)> fProgress = nullptr
|
||||
) {
|
||||
LPPROGRESS_ROUTINE pRoutine = nullptr;
|
||||
LPVOID pData = nullptr;
|
||||
if (fProgress)
|
||||
{
|
||||
pRoutine = ProgressRoutine;
|
||||
pData = &fProgress;
|
||||
}
|
||||
DWORD flags = MOVEFILE_COPY_ALLOWED;
|
||||
BOOL ok = MoveFileWithProgressA (
|
||||
lpSrcPath.c_str (),
|
||||
lpDestPath.c_str (),
|
||||
pRoutine,
|
||||
pData,
|
||||
flags
|
||||
);
|
||||
return ok != FALSE;
|
||||
}
|
||||
bool RenameDirectoryW (
|
||||
const std::wstring &lpParentDir,
|
||||
const std::wstring &lpSrcName,
|
||||
const std::wstring &lpDestName,
|
||||
std::function <void (int)> fProgress = nullptr
|
||||
) {
|
||||
struct PathBuilder
|
||||
{
|
||||
LPWSTR src = nullptr;
|
||||
LPWSTR dest = nullptr;
|
||||
~PathBuilder ()
|
||||
{
|
||||
delete [] src;
|
||||
delete [] dest;
|
||||
}
|
||||
} pb;
|
||||
pb.src = new WCHAR [lpParentDir.length () + lpSrcName.length () + 2];
|
||||
pb.dest = new WCHAR [lpParentDir.length () + lpDestName.length () + 2];
|
||||
PathCombineW (pb.src, lpParentDir.c_str (), lpSrcName.c_str ());
|
||||
PathCombineW (pb.dest, lpParentDir.c_str (), lpDestName.c_str ());
|
||||
return RenameDirectoryW (pb.src, pb.dest, fProgress);
|
||||
}
|
||||
bool RenameDirectoryA (
|
||||
const std::string &lpParentDir,
|
||||
const std::string &lpSrcName,
|
||||
const std::string &lpDestName,
|
||||
std::function <void (int)> fProgress = nullptr
|
||||
) {
|
||||
struct PathBuilder
|
||||
{
|
||||
LPSTR src = nullptr;
|
||||
LPSTR dest = nullptr;
|
||||
~PathBuilder ()
|
||||
{
|
||||
delete [] src;
|
||||
delete [] dest;
|
||||
}
|
||||
} pb;
|
||||
pb.src = new CHAR [lpParentDir.length () + lpSrcName.length () + 2];
|
||||
pb.dest = new CHAR [lpParentDir.length () + lpDestName.length () + 2];
|
||||
PathCombineA (pb.src, lpParentDir.c_str (), lpSrcName.c_str ());
|
||||
PathCombineA (pb.dest, lpParentDir.c_str (), lpDestName.c_str ());
|
||||
return RenameDirectoryA (pb.src, pb.dest, fProgress);
|
||||
}
|
||||
bool RenameDirectory (
|
||||
const std::wstring &src,
|
||||
const std::wstring &dst,
|
||||
std::function <void (int)> fProgress = nullptr
|
||||
) {
|
||||
return RenameDirectoryW (src, dst, fProgress);
|
||||
}
|
||||
bool RenameDirectory (
|
||||
const std::string &src,
|
||||
const std::string &dst,
|
||||
std::function <void (int)> fProgress = nullptr
|
||||
) {
|
||||
return RenameDirectoryA (src, dst, fProgress);
|
||||
}
|
||||
bool RenameDirectory (
|
||||
const std::wstring &parentDir,
|
||||
const std::wstring &srcName,
|
||||
const std::wstring &dstName,
|
||||
std::function <void (int)> fProgress = nullptr
|
||||
) {
|
||||
return RenameDirectoryW (parentDir, srcName, dstName, fProgress);
|
||||
}
|
||||
bool RenameDirectory (
|
||||
const std::string &parentDir,
|
||||
const std::string &srcName,
|
||||
const std::string &dstName,
|
||||
std::function <void (int)> fProgress = nullptr
|
||||
) {
|
||||
return RenameDirectoryA (parentDir, srcName, dstName, fProgress);
|
||||
}
|
||||
std::wstring CombinePath (const std::wstring &left, const std::wstring &right)
|
||||
{
|
||||
std::vector <WCHAR> buf (left.capacity () + right.capacity () + 2);
|
||||
PathCombineW (buf.data (), left.c_str (), right.c_str ());
|
||||
return buf.data ();
|
||||
}
|
||||
#ifdef PathCommonPrefix
|
||||
#undef PathCommonPrefix
|
||||
#endif
|
||||
std::wstring PathCommonPrefix (const std::wstring &file1, const std::wstring &file2)
|
||||
{
|
||||
std::vector <WCHAR> buf (Max <size_t> (file1.capacity (), file2.capacity (), MAX_PATH) + 2);
|
||||
PathCommonPrefixW (file1.c_str (), file2.c_str (), buf.data ());
|
||||
return buf.data ();
|
||||
}
|
||||
#undef GetFullPathName
|
||||
std::wstring GetFullPathName (const std::wstring &lpFileName)
|
||||
{
|
||||
if (lpFileName.empty ()) return L"";
|
||||
DWORD length = GetFullPathNameW (lpFileName.c_str (), 0, nullptr, nullptr);
|
||||
if (length == 0) return L"";
|
||||
std::vector <WCHAR> buffer (length + 1, L'\0');
|
||||
DWORD result = GetFullPathNameW (lpFileName.c_str (), length, buffer.data (), nullptr);
|
||||
if (result == 0) return L"";
|
||||
return std::wstring (buffer.data (), result);
|
||||
}
|
||||
bool PathEquals (const std::wstring &path1, const std::wstring &path2)
|
||||
{
|
||||
size_t maxlen = Max <size_t> (path1.capacity () + 1, path2.capacity () + 1, MAX_PATH);
|
||||
std::vector <WCHAR> buf1 (maxlen), buf2 (maxlen);
|
||||
PathCanonicalizeW (buf1.data (), path1.c_str ());
|
||||
PathCanonicalizeW (buf2.data (), path2.c_str ());
|
||||
return IsNormalizeStringEquals (buf1.data (), buf2.data ());
|
||||
}
|
||||
46
appinstaller/ieshell.h
Normal file
@@ -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; }
|
||||
488
appinstaller/initfile.h
Normal file
@@ -0,0 +1,488 @@
|
||||
#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"
|
||||
|
||||
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
|
||||
};
|
||||
595
appinstaller/main.cpp
Normal file
@@ -0,0 +1,595 @@
|
||||
#include <Windows.h>
|
||||
#include <set>
|
||||
#include <msclr/marshal_cppstd.h>
|
||||
#include <ShObjIdl.h>
|
||||
#include <MsHTML.h>
|
||||
#include <ExDisp.h>
|
||||
#include <atlbase.h>
|
||||
#include "cmdargs.h"
|
||||
#include "themeinfo.h"
|
||||
#include "mpstr.h"
|
||||
#include "initfile.h"
|
||||
#include "resource.h"
|
||||
#include "vemani.h"
|
||||
#include "ieshell.h"
|
||||
using namespace System;
|
||||
using namespace System::Runtime::InteropServices;
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define DEBUGMODE true
|
||||
#else
|
||||
#define DEBUGMODE false
|
||||
#endif
|
||||
|
||||
LPCWSTR g_lpAppId = L"Microsoft.DesktopAppInstaller";
|
||||
auto &g_identity = g_lpAppId;
|
||||
auto &m_idenName = g_lpAppId;
|
||||
struct iconhandle
|
||||
{
|
||||
HICON hIcon = nullptr;
|
||||
iconhandle (HICON hIcon = nullptr): hIcon (hIcon) {}
|
||||
~iconhandle () { try { if (hIcon) DestroyIcon (hIcon); hIcon = nullptr; } catch (...) {} }
|
||||
};
|
||||
iconhandle g_hIconMain (LoadRCIcon (IDI_ICON_MAIN));
|
||||
initfile g_initfile (CombinePath (GetProgramRootDirectoryW (), L"config.ini"));
|
||||
ref class MainHtmlWnd;
|
||||
msclr::gcroot <MainHtmlWnd ^> g_mainwnd;
|
||||
vemanifest g_vemani (
|
||||
IsFileExists (CombinePath (GetProgramRootDirectoryW (), L"VisualElementsManifest.xml")) ?
|
||||
CombinePath (GetProgramRootDirectoryW (), L"VisualElementsManifest.xml") :
|
||||
CombinePath (GetProgramRootDirectoryW (), L"AppInstaller.VisualElementsManifest.xml")
|
||||
);
|
||||
resxmldoc g_scaleres (
|
||||
IsFileExists (CombinePath (GetProgramRootDirectoryW (), L"VisualElements\\scale.xml")) ?
|
||||
CombinePath (GetProgramRootDirectoryW (), L"VisualElements\\scale.xml") :
|
||||
CombinePath (GetProgramRootDirectoryW (), L"VisualElementsManifest.xml")
|
||||
);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
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) picbox->Image = img;
|
||||
}
|
||||
catch (...) { }
|
||||
if (backcolor != Drawing::Color::Transparent)
|
||||
{
|
||||
picbox->BackColor = backcolor;
|
||||
this->BackColor = backcolor;
|
||||
}
|
||||
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 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->Image = 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) { picbox->BackColor = color; this->BackColor = color; }
|
||||
// 渐变消失
|
||||
void FadeOut () { timer->Start (); }
|
||||
// 立即消失
|
||||
void FadeAway () { this->Visible = false; this->Close (); }
|
||||
~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:
|
||||
using WebBrowser = System::Windows::Forms::WebBrowser;
|
||||
private:
|
||||
WebBrowser ^webui;
|
||||
SplashForm ^splash;
|
||||
public:
|
||||
[ComVisible (true)]
|
||||
ref class IBridge
|
||||
{
|
||||
private:
|
||||
MainHtmlWnd ^wndinst = nullptr;
|
||||
public:
|
||||
IBridge (MainHtmlWnd ^wnd): wndinst (wnd) {}
|
||||
ref class _I_System
|
||||
{
|
||||
private:
|
||||
MainHtmlWnd ^wndinst = nullptr;
|
||||
public:
|
||||
ref class _I_UI
|
||||
{
|
||||
private:
|
||||
MainHtmlWnd ^wndinst = nullptr;
|
||||
public:
|
||||
_I_UI (MainHtmlWnd ^wnd): wndinst (wnd) {}
|
||||
property int DPIPercent { int get () { return GetDPI (); }}
|
||||
property double DPI { double get () { return DPIPercent * 0.01; }}
|
||||
void showSplash () { wndinst->SplashScreen->Show (); }
|
||||
void fadeAwaySplash () { wndinst->SplashScreen->FadeAway (); }
|
||||
void fadeOutSplash () { wndinst->SplashScreen->FadeOut (); }
|
||||
};
|
||||
private:
|
||||
_I_UI ^ui = gcnew _I_UI (wndinst);
|
||||
public:
|
||||
_I_System (MainHtmlWnd ^wnd): wndinst (wnd) {}
|
||||
property _I_UI ^UI { _I_UI ^get () { return ui; } }
|
||||
};
|
||||
ref class _I_IEFrame
|
||||
{
|
||||
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; }
|
||||
}
|
||||
property int Version { int get () { return GetInternetExplorerVersionMajor (); }}
|
||||
};
|
||||
ref class _I_Storage
|
||||
{
|
||||
private:
|
||||
MainHtmlWnd ^wndinst = nullptr;
|
||||
public:
|
||||
_I_Storage (MainHtmlWnd ^wnd): wndinst (wnd) {}
|
||||
ref class Path
|
||||
{
|
||||
|
||||
};
|
||||
};
|
||||
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))); }
|
||||
};
|
||||
private:
|
||||
_I_System ^system = gcnew _I_System (wndinst);
|
||||
_I_IEFrame ^ieframe = gcnew _I_IEFrame (wndinst);
|
||||
_I_Storage ^storage = gcnew _I_Storage (wndinst);
|
||||
_I_String ^str = gcnew _I_String ();
|
||||
public:
|
||||
property _I_System ^System { _I_System ^get () { return system; }}
|
||||
property _I_IEFrame ^IEFrame { _I_IEFrame ^get () { return ieframe; }}
|
||||
property _I_Storage ^Storage { _I_Storage ^get () { return storage; }}
|
||||
property _I_String ^String { _I_String ^get () { return str; }}
|
||||
};
|
||||
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 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 (...) {}
|
||||
}
|
||||
unsigned ww = 0, wh = 0;
|
||||
auto &ini = g_initfile;
|
||||
auto setsect = ini ["Settings"];
|
||||
if (setsect [L"SavePosAndSizeBeforeCancel"].read_bool ())
|
||||
{
|
||||
ww = setsect [L"LastWidth"].read_uint (setsect [L"DefaultWidth"].read_uint (rcInt (IDS_DEFAULTWIDTH)));
|
||||
wh = setsect [L"LastHeight"].read_uint (setsect [L"DefaultHeight"].read_uint (rcInt (IDS_DEFAULTHEIGHT)));
|
||||
}
|
||||
else
|
||||
{
|
||||
ww = setsect [L"DefaultWidth"].read_uint (rcInt (IDS_DEFAULTWIDTH));
|
||||
wh = setsect [L"DefaultHeight"].read_uint (rcInt (IDS_DEFAULTHEIGHT));
|
||||
}
|
||||
this->MinimumSize = System::Drawing::Size (
|
||||
setsect [L"MinimumWidth"].read_uint (rcInt (IDS_MINWIDTH)) * DPI,
|
||||
setsect [L"MinimumHeight"].read_uint (rcInt (IDS_MINHIEHGT)) * DPI
|
||||
);
|
||||
this->ClientSize = System::Drawing::Size (ww * DPI, wh * DPI);
|
||||
this->WindowState = (System::Windows::Forms::FormWindowState)setsect [L"LastWndState"].read_int ((int)System::Windows::Forms::FormWindowState::Normal);
|
||||
this->Text = rcString (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)
|
||||
{
|
||||
if (e->Url->ToString () == webui->Url->ToString ())
|
||||
{
|
||||
|
||||
ExecScript ("Windows.UI.DPI.mode = 1");
|
||||
ExecScript ("Bridge.Frame.scale = Bridge.Frame.scale * Bridge.UI.dpi");
|
||||
splash->FadeOut ();
|
||||
}
|
||||
}
|
||||
void OnCreate (System::Object ^sender, System::EventArgs ^e)
|
||||
{
|
||||
splash->Owner = this;
|
||||
splash->ChangePosAndSize ();
|
||||
splash->Show ();
|
||||
splash->Update ();
|
||||
webui->Navigate (CStringToMPString (CombinePath (GetProgramRootDirectoryW (), L"html\\install.html")));
|
||||
}
|
||||
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 OnResize (Object ^sender, EventArgs ^e)
|
||||
{
|
||||
}
|
||||
void OnResizeEnd (Object ^sender, EventArgs ^e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
MainHtmlWnd ()
|
||||
{
|
||||
splash = gcnew SplashForm (
|
||||
gcnew String (g_vemani.splash_screen_image (L"App").c_str ()),
|
||||
StringToColor (gcnew String (g_vemani.splash_screen_backgroundcolor (L"App").c_str ())),
|
||||
this
|
||||
);
|
||||
System::Windows::Forms::Application::DoEvents ();
|
||||
Init ();
|
||||
}
|
||||
Object ^CallScriptFunction (String ^lpFuncName, ... array <Object ^> ^alpParams)
|
||||
{
|
||||
try { return this->webui->Document->InvokeScript (lpFuncName, alpParams); }
|
||||
catch (Exception ^e) {}
|
||||
return nullptr;
|
||||
}
|
||||
Object ^CallScriptFunction (String ^lpScriptName)
|
||||
{
|
||||
try { return this->webui->Document->InvokeScript (lpScriptName); }
|
||||
catch (Exception ^e) {}
|
||||
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); }
|
||||
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);
|
||||
}
|
||||
}
|
||||
};
|
||||
using MainWnd = MainHtmlWnd;
|
||||
std::vector <std::wstring> LoadFileListW (const std::wstring &filePath)
|
||||
{
|
||||
std::vector <std::wstring> result;
|
||||
HANDLE hFile = CreateFileW (
|
||||
filePath.c_str (),
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
nullptr,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
nullptr);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE) return result;
|
||||
LARGE_INTEGER fileSize {};
|
||||
if (!GetFileSizeEx (hFile, &fileSize) || fileSize.QuadPart == 0)
|
||||
{
|
||||
CloseHandle (hFile);
|
||||
return result;
|
||||
}
|
||||
DWORD size = static_cast <DWORD> (fileSize.QuadPart);
|
||||
std::vector <WCHAR> buf;
|
||||
std::wstring buffer;
|
||||
buffer.resize (size / sizeof (wchar_t) + 2 + 2);
|
||||
DWORD readBytes = 0;
|
||||
ReadFile (hFile, buf.data (), size, &readBytes, nullptr);
|
||||
buffer += buf.data ();
|
||||
CloseHandle (hFile);
|
||||
buffer [readBytes / sizeof (wchar_t)] = L'\0';
|
||||
size_t start = 0;
|
||||
while (true)
|
||||
{
|
||||
size_t pos = buffer.find (L'\n', start);
|
||||
std::wstring line;
|
||||
if (pos == std::wstring::npos)
|
||||
{
|
||||
line = buffer.substr (start);
|
||||
}
|
||||
else
|
||||
{
|
||||
line = buffer.substr (start, pos - start);
|
||||
start = pos + 1;
|
||||
}
|
||||
if (!line.empty () && line.back () == L'\r') line.pop_back ();
|
||||
if (!line.empty ()) result.push_back (line);
|
||||
if (pos == std::wstring::npos) break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
enum class CMDPARAM: DWORD
|
||||
{
|
||||
NONE = 0b000,
|
||||
SILENT = 0b001,
|
||||
VERYSILENT = 0b011,
|
||||
MULTIPLE = 0b100
|
||||
};
|
||||
DWORD CmdMapsToFlags (std::map <cmdkey, cmdvalue> cmdpairs, std::set <std::wnstring> &files, std::set <std::wnstring> &uris)
|
||||
{
|
||||
DWORD dwret = 0;
|
||||
for (auto &it : cmdpairs)
|
||||
{
|
||||
switch (it.first.type)
|
||||
{
|
||||
case paramtype::file: {
|
||||
if (IsFileExists (it.first.key)) files.insert (it.first.key);
|
||||
} break;
|
||||
case paramtype::uri: {
|
||||
uris.insert (it.first.key);
|
||||
} break;
|
||||
default:
|
||||
case paramtype::string: {
|
||||
auto &key = it.first;
|
||||
auto &value = it.second;
|
||||
if (key.key.equals (L"silent")) dwret |= (DWORD)CMDPARAM::SILENT;
|
||||
else if (key.key.equals (L"verysilent")) dwret |= (DWORD)CMDPARAM::SILENT;
|
||||
else if (key.key.equals (L"multiple"))
|
||||
{
|
||||
if (value.type == paramtype::file)
|
||||
{
|
||||
auto strlist = LoadFileListW (value.value);
|
||||
for (auto &it_s : strlist)
|
||||
{
|
||||
if (std::wnstring::empty (it_s)) continue;
|
||||
std::wnstring filepath = it_s;
|
||||
std::wstring listdir = GetFileDirectoryW (value.value);
|
||||
if (!IsFileExists (filepath)) filepath = ProcessEnvVars (filepath);
|
||||
if (!IsFileExists (filepath)) filepath = CombinePath (listdir, filepath);
|
||||
if (!IsFileExists (filepath)) filepath = CombinePath (listdir, it_s);
|
||||
if (!IsFileExists (filepath)) continue;
|
||||
else files.insert (filepath);
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
if (files.size () > 1) dwret |= (DWORD)CMDPARAM::MULTIPLE;
|
||||
return dwret;
|
||||
}
|
||||
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 (m_idenName);
|
||||
SetProcessDPIAware ();
|
||||
{
|
||||
// 设置当前目录为程序所在目录
|
||||
std::wnstring currdir = GetCurrentProgramPathW ();
|
||||
std::wnstring rootdir = GetProgramRootDirectoryW ();
|
||||
if (!PathEquals (currdir, rootdir)) SetCurrentDirectoryW (rootdir.c_str ());
|
||||
}
|
||||
CoInitializeEx (NULL, COINIT_MULTITHREADED);
|
||||
destruct relco ([] () {
|
||||
CoUninitialize ();
|
||||
});
|
||||
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;
|
||||
}
|
||||
51
appinstaller/module.h
Normal file
@@ -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
|
||||
42
appinstaller/mpstr.h
Normal file
@@ -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);
|
||||
}
|
||||
465
appinstaller/nstring.h
Normal file
@@ -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;
|
||||
}
|
||||
4
appinstaller/packages.config
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="pugixml" version="1.15.0" targetFramework="native" />
|
||||
</packages>
|
||||
10
appinstaller/raii.h
Normal file
@@ -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;
|
||||
121
appinstaller/rctools.h
Normal file
@@ -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
|
||||
BIN
appinstaller/res/icons/color.ico
Normal file
|
After Width: | Height: | Size: 184 KiB |
BIN
appinstaller/res/icons/file.ico
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
appinstaller/res/icons/main.ico
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
appinstaller/res/icons/taskbar.ico
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
appinstaller/res/icons/titlebar.ico
Normal file
|
After Width: | Height: | Size: 403 KiB |
BIN
appinstaller/res/icons/white.ico
Normal file
|
After Width: | Height: | Size: 153 KiB |
BIN
appinstaller/resource.h
Normal file
154
appinstaller/strcmp.h
Normal file
@@ -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 ();
|
||||
}
|
||||
21
appinstaller/strcode.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <Windows.h>
|
||||
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;
|
||||
}
|
||||
160
appinstaller/themeinfo.h
Normal file
@@ -0,0 +1,160 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
#include <dwmapi.h>
|
||||
|
||||
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;
|
||||
}
|
||||
265
appinstaller/typestrans.h
Normal file
@@ -0,0 +1,265 @@
|
||||
#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>
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#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
|
||||
322
appinstaller/vemani.h
Normal file
@@ -0,0 +1,322 @@
|
||||
#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"
|
||||
|
||||
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))); }
|
||||
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 (...) {}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
std::wstring get (const std::wstring &id) const { return pugi::as_wide (get (WStringToString (id)).c_str ()); }
|
||||
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); }
|
||||
};
|
||||
124
appinstaller/version.h
Normal file
@@ -0,0 +1,124 @@
|
||||
#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;
|
||||
BIN
certmgr/certmgr.rc
Normal file
@@ -148,6 +148,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="certmgr.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
</ItemGroup>
|
||||
@@ -174,6 +175,9 @@
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="certmgr.rc" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
<ClInclude Include="certmgr.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
@@ -39,4 +42,9 @@
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="certmgr.rc">
|
||||
<Filter>资源文件</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
14
certmgr/resource.h
Normal file
@@ -0,0 +1,14 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by certmgr.rc
|
||||
|
||||
// 新对象的下一组默认值
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
@@ -195,24 +195,14 @@ int main (int argc, char *argv [])
|
||||
std::wcout << L"\\> ";
|
||||
std::wstring pkgPathStr = L"E:\\Profiles\\Bruce\\Desktop\\Discourse.appx";
|
||||
pkgPathStr = L"F:\\BaiduNetdiskDownload\\Collection4\\Microsoft.BingFinance_2015.709.2014.2069_neutral_~_8wekyb3d8bbwe\\FinanceApp_3.0.4.336_x86.appx";
|
||||
pkgPathStr = L"F:\\BaiduNetdiskDownload\\Collection4\\Microsoft.BingFinance_2015.709.2014.2069_neutral_~_8wekyb3d8bbwe.appxbundle";
|
||||
pkgPathStr = L"";
|
||||
//pkgPathStr = L"F:\\BaiduNetdiskDownload\\Collection4\\Microsoft.BingFinance_2015.709.2014.2069_neutral_~_8wekyb3d8bbwe.appxbundle";
|
||||
//pkgPathStr = L"";
|
||||
if (pkgPathStr.empty ()) std::getline (std::wcin, pkgPathStr);
|
||||
pkgPathStr.erase (
|
||||
std::remove (pkgPathStr.begin (), pkgPathStr.end (), L'\"'),
|
||||
pkgPathStr.end ()
|
||||
);
|
||||
std::wcout << L"Installing ..." << std::endl;
|
||||
std::wstring ec, dm;
|
||||
HRESULT hr = AddAppxPackage (pkgPathStr, [] (int progress) {
|
||||
std::wcout << L"\r " << progress << L"%";
|
||||
}, ec, dm);
|
||||
if (SUCCEEDED (hr)) std::wcout << std::endl << L"Installed Successfully." << std::endl;
|
||||
else
|
||||
{
|
||||
std::wcout << std::endl << L"Exception: " << ec << L"(0x" << std::hex << std::setw (8) << std::setfill (L'0') << hr << L")" << std::endl;
|
||||
std::wcout << L"Detail Message: " << dm << std::endl;
|
||||
}
|
||||
read_package (pkgPathStr);
|
||||
system ("pause");
|
||||
return 0;
|
||||
}
|
||||
BIN
notice/notice.rc
BIN
pkgmgr/pkgmgr.rc
@@ -1068,7 +1068,8 @@ ULONG DestroyAppxFileStream (_In_ HANDLE hFileStream)
|
||||
if (!hFileStream) return 0;
|
||||
IStream *ptr = reinterpret_cast <IStream *> (hFileStream);
|
||||
if (!ptr) return 0;
|
||||
return ptr->Release ();
|
||||
ULONG ret = ptr->Release ();
|
||||
return ret;
|
||||
}
|
||||
HANDLE GetAppxBundleApplicationPackageFile (_In_ HPKGREAD hReader)
|
||||
{
|
||||
|
||||
4
shared/AppInstaller.VisualElementsManifest.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" GeneratedByTileIconifier="true">
|
||||
<VisualElements ShowNameOnSquare150x150Logo="on" Square150x150Logo="VisualElements\150x150.png" Square70x70Logo="VisualElements\70x70.png" ForegroundText="light" BackgroundColor="#0078d7" TileIconifierColorSelection="Default" TileIconifierCreatedWithUpgrade="true" />
|
||||
</Application>
|
||||
BIN
shared/VisualElements/150x150.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
9
shared/VisualElements/150x150_Metadata.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0"?>
|
||||
<ShortcutItemImage xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<OriginalBytes>iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAA3kSURBVHhe7d2NkR3HkUVhmkSTaJJMkCkyQSbQElCVqjOIB2AG815O/9TtPl8EYyUIyOnMrLxL7m7E/qH7+Oeff/797du3v8d//YtfknQHdfzjr+8MAukmxqH/cPyPDALpwsZxf3j8jwwCXUo9Zh71v/ml26nex18vMQgUrR4vj/jR7UKgep6t9xgEilKP9Z3Df3SbEKheZ8tfZxBoafU4Pzn8R5cPgepxtrotg0BLqcf4wuE/umwIVG+zxf0YBDpVPb7m4T+6XAhUT7O1YxgEOlQ9tg0O/9FlQqB6mS0dzyDQrupxbXz4j+JDoHqYrZzLINCm6jHtePiPYkOgvn22sA6DQF9Sj+egw38UFwL1zfPT12QQ6CX1WE44/EcxIVDfOj95fQaBfqsex8mH/2j5EKhvnJ+axSDQD+oxLHT4j5YNgfq2+Ym5DIKbq+UveviPlguB+qb5addgENxMLTvg8B8tEwL1LfOTrscguLhabtjhPzo9BOob5qdcm0FwMbXM4MN/dFoI1M+en3AfBkG4Wt5FDv/R4SFQP3P+6HsyCMLUsi54+I8OC4H6WfNHyiBYXC3n4of/aPcQqJ8xf5QeGQSLqWXc6PAf7RYCVXv+CH3EIDhZDf+mh/9o8xComrO0nmEQHKyG7eH/YLMQqFqzpF5lEOyshuvhf+jLIVA1Zil9hUGwsRqmh/+UdgjUn50ltBWD4ItqeB7+y14Ogfoz849qDwbBi2pYHv6XPB0C9XvnH9HeDIJP1HA8/M18GgL1e+Zv1ZEMgg+Mofggt/VhCNR/Nn+LzmIQvGMMxIe5rV9CoH5t/kdagUHwkzEMH+i2vodA/ev5S1qNQfBgDMKHuq2apzMNYBBgDMEHu4G3B1V/8a8VwCAYxgAMgaaPHlD9mkGQ4/ZBMJo3BF7w7IOp32MQ5Lh1EIzGDYFPdB9I/RmDIMdtg2A0bQi8Y6sHUTUMghy3DILRsCGAvR5A1TQIctwuCEaztw6BoxZeP8MgyHGrIBiN3i4Ezlpw/UyDIMdtgmA0eYsQWGWh9Q0GQY5bBMFo8LIhsOoC65sMghyXD4LR3KVCIGVh9Y0GQY5LB8FoLD4EUhdU32wQ5LhsEIymIkPgKgupHgyCHJcMgtFQTAhcNYmrJ4Mgx+Xe4Whm6RC46uH/rHo0CHJc6l2ORpYLgbsc/s+qZ4Mgx2Xe6WhiiRC46+H/rGZgEOS4xLsdDZwWAh7++2omBkGO+Hc8Pv7QEPDwn1MzMghyRL/r8eG7h4CH31MzMwhyxL7z8dG7hICHv42aoUGQI/Ldjw/eLAQ8/H3UTA2CHHF3MD72SyHg4R+jZmwQ5Ii6i/GhL4eAh3+OmrlBkCPmTsZHPhUCHv4aagcGQYyn/z9Un6o+dH7vrzz8NdVODIKlZRz/m/rg+d2Th5+hdmQQLCfr+N/Uh3v4mWpnBsESMo//jQGQrXZnEJwm+/gLjfiPAOFqdwbBofKPv9DMdwZBttqdQbC7axx/oaFfGATZancGwS6uc/yFpj5kEGSr3RkEm7nW8Rca+5RBkK12ZxB8yfWOv9Dc0wyCbLU7g+Bl1zz+QoMvMwiy1e4Mgqdc9/gLTbYZBNlqdwbBh659/IVGv8wgyFa7Mwh+cP3jLzS7GYMgW+3OILjJ8Rca3pxBkK12d9MguM/xF5rejUGQrXZ3oyC41/EXGt+dQZCtdnfxILjf8ReaP4xBkK12d8EguOfxFwZwOIMgW+3uIkFw3+MvDOE0BkG22l1wENz7+AuDOJ1BkK12FxYEHn9hGMswCLLV7gKCwON/w0CWYxBkq90tGgQe/yOGsiyDIFvtbqEg8Ph/xmCWZxBkq92dHAQe/3sYTgyDIFvt7oQg8Pg/woDiGATZancHBYHH/zsMKZZBkK12t2MQePyfYVDxDIJstbuNg8DjfwbDugyDIFvtboMg8PifxcAuxyDIVrtrBoHH/wqGdlkGQbba3QtB4PG/isFdnkGQrXb3SRB4/B0M7zYMgmy1u3eCwOPvYoC3YxBkq92xQ4//K+oY7swgyFQ7e+fvBGIs8+7m58ggyFA78vA3ND9LbwyCNdVOPPwdzM/TzwyCNdQOPPwdzc/URwyCc9TMPfwDzM/VZwyCY9SMPfwDzc/WswyCfdRMPfwTzM/XqwyCbdQMPfwTzTbUZRD01Mw8/AXMdvRVBsFzakYe/kJmW9qKQfC+momHv6DZnrZmEEw1Aw9/YbNN7eWuQVA9e/gBZrva210eVPXo4QeZbesoV31g1ZOHH2i2r6Nd5cFVDx5+sDkGnSX1AdY3e/gXMMehs6U8yPpGD/9C5li0ilUfaH2Th39BczxazSoPtr7Bw7+wOSat6qwHXD/Tw7+BOS6t7qgHXT/Dw7+ROTal2OuBV00P/4bm+JRmqwdfNTz8G5tjVCrW2EaZOB7+RuY4lYo1tlEmhoe/sTlWpWKNbZRZnoe/kzlepWKNbZRZloe/szlmpWKNbZRZjod/kDlupWKNbZRZhod/sDl2pWKNbZQ5nYd/kjl+pWKNbZQ5jYd/srkGpWKNUg/vSKFYo9TDO1Io1ij18I4UijVKPbwjhWKNUg/vSKFYo9TDO1Io1ij18I4UijVKPbwjhWKNbf4f4tzcfEZKxRrbKOP/Rd5dzfUrFWtso8x3BsHNzLUrFWtso8wvDIKbmOtWKtbYRpkPGQQXN9esVKyxjTKfMgguaq5XqVhjG2WeZhBczFyrUrHGNsq8zCC4iLlOpWKNbZRpOysI6mfWz+bfquv/W1Qs1thGmS87KgjqZ/Cz/o9fVhdzVCjW2EaZzewVBFXz8fDf8B+rizkqFGtso8zmtgqCqvHe4b/ht6mLOSoUa2yjzG66QVB/5neH/4bfri7mqFCssY0yu3s2COr3PHP4b/hj6mKOCsUa2yhzmI+CoH7tlcN/wx9XF3NUKNbYRpnDvQVB/dU5/De0oS7mqFCssY0ysWhDXcxRoVhjG2Vi0Ya6mKNCscY2ysSiDXUxR4VijW2UiUUb6mKOCsUa2ygTizbUxRwVijW2USYWbaiLOSoUa2yjTCzaUBdzVCjW2EaZWLShLuaoUKyxjTKxaENdzFGhWGMbZWLRhrqYo0KxxjbKxKINdTFHhWKNbZSJRRvqYo4KxRrbKBOLNtTFHBWKNbZRJhZtqIs5KhRrbKNMLNpQF3NUKNbYRplYtKEu5qhQrLGNMrFoQ13MUaFYYxtlYtGGupijQrHGNsrEog11MUeFYo1tlIlFG+pijgrFGtsoE4s21MUcFYo1tlEmFm2oizkqFGtso0ws2lAXc1Qo1thGmVi0oS7mqFCssY0ysWhDXcxRoVhjG2Vi0Ya6mKNCscY2ysSiDXUxR4VijW2UiUUb6mKOCsUa2ygTizbUxRwVijW2USYWbaiLOSoUa2yjTCzaUBdzVCjW2EaZWLShLuaoUKyxjTKxaENdzFGhWGMbZWLRhrqYo0KxxjbKxKINdTFHhWKNbZSJRRvqYo4KxRrbKBOLNtTFHBWKNbZRJhZtqIs5KhRrbKNMLNpQF3NUKNbYRplYtKEu5qhQrLGNMrFoQ11jhv+Zo1Qi1thGmVi0oa5v3779i1kqEGtso0ws2lDXmOGfc5RKxBrbKBOLNvQV4+8C/maeCsMK2ygTizb0FWOOf81xKg0rbKNMLNrQV42/C/gvM1UQ1tdGmVi0oa8as/R/FhCI9bVRJhZtaAtjnv6jQBhW10aZWLShrYyZGgJBWFsbZWLRhrY05moIhGBlbZSJRRva2pjtn/6vB9fHutooE4s2tJcx478MgnWxpjbKxKIN7W3M2iBYEOtpo0ws2tBRxswNgoWwljbKxKINHW3M3iBYAOtoo0ws2tBZxg4MghOxhjbKxKINnW3swiA4AeNvo0ws2tAqxk4MggMx9jbKxKINrWbsxiA4AONuo0ws2tCqxo4Mgh0x5jbKxKINrW7syiDYAeNto0ws2lCKsTODYEOMtY0ysWhDacbuDIINMM42ysSiDaUaOzQIvoAxtlEmFm0o3dilQdDA+NooE4s2dBVjpwbBCxhbG2Vi0YauZuzWIHgC42qjTCza0FWNHRsEv8GY2igTizZ0dWPXBsE7GE8bZWLRhu5i7NwgeMBY2igTizZ0N2P3BsHAONooE4s2dFfjDdw6CBhDG2Vi0YbubryFWwYB7bdRJtV/aEOaxqO4VRDQdhtlIo09/4s2pB+N93GLIKDdNsqk+pM2pPeNR3LpIKDNNsrEqZ3SgvS58WYuGQS010aZRH/RgvS8ejhXCgLaaqNMlLG///L5Us94R5cIAtppo0wa/9lf2xiPKToIaKONMkn8W39trx5WYhDw+W2USeHxa1/1yJKCgM9uo0wCj1/HqQeXEAR8bhtllsUO/Gd+nWM8vqWDgM9so8xymLn/XV9rqMe4YhDweW2UWYaHr6XV41wpCPisNsqczsNXlHqsKwQBn9NGmdN4+IpWj/fMIOAz2ihzOA9fl1KP+Ywg4Me3UeYwHr4urR73kUHAj22jzO48fN1KPfYjgoAf10aZ3Xj4urV6/HsGAT+mjTKb8/ClB3UMewQB5dsosxkPX/qNOo4tg4CybZT5Mg9fekEdyxZBQLk2yrR5+NIX1PF8JQgo00aZl3n40obqmDpBwB9vo8zTPHxpR3VcrwQBf6yNMp/y8KUD1bE9EwT89jbKfMjDl05Ux/e7IOC3tVHmFx6+tJA6xveCgP+4jTLfefjSwuo4H4OAX26jjIcvJaljraPl37Z5+Gf644//AZoB5wgfxM0FAAAAAElFTkSuQmCC</OriginalBytes>
|
||||
<OriginalPath>E:\Profiles\Bruce\Desktop\新建文件夹\Microsoft.DesktopAppInstaller_1.22.11261.0_x64__8wekyb3d8bbwe\Assets\AppPackageAppList.targetsize-256_altform-unplated.png</OriginalPath>
|
||||
<Height>48</Height>
|
||||
<Width>48</Width>
|
||||
<X>26</X>
|
||||
<Y>20</Y>
|
||||
</ShortcutItemImage>
|
||||
BIN
shared/VisualElements/44x44.png
Normal file
|
After Width: | Height: | Size: 467 B |
BIN
shared/VisualElements/70x70.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
9
shared/VisualElements/70x70_Metadata.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0"?>
|
||||
<ShortcutItemImage xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<OriginalBytes>iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAYAAADjVADoAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAJ8SURBVHhe7drhceJADIZhSkgpKSklXAn3L38pgdKuhFQAJ2lfM8bYgrWFd5fsM8MEhNDKX2Amk+HQdV3XdV3XVeRyuXxy9ynS/yW3H7n9ldsH5XbpBZ3P53/yU31Rdmlfar9qNxBZehzAmBuGPp/aZrUTiCy5FMDYbBhaT08/VG8gstQzAYzdhKGPUzlLPYHIErkBjFkY+jM9XK18IHL4STdZS0L85m6EsoHIwdlh8C66viM2vKvmlAtEDn0qjHEAU1p/i0DkwMUwvACmtK/5QOSwmzByApjS1zUdiBx02hLAlM6JDERmHRn9epFBDHReQCAnxu2DQzd9NJbovJWB7BuC4uCrCgLZPwTF4XcKBVImBMUCi3YMpFwIiiUeenEgZUNQepE5IgPROTPvjBuv+AXMSsfl27Kgvq6aAAbp2PVyFta+6gIYpOO38y5A69UGMEhrxNELYrSpPoBBWicWow2lO9UEMEhrxWJ0W9g9FKONPKznt+5Jq8ditNHH1X0M5uii0RhtKJlpIHpfazwsyzYMxmhD6YZePKEYWstil1CMNpRctJbFLqEYbSi5aC2LXUIx2lBy0VoWu4RitKHkorUsdgnFaEPJRWtZ7BKK0YaSi9ay2CUUow0lF61lsUsoRhtKLlrLkj9sjuwThtGGkovW8mSXh/84ycFYQ8lFaz1kp5BAGGcouWitj+y2KRDGGEouWuslO64KhJcbSi5a6ye7ZgXCywwlF63tkJ2fCoR2Q2mRzNvvOxDRZH83ENoMpTu8vo1/4z2iFzIXCE8bSldvFcCUXNwfuTj93pOhbCi9dwBjcpEfctMvgP1QMr8mgK7ruq7ruvYdDv8B85b251lfl2cAAAAASUVORK5CYII=</OriginalBytes>
|
||||
<OriginalPath>E:\Profiles\Bruce\Desktop\新建文件夹\Microsoft.DesktopAppInstaller_1.22.11261.0_x64__8wekyb3d8bbwe\Assets\AppPackageAppList.scale-150.png</OriginalPath>
|
||||
<Height>44</Height>
|
||||
<Width>44</Width>
|
||||
<X>3</X>
|
||||
<Y>3</Y>
|
||||
</ShortcutItemImage>
|
||||
BIN
shared/VisualElements/SmallLogo.png
Normal file
|
After Width: | Height: | Size: 271 B |
BIN
shared/VisualElements/SplashLarge.png
Normal file
|
After Width: | Height: | Size: 7.1 KiB |
BIN
shared/VisualElements/SplashScreen.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
14
shared/VisualElements/scale.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<resource id="splash">
|
||||
<scale dpi="100">splash\SplashScreen.scale-100.png</scale>
|
||||
<scale dpi="125">splash\SplashScreen.scale-125.png</scale>
|
||||
<scale dpi="150">splash\SplashScreen.scale-150.png</scale>
|
||||
<scale dpi="200">splash\SplashScreen.scale-200.png</scale>
|
||||
<scale dpi="default">SplashScreen.png</scale>
|
||||
</resource>
|
||||
<resource id="splashlarge">
|
||||
<scale dpi="100">SplashLarge.png</scale>
|
||||
<scale dpi="default">SplashLarge.png</scale>
|
||||
</resource>
|
||||
</resources>
|
||||
BIN
shared/VisualElements/splash/SplashScreen.scale-100.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
shared/VisualElements/splash/SplashScreen.scale-125.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
shared/VisualElements/splash/SplashScreen.scale-150.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
shared/VisualElements/splash/SplashScreen.scale-200.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
12
shared/VisualElementsManifest.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<Application>
|
||||
<VisualElements
|
||||
DisplayName='App Installer'
|
||||
Logo='VisualElements\150x150.png'
|
||||
SmallLogo='VisualElements\70x70.png'
|
||||
ForegroundText='light'
|
||||
Lnk32x32Logo="Icons\Main.ico"
|
||||
BackgroundColor='#0078D7'>
|
||||
<DefaultTile ShowName='allLogos'/>
|
||||
<SplashScreen Image="VisualElements\SplashLarge.png" BackgroundColor="#0078d7" />
|
||||
</VisualElements>
|
||||
</Application>
|
||||
357
shared/html/applist.html
Normal file
@@ -0,0 +1,357 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>App Launch List</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" type="text/css" href="libs/winjs/2.0/css/ui-light.css">
|
||||
<script src="js/bridge.js"></script>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div [role=template] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
* {
|
||||
font-family: "Microsoft YaHei UI", "Microsoft YaHei", "Segoe UI", "Ebrima", "Nirmala", "Gadugi", "Segoe UI Emoji", "Segoe UI Symbol", "Meiryo", "Leelawadee", "Microsoft JhengHei", "Malgun Gothic", "Estrangelo Edessa", "Microsoft Himalaya", "Microsoft New Tai Lue", "Microsoft PhagsPa", "Microsoft Tai Le", "Microsoft Yi Baiti", "Mongolian Baiti", "MV Boli", "Myanmar Text", "Javanese Text", "Cambria Math", "Segoe UI Symbol";
|
||||
}
|
||||
|
||||
.applist-font-title {
|
||||
color: black;
|
||||
font-size: 11pt;
|
||||
}
|
||||
|
||||
.applist-font-text {
|
||||
color: black;
|
||||
font-size: 11pt;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.applist-window {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border: 2px solid rgb(42, 42, 42);
|
||||
background-color: white;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.applist-title {
|
||||
position: absolute;
|
||||
height: 65px;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
padding: 0 23px;
|
||||
box-sizing: border-box;
|
||||
background: white;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.applist-control {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 118px;
|
||||
box-sizing: border-box;
|
||||
background: white;
|
||||
z-index: 1;
|
||||
padding-bottom: 24px;
|
||||
padding-top: 11px;
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.applist-listview {
|
||||
position: absolute;
|
||||
top: 56px;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
-ms-overflow-style: -ms-autohiding-scrollbar;
|
||||
}
|
||||
|
||||
.applist-list-item {
|
||||
height: 60px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
background-color: rgba(0, 255, 255, 0);
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-ms-flex-wrap: nowrap;
|
||||
flex-wrap: nowrap;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
-ms-flex-pack: start;
|
||||
justify-content: flex-start;
|
||||
-ms-transition: all 0.1s cubic-bezier(0.22, 0.61, 0.36, 1);
|
||||
transition: all 0.1s cubic-bezier(0.22, 0.61, 0.36, 1);
|
||||
}
|
||||
|
||||
.applist-list-item:hover {
|
||||
background-color: rgb(222, 222, 222);
|
||||
}
|
||||
|
||||
.applist-list-item:active {
|
||||
-ms-transform: scale(0.9696);
|
||||
transform: scale(0.9696);
|
||||
-ms-transform-origin: center;
|
||||
transform-origin: center;
|
||||
}
|
||||
|
||||
.applist-item-divide {
|
||||
width: 12px;
|
||||
height: 100%;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.applist-item-picbox {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
min-width: 40px;
|
||||
min-height: 40px;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
background-color: #001020;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.applist-item-pic {
|
||||
min-width: 32px;
|
||||
min-height: 32px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.applist-item-title {
|
||||
padding-top: 11pt;
|
||||
padding-bottom: 0pt;
|
||||
height: 100%;
|
||||
width: auto;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-height: 3.9em;
|
||||
line-height: 1.3em;
|
||||
}
|
||||
|
||||
.applist-btn-cancel {
|
||||
position: absolute;
|
||||
right: 24px;
|
||||
bottom: 24px;
|
||||
width: 200px;
|
||||
height: 32px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.applist-item-img-border {
|
||||
background: transparent;
|
||||
border: 1px solid rgba(254, 254, 254, 0.1);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 2;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.win10 .applist-font-title {
|
||||
font-size: 13pt;
|
||||
}
|
||||
|
||||
.win10.applist-window {
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.win10 .applist-title {
|
||||
height: 56px;
|
||||
padding: 0 24px;
|
||||
}
|
||||
|
||||
.win10 .applist-control {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.win10 .applist-listview {
|
||||
bottom: 118px;
|
||||
}
|
||||
|
||||
.win10 .applist-list-item {
|
||||
height: 50px;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
}
|
||||
|
||||
.win10 .applist-list-item:active {
|
||||
transform: scale(0.9709);
|
||||
}
|
||||
|
||||
.win10 .applist-item-divide {
|
||||
width: 12px;
|
||||
}
|
||||
|
||||
.win10 .applist-item-title {
|
||||
padding-top: 5pt;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div role="template" id="applist-item-template">
|
||||
<div class="applist-list-item">
|
||||
<div class="applist-item-picbox" style="background-color: rgb(0,0,0);">
|
||||
<img class="applist-item-pic" src="./Images/AppLogoDefault.png" width="32" height="32">
|
||||
<div class="applist-item-img-border"></div>
|
||||
</div>
|
||||
<div class="applist-item-divide"></div>
|
||||
<div class="applist-item-title">
|
||||
<span class="applist-font-text">My Application0</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="applist-window win10">
|
||||
<div class="applist-title">
|
||||
<span class="applist-font-title">你要如何打开这个文件?</span>
|
||||
</div>
|
||||
<div class="applist-listview">
|
||||
</div>
|
||||
<div class="applist-control">
|
||||
<button class="applist-btn-cancel win-commandbutton div-button-size div-std-button-center" onclick="EventCancelWindow()" tabindex="0">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
(function(global) {
|
||||
"use strict";
|
||||
"App Select List, For Internet Explorer 10 and above.";
|
||||
var AppListElements = new function() {
|
||||
Object.defineProperty(this, "template", {
|
||||
get: function() {
|
||||
return document.getElementById("applist-item-template").querySelector(".applist-list-item").cloneNode(true);
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "listview", {
|
||||
get: function() {
|
||||
return document.querySelector(".applist-listview");
|
||||
}
|
||||
});
|
||||
}();
|
||||
|
||||
function AppListNodeElement(node) {
|
||||
var _node = node;
|
||||
var _appid = "";
|
||||
var _title = "";
|
||||
var _logo = "";
|
||||
var _color = "";
|
||||
Object.defineProperty(this, "node", {
|
||||
get: function() {
|
||||
return _node;
|
||||
},
|
||||
set: function(value) {
|
||||
_node = value;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "appid", {
|
||||
get: function() {
|
||||
if (this.node) return this.node.getAttribute("data-appid");
|
||||
else return _appid;
|
||||
},
|
||||
set: function(value) {
|
||||
_appid = value;
|
||||
if (this.node) this.node.setAttribute("data-appid", value);
|
||||
}
|
||||
})
|
||||
Object.defineProperty(this, "title", {
|
||||
get: function() {
|
||||
if (this.node) return this.node.querySelector(".applist-item-title").textContent;
|
||||
else return _title;
|
||||
},
|
||||
set: function(value) {
|
||||
_title = value;
|
||||
if (this.node) this.node.querySelector(".applist-item-title").textContent = value;
|
||||
}
|
||||
})
|
||||
Object.defineProperty(this, "logo", {
|
||||
get: function() {
|
||||
if (this.node) return this.node.querySelector(".applist-item-pic").getAttribute("src");
|
||||
else return _logo;
|
||||
},
|
||||
set: function(value) {
|
||||
_logo = value;
|
||||
if (this.node) this.node.querySelector(".applist-item-pic").setAttribute("src", value);
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "color", {
|
||||
get: function() {
|
||||
if (this.node) return this.node.querySelector(".applist-item-picbox").style.backgroundColor;
|
||||
else return _color;
|
||||
},
|
||||
set: function(value) {
|
||||
_color = value;
|
||||
if (this.node) this.node.querySelector(".applist-item-picbox").style.backgroundColor = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function createItem(title, logo, appid, color) {
|
||||
var item = AppListElements.template.cloneNode(true);
|
||||
var inode = new AppListNodeElement(item);
|
||||
inode.title = title;
|
||||
inode.logo = logo;
|
||||
inode.appid = appid;
|
||||
inode.color = color;
|
||||
return item;
|
||||
}
|
||||
|
||||
function addItem(node) {
|
||||
AppListElements.listview.appendChild(node);
|
||||
}
|
||||
global.AppList = {
|
||||
Item: {
|
||||
create: createItem
|
||||
},
|
||||
List: {
|
||||
add: addItem
|
||||
}
|
||||
};
|
||||
})(this);
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
447
shared/html/css/pages.css
Normal file
@@ -0,0 +1,447 @@
|
||||
body {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
-ms-overflow-style: -ms-autohiding-scrollbar;
|
||||
user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
|
||||
body * {
|
||||
-ms-overflow-style: -ms-autohiding-scrollbar;
|
||||
}
|
||||
|
||||
.pagecontainer {
|
||||
padding: 0px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
box-sizing: border-box;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.pagecontainer.full {
|
||||
padding: 0px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.pagecontainer>.page {
|
||||
position: relative;
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
box-sizing: border-box;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.page.padding {
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.page.splash {
|
||||
padding: 0px;
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
.page.splash>img {
|
||||
width: 620px;
|
||||
height: 300px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.page.splash progress.win-ring {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin-top: 32px;
|
||||
border-style: none;
|
||||
background-color: transparent;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.page.splash>.content {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
top: calc(50% + 300px / 2);
|
||||
left: 50%;
|
||||
width: 100%;
|
||||
transform: translateX(-50%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
progress.win-ring:indeterminate::-ms-fill {
|
||||
animation-delay: 1.5s;
|
||||
}
|
||||
|
||||
.page.preinstall .content.preinstall,
|
||||
.page.installsuccess .content.installsuccess,
|
||||
.page.installfailed .content.installfailed {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
height: calc(100% - 100px);
|
||||
bottom: auto;
|
||||
box-sizing: border-box;
|
||||
padding: 24px 24px 0px 24px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
word-break: break-all;
|
||||
max-width: 100%;
|
||||
max-height: calc(100% - 100px);
|
||||
}
|
||||
|
||||
.page>.controls {
|
||||
position: absolute;
|
||||
top: auto;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
height: 100px;
|
||||
max-height: 100px;
|
||||
padding: 10px 24px 24px 24px;
|
||||
box-sizing: border-box;
|
||||
overflow-y: hidden;
|
||||
overflow-x: auto;
|
||||
-ms-overflow-style: -ms-autohiding-scrollbar;
|
||||
/* display: flex; */
|
||||
flex-direction: row-reverse;
|
||||
flex-wrap: nowrap;
|
||||
align-content: center;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.page>.controls .command {
|
||||
float: right;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
align-content: center;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.page>.controls .command button {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.page>.controls .checkbox {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
align-content: center;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
-ms-flex-direction: row;
|
||||
-ms-flex-wrap: nowrap;
|
||||
-ms-flex-line-pack: center;
|
||||
-ms-flex-pack: start;
|
||||
-ms-flex-align: center;
|
||||
}
|
||||
|
||||
.page>.controls .checkbox input[type="checkbox"] {
|
||||
min-width: 21px;
|
||||
min-height: 21px;
|
||||
}
|
||||
|
||||
.page>.controls .checkbox label {
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.page>.content p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.page>.content ul {
|
||||
margin: 0;
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
.page>.content ul li {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.storelogo {
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
position: relative;
|
||||
background-color: #464646;
|
||||
float: right;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
-ms-flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
-ms-flex-wrap: nowrap;
|
||||
align-content: center;
|
||||
-ms-flex-line-pack: center;
|
||||
justify-content: center;
|
||||
-ms-flex-pack: center;
|
||||
align-items: center;
|
||||
-ms-flex-align: center;
|
||||
min-width: 90px;
|
||||
min-height: 90px;
|
||||
max-width: 90px;
|
||||
max-height: 90px;
|
||||
}
|
||||
|
||||
.storelogo .filter img {
|
||||
max-width: 90px;
|
||||
max-height: 90px;
|
||||
aspect-ratio: auto;
|
||||
}
|
||||
|
||||
.storelogo .filter {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(254, 0.1);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
-ms-flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
-ms-flex-wrap: nowrap;
|
||||
align-content: center;
|
||||
-ms-flex-line-pack: center;
|
||||
justify-content: center;
|
||||
-ms-flex-pack: center;
|
||||
align-items: center;
|
||||
-ms-flex-align: center;
|
||||
}
|
||||
|
||||
.storelogo::after {
|
||||
border: 1px solid rgba(254, 254, 254, 0.1);
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.page>.content .functions {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
min-height: 10%;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
max-height: calc(100% - 10.5em);
|
||||
user-select: all;
|
||||
-ms-user-select: element;
|
||||
box-sizing: border-box;
|
||||
transition: width 0.5s cubic-bezier(0.1, 0.9, 0.2, 1), height 0.5s cubic-bezier(0.1, 0.9, 0.2, 1), top 0.5s cubic-bezier(0.1, 0.9, 0.2, 1), left 0.5s cubic-bezier(0.1, 0.9, 0.2, 1), right 0.5s cubic-bezier(0.1, 0.9, 0.2, 1), bottom 0.5s cubic-bezier(0.1, 0.9, 0.2, 1), margin 0.5s cubic-bezier(0.1, 0.9, 0.2, 1), padding 0.5s cubic-bezier(0.1, 0.9, 0.2, 1);
|
||||
list-style-position: outside;
|
||||
/*test*/
|
||||
border: 1px solid black;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.page>.progress {
|
||||
position: absolute;
|
||||
top: auto;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 100px;
|
||||
height: auto;
|
||||
padding: 0 24px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.progress * {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.page>.reason {
|
||||
position: absolute;
|
||||
top: auto;
|
||||
left: 0;
|
||||
bottom: 100px;
|
||||
height: auto;
|
||||
min-height: 10%;
|
||||
padding: 0 24px;
|
||||
box-sizing: border-box;
|
||||
max-height: calc(100% - 10.5em);
|
||||
width: 100%;
|
||||
transition: all 0.5s cubic-bezier(0.1, 0.9, 0.2, 1);
|
||||
}
|
||||
|
||||
.page>.reason p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.page>.reason textarea {
|
||||
width: 100%;
|
||||
height: calc(100% - 1.3em);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.moreinfo-content p {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.moreinfo-content table tbody tr td {
|
||||
border-bottom: 1px solid #ccc;
|
||||
border-left: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.page>* {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page.splash>.splash {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.page.loading,
|
||||
.page.select,
|
||||
.page.preinstall,
|
||||
.page.installing,
|
||||
.page.installsuccess,
|
||||
.page.installfailed {}
|
||||
|
||||
.page.loading>.content.loading {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 16pt;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.ring-loading {
|
||||
font-family: Setup, "Segoe Boot Semilight", "Segoe Boot Semilight";
|
||||
}
|
||||
|
||||
.page.select>.select {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.page.select>.controls.select,
|
||||
.page.installsuccess>.controls.installsuccess,
|
||||
.page.installfailed>.controls.installfailed {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.page.preinstall>.controls.preinstall,
|
||||
.page.installing>.controls.installing {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.page.select>.controls.select>.checkbox {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page.select>.controls.select>.command button:nth-of-type(2) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page.select>.content.select,
|
||||
.page.preinstall>.content.preinstall,
|
||||
.page.installing>.content.installing,
|
||||
.page.installsuccess>.content.installsuccess,
|
||||
.page.installfailed>.content.installfailed {
|
||||
padding: 24px 24px 0 24px;
|
||||
}
|
||||
|
||||
.page:not(.multiple) .multiple {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page.select>.content.select .multiple {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page.select>.content.select .storelogo {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page.select>.content.select p,
|
||||
.page.select>.content.select br,
|
||||
.page.select>.content.select .functions,
|
||||
.page.select>.content.select .moreinfo {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page.preinstall>.content.preinstall,
|
||||
.page.installing>.content.installing,
|
||||
.page.installsuccess>.content.installsuccess,
|
||||
.page.installfailed>.content.installfailed {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.page.installing>.progress.installing {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.page.installing>.content.installing {
|
||||
height: calc(100% - 200px);
|
||||
max-height: calc(100% - 24px);
|
||||
}
|
||||
|
||||
.page.installing>.content.installing .pkgfunctions-label,
|
||||
.page.installing>.content.installing .functions,
|
||||
.page.installing>.content.installing .moreinfo,
|
||||
.page.installsuccess>.content.installsuccess .pkgfunctions-label,
|
||||
.page.installsuccess>.content.installsuccess .functions,
|
||||
.page.installsuccess>.content.installsuccess .moreinfo,
|
||||
.page.installfailed>.content.installfailed .pkgfunctions-label,
|
||||
.page.installfailed>.content.installfailed .functions,
|
||||
.page.installfailed>.content.installfailed .moreinfo {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page.installing>.controls.installing .command {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page.installsuccess>.content.installsuccess {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.page.installsuccess>.controls.installsuccess .checkbox,
|
||||
.page.installfailed>.controls.installfailed .checkbox {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page.installfailed>.reason {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.page.preinstall.multiple>.content.preinstall h1.pkgtitle,
|
||||
.page.installing.multiple>.content.installing h1.pkgtitle,
|
||||
.page.installsuccess.multiple>.content.installsuccess h1.pkgtitle,
|
||||
.page.installfailed.multiple>.content.installfailed h1.pkgtitle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page.installing.multiple>.content .currentfile label,
|
||||
.page.installing.multiple>.content .currentfile select,
|
||||
.page.installing.multiple>.content .currentfile br {
|
||||
display: none;
|
||||
}
|
||||
26
shared/html/css/popup.css
Normal file
@@ -0,0 +1,26 @@
|
||||
.popup {
|
||||
width: 288px;
|
||||
height: 252px;
|
||||
position: absolute;
|
||||
box-sizing: border-box;
|
||||
max-width: 50%;
|
||||
max-height: 50%;
|
||||
padding: 20px;
|
||||
margin: 5px;
|
||||
background-color: white;
|
||||
overflow-x: auto;
|
||||
overflow-y: auto;
|
||||
-ms-overflow-style: -ms-autohiding-scrollbar;
|
||||
border: 2px solid black;
|
||||
}
|
||||
|
||||
.popup .content {
|
||||
width: 100%;
|
||||
max-height: 100%;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.popup .content.with-ctrls {
|
||||
max-height: calc(100% - 40px);
|
||||
}
|
||||
BIN
shared/html/fonts/SETUP.TTF
Normal file
BIN
shared/html/fonts/SETUP.eot
Normal file
BIN
shared/html/fonts/SegoeIcons.eot
Normal file
BIN
shared/html/fonts/SegoeIcons.ttf
Normal file
34
shared/html/fonts/fonts.css
Normal file
@@ -0,0 +1,34 @@
|
||||
@font-face
|
||||
{
|
||||
font-family: "Segoe UI Symbol";
|
||||
src: url('seguisym.eot') format('embedded-opentype'),
|
||||
url('seguisym.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face
|
||||
{
|
||||
font-family: "Segoe MDL2 Assets";
|
||||
src: url('segmdl2.eot') format('embedded-opentype'),
|
||||
url('segmdl2.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face
|
||||
{
|
||||
font-family: "Segoe Fluent Icons";
|
||||
src: url('SegoeIcons.eot') format('embedded-opentype'),
|
||||
url('SegoeIcons.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Setup";
|
||||
src: url('SETUP.EOT') format('embedded-opentype'),
|
||||
url('SETUP.TTF') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
BIN
shared/html/fonts/segmdl2.eot
Normal file
BIN
shared/html/fonts/segmdl2.ttf
Normal file
BIN
shared/html/fonts/seguisym.eot
Normal file
BIN
shared/html/fonts/seguisym.ttf
Normal file
BIN
shared/html/images/SplashLarge.png
Normal file
|
After Width: | Height: | Size: 7.1 KiB |
BIN
shared/html/images/SplashScreen.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
shared/html/images/splash.default.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
shared/html/images/storelogo.default.png
Normal file
|
After Width: | Height: | Size: 429 B |
112
shared/html/install.html
Normal file
@@ -0,0 +1,112 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>App Installer</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script type="text/javascript" src="js/module.js"></script>
|
||||
<script type="text/javascript" src="js/polyfill-ie.js"></script>
|
||||
<link rel="stylesheet" href="libs/winjs/2.0/css/ui-light.css">
|
||||
<script type="text/javascript" src="libs/winjs/2.0/js/base.js"></script>
|
||||
<script type="text/javascript" src="libs/winjs/2.0/js/ui.js"></script>
|
||||
<script type="text/javascript" src="js/color.js"></script>
|
||||
<script type="text/javascript" src="js/promise.js"></script>
|
||||
<script type="text/javascript" src="js/bridge.js"></script>
|
||||
<script type="text/javascript" src="js/dpimodes.js"></script>
|
||||
<script type="text/javascript" src="js/animation.js"></script>
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
<link rel="stylesheet" href="css/pages.css">
|
||||
<script type="text/javascript" src="js/event.js"></script>
|
||||
<script type="text/javascript" src="js/pages.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="page-container" class="pagecontainer full">
|
||||
<div class="page preinstall">
|
||||
<!-- Splash Screen -->
|
||||
<img class="splash" src="images/splash.default.png" alt="Splash Screen">
|
||||
<div class="content splash">
|
||||
<progress class="win-ring"></progress>
|
||||
</div>
|
||||
<!-- Loading... -->
|
||||
<div class="content loading">
|
||||
<span class="ring-loading"></span>
|
||||
<span>请稍候...</span>
|
||||
</div>
|
||||
<!-- Main Page -->
|
||||
<div class="content select preinstall installing installsuccess installfailed">
|
||||
<div style="width: 100%; box-sizing: border-box;" class="currentfile multiple">
|
||||
<h1 class="win-type-x-large">有多个包将要安装</h1><br />
|
||||
<label for="select-package" class="win-label">在这里请选择一个包查看信息。</label><br />
|
||||
<select id="select-package"></select><br />
|
||||
</div>
|
||||
<div class="storelogo">
|
||||
<div class="filter">
|
||||
<img src="images/splash.default.png" alt="App Store Logo">
|
||||
</div>
|
||||
</div>
|
||||
<h1 class="win-type-x-large pkgtitle">Install {Package Title}?</h1>
|
||||
<p class="pkgtitle multiple">{Package Title}</p>
|
||||
<p>Microsoft Store Application</p>
|
||||
<p class="pkgpublisher">Publisher: {Package Publisher}</p>
|
||||
<p class="pkgversion"> Version: {Package Version}</p><br />
|
||||
<p class="pkgfunctions-label"><span>Functions</span>: </p>
|
||||
<div class="functions">
|
||||
<ul>
|
||||
<li>使用全部的系统资源</li>
|
||||
</ul>
|
||||
</div>
|
||||
<a class="moreinfo">更多信息</a>
|
||||
<script>
|
||||
(function() {
|
||||
"use strict";
|
||||
var monitor = Windows.UI.Event.Monitor;
|
||||
var page = document.querySelector(".page");
|
||||
var content = page.querySelector(".content.preinstall");
|
||||
var functions = page.querySelector(".functions");
|
||||
var funculist = functions.querySelector("ul");
|
||||
|
||||
function sizeChangeEvent(e) {
|
||||
var height = content.getBoundingClientRect().height;
|
||||
var top = functions.getBoundingClientRect().top;
|
||||
var newheight = parseInt((height - top - 10));
|
||||
var listheight = (funculist.scrollHeight || funculist.offsetHeight || funculist.clientHeight || funculist.getBoundingClientRect().height || 10) + 20;
|
||||
console.log(newheight, listheight);
|
||||
if (newheight > listheight) newheight = listheight;
|
||||
functions.style.height = newheight + "px";
|
||||
}
|
||||
var deb_sizechange = debounce(sizeChangeEvent, 500);
|
||||
monitor.observe(content, Windows.UI.Event.Monitor.EventType.resize, deb_sizechange);
|
||||
monitor.observe(content, Windows.UI.Event.Monitor.EventType.position, deb_sizechange);
|
||||
monitor.observe(funculist, Windows.UI.Event.Monitor.EventType.child, deb_sizechange);
|
||||
setTimeout(sizeChangeEvent, 0);
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
<div class="progress installing">
|
||||
<div>
|
||||
<span class="ring-loading"></span> <span class="status">Installing... 0%</span>
|
||||
</div>
|
||||
<progress min="0" max="100" value="50" class="win-progress-bar"></progress>
|
||||
</div>
|
||||
<div class="reason installfailed">
|
||||
<p><span>Reason</span>: </p>
|
||||
<textarea class="win-textarea" readonly></textarea>
|
||||
</div>
|
||||
<div class="controls select preinstall installing installsuccess installfailed">
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" id="preinst-enablelaunch" class="win-checkbox">
|
||||
<label for="preinst-enablelaunch">Launch app after installation</label>
|
||||
</div>
|
||||
<div class="command">
|
||||
<button>Install</button>
|
||||
<button>Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
188
shared/html/js/animation.js
Normal file
@@ -0,0 +1,188 @@
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
var AnimationKeyFrames = {
|
||||
// 弹出(从边缘)
|
||||
Flyout: new(function Flyout() {
|
||||
if (this._instance) { return this._instance; }
|
||||
this._instance = this;
|
||||
// 向顶端
|
||||
this.toTop = "WinJS-showFlyoutTop";
|
||||
// 向底端
|
||||
this.toBottom = "WinJS-showFlyoutBottom";
|
||||
// 向左
|
||||
this.toLeft = "WinJS-showFlyoutLeft";
|
||||
// 向右
|
||||
this.toRight = "WinJS-showFlyoutRight";
|
||||
// 从底端(别名,向顶端)
|
||||
this.fromBottom = this.toTop;
|
||||
// 从顶端(别名,向底端)
|
||||
this.fromTop = this.toBottom;
|
||||
// 从左侧
|
||||
this.fromLeft = this.toRight;
|
||||
// 从右侧
|
||||
this.fromRight = this.toLeft;
|
||||
})(),
|
||||
// WinJS 内部使用,建议不用这个
|
||||
Progress: {
|
||||
fadeOut: "win-progress-fade-out"
|
||||
},
|
||||
// WinJS 内部使用,对于搜索框弹出搜索推荐
|
||||
SearchBox: {
|
||||
// 显示搜索推荐
|
||||
showPopup: {
|
||||
flyoutBelow: "WinJS-flyoutBelowSearchBox-showPopup",
|
||||
flyoutAbove: "WinJS-flyoutAboveSearchBox-showPopup"
|
||||
}
|
||||
},
|
||||
// 渐变
|
||||
Opacity: {
|
||||
// 显示
|
||||
visible: "WinJS-opacity-in",
|
||||
// 消失
|
||||
hidden: "WinJS-opacity-out"
|
||||
},
|
||||
// 缩放
|
||||
Scale: {
|
||||
// 放大一点
|
||||
up: "WinJS-scale-up",
|
||||
// 缩小一点
|
||||
down: "WinJS-scale-down"
|
||||
},
|
||||
// 默认分类
|
||||
Default: {
|
||||
// 从右返回
|
||||
remove: "WinJS-default-remove",
|
||||
// 从左返回
|
||||
removertl: "WinJS-default-remove-rtl",
|
||||
// 向右移动
|
||||
apply: "WinJS-default-apply",
|
||||
// 向左移动
|
||||
applyrtl: "WinJS-default-apply-rtl"
|
||||
},
|
||||
// 从边缘
|
||||
Edge: {
|
||||
// 从顶部
|
||||
show: "WinJS-showEdgeUI",
|
||||
// 到顶部
|
||||
hide: "WinJS-hideEdgeUI"
|
||||
},
|
||||
Panel: {
|
||||
// 从右侧
|
||||
show: "WinJS-showPanel",
|
||||
// 从左侧
|
||||
showrtl: "WinJS-showPanel-rtl",
|
||||
// 到右侧
|
||||
hide: "WinJS-hidePanel",
|
||||
// 到左侧
|
||||
hidertl: "WinJS-hidePanel-rtl"
|
||||
},
|
||||
Popup: {
|
||||
show: "WinJS-showPopup"
|
||||
},
|
||||
// 对元素的拖放
|
||||
Drag: {
|
||||
// 从右复位
|
||||
sourceEnd: "WinJS-dragSourceEnd",
|
||||
// 从左复位
|
||||
sourceEndRtl: "WinJS-dragSourceEnd-rtl"
|
||||
},
|
||||
// 进入内容
|
||||
Content: {
|
||||
// 从右进入
|
||||
enter: "WinJS-enterContent",
|
||||
// 从左进入
|
||||
enterrtl: "WinJS-enterContent-rtl"
|
||||
},
|
||||
Page: {
|
||||
// 从右进入
|
||||
enter: "WinJS-enterPage",
|
||||
// 从左进入
|
||||
enterrtl: "WinJS-enterPage-rtl"
|
||||
},
|
||||
Exit: "WinJS-exit",
|
||||
UpdateBadge: "WinJS-updateBadge"
|
||||
};
|
||||
Object.freeze(AnimationKeyFrames);
|
||||
/**
|
||||
* 生成用于 element.style.animation 的字符串
|
||||
* @param {string} swKeyFrames - 动画关键帧名称
|
||||
* @param {number} uMillisecond - 动画持续时间(毫秒)
|
||||
* @param {string} [swTimingFunc] - 缓动函数,默认 cubic-bezier(0.1, 0.9, 0.2, 1)
|
||||
* @param {number} [uDelayMs] - 延迟时间(毫秒),默认 0
|
||||
* @param {string} [swIteration] - 播放次数,默认 "1"
|
||||
* @param {string} [swDirection] - 播放方向,默认 "normal"
|
||||
* @param {string} [swFillMode] - 填充模式,默认 "forwards"
|
||||
* @param {string} [swPlayState] - 播放状态,默认 ""
|
||||
* @returns {string} 可直接赋给 element.style.animation
|
||||
*/
|
||||
function generateAnimeString(swKeyFrames, uMillisecond, swTimingFunc, uDelayMs, swIteration, swDirection, swFillMode, swPlayState) {
|
||||
// 默认参数
|
||||
if (!swTimingFunc) { swTimingFunc = "cubic-bezier(0.1, 0.9, 0.2, 1)"; }
|
||||
if (!uDelayMs) { uDelayMs = 0; }
|
||||
if (!swIteration) { swIteration = "1"; }
|
||||
if (!swDirection) { swDirection = "normal"; }
|
||||
if (!swFillMode) { swFillMode = "forwards"; }
|
||||
if (!swPlayState) { swPlayState = ""; }
|
||||
if (!uMillisecond) { uMillisecond = 500; }
|
||||
if (!swKeyFrames) { swKeyFrames = AnimationKeyFrames.Flyout.toLeft; }
|
||||
// 毫秒转秒
|
||||
var swDuration = (uMillisecond * 0.001) + "s";
|
||||
var swDelay = (uDelayMs * 0.001) + "s";
|
||||
// 拼接函数
|
||||
function buildOne(name) {
|
||||
return name + " " +
|
||||
swDuration + " " +
|
||||
swTimingFunc + " " +
|
||||
swDelay + " " +
|
||||
swIteration + " " +
|
||||
swDirection + " " +
|
||||
swFillMode +
|
||||
(swPlayState ? (" " + swPlayState) : "");
|
||||
}
|
||||
var swResult = "";
|
||||
if (typeof swKeyFrames === "string") {
|
||||
swResult = buildOne(swKeyFrames);
|
||||
} else if (swKeyFrames instanceof Array) {
|
||||
var parts = [];
|
||||
for (var i = 0; i < swKeyFrames.length; i++) {
|
||||
parts.push(buildOne(swKeyFrames[i]));
|
||||
}
|
||||
swResult = parts.join(", ");
|
||||
}
|
||||
return swResult;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
Windows: {
|
||||
UI: {
|
||||
Animation: {
|
||||
Keyframes: AnimationKeyFrames,
|
||||
Animation: generateAnimeString,
|
||||
/**
|
||||
* 异步设置动画,返回一个 Promise 对象,动画结束后会执行
|
||||
* @param {HTMLElement} element 元素节点
|
||||
* @param {string|Array <string>} swKeyFrames 动画关键帧名称
|
||||
* @param {number} uMillisecond 动画持续时间(毫秒)
|
||||
* @param {string} [swTimingFunc] 缓动函数,默认 cubic-bezier(0.1, 0.9, 0.2, 1)
|
||||
* @param {number} [uDelayMs] 延迟时间(毫秒),默认 0
|
||||
* @param {string} [swIteration] 播放次数,默认 "1"
|
||||
* @param {string} [swDirection] 播放方向,默认 "normal"
|
||||
* @param {string} [swFillMode] 填充模式,默认 "forwards"
|
||||
* @param {string} [swPlayState] 播放状态,默认 ""
|
||||
* @returns {Promise}
|
||||
*/
|
||||
RunAsync: function(element, swKeyFrames, uMillisecond, swTimingFunc, uDelayMs, swIteration, swDirection, swFillMode, swPlayState) {
|
||||
return new WinJS.Promise(function(complete) {
|
||||
element.style.animation = generateAnimeString(swKeyFrames, uMillisecond, swTimingFunc, uDelayMs, swIteration, swDirection, swFillMode, swPlayState);
|
||||
element.addEventListener("animationend", function() {
|
||||
element.style.animation = "";
|
||||
complete();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
||||
41
shared/html/js/bridge.js
Normal file
@@ -0,0 +1,41 @@
|
||||
(function(global) {
|
||||
"use strict";
|
||||
var ext = global.external;
|
||||
|
||||
function blankFunc(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) {
|
||||
console.log("blankFunc called with arguments: " + arg1 + ", " + arg2 + ", " + arg3 + ", " + arg4 + ", " + arg5 + ", " + arg6 + ", " + arg7 + ", " + arg8 + ", " + arg9 + ", " + arg10);
|
||||
}
|
||||
|
||||
global.Bridge = {
|
||||
External: ext,
|
||||
Frame: {
|
||||
isIe10: function() { return ext.IEFrame.Version === 10; },
|
||||
isIe11: function() { return ext.IEFrame.Version === 11; }
|
||||
},
|
||||
UI: {},
|
||||
String: {
|
||||
trim: function(str) { return ext.String.Trim(str); },
|
||||
tolower: function(str) { return ext.String.ToLower(str); },
|
||||
toupper: function(str) { return ext.String.ToUpper(str); },
|
||||
},
|
||||
NString: {
|
||||
equals: function(str1, str2) { return ext.String.NString.NEquals(str1, str2); },
|
||||
compare: function(str1, str2) { return ext.String.NString.Compare(str1, str2); },
|
||||
empty: function(str) { return ext.String.NString.Empty(str); },
|
||||
length: function(str) { return ext.String.NString.Length(str); },
|
||||
}
|
||||
}
|
||||
Object.defineProperty(global.Bridge.Frame, "scale", {
|
||||
get: function() { return ext.IEFrame.Scale; },
|
||||
set: function(value) { ext.IEFrame.Scale = value; return ext.IEFrame.Scale; }
|
||||
});
|
||||
Object.defineProperty(global.Bridge.Frame, "version", {
|
||||
get: function() { return ext.IEFrame.Version; },
|
||||
});
|
||||
Object.defineProperty(global.Bridge.UI, "dpiPercent", {
|
||||
get: function() { return ext.System.UI.DPIPercent; }
|
||||
});
|
||||
Object.defineProperty(global.Bridge.UI, "dpi", {
|
||||
get: function() { return ext.System.UI.DPI; }
|
||||
});
|
||||
})(this);
|
||||
463
shared/html/js/color.js
Normal file
@@ -0,0 +1,463 @@
|
||||
(function(global) {
|
||||
"use strict";
|
||||
|
||||
function RGB(parent) {
|
||||
Object.defineProperty(this, "red", {
|
||||
get: function() { return parent.red; },
|
||||
set: function(value) { parent.red = value; }
|
||||
});
|
||||
Object.defineProperty(this, "green", {
|
||||
get: function() { return parent.green; },
|
||||
set: function(value) { parent.green = value; }
|
||||
});
|
||||
Object.defineProperty(this, "blue", {
|
||||
get: function() { return parent.blue; },
|
||||
set: function(value) { parent.blue = value; }
|
||||
});
|
||||
this.toString = function() { return "rgb(" + parent.red + "," + parent.green + "," + parent.blue + ")"; };
|
||||
this.valueOf = function() { return parent.valueOf(); };
|
||||
this.convert = function(type) { return new type(parent); };
|
||||
Object.defineProperty(this, "hex", {
|
||||
get: function() { return parent.hex; },
|
||||
set: function(value) { parent.hex = value; }
|
||||
});
|
||||
Object.defineProperty(this, "color", {
|
||||
get: function() { return parent; }
|
||||
});
|
||||
}
|
||||
|
||||
function RGBA(parent) {
|
||||
parent.RGB.constructor.call(this, parent);
|
||||
Object.defineProperty(this, "alpha", {
|
||||
get: function() { return parent.alpha; },
|
||||
set: function(value) { parent.alpha = value; }
|
||||
});
|
||||
this.toString = function() { return "rgba(" + parent.red + "," + parent.green + "," + parent.blue + "," + (parent.alpha / 255).toFixed(2) + ")"; };
|
||||
this.valueOf = function() { return parent.valueOf(); };
|
||||
}
|
||||
|
||||
function HSL(parent) {
|
||||
parent.RGB.constructor.call(this, parent);
|
||||
/**
|
||||
* @type {number} 色调 0 - 360
|
||||
*/
|
||||
Object.defineProperty(this, "hue", {
|
||||
get: function() {
|
||||
var r = parent.red / 255,
|
||||
g = parent.green / 255,
|
||||
b = parent.blue / 255;
|
||||
var max = Math.max(r, g, b),
|
||||
min = Math.min(r, g, b);
|
||||
var h, s, l = (max + min) / 2;
|
||||
if (max == min) {
|
||||
h = s = 0; // achromatic
|
||||
} else {
|
||||
var d = max - min;
|
||||
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||||
switch (max) {
|
||||
case r:
|
||||
h = (g - b) / d + (g < b ? 6 : 0);
|
||||
break;
|
||||
case g:
|
||||
h = (b - r) / d + 2;
|
||||
break;
|
||||
case b:
|
||||
h = (r - g) / d + 4;
|
||||
break;
|
||||
}
|
||||
h /= 6;
|
||||
}
|
||||
return h * 360;
|
||||
},
|
||||
set: function(value) {
|
||||
var r = parent.red / 255,
|
||||
g = parent.green / 255,
|
||||
b = parent.blue / 255;
|
||||
var max = Math.max(r, g, b),
|
||||
min = Math.min(r, g, b);
|
||||
var h = value / 360,
|
||||
s = (max == 0 ? 0 : (max - min) / (max + min)),
|
||||
l = (max + min) / 2;
|
||||
if (s == 0) {
|
||||
r = g = b = l; // achromatic
|
||||
} else {
|
||||
var hue2rgb = function hue2rgb(p, q, t) {
|
||||
if (t < 0) t += 1;
|
||||
if (t > 1) t -= 1;
|
||||
if (t < 1 / 6) return p + (q - p) * 6 * t;
|
||||
if (t < 1 / 2) return q;
|
||||
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
var p = 2 * l - q;
|
||||
r = hue2rgb(p, q, h + 1 / 3);
|
||||
g = hue2rgb(p, q, h);
|
||||
b = hue2rgb(p, q, h - 1 / 3);
|
||||
}
|
||||
parent.red = Math.round(r * 255);
|
||||
parent.green = Math.round(g * 255);
|
||||
parent.blue = Math.round(b * 255);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* @type {number} 饱和度 0 - 1
|
||||
*/
|
||||
Object.defineProperty(this, "saturation", {
|
||||
get: function() {
|
||||
var r = parent.red / 255,
|
||||
g = parent.green / 255,
|
||||
b = parent.blue / 255;
|
||||
var max = Math.max(r, g, b),
|
||||
min = Math.min(r, g, b);
|
||||
var h, s, l = (max + min) / 2;
|
||||
if (max == min) {
|
||||
s = 0; // achromatic
|
||||
} else {
|
||||
var d = max - min;
|
||||
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||||
}
|
||||
return s;
|
||||
},
|
||||
set: function(value) {
|
||||
var r = parent.red / 255,
|
||||
g = parent.green / 255,
|
||||
b = parent.blue / 255;
|
||||
var max = Math.max(r, g, b),
|
||||
min = Math.min(r, g, b);
|
||||
var h = parent.hue / 360,
|
||||
s = value,
|
||||
l = (max + min) / 2;
|
||||
if (s == 0) {
|
||||
r = g = b = l; // achromatic
|
||||
} else {
|
||||
var hue2rgb = function hue2rgb(p, q, t) {
|
||||
if (t < 0) t += 1;
|
||||
if (t > 1) t -= 1;
|
||||
if (t < 1 / 6) return p + (q - p) * 6 * t;
|
||||
if (t < 1 / 2) return q;
|
||||
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
var p = 2 * l - q;
|
||||
r = hue2rgb(p, q, h + 1 / 3);
|
||||
g = hue2rgb(p, q, h);
|
||||
b = hue2rgb(p, q, h - 1 / 3);
|
||||
}
|
||||
parent.red = Math.round(r * 255);
|
||||
parent.green = Math.round(g * 255);
|
||||
parent.blue = Math.round(b * 255);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* @type {number} 亮度 0 - 1
|
||||
*/
|
||||
Object.defineProperty(this, "lightness", {
|
||||
get: function() {
|
||||
var r = parent.red / 255,
|
||||
g = parent.green / 255,
|
||||
b = parent.blue / 255;
|
||||
var max = Math.max(r, g, b),
|
||||
min = Math.min(r, g, b);
|
||||
var h, s, l = (max + min) / 2;
|
||||
return l;
|
||||
},
|
||||
set: function(value) {
|
||||
var r = parent.red / 255,
|
||||
g = parent.green / 255,
|
||||
b = parent.blue / 255;
|
||||
var max = Math.max(r, g, b),
|
||||
min = Math.min(r, g, b);
|
||||
var h = parent.hue / 360,
|
||||
s = parent.saturation,
|
||||
l = value;
|
||||
if (s == 0) {
|
||||
r = g = b = l; // achromatic
|
||||
} else {
|
||||
var hue2rgb = function hue2rgb(p, q, t) {
|
||||
if (t < 0) t += 1;
|
||||
if (t > 1) t -= 1;
|
||||
if (t < 1 / 6) return p + (q - p) * 6 * t;
|
||||
if (t < 1 / 2) return q;
|
||||
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
var p = 2 * l - q;
|
||||
r = hue2rgb(p, q, h + 1 / 3);
|
||||
g = hue2rgb(p, q, h);
|
||||
b = hue2rgb(p, q, h - 1 / 3);
|
||||
}
|
||||
parent.red = Math.round(r * 255);
|
||||
parent.green = Math.round(g * 255);
|
||||
parent.blue = Math.round(b * 255);
|
||||
}
|
||||
});
|
||||
this.toString = function() { return "hsl(" + this.hue + "," + (this.saturation * 100).toFixed(2) + "%," + (this.lightness * 100).toFixed(2) + "%)"; };
|
||||
this.valueOf = function() { return parent.valueOf(); };
|
||||
}
|
||||
|
||||
function HSLA(parent) {
|
||||
parent.HSL.constructor.call(this, parent);
|
||||
Object.defineProperty(this, "alpha", {
|
||||
get: function() { return parent.alpha; },
|
||||
set: function(value) { parent.alpha = value; }
|
||||
});
|
||||
this.toString = function() { return "hsla(" + this.hue + "," + (this.saturation * 100).toFixed(2) + "%," + (this.lightness * 100).toFixed(2) + "%," + (parent.alpha / 255).toFixed(2) + ")"; };
|
||||
this.valueOf = function() { return parent.valueOf(); };
|
||||
}
|
||||
|
||||
function HWB(parent) {
|
||||
parent.RGB.constructor.call(this, parent);
|
||||
/**
|
||||
* @type {number} 色调 0 - 360
|
||||
*/
|
||||
Object.defineProperty(this, "hue", {
|
||||
get: function() {
|
||||
var r = parent.red / 255,
|
||||
g = parent.green / 255,
|
||||
b = parent.blue / 255;
|
||||
var max = Math.max(r, g, b),
|
||||
min = Math.min(r, g, b);
|
||||
var h, w, b = (max + min) / 2;
|
||||
if (max == min) {
|
||||
h = w = 0; // achromatic
|
||||
} else {
|
||||
var d = max - min;
|
||||
w = (max == 0 ? 0 : d / max);
|
||||
switch (max) {
|
||||
case r:
|
||||
h = (g - b) / d + (g < b ? 6 : 0);
|
||||
break;
|
||||
case g:
|
||||
h = (b - r) / d + 2;
|
||||
break;
|
||||
case b:
|
||||
h = (r - g) / d + 4;
|
||||
break;
|
||||
}
|
||||
h /= 6;
|
||||
}
|
||||
return h * 360;
|
||||
},
|
||||
set: function(value) {
|
||||
var r = parent.red / 255,
|
||||
g = parent.green / 255,
|
||||
b = parent.blue / 255;
|
||||
var max = Math.max(r, g, b),
|
||||
min = Math.min(r, g, b);
|
||||
var h = value / 360,
|
||||
w = parent.white,
|
||||
b = (1 - w) * max;
|
||||
if (max == min) {
|
||||
r = g = b = max; // achromatic
|
||||
} else {
|
||||
var hue2rgb = function hue2rgb(p, q, t) {
|
||||
if (t < 0) t += 1;
|
||||
if (t > 1) t -= 1;
|
||||
if (t < 1 / 6) return p + (q - p) * 6 * t;
|
||||
if (t < 1 / 2) return q;
|
||||
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
var q = b < 0.5 ? b * (1 + w) : b + w - b * w;
|
||||
var p = 2 * b - q;
|
||||
r = hue2rgb(p, q, h + 1 / 3);
|
||||
g = hue2rgb(p, q, h);
|
||||
b = hue2rgb(p, q, h - 1 / 3);
|
||||
}
|
||||
parent.red = Math.round(r * 255);
|
||||
parent.green = Math.round(g * 255);
|
||||
parent.blue = Math.round(b * 255);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* @type {number} 白色分量 0 - 1
|
||||
*/
|
||||
Object.defineProperty(this, "white", {
|
||||
get: function() {
|
||||
var r = parent.red / 255,
|
||||
g = parent.green / 255,
|
||||
b = parent.blue / 255;
|
||||
var max = Math.max(r, g, b),
|
||||
min = Math.min(r, g, b);
|
||||
var h, w, b = (max + min) / 2;
|
||||
if (max == min) {
|
||||
w = 0; // achromatic
|
||||
} else {
|
||||
var d = max - min;
|
||||
w = (max == 0 ? 0 : d / max);
|
||||
}
|
||||
return w;
|
||||
},
|
||||
set: function(value) {
|
||||
var r = parent.red / 255,
|
||||
g = parent.green / 255,
|
||||
b = parent.blue / 255;
|
||||
var max = Math.max(r, g, b),
|
||||
min = Math.min(r, g, b);
|
||||
var h = parent.hue / 360,
|
||||
w = value,
|
||||
b = (1 - w) * max;
|
||||
if (max == min) {
|
||||
r = g = b = max; // achromatic
|
||||
} else {
|
||||
var hue2rgb = function hue2rgb(p, q, t) {
|
||||
if (t < 0) t += 1;
|
||||
if (t > 1) t -= 1;
|
||||
if (t < 1 / 6) return p + (q - p) * 6 * t;
|
||||
if (t < 1 / 2) return q;
|
||||
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
var q = b < 0.5 ? b * (1 + w) : b + w - b * w;
|
||||
var p = 2 * b - q;
|
||||
r = hue2rgb(p, q, h + 1 / 3);
|
||||
g = hue2rgb(p, q, h);
|
||||
b = hue2rgb(p, q, h - 1 / 3);
|
||||
}
|
||||
parent.red = Math.round(r * 255);
|
||||
parent.green = Math.round(g * 255);
|
||||
parent.blue = Math.round(b * 255);
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "black", {
|
||||
get: function() {
|
||||
var r = parent.red / 255,
|
||||
g = parent.green / 255,
|
||||
b = parent.blue / 255;
|
||||
var max = Math.max(r, g, b),
|
||||
min = Math.min(r, g, b);
|
||||
var h, w, b = (max + min) / 2;
|
||||
if (max == min) {
|
||||
w = 0; // achromatic
|
||||
} else {
|
||||
var d = max - min;
|
||||
w = (max == 0 ? 0 : d / max);
|
||||
}
|
||||
return 1 - w;
|
||||
},
|
||||
set: function(value) {
|
||||
var r = parent.red / 255,
|
||||
g = parent.green / 255,
|
||||
b = parent.blue / 255;
|
||||
var max = Math.max(r, g, b),
|
||||
min = Math.min(r, g, b);
|
||||
var h = parent.hue / 360,
|
||||
w = 1 - value,
|
||||
b = (1 - w) * max;
|
||||
if (max == min) {
|
||||
r = g = b = max; // achromatic
|
||||
} else {
|
||||
var hue2rgb = function hue2rgb(p, q, t) {
|
||||
if (t < 0) t += 1;
|
||||
if (t > 1) t -= 1;
|
||||
if (t < 1 / 6) return p + (q - p) * 6 * t;
|
||||
if (t < 1 / 2) return q;
|
||||
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
var q = b < 0.5 ? b * (1 + w) : b + w - b * w;
|
||||
var p = 2 * b - q;
|
||||
r = hue2rgb(p, q, h + 1 / 3);
|
||||
g = hue2rgb(p, q, h);
|
||||
b = hue2rgb(p, q, h - 1 / 3);
|
||||
}
|
||||
parent.red = Math.round(r * 255);
|
||||
parent.green = Math.round(g * 255);
|
||||
parent.blue = Math.round(b * 255);
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "alpha", {
|
||||
get: function() { return parent.alpha; },
|
||||
set: function(value) { parent.alpha = value; }
|
||||
});
|
||||
this.toString = function() {
|
||||
if (parent.alpha == 255) {
|
||||
return "hwb(" + this.hue + "," + (this.white * 100).toFixed(2) + "%," + (this.black * 100).toFixed(2) + "%)";
|
||||
} else {
|
||||
return "hwb(" + this.hue + "," + (this.white * 100).toFixed(2) + "%," + (this.black * 100).toFixed(2) + "% / " + (parent.alpha / 255).toFixed(2) + ")";
|
||||
}
|
||||
};
|
||||
this.valueOf = function() { return parent.valueOf(); };
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param {number} red 红色通道值 0-255
|
||||
* @param {number} green 绿色通道值 0-255
|
||||
* @param {number} blue 蓝色通道值 0-255
|
||||
* @param {number} alpha 透明度通道值 0-255
|
||||
*/
|
||||
function Color(red, green, blue, alpha) {
|
||||
red = red & 0xFF;
|
||||
green = green & 0xFF;
|
||||
blue = blue & 0xFF;
|
||||
alpha = (typeof alpha === "undefined") ? 255 : (alpha & 0xFF);
|
||||
this.rgbData = (red << 16) | (green << 8) | blue;
|
||||
this.alpha = alpha;
|
||||
// 红色通道
|
||||
Object.defineProperty(this, "red", {
|
||||
get: function() { return (this.rgbData >>> 16) & 0xFF; },
|
||||
set: function(value) { this.rgbData = ((value & 0xFF) << 16) | (this.rgbData & 0x00FFFF); }
|
||||
});
|
||||
// 绿色通道
|
||||
Object.defineProperty(this, "green", {
|
||||
get: function() { return (this.rgbData >>> 8) & 0xFF; },
|
||||
set: function(value) { this.rgbData = (this.rgbData & 0xFF00FF) | ((value & 0xFF) << 8); }
|
||||
});
|
||||
// 蓝色通道
|
||||
Object.defineProperty(this, "blue", {
|
||||
get: function() { return this.rgbData & 0xFF; },
|
||||
set: function(value) { this.rgbData = (this.rgbData & 0xFFFF00) | (value & 0xFF); }
|
||||
});
|
||||
// Alpha 通道单独存储
|
||||
Object.defineProperty(this, "alpha", {
|
||||
get: function() { return this._alpha; },
|
||||
set: function(value) { this._alpha = value & 0xFF; }
|
||||
});
|
||||
// hex 属性
|
||||
Object.defineProperty(this, "hex", {
|
||||
get: function() {
|
||||
function padZero(str, length) {
|
||||
while (str.length < length) str = "0" + str;
|
||||
return str;
|
||||
}
|
||||
var r = padZero(this.red.toString(16), 2),
|
||||
g = padZero(this.green.toString(16), 2),
|
||||
b = padZero(this.blue.toString(16), 2),
|
||||
a = padZero(this.alpha.toString(16), 2);
|
||||
return this.alpha === 255 ? "#" + r + g + b : "#" + r + g + b + a;
|
||||
},
|
||||
set: function(value) {
|
||||
var hex = value.replace(/^#/, "");
|
||||
if (hex.length === 3) hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
|
||||
if (hex.length === 6) hex = hex + "ff";
|
||||
if (hex.length === 8) {
|
||||
this.red = parseInt(hex.substr(0, 2), 16);
|
||||
this.green = parseInt(hex.substr(2, 2), 16);
|
||||
this.blue = parseInt(hex.substr(4, 2), 16);
|
||||
this.alpha = parseInt(hex.substr(6, 2), 16);
|
||||
}
|
||||
}
|
||||
});
|
||||
this.toString = function() { return this.hex; };
|
||||
this.valueOf = function() {
|
||||
function padZero(str, length) {
|
||||
while (str.length < length) str = "0" + str;
|
||||
return str;
|
||||
}
|
||||
var r = padZero(this.red.toString(16), 2),
|
||||
g = padZero(this.green.toString(16), 2),
|
||||
b = padZero(this.blue.toString(16), 2),
|
||||
a = padZero(this.alpha.toString(16), 2);
|
||||
return "#" + r + g + b + a;
|
||||
};
|
||||
this.RGB = new RGB(this);
|
||||
this.RGBA = new RGBA(this);
|
||||
this.HSL = new HSL(this);
|
||||
this.HSLA = new HSLA(this);
|
||||
this.HWB = new HWB(this);
|
||||
}
|
||||
module.exports = { Color: Color };
|
||||
})(this);
|
||||
178
shared/html/js/dpimodes.js
Normal file
@@ -0,0 +1,178 @@
|
||||
(function(global) {
|
||||
"use strict";
|
||||
var highDpiMode = 0; // 默认不进行转换
|
||||
var dpiValue = 1.0; // 默认 100%
|
||||
|
||||
function IsIeVersionElder() {
|
||||
return Bridge.Frame.version < 11;
|
||||
}
|
||||
// 0 - 不使用
|
||||
// 1 - 转换为 px
|
||||
// 2 - 转换为 pt
|
||||
function setHighDpiMode(modeType) {
|
||||
highDpiMode = modeType;
|
||||
refreshModeDisplay();
|
||||
}
|
||||
|
||||
function refreshModeDisplay() {
|
||||
switch (highDpiMode) {
|
||||
case 1:
|
||||
convertAllPtToPx();
|
||||
break;
|
||||
case 2:
|
||||
convertAllPxToPt();
|
||||
break;
|
||||
}
|
||||
var images = document.getElementsByTagName('img');
|
||||
for (var i = 0; i < images.length; i++) {
|
||||
var img = images[i];
|
||||
var parent = img.parentElement;
|
||||
if (!parent) continue;
|
||||
var parentWidth = parent.offsetWidth;
|
||||
var parentHeight = parent.offsetHeight;
|
||||
var scaledWidth = img.naturalWidth * dpiValue;
|
||||
var scaledHeight = img.naturalHeight * dpiValue;
|
||||
if (scaledWidth > parentWidth || scaledHeight > parentHeight) {
|
||||
img.style.transform = 'none';
|
||||
} else {
|
||||
img.style.transform = 'scale(' + dpiValue + ')';
|
||||
}
|
||||
// console.log('Image:', img, 'Parent Size:', parentWidth, parentHeight, 'Scaled:', scaledWidth, scaledHeight, 'Transform:', img.style.transform);
|
||||
}
|
||||
if (IsIeVersionElder && IsIeVersionElder()) {
|
||||
var contentElements = document.getElementsByClassName('content');
|
||||
var controlElements = document.getElementsByClassName('control-column-bottom');
|
||||
if (controlElements.length === 0 || contentElements.length === 0) {
|
||||
console.error('未找到相应元素');
|
||||
} else {
|
||||
var controlElement = controlElements[0];
|
||||
var vheight = controlElement.currentStyle ?
|
||||
controlElement.currentStyle.height :
|
||||
window.getComputedStyle(controlElement).height;
|
||||
for (var i = 0; i < contentElements.length; i++) {
|
||||
var element = contentElements[i];
|
||||
element.style.height = 'calc(100% - ' + vheight + ')';
|
||||
// console.log('Set height of', element, 'to', 'calc(100% - ' + vheight + ')');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function convertAllPtToPx() {
|
||||
var conversionFactor = 96 / 72;
|
||||
var allElements = document.getElementsByTagName("*");
|
||||
for (var i = 0; i < allElements.length; i++) {
|
||||
var el = allElements[i];
|
||||
if (el.style && el.style.cssText) {
|
||||
el.style.cssText = el.style.cssText.replace(/(\d+(\.\d+)?)pt/g, function(match, p1) {
|
||||
var pxValue = parseFloat(p1) * conversionFactor;
|
||||
return pxValue + "px";
|
||||
});
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < document.styleSheets.length; i++) {
|
||||
var styleSheet = document.styleSheets[i];
|
||||
try {
|
||||
var rules = styleSheet.cssRules || styleSheet.rules;
|
||||
if (rules) {
|
||||
for (var j = 0; j < rules.length; j++) {
|
||||
var rule = rules[j];
|
||||
if (rule.style) {
|
||||
for (var k = 0; k < rule.style.length; k++) {
|
||||
var propertyName = rule.style[k];
|
||||
var value = rule.style.getPropertyValue(propertyName);
|
||||
if (value.indexOf("pt") !== -1) {
|
||||
var newValue = value.replace(/(\d+(\.\d+)?)pt/g, function(match, p1) {
|
||||
var pxValue = parseFloat(p1) * conversionFactor;
|
||||
return pxValue + "px";
|
||||
});
|
||||
var priority = (rule.style.getPropertyPriority) ? rule.style.getPropertyPriority(propertyName) : "";
|
||||
rule.style.setProperty(propertyName, newValue, priority);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn("Could not access stylesheet", styleSheet.href, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function convertAllPxToPt() {
|
||||
var conversionFactor = 72 / 96;
|
||||
var allElements = document.getElementsByTagName("*");
|
||||
for (var i = 0; i < allElements.length; i++) {
|
||||
var el = allElements[i];
|
||||
if (el.style && el.style.cssText) {
|
||||
el.style.cssText = el.style.cssText.replace(/(\d+(\.\d+)?)px/g, function(match, p1) {
|
||||
var pxValue = parseFloat(p1) * conversionFactor;
|
||||
return pxValue + "pt";
|
||||
});
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < document.styleSheets.length; i++) {
|
||||
var styleSheet = document.styleSheets[i];
|
||||
try {
|
||||
var rules = styleSheet.cssRules || styleSheet.rules;
|
||||
if (rules) {
|
||||
for (var j = 0; j < rules.length; j++) {
|
||||
var rule = rules[j];
|
||||
if (rule.style) {
|
||||
for (var k = 0; k < rule.style.length; k++) {
|
||||
var propertyName = rule.style[k];
|
||||
var value = rule.style.getPropertyValue(propertyName);
|
||||
if (value.indexOf("px") !== -1) {
|
||||
var newValue = value.replace(/(\d+(\.\d+)?)px/g, function(match, p1) {
|
||||
var pxValue = parseFloat(p1) * conversionFactor;
|
||||
return pxValue + "pt";
|
||||
});
|
||||
var priority = (rule.style.getPropertyPriority) ? rule.style.getPropertyPriority(propertyName) : "";
|
||||
rule.style.setProperty(propertyName, newValue, priority);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn("Could not access stylesheet", styleSheet.href, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setPageZoom(zoomLevel) {
|
||||
// document.body.style.zoom = zoomLevel;
|
||||
dpiValue = zoomLevel;
|
||||
refreshModeDisplay();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
Windows: {
|
||||
UI: {
|
||||
DPI: new function() {
|
||||
Object.defineProperty(this, "mode", {
|
||||
get: function() {
|
||||
return highDpiMode;
|
||||
},
|
||||
set: function(modeType) {
|
||||
setHighDpiMode(modeType);
|
||||
return highDpiMode;
|
||||
}
|
||||
});
|
||||
this.refresh = refreshModeDisplay;
|
||||
Object.defineProperty(this, "zoom", {
|
||||
get: function() {
|
||||
return dpiValue;
|
||||
},
|
||||
set: function(zoomLevel) {
|
||||
setPageZoom(zoomLevel);
|
||||
return dpiValue;
|
||||
}
|
||||
});
|
||||
this.ptToPx = convertAllPtToPx;
|
||||
this.pxToPt = convertAllPxToPt;
|
||||
}()
|
||||
}
|
||||
}
|
||||
};
|
||||
})(this);
|
||||
338
shared/html/js/event.js
Normal file
@@ -0,0 +1,338 @@
|
||||
(function(global) {
|
||||
"use strict";
|
||||
|
||||
if (!global.Windows) global.Windows = {};
|
||||
if (!global.Windows.UI) global.Windows.UI = {};
|
||||
if (!global.Windows.UI.Event) global.Windows.UI.Event = {};
|
||||
|
||||
var Monitor = (function() {
|
||||
var _sIdAttr = "data-monitor-id";
|
||||
var _idCounter = 1;
|
||||
var _aRegistry = {};
|
||||
var _typeRegistry = {}; // 按事件类型分类缓存
|
||||
var _polling = false;
|
||||
var _loopHandle = null;
|
||||
var _cleanupThreshold = 30000; // 30秒清理一次
|
||||
var _lastCleanup = Date.now();
|
||||
var _checkInterval = 200; // 节流时间
|
||||
var _eventTypes = [
|
||||
"resize",
|
||||
"position",
|
||||
"attribute",
|
||||
"child"
|
||||
];
|
||||
|
||||
// 缓存 DOM 元素引用
|
||||
var _elementCache = {};
|
||||
|
||||
function _ensureId(el) {
|
||||
if (!el.getAttribute(_sIdAttr)) {
|
||||
el.setAttribute(_sIdAttr, "monitor_" + (_idCounter++));
|
||||
}
|
||||
return el.getAttribute(_sIdAttr);
|
||||
}
|
||||
|
||||
function _getElementById(id) {
|
||||
if (_elementCache[id] && _elementCache[id].parentNode) {
|
||||
return _elementCache[id];
|
||||
}
|
||||
var el = document.querySelector("[" + _sIdAttr + "=\"" + id + "\"]");
|
||||
if (el) _elementCache[id] = el;
|
||||
return el;
|
||||
}
|
||||
|
||||
function _getAttrSnapshot(el) {
|
||||
var attrs = {};
|
||||
for (var i = 0; i < el.attributes.length; i++) {
|
||||
var attr = el.attributes[i];
|
||||
attrs[attr.name] = attr.value;
|
||||
}
|
||||
attrs["_rect"] = el.getBoundingClientRect();
|
||||
return attrs;
|
||||
}
|
||||
|
||||
function _hasChanged(snapshotA, snapshotB) {
|
||||
for (var key in snapshotA) {
|
||||
if (snapshotA.hasOwnProperty(key)) {
|
||||
if (key === "_rect") {
|
||||
var a = snapshotA[key],
|
||||
b = snapshotB[key];
|
||||
if (!b || a.top !== b.top || a.left !== b.left || a.width !== b.width || a.height !== b.height) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (snapshotA[key] !== snapshotB[key]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function _pollOnce() {
|
||||
var now = Date.now();
|
||||
|
||||
// 按事件类型遍历,减少不必要检查
|
||||
for (var type in _typeRegistry) {
|
||||
if (!_typeRegistry.hasOwnProperty(type)) continue;
|
||||
|
||||
var list = _typeRegistry[type];
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
var item = list[i];
|
||||
var el = _getElementById(item.id);
|
||||
if (!el) {
|
||||
list.splice(i--, 1);
|
||||
delete _elementCache[item.id];
|
||||
continue;
|
||||
}
|
||||
|
||||
var newSnapshot = _getAttrSnapshot(el);
|
||||
if (_hasChanged(item.snapshot, newSnapshot)) {
|
||||
item.snapshot = newSnapshot;
|
||||
try {
|
||||
item.callback.call(el, { type: type });
|
||||
} catch (ex) {
|
||||
console.error("Monitor callback error:", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 清理过期节点
|
||||
if (now - _lastCleanup > _cleanupThreshold) {
|
||||
_cleanup();
|
||||
_lastCleanup = now;
|
||||
}
|
||||
}
|
||||
|
||||
function _startLoop() {
|
||||
if (_polling) return;
|
||||
_polling = true;
|
||||
|
||||
function loop() {
|
||||
_pollOnce();
|
||||
_loopHandle = global.requestAnimationFrame ? requestAnimationFrame(loop) : setTimeout(loop, _checkInterval);
|
||||
}
|
||||
loop();
|
||||
}
|
||||
|
||||
function _stopLoop() {
|
||||
_polling = false;
|
||||
if (_loopHandle) {
|
||||
if (global.cancelAnimationFrame) cancelAnimationFrame(_loopHandle);
|
||||
else clearTimeout(_loopHandle);
|
||||
_loopHandle = null;
|
||||
}
|
||||
}
|
||||
|
||||
function _cleanup() {
|
||||
for (var type in _typeRegistry) {
|
||||
if (!_typeRegistry.hasOwnProperty(type)) continue;
|
||||
var list = _typeRegistry[type];
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
if (!_getElementById(list[i].id)) {
|
||||
list.splice(i--, 1);
|
||||
delete _elementCache[list[i].id];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function observe(el, type, callback) {
|
||||
if (_eventTypes.indexOf(type) < 0) throw new Error("Unsupported event type: " + type);
|
||||
var id = _ensureId(el);
|
||||
if (!_typeRegistry[type]) _typeRegistry[type] = [];
|
||||
_typeRegistry[type].push({
|
||||
id: id,
|
||||
callback: callback,
|
||||
snapshot: _getAttrSnapshot(el)
|
||||
});
|
||||
_startLoop();
|
||||
}
|
||||
|
||||
function detach(el, type, callback) {
|
||||
if (!_typeRegistry[type]) return;
|
||||
var id = el.getAttribute(_sIdAttr);
|
||||
if (!id) return;
|
||||
var list = _typeRegistry[type];
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
if (list[i].id === id && (!callback || list[i].callback === callback)) {
|
||||
list.splice(i--, 1);
|
||||
delete _elementCache[id];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function clearAll() {
|
||||
_typeRegistry = {};
|
||||
_elementCache = {};
|
||||
_stopLoop();
|
||||
}
|
||||
|
||||
return {
|
||||
observe: observe,
|
||||
detach: detach,
|
||||
clearAll: clearAll,
|
||||
EventType: {
|
||||
resize: "resize",
|
||||
position: "position",
|
||||
attribute: "attribute",
|
||||
child: "child"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
global.Windows.UI.Event.Monitor = Monitor;
|
||||
|
||||
})(window);
|
||||
|
||||
/*
|
||||
|
||||
// 1) 监听元素尺寸变化
|
||||
var el = document.getElementById("box");
|
||||
Windows.UI.Event.Monitor.observe(el, "resize", function (e) {
|
||||
console.log("resized", e.oldValue, e.newValue, e.rect);
|
||||
});
|
||||
|
||||
// 2) 监听属性变化
|
||||
Windows.UI.Event.Monitor.observe(el, "attributeChange", function (e) {
|
||||
console.log("attrs changed", e.detail); // detail.added / removed / changed
|
||||
});
|
||||
|
||||
// 3) 监听附着/分离
|
||||
Windows.UI.Event.Monitor.observe(el, "attach", function (e) {
|
||||
console.log("attached to doc");
|
||||
});
|
||||
Windows.UI.Event.Monitor.observe(el, "detach", function (e) {
|
||||
console.log("detached from doc");
|
||||
});
|
||||
|
||||
// 4) 取消监听
|
||||
Windows.UI.Event.Monitor.unobserve(el, "resize", handler);
|
||||
|
||||
*/
|
||||
|
||||
(function(global) {
|
||||
"use strict";
|
||||
|
||||
var EventUtil = {};
|
||||
|
||||
/**
|
||||
* 添加事件,兼容 IE10/IE11
|
||||
* @param {Element|Window|Document} el 目标元素
|
||||
* @param {string} sType 事件类型,如 "click", "resize", "scroll"
|
||||
* @param {function} pfHandler 回调函数
|
||||
* @param {boolean} [bUseCapture] 是否捕获阶段,默认 false
|
||||
*/
|
||||
EventUtil.addEvent = function(el, sType, pfHandler, bUseCapture) {
|
||||
if (!el || typeof sType !== "string" || typeof pfHandler !== "function") return;
|
||||
|
||||
bUseCapture = !!bUseCapture;
|
||||
|
||||
if (el.addEventListener) {
|
||||
// 标准方式
|
||||
el.addEventListener(sType, pfHandler, bUseCapture);
|
||||
} else if (el.attachEvent) {
|
||||
// IE8-9 fallback
|
||||
el.attachEvent("on" + sType, pfHandler);
|
||||
} else {
|
||||
// 最原始方式
|
||||
var oldHandler = el["on" + sType];
|
||||
el["on" + sType] = function(e) {
|
||||
if (oldHandler) oldHandler(e || window.event);
|
||||
pfHandler(e || window.event);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 移除事件,兼容 IE10/IE11
|
||||
* @param {Element|Window|Document} el 目标元素
|
||||
* @param {string} sType 事件类型,如 "click", "resize", "scroll"
|
||||
* @param {function} pfHandler 回调函数
|
||||
* @param {boolean} [bUseCapture] 是否捕获阶段,默认 false
|
||||
*/
|
||||
EventUtil.removeEvent = function(el, sType, pfHandler, bUseCapture) {
|
||||
if (!el || typeof sType !== "string" || typeof pfHandler !== "function") return;
|
||||
|
||||
bUseCapture = !!bUseCapture;
|
||||
|
||||
if (el.removeEventListener) {
|
||||
el.removeEventListener(sType, pfHandler, bUseCapture);
|
||||
} else if (el.detachEvent) {
|
||||
el.detachEvent("on" + sType, pfHandler);
|
||||
} else {
|
||||
var oldHandler = el["on" + sType];
|
||||
if (oldHandler === pfHandler) {
|
||||
el["on" + sType] = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 暴露到全局命名空间
|
||||
if (typeof module !== "undefined" && module.exports) {
|
||||
module.exports = {
|
||||
Windows: {
|
||||
UI: {
|
||||
Event: {
|
||||
Util: EventUtil
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
} else {
|
||||
global.Windows = global.Windows || {};
|
||||
global.Windows.UI = global.Windows.UI || {};
|
||||
global.Windows.UI.Event = global.Windows.UI.Event || {};
|
||||
global.Windows.UI.Event.Util = EventUtil;
|
||||
}
|
||||
|
||||
})(this);
|
||||
/*
|
||||
使用示例:
|
||||
var handler = function (e) {
|
||||
console.log("事件触发", e.type);
|
||||
};
|
||||
|
||||
// 添加事件
|
||||
Windows.UI.Event.Util.addEvent(window, "resize", handler);
|
||||
|
||||
// 删除事件
|
||||
Windows.UI.Event.Util.removeEvent(window, "resize", handler);
|
||||
|
||||
*/
|
||||
(function(global) {
|
||||
"use strict";
|
||||
/**
|
||||
*
|
||||
* @param {function} fn
|
||||
* @param {number} delay
|
||||
* @param {boolean} immediate 是否在第一次立即执行(可选,默认 false)
|
||||
* @returns {function} 返回一个新的函数,该函数在 delay 时间后执行 fn 函数,如果在 delay 时间内再次调用该函数,则会重新计时。
|
||||
*/
|
||||
function debounce(fn, delay, immediate) {
|
||||
var timer = null;
|
||||
var lastCall = 0;
|
||||
return function() {
|
||||
var context = this;
|
||||
var args = arguments;
|
||||
var now = +new Date();
|
||||
var callNow = immediate && !timer;
|
||||
if (now - lastCall >= delay) {
|
||||
lastCall = now;
|
||||
if (callNow) {
|
||||
fn.apply(context, args);
|
||||
}
|
||||
}
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(function() {
|
||||
lastCall = +new Date();
|
||||
if (!immediate) {
|
||||
fn.apply(context, args);
|
||||
}
|
||||
}, delay);
|
||||
};
|
||||
}
|
||||
module.exports = { debounce: debounce };
|
||||
})(this);
|
||||
187
shared/html/js/module.js
Normal file
@@ -0,0 +1,187 @@
|
||||
/**
|
||||
* @module module
|
||||
* @description 模块化相关的函数。
|
||||
|
||||
* 将模块化相关的函数封装在一个对象中,方便使用。
|
||||
* 1. directexports(cObject, cDirection):直接将对象或函数公开到指定方向。
|
||||
* 2. exports:公开的对象或函数。
|
||||
* 3. imports:已加载的脚本。
|
||||
* 4. unload:卸载已加载的脚本。
|
||||
* 5. namespace(swNameSpace, cDirection):创建命名空间。
|
||||
* 6. export(cObject, cDirection):兼容旧版本的函数。
|
||||
* 7. import(aswSrc):兼容旧版本的函数。
|
||||
* 兼容的旧版本函数需要引用预处理模块,否则不会兼容。
|
||||
*/
|
||||
(function(global) {
|
||||
"use strict";
|
||||
// 是否为通过构造函数创建的对象实例
|
||||
function isNewFunctionInstance(obj) {
|
||||
return typeof obj === "object" && Object.getPrototypeOf(obj) !== Object.prototype;
|
||||
}
|
||||
var module = new function() {
|
||||
if (this._instance) return this._instance;
|
||||
else this._instance = this;
|
||||
/**
|
||||
* 便于从代码块中公开。
|
||||
* @param {Object} cObject 需要公开的内容,以对象的形式分配好命名空间和别名。如:
|
||||
* {
|
||||
* myFunc: function() { },
|
||||
* myObj: function () {
|
||||
* // object constructor
|
||||
* }
|
||||
* }
|
||||
* 然后默认公开到全局。则公开后可以直接通过 myFunc() 或 myObj() 调用。
|
||||
* @param {global | Object} cDirection 公开方向
|
||||
* @returns {void}
|
||||
*/
|
||||
this.directexports = function(cObject, cDirection) {
|
||||
if (!cDirection) cDirection = global;
|
||||
if (typeof cObject === "function") {
|
||||
cDirection[cObject.name] = cObject;
|
||||
return;
|
||||
} else if (typeof cObject === "object") {
|
||||
var keys = Object.keys(cObject);
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
if (typeof cDirection[keys[i]] === "undefined") {
|
||||
cDirection[keys[i]] = {};
|
||||
}
|
||||
if (isNewFunctionInstance(cObject[keys[i]])) {
|
||||
cDirection[keys[i]] = cObject[keys[i]];
|
||||
} else if (typeof cObject[keys[i]] === "object") {
|
||||
this.directexports(cObject[keys[i]], cDirection[keys[i]]);
|
||||
} else {
|
||||
cDirection[keys[i]] = cObject[keys[i]];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cDirection = cObject;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @property {global | Object} exports 欲公开的内容以对象的形式分配好命名空间和别名。如:
|
||||
*/
|
||||
Object.defineProperty(this, "exports", {
|
||||
get: function() {
|
||||
return global;
|
||||
},
|
||||
set: function(cObject, cDirection) {
|
||||
this.directexports(cObject, cDirection);
|
||||
}
|
||||
});
|
||||
if (typeof Array.isArray === "undefined") {
|
||||
/**
|
||||
* 判断是否为数组。这是函数补充。
|
||||
* @param {*} arg 需要判断的对象
|
||||
* @returns {boolean}
|
||||
*/
|
||||
Array.isArray = function(arg) {
|
||||
return Object.prototype.toString.call(arg) === "[object Array]" || arg instanceof Array || arg instanceof HTMLCollection || arg instanceof NodeList;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @property {HTMLCollection | NodeList | null} imports 当前页面已加载的脚本。会以 NodeList 形式返回。如果为设置,则是追加脚本,而不是覆盖。传入脚本路径或其数组。
|
||||
*/
|
||||
Object.defineProperty(this, "imports", {
|
||||
get: function() {
|
||||
if (typeof window !== "undefined" && typeof document !== "undefined") {
|
||||
var scripts = document.querySelectorAll("script[src]");
|
||||
return scripts;
|
||||
} else return null;
|
||||
},
|
||||
set: function(aswSrc) {
|
||||
if (typeof aswSrc === "string") {
|
||||
var scripts = this.imports;
|
||||
if (scripts && scripts.length > 0) {
|
||||
for (var i = 0; i < scripts.length; i++) {
|
||||
if (scripts[i].src === aswSrc) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
var script = document.createElement("script");
|
||||
script.src = aswSrc;
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
} else if (Array.isArray(aswSrc) || aswSrc instanceof Array || aswSrc instanceof HTMLCollection || aswSrc instanceof NodeList) {
|
||||
for (var i = 0; i < aswSrc.length; i++) {
|
||||
this.imports = aswSrc[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
/**
|
||||
* @property {HTMLCollection | NodeList | null} unload 卸载当前页面已加载的脚本。传入脚本路径或其数组。无法只读
|
||||
*/
|
||||
Object.defineProperty(this, "unload", {
|
||||
set: function(aswSrc) {
|
||||
if (typeof aswSrc === "string") {
|
||||
var scripts = this.imports;
|
||||
if (scripts && scripts.length > 0) {
|
||||
for (var i = 0; i < scripts.length; i++) {
|
||||
if (scripts[i].src === aswSrc) {
|
||||
scripts[i].remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (Array.isArray(aswSrc) || aswSrc instanceof Array || aswSrc instanceof HTMLCollection || aswSrc instanceof NodeList) {
|
||||
for (var i = 0; i < aswSrc.length; i++) {
|
||||
this.unload = aswSrc[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "global", {
|
||||
get: function() {
|
||||
return global;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* 命名空间,其实为一种字典。
|
||||
* @param {string} swNameSpace 命名空间路径。如:"WinJS.Namespace"。不能为空。命名空间之间用"."分隔。
|
||||
* @param {*} cDirection 创建的路径,默认创建到全局
|
||||
* @returns
|
||||
*/
|
||||
this.namespace = function(swNameSpace, cDirection) {
|
||||
if (!cDirection) cDirection = global;
|
||||
var strarr = (swNameSpace || "").split(".");
|
||||
if (!strarr.length) strarr.push(swns);
|
||||
|
||||
function setNs(strarr, direct) {
|
||||
var newdirect = null;
|
||||
if (!strarr.length) return direct;
|
||||
else {
|
||||
if (typeof direct[strarr[0]] === "undefined") {
|
||||
direct[strarr[0]] = {};
|
||||
}
|
||||
newdirect = direct[strarr[0]];
|
||||
}
|
||||
strarr.shift();
|
||||
return setNs((strarr || []), newdirect);
|
||||
}
|
||||
return setNs(strarr, cDirection);
|
||||
};
|
||||
if (typeof preprocess !== "undefined" && preprocess.ifdef("COMPATIBLE")) {
|
||||
/**
|
||||
* 兼容旧版本的函数。
|
||||
* @param {Object | Function} cObject 欲公开的对象或函数
|
||||
* @param {global | Object} cDirection 公开方向
|
||||
*/
|
||||
this.export = function(cObject, cDirection) {
|
||||
this.directexports(cObject, cDirection);
|
||||
};
|
||||
/**
|
||||
*
|
||||
* @param {Array <string> | string} aswSrc 脚本路径或其数组
|
||||
* @returns {boolean} 是否成功添加脚本。在兼容模式下只会返回真。
|
||||
*/
|
||||
this.import = function(aswSrc) {
|
||||
this.imports = aswSrc;
|
||||
return true;
|
||||
};
|
||||
}
|
||||
};
|
||||
module.exports = {
|
||||
module: module,
|
||||
namespace: module.namespace,
|
||||
};
|
||||
})(this);
|
||||
74
shared/html/js/pages.js
Normal file
@@ -0,0 +1,74 @@
|
||||
(function(global) {
|
||||
"use strict";
|
||||
Object.defineProperty(global, "pagecontainer", {
|
||||
get: function() { return document.querySelector(".pagecontainer"); }
|
||||
});
|
||||
|
||||
function getPage() {
|
||||
return pagecontainer.querySelector(".page");
|
||||
}
|
||||
var supportPageList = [
|
||||
"splash",
|
||||
"select",
|
||||
"preinstall",
|
||||
"installing",
|
||||
"installsuccess",
|
||||
"installfailed"
|
||||
];
|
||||
var supportMulPageList = [
|
||||
"preinstall",
|
||||
"installing",
|
||||
"installsuccess",
|
||||
"installfailed"
|
||||
];
|
||||
|
||||
function setPage(swPageLabel, bIsMulti) {
|
||||
var page = getPage();
|
||||
swPageLabel = ("" + (swPageLabel || ""));
|
||||
for (var i = 0; i < supportPageList.length; i++) {
|
||||
if (Bridge.NString.equals(swPageLabel, supportPageList[i])) {
|
||||
page.classList.add(supportPageList[i]);
|
||||
} else {
|
||||
if (page.classList.contains(supportPageList[i])) page.classList.remove(supportPageList[i]);
|
||||
}
|
||||
}
|
||||
if (page.classList.contains("multiple")) page.classList.remove("multiple");
|
||||
for (var j = 0; j < supportMulPageList.length; j++) {
|
||||
if (Bridge.NString.equals(swPageLabel, supportMulPageList[j]) && bIsMulti) {
|
||||
page.classList.add("multiple");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getPageLabel() {
|
||||
var page = getPage();
|
||||
for (var i = 0; i < supportPageList.length; i++) {
|
||||
if (page.classList.contains(supportPageList[i])) {
|
||||
return supportPageList[i];
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function isMultiPage() {
|
||||
var page = getPage();
|
||||
return page.classList.contains("multiple");
|
||||
}
|
||||
|
||||
function setPageMultiple(bIsMulti) {
|
||||
setPage(getPageLabel(), bIsMulti);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
Page: {}
|
||||
};
|
||||
Object.defineProperty(Page, "current", {
|
||||
get: function() { return getPageLabel(); },
|
||||
set: function(swPageLabel) { setPage(swPageLabel, isMultiPage()); }
|
||||
});
|
||||
Object.defineProperty(Page, "multiple", {
|
||||
get: function() { return isMultiPage(); },
|
||||
set: function(bIsMulti) { setPage(getPageLabel(), bIsMulti); }
|
||||
});
|
||||
})(this);
|
||||
130
shared/html/js/polyfill-ie.js
Normal file
@@ -0,0 +1,130 @@
|
||||
(function(global) {
|
||||
if (typeof msWriteProfilerMark === "undefined") {
|
||||
function msWriteProfilerMark(swMark) {
|
||||
if (typeof performance !== "undefined" && typeof performance.mark === "function") {
|
||||
return performance.mark(swMark);
|
||||
} else if (typeof console !== "undefined" && typeof console.log === "function") {
|
||||
return console.log(swMark);
|
||||
}
|
||||
}
|
||||
module.exports = {
|
||||
msWriteProfilerMark: msWriteProfilerMark
|
||||
};
|
||||
}
|
||||
})(this);
|
||||
(function(global) {
|
||||
|
||||
if (typeof global.Debug === "undefined") {
|
||||
var fakeDebug = {};
|
||||
|
||||
// 基本属性
|
||||
fakeDebug.debuggerEnabled = true;
|
||||
fakeDebug.setNonUserCodeExceptions = false;
|
||||
|
||||
// 常量
|
||||
fakeDebug.MS_ASYNC_CALLBACK_STATUS_ASSIGN_DELEGATE = 0;
|
||||
fakeDebug.MS_ASYNC_CALLBACK_STATUS_JOIN = 1;
|
||||
fakeDebug.MS_ASYNC_CALLBACK_STATUS_CHOOSEANY = 2;
|
||||
fakeDebug.MS_ASYNC_CALLBACK_STATUS_CANCEL = 3;
|
||||
fakeDebug.MS_ASYNC_CALLBACK_STATUS_ERROR = 4;
|
||||
|
||||
fakeDebug.MS_ASYNC_OP_STATUS_SUCCESS = 1;
|
||||
fakeDebug.MS_ASYNC_OP_STATUS_CANCELED = 2;
|
||||
fakeDebug.MS_ASYNC_OP_STATUS_ERROR = 3;
|
||||
|
||||
// 方法:输出
|
||||
fakeDebug.write = function(msg) {
|
||||
if (console && console.log) console.log("[Debug.write] " + msg);
|
||||
};
|
||||
fakeDebug.writeln = function(msg) {
|
||||
if (console && console.log) console.log("[Debug.writeln] " + msg);
|
||||
};
|
||||
|
||||
// 方法:断言 / 中断
|
||||
fakeDebug.assert = function(cond, msg) {
|
||||
if (!cond) {
|
||||
if (console && console.error) {
|
||||
console.error("[Debug.assert] Assertion failed: " + (msg || ""));
|
||||
}
|
||||
// 可选触发断点
|
||||
// debugger;
|
||||
}
|
||||
};
|
||||
fakeDebug.break = function() {
|
||||
debugger;
|
||||
};
|
||||
|
||||
// 方法:异步跟踪(空实现)
|
||||
fakeDebug.msTraceAsyncCallbackCompleted = function() {};
|
||||
fakeDebug.msTraceAsyncCallbackStarting = function() {};
|
||||
fakeDebug.msTraceAsyncOperationCompleted = function() {};
|
||||
fakeDebug.msTraceAsyncOperationStarting = function() {};
|
||||
fakeDebug.msUpdateAsyncCallbackRelation = function() {};
|
||||
|
||||
global.Debug = fakeDebug;
|
||||
}
|
||||
|
||||
})(this);
|
||||
(function(global) {
|
||||
|
||||
if (typeof global.setImmediate === "undefined") {
|
||||
var nextHandle = 1; // 唯一任务 id
|
||||
var tasksByHandle = {};
|
||||
var currentlyRunning = false;
|
||||
|
||||
function addTask(fn, args) {
|
||||
tasksByHandle[nextHandle] = function() {
|
||||
fn.apply(undefined, args);
|
||||
};
|
||||
return nextHandle++;
|
||||
}
|
||||
|
||||
function run(handle) {
|
||||
if (currentlyRunning) {
|
||||
// 如果已经在运行,延迟一下
|
||||
setTimeout(run, 0, handle);
|
||||
} else {
|
||||
var task = tasksByHandle[handle];
|
||||
if (task) {
|
||||
currentlyRunning = true;
|
||||
try {
|
||||
task();
|
||||
} finally {
|
||||
delete tasksByHandle[handle];
|
||||
currentlyRunning = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function installSetImmediate() {
|
||||
if (typeof MessageChannel !== "undefined") {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = function(event) {
|
||||
run(event.data);
|
||||
};
|
||||
return function() {
|
||||
var handle = addTask(arguments[0], Array.prototype.slice.call(arguments, 1));
|
||||
channel.port2.postMessage(handle);
|
||||
return handle;
|
||||
};
|
||||
} else {
|
||||
// fallback: setTimeout
|
||||
return function() {
|
||||
var handle = addTask(arguments[0], Array.prototype.slice.call(arguments, 1));
|
||||
setTimeout(run, 0, handle);
|
||||
return handle;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
global.setImmediate = installSetImmediate();
|
||||
|
||||
// 对应 clearImmediate
|
||||
if (typeof global.clearImmediate === "undefined") {
|
||||
global.clearImmediate = function(handle) {
|
||||
delete tasksByHandle[handle];
|
||||
};
|
||||
}
|
||||
}
|
||||
})(this);
|
||||
60
shared/html/js/popup.js
Normal file
@@ -0,0 +1,60 @@
|
||||
(function(global) {
|
||||
"use strict";
|
||||
var flags = {
|
||||
HIDE_WHEN_CLICK_OUTSIDE: 0x00000001,
|
||||
SHOW_CONTROL_BUTTONS: 0x00000002,
|
||||
};
|
||||
|
||||
function Popup(content, options) {
|
||||
var _content = content;
|
||||
var _flags = options["flags"] || 0;
|
||||
var _element = null;
|
||||
_element = document.createElement("div");
|
||||
_element.className = "popup";
|
||||
_element.style.position = "absolute";
|
||||
_element.style.display = "none";
|
||||
document.body.appendChild(_element);
|
||||
if (_content instanceof HTMLElement) {
|
||||
_element.appendChild(_content);
|
||||
} else if (typeof _content === "string") {
|
||||
_element.textContent = _content;
|
||||
}
|
||||
Object.defineProperty(this, "content", {
|
||||
get: function() { return _content; },
|
||||
set: function(value) {
|
||||
_element.innerHTML = "";
|
||||
if (value instanceof HTMLElement) {
|
||||
_element.appendChild(value);
|
||||
} else if (typeof value === "string") {
|
||||
_element.textContent = value;
|
||||
}
|
||||
_content = value;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "", {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
Popup.Options = function() {
|
||||
this.flags = 0;
|
||||
this.position = {
|
||||
left: null,
|
||||
top: null
|
||||
};
|
||||
this.size = {
|
||||
width: null,
|
||||
height: null
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
Windows: {
|
||||
UI: {
|
||||
Popups: {
|
||||
DisplayBlock: Popup
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
})(this);
|
||||
241
shared/html/js/promise.js
Normal file
@@ -0,0 +1,241 @@
|
||||
(function(global) {
|
||||
"use strict";
|
||||
|
||||
function PromisePolyfill(pfExecutor) {
|
||||
var swState = "pending"; // "fulfilled" | "rejected"
|
||||
var vValue = undefined;
|
||||
var aHandlers = [];
|
||||
var pfOnCancel = null;
|
||||
|
||||
function invokeHandlers() {
|
||||
if (swState === "pending") return;
|
||||
for (var i = 0; i < aHandlers.length; i++) {
|
||||
handle(aHandlers[i]);
|
||||
}
|
||||
aHandlers = [];
|
||||
}
|
||||
|
||||
function handle(hHandler) {
|
||||
if (swState === "pending") {
|
||||
aHandlers.push(hHandler);
|
||||
return;
|
||||
}
|
||||
var pfCallback = swState === "fulfilled" ? hHandler.onFulfilled : hHandler.onRejected;
|
||||
if (!pfCallback) {
|
||||
if (swState === "fulfilled") {
|
||||
hHandler.resolve(vValue);
|
||||
} else {
|
||||
hHandler.reject(vValue);
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
var vResult = pfCallback(vValue);
|
||||
hHandler.resolve(vResult);
|
||||
} catch (ex) {
|
||||
hHandler.reject(ex);
|
||||
}
|
||||
}
|
||||
|
||||
function resolve(vResult) {
|
||||
try {
|
||||
if (vResult === self) throw new TypeError("A promise cannot be resolved with itself.");
|
||||
if (vResult && (typeof vResult === "object" || typeof vResult === "function")) {
|
||||
var pfThen = vResult.then;
|
||||
if (typeof pfThen === "function") {
|
||||
pfThen.call(vResult, resolve, reject);
|
||||
return;
|
||||
}
|
||||
}
|
||||
swState = "fulfilled";
|
||||
vValue = vResult;
|
||||
invokeHandlers();
|
||||
} catch (ex) {
|
||||
reject(ex);
|
||||
}
|
||||
}
|
||||
|
||||
function reject(vReason) {
|
||||
swState = "rejected";
|
||||
vValue = vReason;
|
||||
if (typeof PromisePolyfill.onerror === "function") {
|
||||
PromisePolyfill.onerror(vReason);
|
||||
}
|
||||
invokeHandlers();
|
||||
}
|
||||
var self = this;
|
||||
try {
|
||||
pfExecutor(resolve, reject, function(pfCancel) {
|
||||
pfOnCancel = pfCancel;
|
||||
});
|
||||
} catch (ex) {
|
||||
reject(ex);
|
||||
}
|
||||
this.then = function(pfOnFulfilled, pfOnRejected) {
|
||||
return new PromisePolyfill(function(resolve, reject) {
|
||||
handle({
|
||||
onFulfilled: pfOnFulfilled,
|
||||
onRejected: pfOnRejected,
|
||||
resolve: resolve,
|
||||
reject: reject
|
||||
});
|
||||
});
|
||||
};
|
||||
this["catch"] = function(pfOnRejected) {
|
||||
return this.then(null, pfOnRejected);
|
||||
};
|
||||
this.done = function(pfOnFulfilled, pfOnRejected) {
|
||||
this.then(pfOnFulfilled, pfOnRejected)["catch"](function(ex) {
|
||||
setTimeout(function() { throw ex; }, 0);
|
||||
});
|
||||
};
|
||||
this.cancel = function() {
|
||||
if (pfOnCancel) {
|
||||
try { pfOnCancel(); } catch (ex) {}
|
||||
}
|
||||
reject(new Error("Promise was canceled"));
|
||||
};
|
||||
this._oncancel = pfOnCancel;
|
||||
this._state = swState;
|
||||
this._value = vValue;
|
||||
}
|
||||
PromisePolyfill.is = function(vObj) {
|
||||
return vObj instanceof PromisePolyfill;
|
||||
};
|
||||
PromisePolyfill.resolve = function(vValue) {
|
||||
return new PromisePolyfill(function(resolve) { resolve(vValue); });
|
||||
};
|
||||
PromisePolyfill.reject = function(vReason) {
|
||||
return new PromisePolyfill(function(resolve, reject) { reject(vReason); });
|
||||
};
|
||||
PromisePolyfill.all = function(aPromises) {
|
||||
return new PromisePolyfill(function(resolve, reject) {
|
||||
var nRemaining = aPromises.length;
|
||||
var aResults = new Array(nRemaining);
|
||||
if (nRemaining === 0) resolve([]);
|
||||
|
||||
function resolver(iIndex) {
|
||||
return function(vValue) {
|
||||
aResults[iIndex] = vValue;
|
||||
nRemaining--;
|
||||
if (nRemaining === 0) resolve(aResults);
|
||||
};
|
||||
}
|
||||
for (var i = 0; i < aPromises.length; i++) {
|
||||
PromisePolyfill.resolve(aPromises[i]).then(resolver(i), reject);
|
||||
}
|
||||
});
|
||||
};
|
||||
PromisePolyfill.race = function(aPromises) {
|
||||
return new PromisePolyfill(function(resolve, reject) {
|
||||
for (var i = 0; i < aPromises.length; i++) {
|
||||
PromisePolyfill.resolve(aPromises[i]).then(resolve, reject);
|
||||
}
|
||||
});
|
||||
};
|
||||
PromisePolyfill.join = function(aPromises) {
|
||||
return PromisePolyfill.all(aPromises);
|
||||
};
|
||||
PromisePolyfill.any = function(aPromises) {
|
||||
return new PromisePolyfill(function(resolve, reject) {
|
||||
var nRemaining = aPromises.length;
|
||||
var aErrors = new Array(nRemaining);
|
||||
if (nRemaining === 0) reject(new Error("No promises provided."));
|
||||
|
||||
function resolver(vValue) { resolve(vValue); }
|
||||
|
||||
function rejecter(iIndex) {
|
||||
return function(ex) {
|
||||
aErrors[iIndex] = ex;
|
||||
nRemaining--;
|
||||
if (nRemaining === 0) reject(aErrors);
|
||||
};
|
||||
}
|
||||
for (var i = 0; i < aPromises.length; i++) {
|
||||
PromisePolyfill.resolve(aPromises[i]).then(resolver, rejecter(i));
|
||||
}
|
||||
});
|
||||
};
|
||||
PromisePolyfill.timeout = function(pPromise, nMilliseconds) {
|
||||
return new PromisePolyfill(function(resolve, reject) {
|
||||
var hTimer = setTimeout(function() {
|
||||
reject(new Error("Promise timed out after " + nMilliseconds + "ms"));
|
||||
}, nMilliseconds);
|
||||
PromisePolyfill.resolve(pPromise).then(function(vValue) {
|
||||
clearTimeout(hTimer);
|
||||
resolve(vValue);
|
||||
}, function(ex) {
|
||||
clearTimeout(hTimer);
|
||||
reject(ex);
|
||||
});
|
||||
});
|
||||
};
|
||||
PromisePolyfill.as = function(vValue) {
|
||||
return PromisePolyfill.resolve(vValue);
|
||||
};
|
||||
PromisePolyfill.wrap = function(vValue) {
|
||||
return PromisePolyfill.resolve(vValue);
|
||||
};
|
||||
PromisePolyfill.wrapError = function(vError) {
|
||||
return PromisePolyfill.reject(vError);
|
||||
};
|
||||
PromisePolyfill.thenEach = function(aValues, pfCallback) {
|
||||
var aPromises = [];
|
||||
for (var i = 0; i < aValues.length; i++) {
|
||||
aPromises.push(PromisePolyfill.resolve(aValues[i]).then(pfCallback));
|
||||
}
|
||||
return PromisePolyfill.all(aPromises);
|
||||
};
|
||||
var hListeners = {};
|
||||
PromisePolyfill.addEventListener = function(sType, pfHandler) {
|
||||
if (!hListeners[sType]) hListeners[sType] = [];
|
||||
hListeners[sType].push(pfHandler);
|
||||
};
|
||||
PromisePolyfill.removeEventListener = function(sType, pfHandler) {
|
||||
if (!hListeners[sType]) return;
|
||||
var aList = hListeners[sType];
|
||||
for (var i = 0; i < aList.length; i++) {
|
||||
if (aList[i] === pfHandler) {
|
||||
aList.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
PromisePolyfill.dispatchEvent = function(sType, vDetail) {
|
||||
if (!hListeners[sType]) return;
|
||||
var aList = hListeners[sType].slice();
|
||||
for (var i = 0; i < aList.length; i++) {
|
||||
try { aList[i](vDetail); } catch (ex) {}
|
||||
}
|
||||
};
|
||||
PromisePolyfill.supportedForProcessing = true;
|
||||
PromisePolyfill.onerror = null;
|
||||
if (typeof global.Promise !== "undefined") {
|
||||
var p = global.Promise;
|
||||
if (!p.join) p.join = p.all;
|
||||
if (!p.any) p.any = PromisePolyfill.any;
|
||||
if (!p.timeout) p.timeout = PromisePolyfill.timeout;
|
||||
if (!p.as) p.as = p.resolve;
|
||||
if (!p.wrap) p.wrap = p.resolve;
|
||||
if (!p.wrapError) p.wrapError = p.reject;
|
||||
if (!p.thenEach) p.thenEach = PromisePolyfill.thenEach;
|
||||
if (!p.is) p.is = function(vObj) { return vObj instanceof p; };
|
||||
if (!p.supportedForProcessing) p.supportedForProcessing = true;
|
||||
if (!p.addEventListener) p.addEventListener = PromisePolyfill.addEventListener;
|
||||
if (!p.removeEventListener) p.removeEventListener = PromisePolyfill.removeEventListener;
|
||||
if (!p.dispatchEvent) p.dispatchEvent = PromisePolyfill.dispatchEvent;
|
||||
if (!p.onerror) p.onerror = null;
|
||||
}
|
||||
if (typeof global.WinJS !== "undefined" && typeof global.WinJS.Promise !== "undefined") {
|
||||
var wp = global.WinJS.Promise;
|
||||
if (!wp.resolve) wp.resolve = function(vValue) { return new wp(function(c) { c(vValue); }); };
|
||||
if (!wp.reject) wp.reject = function(vReason) { return new wp(function(c, e) { e(vReason); }); };
|
||||
if (!wp.all) wp.all = function(aPromises) { return wp.join(aPromises); };
|
||||
if (!wp.race) wp.race = PromisePolyfill.race;
|
||||
global.Promise = wp;
|
||||
if (typeof global.Promise === "undefined") global.Promise = wp;
|
||||
}
|
||||
if (typeof global.Promise === "undefined" && typeof global.WinJS === "undefined") {
|
||||
global.Promise = PromisePolyfill;
|
||||
}
|
||||
})(this);
|
||||
5423
shared/html/libs/winjs/2.0/css/ui-dark.css
Normal file
5416
shared/html/libs/winjs/2.0/css/ui-light.css
Normal file
17047
shared/html/libs/winjs/2.0/js/base.js
Normal file
63
shared/html/libs/winjs/2.0/js/en-us/base.strings.js
Normal file
@@ -0,0 +1,63 @@
|
||||
/// <loc filename="Metadata\base.strings_loc_oam.xml" format="messagebundle" />
|
||||
/*!
|
||||
© Microsoft. All rights reserved.
|
||||
|
||||
This library is supported for use in Windows Store apps only.
|
||||
|
||||
Build: 1.0.9600.17018.winblue_gdr.140204-1946
|
||||
|
||||
Version: Microsoft.WinJS.2.0
|
||||
*/
|
||||
|
||||
(function (global) {
|
||||
global.strings = global.strings || {};
|
||||
|
||||
var appxVersion = "Microsoft.WinJS.2.0";
|
||||
var developerPrefix = "Developer.";
|
||||
if (appxVersion.indexOf(developerPrefix) === 0) {
|
||||
appxVersion = appxVersion.substring(developerPrefix.length);
|
||||
}
|
||||
|
||||
function addStrings(keyPrefix, strings) {
|
||||
Object.keys(strings).forEach(function (key) {
|
||||
global.strings[keyPrefix + key.replace("\\", "/")] = strings[key];
|
||||
});
|
||||
}
|
||||
|
||||
addStrings(
|
||||
"ms-resource://"+appxVersion+"/base/",
|
||||
|
||||
{
|
||||
"attributeBindingSingleProperty": "Attribute binding requires a single destination attribute name, often in the form \"this['aria-label']\" or \"width\".",
|
||||
"bindingInitializerNotFound": "Initializer not found:'{0}'",
|
||||
"cannotBindToThis": "Can't bind to 'this'.",
|
||||
"creatingNewProperty": "Creating new property {0}. Full path:{1}",
|
||||
"duplicateBindingDetected": "Binding against element with id {0} failed because a duplicate id was detected.",
|
||||
"elementNotFound": "Element not found:{0}",
|
||||
"errorActivatingControl": "Error activating control: {0}",
|
||||
"errorInitializingBindings": "Error initializing bindings: {0}",
|
||||
"exceptionFromBindingInitializer": "Exception thrown from binding initializer: {0}",
|
||||
"idBindingNotSupported": "Declarative binding to ID field is not supported. Initializer: {0}",
|
||||
"illegalListLength": "List length must be assigned a finite positive number",
|
||||
"invalidBinding": "Invalid binding:'{0}'. Expected to be '<destProp>:<sourceProp>;'. {1}",
|
||||
"invalidFragmentUri": "Unsupported uri for fragment loading. Fragments in the local context can only load from package content or local sources. To load fragments from other sources, use a web context.",
|
||||
"invalidOptionsRecord": "Invalid options record: '{0}', expected to be in the format of an object literal. {1}",
|
||||
"jobInfoIsNoLongerValid": "The job info object can only be used while the job is running",
|
||||
"malformedFormatStringInput": "Malformed, did you mean to escape your '{0}'?",
|
||||
"nestedDOMElementBindingNotSupported": "Binding through a property {0} of type HTMLElement is not supported, Full path:{1}.",
|
||||
"nestingExceeded": "NestingExceeded",
|
||||
"notFound": "NotFound: {0}",
|
||||
"notSupportedForProcessing": "Value is not supported within a declarative processing context, if you want it to be supported mark it using WinJS.Utilities.markSupportedForProcessing. The value was: '{0}'",
|
||||
"nonStaticHTML": "Unable to add dynamic content. A script attempted to inject dynamic content, or elements previously modified dynamically, that might be unsafe. For example, using the innerHTML property or the document.write method to add a script element will generate this exception. If the content is safe and from a trusted source, use a method to explicitly manipulate elements and attributes, such as createElement, or use setInnerHTMLUnsafe (or other unsafe method).",
|
||||
"propertyDoesNotExist": "{0} doesn't exist. Full path:{1}",
|
||||
"propertyIsUndefined": "{0} is undefined",
|
||||
"sparseArrayNotSupported": "Sparse arrays are not supported with proxy: true",
|
||||
"unexpectedTokenExpectedToken": "Unexpected token: {0}, expected token: {1}, at offset {2}",
|
||||
"unexpectedTokenExpectedTokens": "Unexpected token: {0}, expected one of: {1}, at offset {2}",
|
||||
"unexpectedTokenGeneric": "Unexpected token: {0}, at offset {1}",
|
||||
"unsupportedDataTypeForBinding": "Unsupported data type"
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
}(this));
|
||||
530
shared/html/libs/winjs/2.0/js/en-us/ui.strings.js
Normal file
@@ -0,0 +1,530 @@
|
||||
/// <loc filename="Metadata\ui.strings_loc_oam.xml" format="messagebundle" />
|
||||
/*!
|
||||
© Microsoft. All rights reserved.
|
||||
|
||||
This library is supported for use in Windows Store apps only.
|
||||
|
||||
Build: 1.0.9600.17018.winblue_gdr.140204-1946
|
||||
|
||||
Version: Microsoft.WinJS.2.0
|
||||
*/
|
||||
|
||||
(function (global) {
|
||||
global.strings = global.strings || {};
|
||||
|
||||
var appxVersion = "Microsoft.WinJS.2.0";
|
||||
var developerPrefix = "Developer.";
|
||||
if (appxVersion.indexOf(developerPrefix) === 0) {
|
||||
appxVersion = appxVersion.substring(developerPrefix.length);
|
||||
}
|
||||
|
||||
function addStrings(keyPrefix, strings) {
|
||||
Object.keys(strings).forEach(function (key) {
|
||||
global.strings[keyPrefix + key.replace("\\", "/")] = strings[key];
|
||||
});
|
||||
}
|
||||
|
||||
addStrings(
|
||||
"ms-resource://"+appxVersion+"/ui/",
|
||||
|
||||
{
|
||||
"appBarAriaLabel": "App Bar",
|
||||
"appBarCommandAriaLabel": "App Bar Item",
|
||||
"asynchronousRender" : "Top level items must render synchronously",
|
||||
"automaticallyLoadPagesIsDeprecated": "Invalid configuration: automaticallyLoadPages is deprecated. The control will default this property to false. Please refer to the 'ListView loading behaviors' SDK Sample for guidance on how to implement incremental load behavior.",
|
||||
"averageRating": "Average Rating",
|
||||
"backbuttonarialabel": "Back",
|
||||
"badAlignment": "Invalid argument: Flyout alignment should be 'center' (default), 'left', or 'right'.",
|
||||
"badAxis": "Invalid argument: orientation must be a string, either 'horizontal' or 'vertical'",
|
||||
"badButtonElement": "Invalid argument: For a button, toggle, or flyout command, the element must be null or a button element",
|
||||
"badClick": "Invalid argument: The onclick property for an {0} must be a function",
|
||||
"badCurrentPage": "Invalid argument: currentPage must be a number greater than or equal to zero and be within the bounds of the datasource",
|
||||
"badDivElement": "Invalid argument: For a content command, the element must be null or a div element",
|
||||
"badFlyout": "Invalid argument: The flyout property for an {0} must be a Flyout or String id of a Flyout",
|
||||
"badHrElement": "Invalid argument: For a separator, the element must be null or an hr element",
|
||||
"badItemSpacingAmount": "Invalid argument: itemSpacing must be a number greater than or equal to zero",
|
||||
"badLayout": "Invalid argument: The layout property must be 'custom' or 'commands'",
|
||||
"badPlacement": "Invalid argument: Flyout placement should be 'top' (default), 'bottom', 'left', 'right', or 'auto'.",
|
||||
"badReference": "Invalid argument: Invalid href to settings flyout fragment",
|
||||
"cannotChangeCommandsWhenVisible": "Invalid argument: You must call hide() before changing {0} commands",
|
||||
"cannotChangeHiddenProperty": "Unable to set hidden property while parent {0} is visible.",
|
||||
"cannotChangeLayoutWhenVisible": "Invalid argument: The layout property cannot be set when the AppBar is visible, call hide() first",
|
||||
"cannotChangePlacementWhenVisible": "Invalid argument: The placement property cannot be set when the AppBar is visible, call hide() first",
|
||||
"clearYourRating" : "Clear your rating",
|
||||
"closeOverlay" : "Close",
|
||||
"datePicker": "Date Picker",
|
||||
"disableBackdropIsDeprecated" : "Invalid configuration: disableBackdrop is deprecated. Style: .win-listview .win-container.win-backdrop { background-color:transparent; } instead.",
|
||||
"duplicateConstruction": "Invalid argument: Controls may only be instantiated one time for each DOM element",
|
||||
"duplicateSection": "Hub duplicate sections: Each HubSection must be unique",
|
||||
"backdropColorIsDeprecated" : "Invalid configuration: backdropColor is deprecated. Style: .win-listview .win-container.win-backdrop { rgba(155,155,155,0.23); } instead.",
|
||||
"flipViewNavigationDuringStateChange": "Error: After changing itemDataSource or itemTemplate, any navigation in the FlipView control should be delayed until the pageselected event is fired.",
|
||||
"flipViewPanningContainerAriaLabel": "Scrolling Container",
|
||||
"flyoutAriaLabel": "Flyout",
|
||||
"groupInfoIsDeprecated": "GridLayout.groupInfo may be altered or unavailable in future versions. Instead, use CellSpanningLayout.",
|
||||
"groupInfoResultIsInvalid": "Invalid result: groupInfo result for cell spanning groups must include the following numeric properties: cellWidth and cellHeight.",
|
||||
"hubViewportAriaLabel": "Scrolling Container",
|
||||
"indexIsInvalid": "Invalid argument: index must be a non-negative integer.",
|
||||
"invalidHubContent": "Invalid content: Hub content must be made up of HubSections.",
|
||||
"invalidCountReturned": "Error: data adapter should return undefined, null, CountResult.unknown, or a non-negative integer for the count.",
|
||||
"invalidIndexReturned": "Error: data adapter should return undefined, null or a non-negative integer for the index.",
|
||||
"invalidItemReturned": "Error: data adapter returned item that is not an object.",
|
||||
"invalidItemsManagerCallback": "Invalid argument: {0} must be a function.",
|
||||
"invalidKeyReturned": "Error: data adapter returned item with undefined or null key.",
|
||||
"invalidSearchBoxSuggestionKind": "Error: Invalid search suggestion kind.",
|
||||
"invalidTemplate": "Invalid template: Templates must be created before being passed to the ListView, and must contain a valid tree of elements.",
|
||||
"invalidViewBoxChildren": "ViewBox expects to only have one child element",
|
||||
"invalidZoomFactor": "Invalid zoomFactor",
|
||||
"invalidRequestedCountReturned": "Error: data adapter should return CountResult.unknown, CountResult.failure, or a non-negative integer for the count.",
|
||||
"itemInfoIsDeprecated": "GridLayout.itemInfo may be altered or unavailable in future versions. Instead, use CellSpanningLayout.",
|
||||
"itemInfoIsInvalid": "Invalid argument: An itemInfo function must be provided which returns an object with numeric width and height properties.",
|
||||
"itemIsInvalid": "Invalid argument: item must be a DOM element that was returned by the Items Manager, and has not been replaced or released.",
|
||||
"itemRendererIsInvalid": "Invalid argument: itemRenderer must be a function.",
|
||||
"keyIsInvalid": "Invalid argument: key must be a string.",
|
||||
"listDataAdapterIsInvalid": "Invalid argument: listDataAdapter must be an object or an array.",
|
||||
"listDataSourceIsInvalid": "Invalid argument: dataSource must be an object.",
|
||||
"listViewInvalidItem": "Item must provide index, key or description of corresponding item.",
|
||||
"listViewViewportAriaLabel": "Scrolling Container",
|
||||
"loadingBehaviorIsDeprecated": "Invalid configuration: loadingBehavior is deprecated. The control will default this property to 'randomAccess'. Please refer to the 'ListView loading behaviors' SDK Sample for guidance on how to implement incremental load behavior.",
|
||||
"maxRowsIsDeprecated": "GridLayout.maxRows may be altered or unavailable in future versions. Instead, use the maximumRowsOrColumns property.",
|
||||
"menuCommandAriaLabel": "Menu Item",
|
||||
"menuAriaLabel": "Menu",
|
||||
"modeIsInvalid": "Invalid argument: mode must be one of following values: 'none', 'single' or 'multi'.",
|
||||
"mustContainCommands": "Invalid HTML: AppBars/Menus must contain only AppBarCommands/MenuCommands",
|
||||
"navBarContainerViewportAriaLabel": "Scrolling Container",
|
||||
"noAnchor": "Invalid argument: Showing flyout requires a DOM element as its parameter.",
|
||||
"noitemsManagerForCount": "Invalid operation: can't get count if no dataSource has been set",
|
||||
"notCompatibleWithSemanticZoom": "ListView can only be used with SemanticZoom if randomAccess loading behavior is specified.",
|
||||
"nullCommand": "Invalid argument: command must not be null",
|
||||
"off" : "Off",
|
||||
"on" : "On",
|
||||
"loadMorePagesIsDeprecated": "loadMorePages is deprecated. Invoking this function will not have any effect. Please refer to the 'ListView loading behaviors' SDK Sample for guidance on how to implement incremental load behavior.",
|
||||
"pagesToLoadIsDeprecated": "Invalid configuration: pagesToLoad is deprecated. The control will not use this property. Please refer to the 'ListView loading behaviors' SDK Sample for guidance on how to implement incremental load behavior.",
|
||||
"pagesToLoadThresholdIsDeprecated": "Invalid configuration: pagesToLoadThreshold is deprecated. The control will not use this property. Please refer to the 'ListView loading behaviors' SDK Sample for guidance on how to implement incremental load behavior.",
|
||||
"refreshCycleIdentified": "refresh cycle found, likely data inconsistency",
|
||||
"requiresCommands": "Invalid argument: commands must not be empty",
|
||||
"repeaterReentrancy":"Cannot modify Repeater data until Repeater has commited previous modification.",
|
||||
"resetGroupHeaderIsDeprecated": "resetGroupHeader may be altered or unavailable in future versions. Instead, mark the header element as disposable using WinJS.Utilities.markDisposable.",
|
||||
"resetItemIsDeprecated": "resetItem may be altered or unavailable in future versions. Instead, mark the element as disposable using WinJS.Utilities.markDisposable.",
|
||||
"searchBoxAriaLabel": "Searchbox",
|
||||
"searchBoxAriaLabelInputNoPlaceHolder": "Searchbox, enter to submit query, esc to clear text",
|
||||
"searchBoxAriaLabelInputPlaceHolder": "Searchbox, {0}, enter to submit query, esc to clear text",
|
||||
"searchBoxAriaLabelButton": "Click to submit query",
|
||||
"searchBoxAriaLabelQuery": "Suggestion: {0}",
|
||||
"_searchBoxAriaLabelQuery.comment": "Suggestion: query text (example: Suggestion: contoso)",
|
||||
"searchBoxAriaLabelSeparator": "Separator: {0}",
|
||||
"_searchBoxAriaLabelSeparator.comment": "Separator: separator text (example: Separator: People or Separator: Apps)",
|
||||
"searchBoxAriaLabelResult": "Result: {0}, {1}",
|
||||
"_searchBoxAriaLabelResult.comment": "Result: text, detailed text (example: Result: contoso, www.contoso.com)",
|
||||
"selectAMPM": "Select A.M P.M",
|
||||
"selectDay": "Select Day",
|
||||
"selectHour": "Select Hour",
|
||||
"selectMinute": "Select Minute",
|
||||
"selectMonth": "Select Month",
|
||||
"selectYear": "Select Year",
|
||||
"settingsFlyoutAriaLabel": "Settings Flyout",
|
||||
"settingsFlyoutWidthIsDeprecated": "SettingsFlyout.width may be altered or unavailable in future versions. Instead, style the CSS width property on elements with the .win-settingsflyout class.",
|
||||
"tentativeRating": "Tentative Rating",
|
||||
"timePicker": "Time Picker",
|
||||
"tooltipStringsIsInvalid": "Invalid argument: tooltipStrings must be null or an array of strings.",
|
||||
"unrated": "Unrated",
|
||||
"userRating": "User Rating",
|
||||
// AppBar Icons follow, the format of the ui.js and ui.resjson differ for
|
||||
// the AppBarIcon namespace. The remainder of the file therefore differs.
|
||||
// Code point comments are the icon glyphs in the 'Segoe UI Symbol' font.
|
||||
"appBarIcons\\previous": "\uE100", // group:Media
|
||||
"_appBarIcons\\previous.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\next": "\uE101", // group:Media
|
||||
"_appBarIcons\\next.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\play": "\uE102", // group:Media
|
||||
"_appBarIcons\\play.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\pause": "\uE103", // group:Media
|
||||
"_appBarIcons\\pause.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\edit": "\uE104", // group:File
|
||||
"_appBarIcons\\edit.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\save": "\uE105", // group:File
|
||||
"_appBarIcons\\save.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\clear": "\uE106", // group:File
|
||||
"_appBarIcons\\clear.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\delete": "\uE107", // group:File
|
||||
"_appBarIcons\\delete.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\remove": "\uE108", // group:File
|
||||
"_appBarIcons\\remove.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\add": "\uE109", // group:File
|
||||
"_appBarIcons\\add.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\cancel": "\uE10A", // group:Editing
|
||||
"_appBarIcons\\cancel.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\accept": "\uE10B", // group:General
|
||||
"_appBarIcons\\accept.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\more": "\uE10C", // group:General
|
||||
"_appBarIcons\\more.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\redo": "\uE10D", // group:Editing
|
||||
"_appBarIcons\\redo.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\undo": "\uE10E", // group:Editing
|
||||
"_appBarIcons\\undo.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\home": "\uE10F", // group:General
|
||||
"_appBarIcons\\home.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\up": "\uE110", // group:General
|
||||
"_appBarIcons\\up.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\forward": "\uE111", // group:General
|
||||
"_appBarIcons\\forward.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\right": "\uE111", // group:General
|
||||
"_appBarIcons\\right.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\back": "\uE112", // group:General
|
||||
"_appBarIcons\\back.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\left": "\uE112", // group:General
|
||||
"_appBarIcons\\left.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\favorite": "\uE113", // group:Media
|
||||
"_appBarIcons\\favorite.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\camera": "\uE114", // group:System
|
||||
"_appBarIcons\\camera.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\settings": "\uE115", // group:System
|
||||
"_appBarIcons\\settings.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\video": "\uE116", // group:Media
|
||||
"_appBarIcons\\video.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\sync": "\uE117", // group:Media
|
||||
"_appBarIcons\\sync.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\download": "\uE118", // group:Media
|
||||
"_appBarIcons\\download.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\mail": "\uE119", // group:Mail and calendar
|
||||
"_appBarIcons\\mail.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\find": "\uE11A", // group:Data
|
||||
"_appBarIcons\\find.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\help": "\uE11B", // group:General
|
||||
"_appBarIcons\\help.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\upload": "\uE11C", // group:Media
|
||||
"_appBarIcons\\upload.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\emoji": "\uE11D", // group:Communications
|
||||
"_appBarIcons\\emoji.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\twopage": "\uE11E", // group:Layout
|
||||
"_appBarIcons\\twopage.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\leavechat": "\uE11F", // group:Communications
|
||||
"_appBarIcons\\leavechat.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\mailforward": "\uE120", // group:Mail and calendar
|
||||
"_appBarIcons\\mailforward.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\clock": "\uE121", // group:General
|
||||
"_appBarIcons\\clock.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\send": "\uE122", // group:Mail and calendar
|
||||
"_appBarIcons\\send.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\crop": "\uE123", // group:Editing
|
||||
"_appBarIcons\\crop.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\rotatecamera": "\uE124", // group:System
|
||||
"_appBarIcons\\rotatecamera.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\people": "\uE125", // group:Communications
|
||||
"_appBarIcons\\people.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\closepane": "\uE126", // group:Layout
|
||||
"_appBarIcons\\closepane.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\openpane": "\uE127", // group:Layout
|
||||
"_appBarIcons\\openpane.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\world": "\uE128", // group:General
|
||||
"_appBarIcons\\world.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\flag": "\uE129", // group:Mail and calendar
|
||||
"_appBarIcons\\flag.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\previewlink": "\uE12A", // group:General
|
||||
"_appBarIcons\\previewlink.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\globe": "\uE12B", // group:Communications
|
||||
"_appBarIcons\\globe.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\trim": "\uE12C", // group:Editing
|
||||
"_appBarIcons\\trim.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\attachcamera": "\uE12D", // group:System
|
||||
"_appBarIcons\\attachcamera.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\zoomin": "\uE12E", // group:Layout
|
||||
"_appBarIcons\\zoomin.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\bookmarks": "\uE12F", // group:Editing
|
||||
"_appBarIcons\\bookmarks.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\document": "\uE130", // group:File
|
||||
"_appBarIcons\\document.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\protecteddocument": "\uE131", // group:File
|
||||
"_appBarIcons\\protecteddocument.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\page": "\uE132", // group:Layout
|
||||
"_appBarIcons\\page.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\bullets": "\uE133", // group:Editing
|
||||
"_appBarIcons\\bullets.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\comment": "\uE134", // group:Communications
|
||||
"_appBarIcons\\comment.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\mail2": "\uE135", // group:Mail and calendar
|
||||
"_appBarIcons\\mail2.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\contactinfo": "\uE136", // group:Communications
|
||||
"_appBarIcons\\contactinfo.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\hangup": "\uE137", // group:Communications
|
||||
"_appBarIcons\\hangup.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\viewall": "\uE138", // group:Data
|
||||
"_appBarIcons\\viewall.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\mappin": "\uE139", // group:General
|
||||
"_appBarIcons\\mappin.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\phone": "\uE13A", // group:Communications
|
||||
"_appBarIcons\\phone.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\videochat": "\uE13B", // group:Communications
|
||||
"_appBarIcons\\videochat.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\switch": "\uE13C", // group:Communications
|
||||
"_appBarIcons\\switch.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\contact": "\uE13D", // group:Communications
|
||||
"_appBarIcons\\contact.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\rename": "\uE13E", // group:File
|
||||
"_appBarIcons\\rename.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\pin": "\uE141", // group:System
|
||||
"_appBarIcons\\pin.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\musicinfo": "\uE142", // group:Media
|
||||
"_appBarIcons\\musicinfo.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\go": "\uE143", // group:General
|
||||
"_appBarIcons\\go.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\keyboard": "\uE144", // group:System
|
||||
"_appBarIcons\\keyboard.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\dockleft": "\uE145", // group:Layout
|
||||
"_appBarIcons\\dockleft.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\dockright": "\uE146", // group:Layout
|
||||
"_appBarIcons\\dockright.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\dockbottom": "\uE147", // group:Layout
|
||||
"_appBarIcons\\dockbottom.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\remote": "\uE148", // group:System
|
||||
"_appBarIcons\\remote.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\refresh": "\uE149", // group:Data
|
||||
"_appBarIcons\\refresh.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\rotate": "\uE14A", // group:Layout
|
||||
"_appBarIcons\\rotate.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\shuffle": "\uE14B", // group:Media
|
||||
"_appBarIcons\\shuffle.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\list": "\uE14C", // group:Editing
|
||||
"_appBarIcons\\list.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\shop": "\uE14D", // group:General
|
||||
"_appBarIcons\\shop.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\selectall": "\uE14E", // group:Data
|
||||
"_appBarIcons\\selectall.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\orientation": "\uE14F", // group:Layout
|
||||
"_appBarIcons\\orientation.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\import": "\uE150", // group:Data
|
||||
"_appBarIcons\\import.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\importall": "\uE151", // group:Data
|
||||
"_appBarIcons\\importall.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\browsephotos": "\uE155", // group:Media
|
||||
"_appBarIcons\\browsephotos.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\webcam": "\uE156", // group:System
|
||||
"_appBarIcons\\webcam.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\pictures": "\uE158", // group:Media
|
||||
"_appBarIcons\\pictures.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\savelocal": "\uE159", // group:File
|
||||
"_appBarIcons\\savelocal.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\caption": "\uE15A", // group:Media
|
||||
"_appBarIcons\\caption.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\stop": "\uE15B", // group:Media
|
||||
"_appBarIcons\\stop.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\showresults": "\uE15C", // group:Data
|
||||
"_appBarIcons\\showresults.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\volume": "\uE15D", // group:Media
|
||||
"_appBarIcons\\volume.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\repair": "\uE15E", // group:System
|
||||
"_appBarIcons\\repair.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\message": "\uE15F", // group:Communications
|
||||
"_appBarIcons\\message.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\page2": "\uE160", // group:Layout
|
||||
"_appBarIcons\\page2.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\calendarday": "\uE161", // group:Mail and calendar
|
||||
"_appBarIcons\\calendarday.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\calendarweek": "\uE162", // group:Mail and calendar
|
||||
"_appBarIcons\\calendarweek.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\calendar": "\uE163", // group:Mail and calendar
|
||||
"_appBarIcons\\calendar.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\characters": "\uE164", // group:Editing
|
||||
"_appBarIcons\\characters.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\mailreplyall": "\uE165", // group:Mail and calendar
|
||||
"_appBarIcons\\mailreplyall.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\read": "\uE166", // group:Mail and calendar
|
||||
"_appBarIcons\\read.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\link": "\uE167", // group:Communications
|
||||
"_appBarIcons\\link.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\accounts": "\uE168", // group:Communications
|
||||
"_appBarIcons\\accounts.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\showbcc": "\uE169", // group:Mail and calendar
|
||||
"_appBarIcons\\showbcc.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\hidebcc": "\uE16A", // group:Mail and calendar
|
||||
"_appBarIcons\\hidebcc.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\cut": "\uE16B", // group:Editing
|
||||
"_appBarIcons\\cut.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\attach": "\uE16C", // group:Mail and calendar
|
||||
"_appBarIcons\\attach.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\paste": "\uE16D", // group:Editing
|
||||
"_appBarIcons\\paste.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\filter": "\uE16E", // group:Data
|
||||
"_appBarIcons\\filter.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\copy": "\uE16F", // group:Editing
|
||||
"_appBarIcons\\copy.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\emoji2": "\uE170", // group:Mail and calendar
|
||||
"_appBarIcons\\emoji2.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\important": "\uE171", // group:Mail and calendar
|
||||
"_appBarIcons\\important.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\mailreply": "\uE172", // group:Mail and calendar
|
||||
"_appBarIcons\\mailreply.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\slideshow": "\uE173", // group:Media
|
||||
"_appBarIcons\\slideshow.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\sort": "\uE174", // group:Data
|
||||
"_appBarIcons\\sort.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\manage": "\uE178", // group:System
|
||||
"_appBarIcons\\manage.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\allapps": "\uE179", // group:System
|
||||
"_appBarIcons\\allapps.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\disconnectdrive": "\uE17A", // group:System
|
||||
"_appBarIcons\\disconnectdrive.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\mapdrive": "\uE17B", // group:System
|
||||
"_appBarIcons\\mapdrive.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\newwindow": "\uE17C", // group:System
|
||||
"_appBarIcons\\newwindow.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\openwith": "\uE17D", // group:System
|
||||
"_appBarIcons\\openwith.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\contactpresence": "\uE181", // group:Communications
|
||||
"_appBarIcons\\contactpresence.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\priority": "\uE182", // group:Mail and calendar
|
||||
"_appBarIcons\\priority.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\uploadskydrive": "\uE183", // group:File
|
||||
"_appBarIcons\\uploadskydrive.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\gototoday": "\uE184", // group:Mail and calendar
|
||||
"_appBarIcons\\gototoday.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\font": "\uE185", // group:Editing
|
||||
"_appBarIcons\\font.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\fontcolor": "\uE186", // group:Editing
|
||||
"_appBarIcons\\fontcolor.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\contact2": "\uE187", // group:Communications
|
||||
"_appBarIcons\\contact2.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\folder": "\uE188", // group:File
|
||||
"_appBarIcons\\folder.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\audio": "\uE189", // group:Media
|
||||
"_appBarIcons\\audio.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\placeholder": "\uE18A", // group:General
|
||||
"_appBarIcons\\placeholder.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\view": "\uE18B", // group:Layout
|
||||
"_appBarIcons\\view.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\setlockscreen": "\uE18C", // group:System
|
||||
"_appBarIcons\\setlockscreen.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\settile": "\uE18D", // group:System
|
||||
"_appBarIcons\\settile.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\cc": "\uE190", // group:Media
|
||||
"_appBarIcons\\cc.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\stopslideshow": "\uE191", // group:Media
|
||||
"_appBarIcons\\stopslideshow.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\permissions": "\uE192", // group:System
|
||||
"_appBarIcons\\permissions.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\highlight": "\uE193", // group:Editing
|
||||
"_appBarIcons\\highlight.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\disableupdates": "\uE194", // group:System
|
||||
"_appBarIcons\\disableupdates.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\unfavorite": "\uE195", // group:Media
|
||||
"_appBarIcons\\unfavorite.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\unpin": "\uE196", // group:System
|
||||
"_appBarIcons\\unpin.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\openlocal": "\uE197", // group:File
|
||||
"_appBarIcons\\openlocal.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\mute": "\uE198", // group:Media
|
||||
"_appBarIcons\\mute.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\italic": "\uE199", // group:Editing
|
||||
"_appBarIcons\\italic.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\underline": "\uE19A", // group:Editing
|
||||
"_appBarIcons\\underline.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\bold": "\uE19B", // group:Editing
|
||||
"_appBarIcons\\bold.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\movetofolder": "\uE19C", // group:File
|
||||
"_appBarIcons\\movetofolder.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\likedislike": "\uE19D", // group:Data
|
||||
"_appBarIcons\\likedislike.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\dislike": "\uE19E", // group:Data
|
||||
"_appBarIcons\\dislike.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\like": "\uE19F", // group:Data
|
||||
"_appBarIcons\\like.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\alignright": "\uE1A0", // group:Editing
|
||||
"_appBarIcons\\alignright.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\aligncenter": "\uE1A1", // group:Editing
|
||||
"_appBarIcons\\aligncenter.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\alignleft": "\uE1A2", // group:Editing
|
||||
"_appBarIcons\\alignleft.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\zoom": "\uE1A3", // group:Layout
|
||||
"_appBarIcons\\zoom.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\zoomout": "\uE1A4", // group:Layout
|
||||
"_appBarIcons\\zoomout.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\openfile": "\uE1A5", // group:File
|
||||
"_appBarIcons\\openfile.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\otheruser": "\uE1A6", // group:System
|
||||
"_appBarIcons\\otheruser.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\admin": "\uE1A7", // group:System
|
||||
"_appBarIcons\\admin.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\street": "\uE1C3", // group:General
|
||||
"_appBarIcons\\street.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\map": "\uE1C4", // group:General
|
||||
"_appBarIcons\\map.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\clearselection": "\uE1C5", // group:Data
|
||||
"_appBarIcons\\clearselection.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\fontdecrease": "\uE1C6", // group:Editing
|
||||
"_appBarIcons\\fontdecrease.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\fontincrease": "\uE1C7", // group:Editing
|
||||
"_appBarIcons\\fontincrease.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\fontsize": "\uE1C8", // group:Editing
|
||||
"_appBarIcons\\fontsize.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\cellphone": "\uE1C9", // group:Communications
|
||||
"_appBarIcons\\cellphone.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\reshare": "\uE1CA", // group:Communications
|
||||
"_appBarIcons\\reshare.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\tag": "\uE1CB", // group:Data
|
||||
"_appBarIcons\\tag.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\repeatone": "\uE1CC", // group:Media
|
||||
"_appBarIcons\\repeatone.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\repeatall": "\uE1CD", // group:Media
|
||||
"_appBarIcons\\repeatall.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\outlinestar": "\uE1CE", // group:Data
|
||||
"_appBarIcons\\outlinestar.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\solidstar": "\uE1CF", // group:Data
|
||||
"_appBarIcons\\solidstar.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\calculator": "\uE1D0", // group:General
|
||||
"_appBarIcons\\calculator.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\directions": "\uE1D1", // group:General
|
||||
"_appBarIcons\\directions.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\target": "\uE1D2", // group:General
|
||||
"_appBarIcons\\target.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\library": "\uE1D3", // group:Media
|
||||
"_appBarIcons\\library.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\phonebook": "\uE1D4", // group:Communications
|
||||
"_appBarIcons\\phonebook.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\memo": "\uE1D5", // group:Communications
|
||||
"_appBarIcons\\memo.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\microphone": "\uE1D6", // group:System
|
||||
"_appBarIcons\\microphone.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\postupdate": "\uE1D7", // group:Communications
|
||||
"_appBarIcons\\postupdate.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\backtowindow": "\uE1D8", // group:Layout
|
||||
"_appBarIcons\\backtowindow.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\fullscreen": "\uE1D9", // group:Layout
|
||||
"_appBarIcons\\fullscreen.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\newfolder": "\uE1DA", // group:File
|
||||
"_appBarIcons\\newfolder.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\calendarreply": "\uE1DB", // group:Mail and calendar
|
||||
"_appBarIcons\\calendarreply.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\unsyncfolder": "\uE1DD", // group:File
|
||||
"_appBarIcons\\unsyncfolder.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\reporthacked": "\uE1DE", // group:Communications
|
||||
"_appBarIcons\\reporthacked.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\syncfolder": "\uE1DF", // group:File
|
||||
"_appBarIcons\\syncfolder.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\blockcontact": "\uE1E0", // group:Communications
|
||||
"_appBarIcons\\blockcontact.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\switchapps": "\uE1E1", // group:System
|
||||
"_appBarIcons\\switchapps.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\addfriend": "\uE1E2", // group:Communications
|
||||
"_appBarIcons\\addfriend.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\touchpointer": "\uE1E3", // group:System
|
||||
"_appBarIcons\\touchpointer.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\gotostart": "\uE1E4", // group:System
|
||||
"_appBarIcons\\gotostart.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\zerobars": "\uE1E5", // group:System
|
||||
"_appBarIcons\\zerobars.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\onebar": "\uE1E6", // group:System
|
||||
"_appBarIcons\\onebar.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\twobars": "\uE1E7", // group:System
|
||||
"_appBarIcons\\twobars.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\threebars": "\uE1E8", // group:System
|
||||
"_appBarIcons\\threebars.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\fourbars": "\uE1E9", // group:System
|
||||
"_appBarIcons\\fourbars.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\scan": "\uE294", // group:General
|
||||
"_appBarIcons\\scan.comment": "{Locked:qps-ploc,qps-plocm}",
|
||||
"appBarIcons\\preview": "\uE295", // group:General
|
||||
"_appBarIcons\\preview.comment": "{Locked:qps-ploc,qps-plocm}"
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
}(this));
|
||||