mirror of
https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git
synced 2026-04-11 17:57:19 +10:00
Updated manager and added appx manifest reader.
This commit is contained in:
@@ -61,6 +61,9 @@ EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WAShell", "WAShell\WAShell.csproj", "{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Manager", "Manager\Manager.csproj", "{DC074727-72E4-43C5-BAAF-E0D548104797}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{3AE2A022-ED83-41F1-948A-12A7593CBD00} = {3AE2A022-ED83-41F1-948A-12A7593CBD00}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IEHelper", "IEHelper\IEHelper.vcxproj", "{E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}"
|
||||
EndProject
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DataInterface.cs" />
|
||||
<Compile Include="ManifestReader.cs" />
|
||||
<Compile Include="PackageManager.cs" />
|
||||
<Compile Include="PackageReader.cs" />
|
||||
<Compile Include="PkgMgrNative.cs" />
|
||||
|
||||
1000
AppxPackage/ManifestReader.cs
Normal file
1000
AppxPackage/ManifestReader.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -77,7 +77,8 @@ namespace AppxPackage
|
||||
private string familyName = "";
|
||||
private string fullName = "";
|
||||
private string resourceId = "";
|
||||
public PMIdentity (string _name, string _publisher, DataUtils.Version _ver, IEnumerable<Architecture> _archs, string _family, string _full, string _resid)
|
||||
private string publisherId = "";
|
||||
public PMIdentity (string _name, string _publisher, DataUtils.Version _ver, IEnumerable<Architecture> _archs, string _family, string _full, string _resid, string _publisherId)
|
||||
{
|
||||
name = _name;
|
||||
publisher = _publisher;
|
||||
@@ -86,6 +87,7 @@ namespace AppxPackage
|
||||
familyName = _family;
|
||||
fullName = _full;
|
||||
resourceId = _resid;
|
||||
publisherId = _publisherId;
|
||||
}
|
||||
public PMIdentity (PackageManageHelper.FIND_PACKAGE_ID pkgId) :
|
||||
this (
|
||||
@@ -95,7 +97,8 @@ namespace AppxPackage
|
||||
new Architecture [] { (Architecture)pkgId.wProcessArchitecture },
|
||||
Marshal.PtrToStringUni (pkgId.lpFamilyName),
|
||||
Marshal.PtrToStringUni (pkgId.lpFullName),
|
||||
Marshal.PtrToStringUni (pkgId.lpResourceId)
|
||||
Marshal.PtrToStringUni (pkgId.lpResourceId),
|
||||
Marshal.PtrToStringUni (pkgId.lpPublisherId)
|
||||
)
|
||||
{ }
|
||||
public string FamilyName => familyName;
|
||||
@@ -103,8 +106,9 @@ namespace AppxPackage
|
||||
public string Name => name;
|
||||
public List<Architecture> ProcessArchitecture => archs.ToList ();
|
||||
public string Publisher => publisher;
|
||||
public string PublisherId => publisherId;
|
||||
public string ResourceId => resourceId;
|
||||
DataUtils.Version IIdentity.Version => version;
|
||||
public DataUtils.Version Version => version;
|
||||
}
|
||||
[ComVisible (true)]
|
||||
[ClassInterface (ClassInterfaceType.AutoDual)]
|
||||
|
||||
@@ -104,10 +104,10 @@ namespace AppxPackage
|
||||
[ClassInterface (ClassInterfaceType.AutoDual)]
|
||||
public class BaseInfoSectWithPRI: BaseInfoSection
|
||||
{
|
||||
protected Ref<PackageReader> m_reader = null;
|
||||
protected Ref<PriReaderBundle> m_priBundle = null;
|
||||
protected Ref<bool> m_usePri = false;
|
||||
protected Ref<bool> m_enablePri = false;
|
||||
protected Ref<PackageReader> m_reader = new Ref<PackageReader> (null);
|
||||
protected Ref<PriReaderBundle> m_priBundle = new Ref<PriReaderBundle> (null);
|
||||
protected Ref<bool> m_usePri = new Ref<bool> (false);
|
||||
protected Ref<bool> m_enablePri = new Ref<bool> (false);
|
||||
public BaseInfoSectWithPRI (ref IntPtr hReader, PackageReader reader, ref PriReaderBundle priBundle, ref bool usePri, ref bool enablePri) : base (ref hReader)
|
||||
{
|
||||
m_reader.Set (reader);
|
||||
@@ -1168,7 +1168,7 @@ namespace AppxPackage
|
||||
public PackageReader (string filePath) { FilePath = filePath; }
|
||||
public PackageReader () { }
|
||||
public string JSONText { get { return BuildJsonText (); } }
|
||||
private string BuildJsonText ()
|
||||
public string BuildJsonText ()
|
||||
{
|
||||
var obj = BuildJsonObject ();
|
||||
return Newtonsoft.Json.JsonConvert.SerializeObject (
|
||||
|
||||
@@ -210,7 +210,8 @@ namespace NativeWrappers
|
||||
string s = Marshal.PtrToStringUni (nativePtr);
|
||||
try
|
||||
{
|
||||
crt_free (nativePtr);
|
||||
PackageReaderFreeString (nativePtr);
|
||||
nativePtr = IntPtr.Zero;
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -303,5 +304,103 @@ namespace NativeWrappers
|
||||
{
|
||||
}
|
||||
}
|
||||
// ================= Manifest Reader =================
|
||||
|
||||
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
|
||||
public static extern IntPtr CreateManifestReader ();
|
||||
|
||||
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
|
||||
[return: MarshalAs (UnmanagedType.Bool)]
|
||||
public static extern bool LoadManifestFromFile (
|
||||
IntPtr hReader,
|
||||
string lpFilePath
|
||||
);
|
||||
|
||||
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
|
||||
public static extern void DestroyManifestReader (IntPtr hReader);
|
||||
|
||||
[DllImport (DllName, CallingConvention = CallConv)]
|
||||
public static extern ushort GetManifestType (IntPtr hReader);
|
||||
|
||||
[DllImport (DllName, CallingConvention = CallConv)]
|
||||
[return: MarshalAs (UnmanagedType.Bool)]
|
||||
public static extern bool IsManifestValid (IntPtr hReader);
|
||||
|
||||
[DllImport (DllName, CallingConvention = CallConv)]
|
||||
public static extern ushort GetManifestRole (IntPtr hReader);
|
||||
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
|
||||
public static extern IntPtr GetManifestIdentityStringValue (
|
||||
IntPtr hReader,
|
||||
uint dwName
|
||||
);
|
||||
|
||||
[DllImport (DllName, CallingConvention = CallConv)]
|
||||
[return: MarshalAs (UnmanagedType.Bool)]
|
||||
public static extern bool GetManifestIdentityVersion (
|
||||
IntPtr hReader,
|
||||
out VERSION pVersion
|
||||
);
|
||||
|
||||
[DllImport (DllName, CallingConvention = CallConv)]
|
||||
[return: MarshalAs (UnmanagedType.Bool)]
|
||||
public static extern bool GetManifestIdentityArchitecture (
|
||||
IntPtr hReader,
|
||||
out DWORD pdwArchi
|
||||
);
|
||||
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
|
||||
public static extern IntPtr GetManifestPropertiesStringValue (
|
||||
IntPtr hReader,
|
||||
string lpName
|
||||
);
|
||||
|
||||
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
|
||||
public static extern HRESULT GetManifestPropertiesBoolValue (
|
||||
IntPtr hReader,
|
||||
string lpName,
|
||||
out BOOL pRet
|
||||
);
|
||||
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
|
||||
[return: MarshalAs (UnmanagedType.Bool)]
|
||||
public static extern bool AddManifestApplicationItemGetName (string lpName);
|
||||
|
||||
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
|
||||
[return: MarshalAs (UnmanagedType.Bool)]
|
||||
public static extern bool RemoveManifestApplicationItemGetName (string lpName);
|
||||
|
||||
[DllImport (DllName, CallingConvention = CallConv)]
|
||||
public static extern IntPtr GetManifestApplications (IntPtr hReader);
|
||||
|
||||
[DllImport (DllName, CallingConvention = CallConv)]
|
||||
public static extern void DestroyManifestApplications (IntPtr hEnumerator);
|
||||
[DllImport (DllName, CallingConvention = CallConv)]
|
||||
public static extern IntPtr GetManifestResourcesLanguages (IntPtr hReader);
|
||||
|
||||
[DllImport (DllName, CallingConvention = CallConv)]
|
||||
public static extern IntPtr GetManifestResourcesLanguagesToLcid (IntPtr hReader);
|
||||
|
||||
[DllImport (DllName, CallingConvention = CallConv)]
|
||||
public static extern IntPtr GetManifestResourcesScales (IntPtr hReader);
|
||||
|
||||
[DllImport (DllName, CallingConvention = CallConv)]
|
||||
public static extern DWORD GetManifestResourcesDxFeatureLevels (IntPtr hReader);
|
||||
[DllImport (DllName, CallingConvention = CallConv)]
|
||||
public static extern IntPtr GetManifestDependencesInfoList (IntPtr hReader);
|
||||
|
||||
[DllImport (DllName, CallingConvention = CallConv)]
|
||||
public static extern IntPtr GetManifestCapabilitiesList (IntPtr hReader);
|
||||
|
||||
[DllImport (DllName, CallingConvention = CallConv)]
|
||||
public static extern IntPtr GetManifestDeviceCapabilitiesList (IntPtr hReader);
|
||||
|
||||
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
|
||||
[return: MarshalAs (UnmanagedType.Bool)]
|
||||
public static extern bool GetManifestPrerequisite (
|
||||
IntPtr hReader,
|
||||
string lpName,
|
||||
out VERSION pVerRet
|
||||
);
|
||||
[DllImport (DllName, CallingConvention = CallConv)]
|
||||
public static extern void PackageReaderFreeString (IntPtr p);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -57,11 +57,13 @@ namespace AppxPackage
|
||||
[DllImport (DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
[return: MarshalAs (UnmanagedType.Bool)]
|
||||
public static extern bool IsMsResourceUri ([MarshalAs (UnmanagedType.LPWStr)] string pResUri);
|
||||
[DllImport (DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void PriFormatFreeString (IntPtr ptr);
|
||||
public static string PtrToString (IntPtr ptr)
|
||||
{
|
||||
if (ptr == IntPtr.Zero) return null;
|
||||
string s = Marshal.PtrToStringUni (ptr);
|
||||
Marshal.FreeHGlobal (ptr); // 如果 DLL 返回的内存要求 free
|
||||
PriFormatFreeString (ptr); // 如果 DLL 返回的内存要求 free
|
||||
return s;
|
||||
}
|
||||
[DllImport (DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
|
||||
@@ -496,6 +496,8 @@ namespace Bridge
|
||||
{
|
||||
public AppxPackage.PackageReader Reader (string packagePath) { return new AppxPackage.PackageReader (packagePath); }
|
||||
public _I_PackageManager Manager => new _I_PackageManager ();
|
||||
public AppxPackage.ManifestReader Manifest (string manifestPath) { return new AppxPackage.ManifestReader (manifestPath); }
|
||||
public AppxPackage.ManifestReader FromInstallLocation (string installLocation) { return Manifest (Path.Combine (installLocation, "AppxManifest.xml")); }
|
||||
}
|
||||
[ComVisible (true)]
|
||||
[ClassInterface (ClassInterfaceType.AutoDual)]
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
|
||||
|
||||
namespace DataUtils
|
||||
{
|
||||
internal static class VisualElementsStore
|
||||
public static class VisualElementsStore
|
||||
{
|
||||
// Publicly accessible instances for internal use
|
||||
public static readonly VisualElementManifest Vemanifest;
|
||||
|
||||
@@ -186,17 +186,6 @@ namespace DataUtils
|
||||
if (string.IsNullOrWhiteSpace (colorStr)) return Color.Transparent;
|
||||
string s = colorStr.Trim ();
|
||||
|
||||
// Named color
|
||||
try
|
||||
{
|
||||
Color byName = Color.FromName (s);
|
||||
if (byName.IsKnownColor || byName.IsNamedColor)
|
||||
{
|
||||
return byName;
|
||||
}
|
||||
}
|
||||
catch { /* ignore */ }
|
||||
|
||||
// Hex: #RGB, #RRGGBB, #AARRGGBB
|
||||
if (s.StartsWith ("#"))
|
||||
{
|
||||
@@ -321,6 +310,17 @@ namespace DataUtils
|
||||
}
|
||||
}
|
||||
|
||||
// Named color
|
||||
try
|
||||
{
|
||||
Color byName = Color.FromName (s);
|
||||
if (byName.IsKnownColor || byName.IsNamedColor)
|
||||
{
|
||||
return byName;
|
||||
}
|
||||
}
|
||||
catch { /* ignore */ }
|
||||
|
||||
// fallback: try parse as known color again (case-insensitive)
|
||||
try
|
||||
{
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
<Compile Include="ManagerShell.Designer.cs">
|
||||
<DependentUpon>ManagerShell.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Polyfill.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="ManagerShell.resx">
|
||||
@@ -66,6 +67,7 @@
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<None Include="app.manifest" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
|
||||
1
Manager/ManagerShell.Designer.cs
generated
1
Manager/ManagerShell.Designer.cs
generated
@@ -40,6 +40,7 @@
|
||||
this.PageScale = 125;
|
||||
this.Text = "Form1";
|
||||
this.Load += new System.EventHandler(this.ManagerShell_Load);
|
||||
this.Resize += new System.EventHandler(this.ManagerShell_Resize);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
@@ -14,12 +14,82 @@ namespace Manager
|
||||
public ManagerShell ()
|
||||
{
|
||||
InitializeComponent ();
|
||||
SplashScreen.SplashBackgroundColor = Color.Honeydew;
|
||||
try
|
||||
{
|
||||
var relativePath = DataUtils.VisualElementsStore.Vemanifest.SplashScreenImage (Program.g_appId);
|
||||
var img = Image.FromFile (relativePath);
|
||||
SplashScreen.SplashImage = img;
|
||||
} catch (Exception e) {
|
||||
var ex = e;
|
||||
}
|
||||
try
|
||||
{
|
||||
SplashScreen.SplashBackgroundColor = DataUtils.UITheme.StringToColor (DataUtils.VisualElementsStore.Vemanifest.SplashScreenBackgroundColor (Program.g_appId));
|
||||
}
|
||||
catch { }
|
||||
InitSize ();
|
||||
}
|
||||
private void InitSize ()
|
||||
{
|
||||
uint ww = 0, wh = 0;
|
||||
var ini = Bridge.InitFileStore.Config;
|
||||
var setsect = ini ["Settings"];
|
||||
var savepos = setsect.GetKey ("PackageManager:SavePosAndSizeBeforeCancel");
|
||||
var lastw = setsect.GetKey ("PackageManager:LastWidth");
|
||||
var lasth = setsect.GetKey ("PackageManager:LastHeight");
|
||||
var defw = setsect.GetKey ("PackageManager:DefaultWidth");
|
||||
var defh = setsect.GetKey ("PackageManager:DefaultHeight");
|
||||
var minw = setsect.GetKey ("PackageManager:MinimumWidth");
|
||||
var minh = setsect.GetKey ("PackageManager:MinimumHeight");
|
||||
var lasts = setsect.GetKey ("PackageManager:LastWndState");
|
||||
if (savepos.ReadBool ())
|
||||
{
|
||||
ww = lastw.ReadUInt (defw.ReadUInt (Properties.Resources.IDS_DEFAULTWIDTH.ParseTo <uint> ()));
|
||||
wh = lasth.ReadUInt (defh.ReadUInt (Properties.Resources.IDS_DEFAULTHEIGHT.ParseTo <uint> ()));
|
||||
}
|
||||
else
|
||||
{
|
||||
ww = defw.ReadUInt (Properties.Resources.IDS_DEFAULTWIDTH.ParseTo<uint> ());
|
||||
wh = defh.ReadUInt (Properties.Resources.IDS_DEFAULTHEIGHT.ParseTo<uint> ());
|
||||
}
|
||||
ClientSize = new Size ((int)(ww * DataUtils.UITheme.DPIDouble), (int)(wh * DataUtils.UITheme.DPIDouble));
|
||||
int hborder = Size.Width - ClientSize.Width,
|
||||
vborder = Size.Height - ClientSize.Height;
|
||||
MinimumSize = new Size (
|
||||
(int)(minw.ReadUInt (Properties.Resources.IDS_MINWIDTH.ParseTo <uint> ()) * DataUtils.UITheme.DPIDouble) + hborder,
|
||||
(int)(minh.ReadUInt (Properties.Resources.IDS_MINHEIGHT.ParseTo <uint> ()) * DataUtils.UITheme.DPIDouble) + vborder
|
||||
);
|
||||
WindowState = (FormWindowState)lasts.ReadInt ((int)FormWindowState.Normal);
|
||||
}
|
||||
private void ManagerShell_Load (object sender, EventArgs e)
|
||||
{
|
||||
var root = Path.GetDirectoryName (DataUtils.Utilities.GetCurrentProgramPath ());
|
||||
WebUI.Navigate (Path.Combine (root, "html\\manager.html"));
|
||||
var pkg = new AppxPackage.PackageReader (@"F:\新建文件夹 (2)\9E2F88E3.Twitter_1.1.13.8_x86__wgeqdkkx372wm.appx");
|
||||
pkg.EnablePri = true;
|
||||
pkg.UsePri = true;
|
||||
var displayName = pkg.Properties.LogoBase64;
|
||||
}
|
||||
private void ManagerShell_Resize (object sender, EventArgs e)
|
||||
{
|
||||
var ini = Bridge.InitFileStore.Config;
|
||||
var setsect = ini ["Settings"];
|
||||
var savepos = setsect.GetKey ("PackageManager:SavePosAndSizeBeforeCancel");
|
||||
var lastw = setsect.GetKey ("PackageManager:LastWidth");
|
||||
var lasth = setsect.GetKey ("PackageManager:LastHeight");
|
||||
var lasts = setsect.GetKey ("PackageManager:LastWndState");
|
||||
switch (WindowState)
|
||||
{
|
||||
case FormWindowState.Normal:
|
||||
case FormWindowState.Maximized:
|
||||
lasts.Write ((int)WindowState);
|
||||
break;
|
||||
}
|
||||
if (WindowState == FormWindowState.Normal && savepos.ReadBool ())
|
||||
{
|
||||
lastw.Write ((int)(ClientSize.Width / DataUtils.UITheme.DPIDouble));
|
||||
lasth.Write ((int)(ClientSize.Height / DataUtils.UITheme.DPIDouble));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
40
Manager/Polyfill.cs
Normal file
40
Manager/Polyfill.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Manager
|
||||
{
|
||||
public static class Polyfill
|
||||
{
|
||||
public static T ParseTo <T> (this string src, T dflt = default (T))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace (src)) return dflt;
|
||||
try
|
||||
{
|
||||
Type targetType = typeof (T);
|
||||
Type underlying = Nullable.GetUnderlyingType (targetType);
|
||||
if (underlying != null)
|
||||
{
|
||||
object v = Convert.ChangeType (src, underlying, CultureInfo.InvariantCulture);
|
||||
return (T)v;
|
||||
}
|
||||
if (targetType.IsEnum)
|
||||
{
|
||||
object enumValue = Enum.Parse (targetType, src, true);
|
||||
return (T)enumValue;
|
||||
}
|
||||
TypeConverter converter = TypeDescriptor.GetConverter (targetType);
|
||||
if (converter != null && converter.CanConvertFrom (typeof (string)))
|
||||
{
|
||||
object v = converter.ConvertFrom (null, CultureInfo.InvariantCulture, src);
|
||||
return (T)v;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
return dflt;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@ namespace Manager
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
static public readonly string g_appUserId = "WindowsModern.PracticalToolsProject!Manager";
|
||||
static public readonly string g_appId = "Manager";
|
||||
/// <summary>
|
||||
/// 应用程序的主入口点。
|
||||
/// </summary>
|
||||
|
||||
154
Manager/Properties/Resources.Designer.cs
generated
154
Manager/Properties/Resources.Designer.cs
generated
@@ -1,71 +1,99 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本: 4.0.30319.42000
|
||||
// 运行时版本:4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能导致不正确的行为,如果
|
||||
// 重新生成代码,则所做更改将丢失。
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Manager.Properties
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 强类型资源类,用于查找本地化字符串等。
|
||||
/// </summary>
|
||||
// 此类是由 StronglyTypedResourceBuilder
|
||||
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
|
||||
// 若要添加或删除成员,请编辑 .ResX 文件,然后重新运行 ResGen
|
||||
// (以 /str 作为命令选项),或重新生成 VS 项目。
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute ("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute ()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute ()]
|
||||
internal class Resources
|
||||
{
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute ("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources ()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回此类使用的缓存 ResourceManager 实例。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute (global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((resourceMan == null))
|
||||
{
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager ("Manager.Properties.Resources", typeof (Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 覆盖当前线程的 CurrentUICulture 属性
|
||||
/// 使用此强类型的资源类的资源查找。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute (global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
return resourceCulture;
|
||||
}
|
||||
set
|
||||
{
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Manager.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 一个强类型的资源类,用于查找本地化的字符串等。
|
||||
/// </summary>
|
||||
// 此类是由 StronglyTypedResourceBuilder
|
||||
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
|
||||
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
|
||||
// (以 /str 作为命令选项),或重新生成 VS 项目。
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回此类使用的缓存的 ResourceManager 实例。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Manager.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用此强类型资源类,为所有资源查找
|
||||
/// 重写当前线程的 CurrentUICulture 属性。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 600 的本地化字符串。
|
||||
/// </summary>
|
||||
internal static string IDS_DEFAULTHEIGHT {
|
||||
get {
|
||||
return ResourceManager.GetString("IDS_DEFAULTHEIGHT", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 800 的本地化字符串。
|
||||
/// </summary>
|
||||
internal static string IDS_DEFAULTWIDTH {
|
||||
get {
|
||||
return ResourceManager.GetString("IDS_DEFAULTWIDTH", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 412 的本地化字符串。
|
||||
/// </summary>
|
||||
internal static string IDS_MINHEIGHT {
|
||||
get {
|
||||
return ResourceManager.GetString("IDS_MINHEIGHT", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 504 的本地化字符串。
|
||||
/// </summary>
|
||||
internal static string IDS_MINWIDTH {
|
||||
get {
|
||||
return ResourceManager.GetString("IDS_MINWIDTH", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
@@ -60,6 +60,7 @@
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
@@ -68,9 +69,10 @@
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
@@ -85,9 +87,10 @@
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
@@ -109,9 +112,25 @@
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="IDS_DEFAULTHEIGHT" xml:space="preserve">
|
||||
<value>600</value>
|
||||
<comment>默认窗口高度</comment>
|
||||
</data>
|
||||
<data name="IDS_DEFAULTWIDTH" xml:space="preserve">
|
||||
<value>800</value>
|
||||
<comment>默认窗口宽度</comment>
|
||||
</data>
|
||||
<data name="IDS_MINHEIGHT" xml:space="preserve">
|
||||
<value>412</value>
|
||||
<comment>默认最小窗口高度</comment>
|
||||
</data>
|
||||
<data name="IDS_MINWIDTH" xml:space="preserve">
|
||||
<value>504</value>
|
||||
<comment>默认最小窗口宽度</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -8,16 +8,16 @@
|
||||
如果想要更改 Windows 用户帐户控制级别,请使用
|
||||
以下节点之一替换 requestedExecutionLevel 节点。n
|
||||
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" /> -->
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
|
||||
<!-- <requestedExecutionLevel level="highestAvailable" uiAccess="false" />
|
||||
|
||||
指定 requestedExecutionLevel 元素将禁用文件和注册表虚拟化。
|
||||
如果你的应用程序需要此虚拟化来实现向后兼容性,则删除此
|
||||
元素。
|
||||
|
||||
-->
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
<!-- <requestedExecutionLevel level="asInvoker" uiAccess="false" /> -->
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
|
||||
@@ -186,7 +186,7 @@ namespace Win32
|
||||
public object Get (string section, string key, object dflt) => GetKey (section, key).Get (dflt);
|
||||
public object Get (string section, string key) => GetKey (section, key).Get ();
|
||||
public bool Set (string section, string key, object value) => GetKey (section, key).Set (value);
|
||||
public object this [string key] => GetSection (key);
|
||||
public InitSection this [string key] => GetSection (key);
|
||||
public string [] GetAllSections ()
|
||||
{
|
||||
var sections = new System.Collections.Generic.List<string> ();
|
||||
|
||||
BIN
Release.7z
Normal file
BIN
Release.7z
Normal file
Binary file not shown.
63
WAShell/Properties/Resources.Designer.cs
generated
Normal file
63
WAShell/Properties/Resources.Designer.cs
generated
Normal file
@@ -0,0 +1,63 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace WAShell.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 一个强类型的资源类,用于查找本地化的字符串等。
|
||||
/// </summary>
|
||||
// 此类是由 StronglyTypedResourceBuilder
|
||||
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
|
||||
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
|
||||
// (以 /str 作为命令选项),或重新生成 VS 项目。
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回此类使用的缓存的 ResourceManager 实例。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WAShell.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用此强类型资源类,为所有资源查找
|
||||
/// 重写当前线程的 CurrentUICulture 属性。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
120
WAShell/Properties/Resources.resx
Normal file
120
WAShell/Properties/Resources.resx
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
1
WAShell/SplashForm.Designer.cs
generated
1
WAShell/SplashForm.Designer.cs
generated
@@ -38,6 +38,7 @@
|
||||
//
|
||||
this.picbox.Anchor = System.Windows.Forms.AnchorStyles.None;
|
||||
this.picbox.BackColor = System.Drawing.Color.Transparent;
|
||||
this.picbox.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
|
||||
this.picbox.Location = new System.Drawing.Point(6, 47);
|
||||
this.picbox.Name = "picbox";
|
||||
this.picbox.Size = new System.Drawing.Size(620, 300);
|
||||
|
||||
@@ -87,9 +87,9 @@ namespace WAShell
|
||||
set
|
||||
{
|
||||
splashImage = value;
|
||||
if (picbox != null && picbox.IsHandleCreated)
|
||||
if (picbox != null)
|
||||
{
|
||||
picbox.Image = splashImage;
|
||||
try { picbox.Image = splashImage; } catch { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,11 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="SplashForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
@@ -78,6 +83,10 @@
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="SplashForm.resx">
|
||||
<DependentUpon>SplashForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
||||
@@ -298,10 +298,10 @@ struct pkg_info
|
||||
pi.users += sid;
|
||||
}
|
||||
{
|
||||
std::wstring sid;
|
||||
WAPParseSetStringValue (sid, it->UserSecurityId);
|
||||
std::wstring sid2;
|
||||
WAPParseSetStringValue (sid2, it->UserSecurityId);
|
||||
if (i) pi.sids += L';';
|
||||
pi.sids += sid;
|
||||
pi.sids += sid2;
|
||||
}
|
||||
i ++;
|
||||
}
|
||||
@@ -857,4 +857,149 @@ HRESULT FindAppxPackagesByFamilyName (LPCWSTR lpPkgFamilyName, PKGMGR_FINDENUMCA
|
||||
void PackageManagerFreeString (LPWSTR lpString)
|
||||
{
|
||||
if (lpString) free (lpString);
|
||||
}
|
||||
}
|
||||
[STAThread]
|
||||
HRESULT CreateAppDataManager (LPCWSTR lpFamilyName, HWRTAPPDATA *ppApplicationData, LPWSTR *pErrorCode, LPWSTR *pDetailMsg)
|
||||
{
|
||||
g_swExceptionCode = L"";
|
||||
g_swExceptionDetail = L"";
|
||||
try
|
||||
{
|
||||
auto adm = ApplicationDataManager::CreateForPackageFamily (ref new String (lpFamilyName ? lpFamilyName : L""));
|
||||
auto insp = reinterpret_cast <IInspectable *> (adm);
|
||||
insp->AddRef ();
|
||||
if (ppApplicationData) *ppApplicationData = (HWRTAPPDATA)insp;
|
||||
return S_OK;
|
||||
}
|
||||
catch (AccessDeniedException ^e)
|
||||
{
|
||||
g_swExceptionDetail = e->ToString ()->Data ();
|
||||
if (pDetailMsg) *pDetailMsg = _wcsdup (g_swExceptionDetail.c_str ());
|
||||
return (SUCCEEDED ((HRESULT)e->HResult) ? E_FAIL : (HRESULT)e->HResult);
|
||||
}
|
||||
catch (Exception ^e)
|
||||
{
|
||||
g_swExceptionDetail = e->ToString ()->Data ();
|
||||
if (pDetailMsg) *pDetailMsg = _wcsdup (g_swExceptionDetail.c_str ());
|
||||
return (SUCCEEDED ((HRESULT)e->HResult) ? E_FAIL : (HRESULT)e->HResult);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
g_swExceptionDetail = StringToWString (e.what () ? e.what () : "Unknown exception.");
|
||||
if (pDetailMsg) *pDetailMsg = _wcsdup (g_swExceptionDetail.c_str ());
|
||||
return E_FAIL;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
g_swExceptionDetail = L"Unknown exception";
|
||||
if (pDetailMsg) *pDetailMsg = _wcsdup (g_swExceptionDetail.c_str ());
|
||||
return E_FAIL;
|
||||
}
|
||||
return E_FAIL;
|
||||
}
|
||||
HRESULT RunAsyncActionOperation (Windows::Foundation::IAsyncAction ^asyncAction, LPWSTR *pErrorCode, LPWSTR *pDetailMsg)
|
||||
{
|
||||
g_swExceptionCode.clear ();
|
||||
g_swExceptionDetail.clear ();
|
||||
if (pErrorCode) *pErrorCode = nullptr;
|
||||
if (pDetailMsg) *pDetailMsg = nullptr;
|
||||
if (!asyncAction) return E_POINTER;
|
||||
HANDLE hCompEvt = CreateEventExW (
|
||||
nullptr,
|
||||
nullptr,
|
||||
CREATE_EVENT_MANUAL_RESET,
|
||||
EVENT_ALL_ACCESS
|
||||
);
|
||||
if (!hCompEvt) return HRESULT_FROM_WIN32 (GetLastError ());
|
||||
auto closeEvt = destruct ([&] () {
|
||||
CloseHandle (hCompEvt);
|
||||
});
|
||||
try
|
||||
{
|
||||
asyncAction->Completed =
|
||||
ref new Windows::Foundation::AsyncActionCompletedHandler (
|
||||
[&hCompEvt] (
|
||||
Windows::Foundation::IAsyncAction^,
|
||||
Windows::Foundation::AsyncStatus)
|
||||
{
|
||||
SetEvent (hCompEvt);
|
||||
});
|
||||
WaitForSingleObject (hCompEvt, INFINITE);
|
||||
switch (asyncAction->Status)
|
||||
{
|
||||
case Windows::Foundation::AsyncStatus::Completed: return S_OK;
|
||||
case Windows::Foundation::AsyncStatus::Canceled:
|
||||
g_swExceptionDetail = L"Async action was canceled.";
|
||||
if (pDetailMsg) *pDetailMsg = _wcsdup (g_swExceptionDetail.c_str ());
|
||||
return E_ABORT;
|
||||
case Windows::Foundation::AsyncStatus::Error:
|
||||
{
|
||||
auto err = asyncAction->ErrorCode;
|
||||
HRESULT hr = (HRESULT)err.Value;
|
||||
auto errStr = Platform::Exception::CreateException (err.Value)->ToString ();
|
||||
if (errStr && errStr->Data ()) g_swExceptionCode = errStr->Data ();
|
||||
if (pErrorCode) *pErrorCode = _wcsdup (g_swExceptionCode.c_str ());
|
||||
if (pDetailMsg) *pDetailMsg = _wcsdup (g_swExceptionDetail.c_str ());
|
||||
return hr;
|
||||
}
|
||||
default: return E_FAIL;
|
||||
}
|
||||
}
|
||||
catch (Platform::Exception^ e)
|
||||
{
|
||||
g_swExceptionDetail = e->ToString ()->Data ();
|
||||
if (pDetailMsg) *pDetailMsg = _wcsdup (g_swExceptionDetail.c_str ());
|
||||
return e->HResult;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
g_swExceptionDetail = StringToWString (e.what () ? e.what () : "Unknown exception.");
|
||||
if (pDetailMsg) *pDetailMsg = _wcsdup (g_swExceptionDetail.c_str ());
|
||||
return E_FAIL;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
g_swExceptionDetail = L"Unknown exception.";
|
||||
if (pDetailMsg) *pDetailMsg = _wcsdup (g_swExceptionDetail.c_str ());
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
#define HWRTAppDataToAppData(pInspectable) \
|
||||
safe_cast <Windows::Storage::ApplicationData ^> (reinterpret_cast <Platform::Object ^>(pInspectable))
|
||||
[MTAThread]
|
||||
HRESULT WRTAppDataClearAll (HWRTAPPDATA hAppData, LPWSTR *pErrorCode, LPWSTR *pDetailMsg)
|
||||
{
|
||||
g_swExceptionCode = L"";
|
||||
g_swExceptionDetail = L"";
|
||||
try
|
||||
{
|
||||
ApplicationData ^appData = HWRTAppDataToAppData (hAppData, appData, pErrorCode, pDetailMsg);
|
||||
if (appData == nullptr) return E_FAIL;
|
||||
return RunAsyncActionOperation (appData->ClearAsync (), pErrorCode, pDetailMsg);
|
||||
}
|
||||
catch (AccessDeniedException ^e)
|
||||
{
|
||||
g_swExceptionDetail = e->ToString ()->Data ();
|
||||
if (pDetailMsg) *pDetailMsg = _wcsdup (g_swExceptionDetail.c_str ());
|
||||
return (SUCCEEDED ((HRESULT)e->HResult) ? E_FAIL : (HRESULT)e->HResult);
|
||||
}
|
||||
catch (Exception ^e)
|
||||
{
|
||||
g_swExceptionDetail = e->ToString ()->Data ();
|
||||
if (pDetailMsg) *pDetailMsg = _wcsdup (g_swExceptionDetail.c_str ());
|
||||
return (SUCCEEDED ((HRESULT)e->HResult) ? E_FAIL : (HRESULT)e->HResult);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
g_swExceptionDetail = StringToWString (e.what () ? e.what () : "Unknown exception.");
|
||||
if (pDetailMsg) *pDetailMsg = _wcsdup (g_swExceptionDetail.c_str ());
|
||||
return E_FAIL;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
g_swExceptionDetail = L"Unknown exception";
|
||||
if (pDetailMsg) *pDetailMsg = _wcsdup (g_swExceptionDetail.c_str ());
|
||||
return E_FAIL;
|
||||
}
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
@@ -194,6 +194,15 @@ extern "C"
|
||||
PKGMGR_API HRESULT FindAppxPackagesByFamilyName (LPCWSTR lpPkgFamilyName, PKGMGR_FINDENUMCALLBACK pfCallback, void *pCustom _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pErrorCode _DEFAULT_INIT_VALUE_FORFUNC_ (NULL), LPWSTR *pDetailMsg _DEFAULT_INIT_VALUE_FORFUNC_ (NULL));
|
||||
// 释放由 pkgmgr.dll 返回的动态字符串。
|
||||
PKGMGR_API void PackageManagerFreeString (LPWSTR lpString);
|
||||
#ifndef TEMPLATE_STRUCT
|
||||
#define TEMPLATE_STRUCT(_typename_) typedef struct _typename_##__ _typename_
|
||||
#endif // ! TEMPLATE_STRUCT
|
||||
TEMPLATE_STRUCT (WRTAPPDATA);
|
||||
typedef WRTAPPDATA *HWRTAPPDATA;
|
||||
// 创建应用数据管理器。通过 Package Family Name
|
||||
PKGMGR_API HRESULT CreateAppDataManager (LPCWSTR lpFamilyName, HWRTAPPDATA *ppApplicationData, LPWSTR *pErrorCode, LPWSTR *pDetailMsg);
|
||||
// 从本地、漫游和临时应用数据存储中删除所有应用程序数据。
|
||||
PKGMGR_API HRESULT WRTAppDataClearAll (HWRTAPPDATA hAppData, LPWSTR *pErrorCode, LPWSTR *pDetailMsg);
|
||||
#ifdef _DEFAULT_INIT_VALUE_
|
||||
#undef _DEFAULT_INIT_VALUE_
|
||||
#endif
|
||||
|
||||
@@ -32,3 +32,5 @@
|
||||
using namespace Platform;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::Management::Deployment;
|
||||
using namespace Windows::Management::Core;
|
||||
using namespace Windows::Storage;
|
||||
|
||||
@@ -1213,4 +1213,544 @@ LPWSTR GetPackageCapabilityDisplayName (LPCWSTR lpCapabilityName)
|
||||
std::wstring ret = GetCapabilityDisplayName (capname);
|
||||
if (IsNormalizeStringEmpty (ret)) return nullptr;
|
||||
else return _wcsdup (ret.c_str ());
|
||||
}
|
||||
}
|
||||
|
||||
void PackageReaderFreeString (LPWSTR lpStrFromThisDll)
|
||||
{
|
||||
if (!lpStrFromThisDll) return;
|
||||
free (lpStrFromThisDll);
|
||||
}
|
||||
|
||||
// ========== 以下是对清单文件的读取 ==========
|
||||
#define ToHandleMRead(_cpp_ptr_) reinterpret_cast <HPKGMANIFESTREAD> (_cpp_ptr_)
|
||||
#define ToPtrManifest(_cpp_ptr_) reinterpret_cast <manifest *> (_cpp_ptr_)
|
||||
HPKGMANIFESTREAD CreateManifestReader () { return ToHandleMRead (new manifest ()); }
|
||||
BOOL LoadManifestFromFile (_In_ HPKGMANIFESTREAD hReader, _In_ LPCWSTR lpFilePath)
|
||||
{
|
||||
auto ptr = ToPtrManifest (hReader);
|
||||
if (!ptr) return false;
|
||||
return ptr->create (lpFilePath);
|
||||
}
|
||||
void DestroyManifestReader (_In_ HPKGMANIFESTREAD hReader)
|
||||
{
|
||||
auto ptr = ToPtrManifest (hReader);
|
||||
if (!ptr) return;
|
||||
return delete ptr;
|
||||
}
|
||||
WORD GetManifestType (_In_ HPKGMANIFESTREAD hReader)
|
||||
{
|
||||
auto ptr = ToPtrManifest (hReader);
|
||||
if (!ptr) return PKGTYPE_UNKNOWN;
|
||||
switch (ptr->type ())
|
||||
{
|
||||
case PackageType::unknown: return PKGTYPE_UNKNOWN;
|
||||
case PackageType::single: return PKGTYPE_APPX;
|
||||
case PackageType::bundle: return PKGTYPE_BUNDLE;
|
||||
}
|
||||
return PKGTYPE_UNKNOWN;
|
||||
}
|
||||
BOOL IsManifestValid (_In_ HPKGMANIFESTREAD hReader)
|
||||
{
|
||||
auto ptr = ToPtrManifest (hReader);
|
||||
if (!ptr) return false;
|
||||
return ptr->valid ();
|
||||
}
|
||||
WORD GetManifestRole (_In_ HPKGMANIFESTREAD hReader)
|
||||
{
|
||||
auto ptr = ToPtrManifest (hReader);
|
||||
if (!ptr) return PKGROLE_UNKNOWN;
|
||||
switch (ptr->type ())
|
||||
{
|
||||
case PackageType::unknown: return PKGROLE_UNKNOWN;
|
||||
case PackageType::bundle: return PKGROLE_APPLICATION;
|
||||
case PackageType::single: {
|
||||
auto ar = ptr->appx_reader ();
|
||||
switch (ar.package_role ())
|
||||
{
|
||||
case PackageRole::unknown: return PKGROLE_UNKNOWN;
|
||||
case PackageRole::application: return PKGROLE_APPLICATION;
|
||||
case PackageRole::framework: return PKGROLE_FRAMEWORK;
|
||||
case PackageRole::resource: return PKGROLE_RESOURCE;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
return PKGROLE_UNKNOWN;
|
||||
}
|
||||
// Identity
|
||||
LPWSTR GetManifestIdentityStringValue (_In_ HPKGMANIFESTREAD hReader, _In_ DWORD dwName)
|
||||
{
|
||||
auto ptr = ToPtrManifest (hReader);
|
||||
if (!ptr) return nullptr;
|
||||
switch (ptr->type ())
|
||||
{
|
||||
case PackageType::single: {
|
||||
auto reader = ptr->appx_reader ();
|
||||
auto id = reader.identity ();
|
||||
switch (LOWORD (dwName))
|
||||
{
|
||||
case PKG_IDENTITY_NAME: return _wcsdup (id.name ().c_str ());
|
||||
case PKG_IDENTITY_PUBLISHER: return _wcsdup (id.publisher ().c_str ());
|
||||
case PKG_IDENTITY_PACKAGEFAMILYNAME: return _wcsdup (id.package_family_name ().c_str ());
|
||||
case PKG_IDENTITY_PACKAGEFULLNAME: return _wcsdup (id.package_full_name ().c_str ());
|
||||
case PKG_IDENTITY_RESOURCEID: return _wcsdup (id.resource_id ().c_str ());
|
||||
}
|
||||
} break;
|
||||
case PackageType::bundle: {
|
||||
auto reader = ptr->bundle_reader ();
|
||||
auto id = reader.identity ();
|
||||
{
|
||||
switch (LOWORD (dwName))
|
||||
{
|
||||
case PKG_IDENTITY_NAME: return _wcsdup (id.name ().c_str ());
|
||||
case PKG_IDENTITY_PUBLISHER: return _wcsdup (id.publisher ().c_str ());
|
||||
case PKG_IDENTITY_PACKAGEFAMILYNAME: return _wcsdup (id.package_family_name ().c_str ());
|
||||
case PKG_IDENTITY_PACKAGEFULLNAME: return _wcsdup (id.package_full_name ().c_str ());
|
||||
case PKG_IDENTITY_RESOURCEID: return _wcsdup (id.resource_id ().c_str ());
|
||||
}
|
||||
}
|
||||
} break;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
BOOL GetManifestIdentityVersion (_In_ HPKGMANIFESTREAD hReader, _Out_ VERSION *pVersion)
|
||||
{
|
||||
auto ptr = ToPtrManifest (hReader);
|
||||
if (!ptr) return FALSE;
|
||||
if (!pVersion) return FALSE;
|
||||
switch (ptr->type ())
|
||||
{
|
||||
case PackageType::single: {
|
||||
auto reader = ptr->appx_reader ();
|
||||
auto id = reader.identity ();
|
||||
auto ver = id.version ();
|
||||
*pVersion = VersionClassToStruct (ver);
|
||||
return !ver.empty ();
|
||||
} break;
|
||||
case PackageType::bundle: {
|
||||
auto reader = ptr->bundle_reader ();
|
||||
auto id = reader.identity ();
|
||||
{
|
||||
auto ver = id.version ();
|
||||
*pVersion = VersionClassToStruct (ver);
|
||||
return !ver.empty ();
|
||||
}
|
||||
} break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
BOOL GetManifestIdentityArchitecture (_In_ HPKGMANIFESTREAD hReader, _Out_ DWORD *pdwArchi)
|
||||
{
|
||||
auto ptr = ToPtrManifest (hReader);
|
||||
if (!ptr) return FALSE;
|
||||
if (!pdwArchi) return FALSE;
|
||||
switch (ptr->type ())
|
||||
{
|
||||
case PackageType::single: {
|
||||
auto reader = ptr->appx_reader ();
|
||||
auto id = reader.identity ();
|
||||
auto archi = id.architecture ();
|
||||
DWORD ret = 0;
|
||||
switch (archi)
|
||||
{
|
||||
case APPX_PACKAGE_ARCHITECTURE::APPX_PACKAGE_ARCHITECTURE_X86:
|
||||
ret = PKG_ARCHITECTURE_X86; break;
|
||||
case APPX_PACKAGE_ARCHITECTURE::APPX_PACKAGE_ARCHITECTURE_ARM:
|
||||
ret = PKG_ARCHITECTURE_ARM; break;
|
||||
case APPX_PACKAGE_ARCHITECTURE::APPX_PACKAGE_ARCHITECTURE_X64:
|
||||
ret = PKG_ARCHITECTURE_X64; break;
|
||||
case APPX_PACKAGE_ARCHITECTURE::APPX_PACKAGE_ARCHITECTURE_NEUTRAL:
|
||||
ret = PKG_ARCHITECTURE_NEUTRAL; break;
|
||||
case (APPX_PACKAGE_ARCHITECTURE)12: // ARM64
|
||||
ret = PKG_ARCHITECTURE_ARM64; break;
|
||||
}
|
||||
*pdwArchi = ret;
|
||||
return ret != PKG_ARCHITECTURE_UNKNOWN;
|
||||
} break;
|
||||
case PackageType::bundle: {
|
||||
auto reader = ptr->bundle_reader ();
|
||||
auto ids = reader.package_id_items ();
|
||||
std::vector <appx_info::appx_iditem> apps;
|
||||
ids.application_packages (apps);
|
||||
DWORD ret = 0;
|
||||
for (auto &it : apps)
|
||||
{
|
||||
auto id = it.identity ();
|
||||
auto archi = id.architecture ();
|
||||
switch (archi)
|
||||
{
|
||||
case APPX_PACKAGE_ARCHITECTURE::APPX_PACKAGE_ARCHITECTURE_X86:
|
||||
ret |= PKG_ARCHITECTURE_X86; break;
|
||||
case APPX_PACKAGE_ARCHITECTURE::APPX_PACKAGE_ARCHITECTURE_ARM:
|
||||
ret |= PKG_ARCHITECTURE_ARM; break;
|
||||
case APPX_PACKAGE_ARCHITECTURE::APPX_PACKAGE_ARCHITECTURE_X64:
|
||||
ret |= PKG_ARCHITECTURE_X64; break;
|
||||
case APPX_PACKAGE_ARCHITECTURE::APPX_PACKAGE_ARCHITECTURE_NEUTRAL:
|
||||
ret |= PKG_ARCHITECTURE_NEUTRAL; break;
|
||||
case (APPX_PACKAGE_ARCHITECTURE)12: // ARM64
|
||||
ret |= PKG_ARCHITECTURE_ARM64; break;
|
||||
}
|
||||
}
|
||||
*pdwArchi = ret;
|
||||
return ret != PKG_ARCHITECTURE_UNKNOWN;
|
||||
} break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
// Properties
|
||||
LPWSTR GetManifestPropertiesStringValue (_In_ HPKGMANIFESTREAD hReader, _In_ LPCWSTR lpName)
|
||||
{
|
||||
auto ptr = ToPtrManifest (hReader);
|
||||
if (!ptr) return nullptr;
|
||||
switch (ptr->type ())
|
||||
{
|
||||
case PackageType::single: {
|
||||
auto reader = ptr->appx_reader ();
|
||||
auto prop = reader.properties ();
|
||||
return _wcsdup (prop.string_value (lpName ? lpName : L"").c_str ());
|
||||
} break;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
HRESULT GetManifestPropertiesBoolValue (_In_ HPKGMANIFESTREAD hReader, _In_ LPCWSTR lpName, _Outptr_ BOOL *pRet)
|
||||
{
|
||||
auto ptr = ToPtrManifest (hReader);
|
||||
if (!ptr) return E_INVALIDARG;
|
||||
if (!pRet) return E_INVALIDARG;
|
||||
*pRet = FALSE;
|
||||
switch (ptr->type ())
|
||||
{
|
||||
case PackageType::single: {
|
||||
auto reader = ptr->appx_reader ();
|
||||
IAppxManifestReader *m = reader.manifest ();
|
||||
if (!m) return E_FAIL;
|
||||
CComPtr <IAppxManifestProperties> p;
|
||||
HRESULT hr = m->GetProperties (&p);
|
||||
if (FAILED (hr)) return hr;
|
||||
return p->GetBoolValue (lpName, pRet);
|
||||
} break;
|
||||
}
|
||||
return E_FAIL;
|
||||
}
|
||||
// Applications
|
||||
BOOL AddManifestApplicationItemGetName (_In_ LPCWSTR lpName)
|
||||
{
|
||||
if (std::wnstring (lpName ? lpName : L"").empty ()) return FALSE;
|
||||
return PushApplicationAttributeItem (lpName);
|
||||
}
|
||||
BOOL RemoveManifestApplicationItemGetName (_In_ LPCWSTR lpName)
|
||||
{
|
||||
if (std::wnstring (lpName ? lpName : L"").empty ()) return FALSE;
|
||||
return RemoveApplicationAttributeItem (lpName);
|
||||
}
|
||||
HAPPENUMERATOR GetManifestApplications (_In_ HPKGMANIFESTREAD hReader)
|
||||
{
|
||||
auto ptr = ToPtrManifest (hReader);
|
||||
if (!ptr) return nullptr;
|
||||
switch (ptr->type ())
|
||||
{
|
||||
case PackageType::single: {
|
||||
auto reader = ptr->appx_reader ();
|
||||
auto app = reader.applications ();
|
||||
auto appvec = new app_enumerator ();
|
||||
app.applications (*appvec);
|
||||
return ToHandleAppEnumerator (appvec);
|
||||
} break;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
void DestroyManifestApplications (_In_ HAPPENUMERATOR hEnumerator)
|
||||
{
|
||||
auto ptr = ToPtrAppxApps (hEnumerator);
|
||||
if (ptr) delete ptr;
|
||||
}
|
||||
// Resources
|
||||
HLIST_PVOID GetManifestResourcesLanguages (_In_ HPKGMANIFESTREAD hReader)
|
||||
{
|
||||
auto ptr = ToPtrManifest (hReader);
|
||||
if (!ptr) return nullptr;
|
||||
std::vector <std::wnstring> langs;
|
||||
switch (ptr->type ())
|
||||
{
|
||||
case PackageType::single:
|
||||
{
|
||||
auto reader = ptr->appx_reader ();
|
||||
auto res = reader.resources ();
|
||||
res.languages (langs);
|
||||
break;
|
||||
}
|
||||
case PackageType::bundle:
|
||||
{
|
||||
auto br = ptr->bundle_reader ();
|
||||
auto res = br.package_id_items ();
|
||||
res.enumerate ([&langs] (IAppxBundleManifestPackageInfo *inf) {
|
||||
auto item = appx_info::appx_iditem (inf);
|
||||
std::vector <std::wnstring> l;
|
||||
auto qr = item.qualified_resources ();
|
||||
qr.languages (l);
|
||||
for (auto &it : l) push_unique <std::wnstring> (langs, it);
|
||||
});
|
||||
break;
|
||||
}
|
||||
default: return nullptr;
|
||||
}
|
||||
if (langs.empty ()) return nullptr;
|
||||
size_t count = langs.size ();
|
||||
size_t bytes = sizeof (LIST_PVOID) + sizeof (LPWSTR) * (count - 1);
|
||||
auto list = (HLIST_PVOID)malloc (bytes);
|
||||
ZeroMemory (list, bytes);
|
||||
if (!list) return nullptr;
|
||||
list->dwSize = 0;
|
||||
for (auto &it : langs) list->alpVoid [list->dwSize ++] = _wcsdup (it.c_str ());
|
||||
return list;
|
||||
}
|
||||
HLIST_LCID GetManifestResourcesLanguagesToLcid (_In_ HPKGMANIFESTREAD hReader)
|
||||
{
|
||||
auto ptr = ToPtrManifest (hReader);
|
||||
if (!ptr) return nullptr;
|
||||
std::vector <std::wnstring> langs;
|
||||
switch (ptr->type ())
|
||||
{
|
||||
case PackageType::single:
|
||||
{
|
||||
auto reader = ptr->appx_reader ();
|
||||
auto res = reader.resources ();
|
||||
res.languages (langs);
|
||||
break;
|
||||
}
|
||||
case PackageType::bundle:
|
||||
{
|
||||
auto br = ptr->bundle_reader ();
|
||||
auto res = br.package_id_items ();
|
||||
res.enumerate ([&langs] (IAppxBundleManifestPackageInfo *inf) {
|
||||
auto item = appx_info::appx_iditem (inf);
|
||||
std::vector <std::wnstring> l;
|
||||
auto qr = item.qualified_resources ();
|
||||
qr.languages (l);
|
||||
for (auto &it : l) push_unique <std::wnstring> (langs, it);
|
||||
});
|
||||
break;
|
||||
}
|
||||
default: return nullptr;
|
||||
}
|
||||
if (langs.empty ()) return nullptr;
|
||||
size_t len = sizeof (LIST_LCID) + sizeof (LCID) * langs.size ();
|
||||
HLIST_LCID hList = (HLIST_LCID)malloc (len);
|
||||
ZeroMemory (hList, len);
|
||||
hList->dwSize = 0;
|
||||
for (auto &it : langs)
|
||||
{
|
||||
LCID lcid = LocaleCodeToLcid (it);
|
||||
if (lcid)
|
||||
{
|
||||
hList->aLcid [hList->dwSize ++] = lcid;
|
||||
}
|
||||
}
|
||||
return hList;
|
||||
}
|
||||
HLIST_UINT32 GetManifestResourcesScales (_In_ HPKGMANIFESTREAD hReader)
|
||||
|
||||
{
|
||||
auto ptr = ToPtrManifest (hReader);
|
||||
if (!ptr) return nullptr;
|
||||
std::vector <UINT32> scales;
|
||||
switch (ptr->type ())
|
||||
{
|
||||
case PackageType::single:
|
||||
{
|
||||
auto reader = ptr->appx_reader ();
|
||||
auto res = reader.resources ();
|
||||
res.scales (scales);
|
||||
break;
|
||||
}
|
||||
case PackageType::bundle:
|
||||
{
|
||||
auto br = ptr->bundle_reader ();
|
||||
auto res = br.package_id_items ();
|
||||
res.enumerate ([&scales] (IAppxBundleManifestPackageInfo *inf) {
|
||||
auto item = appx_info::appx_iditem (inf);
|
||||
std::vector <UINT32> s;
|
||||
auto qr = item.qualified_resources ();
|
||||
qr.scales (s);
|
||||
for (auto &it : s) push_unique (scales, it);
|
||||
});
|
||||
break;
|
||||
}
|
||||
default: return nullptr;
|
||||
}
|
||||
if (scales.empty ()) return nullptr;
|
||||
size_t len = sizeof (LIST_UINT32) + sizeof (UINT32) * scales.size ();
|
||||
HLIST_UINT32 hList = (HLIST_UINT32)malloc (len);
|
||||
ZeroMemory (hList, len);
|
||||
hList->dwSize = 0;
|
||||
for (auto &it : scales)
|
||||
{
|
||||
if (!it) continue;
|
||||
hList->aUI32 [hList->dwSize ++] = it;
|
||||
}
|
||||
return hList;
|
||||
}
|
||||
DWORD GetManifestResourcesDxFeatureLevels (_In_ HPKGMANIFESTREAD hReader)
|
||||
|
||||
{
|
||||
auto ptr = ToPtrManifest (hReader);
|
||||
if (!ptr) return 0;
|
||||
DWORD dwFlags = 0;
|
||||
switch (ptr->type ())
|
||||
{
|
||||
case PackageType::single:
|
||||
{
|
||||
auto reader = ptr->appx_reader ();
|
||||
auto res = reader.resources ();
|
||||
std::vector <DX_FEATURE_LEVEL> dxlevels;
|
||||
res.dx_feature_level (dxlevels);
|
||||
for (auto &it : dxlevels)
|
||||
{
|
||||
switch (it)
|
||||
{
|
||||
case DX_FEATURE_LEVEL::DX_FEATURE_LEVEL_9:
|
||||
dwFlags |= PKG_RESOURCES_DXFEATURE_LEVEL9; break;
|
||||
case DX_FEATURE_LEVEL::DX_FEATURE_LEVEL_10:
|
||||
dwFlags |= PKG_RESOURCES_DXFEATURE_LEVEL10; break;
|
||||
case DX_FEATURE_LEVEL::DX_FEATURE_LEVEL_11:
|
||||
dwFlags |= PKG_RESOURCES_DXFEATURE_LEVEL11; break;
|
||||
case (DX_FEATURE_LEVEL)4:
|
||||
dwFlags |= PKG_RESOURCES_DXFEATURE_LEVEL12; break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PackageType::bundle:
|
||||
{
|
||||
auto br = ptr->bundle_reader ();
|
||||
auto res = br.package_id_items ();
|
||||
res.enumerate ([&dwFlags] (IAppxBundleManifestPackageInfo *inf) {
|
||||
auto item = appx_info::appx_iditem (inf);
|
||||
std::vector <DX_FEATURE_LEVEL> dxlevels;
|
||||
auto qr = item.qualified_resources ();
|
||||
qr.dx_feature_level (dxlevels);
|
||||
for (auto &it : dxlevels)
|
||||
{
|
||||
switch (it)
|
||||
{
|
||||
case DX_FEATURE_LEVEL::DX_FEATURE_LEVEL_9:
|
||||
dwFlags |= PKG_RESOURCES_DXFEATURE_LEVEL9; break;
|
||||
case DX_FEATURE_LEVEL::DX_FEATURE_LEVEL_10:
|
||||
dwFlags |= PKG_RESOURCES_DXFEATURE_LEVEL10; break;
|
||||
case DX_FEATURE_LEVEL::DX_FEATURE_LEVEL_11:
|
||||
dwFlags |= PKG_RESOURCES_DXFEATURE_LEVEL11; break;
|
||||
case (DX_FEATURE_LEVEL)4:
|
||||
dwFlags |= PKG_RESOURCES_DXFEATURE_LEVEL12; break;
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
default: return 0;
|
||||
}
|
||||
return dwFlags;
|
||||
}
|
||||
// Dependencies
|
||||
HLIST_DEPINFO GetManifestDependencesInfoList (_In_ HPKGMANIFESTREAD hReader)
|
||||
{
|
||||
auto ptr = ToPtrManifest (hReader);
|
||||
if (!ptr) return nullptr;
|
||||
std::vector <dep_info> vec;
|
||||
switch (ptr->type ())
|
||||
{
|
||||
case PackageType::single: {
|
||||
auto reader = ptr->appx_reader ();
|
||||
auto deps = reader.dependencies ();
|
||||
deps.dependencies (vec);
|
||||
} break;
|
||||
}
|
||||
size_t len = sizeof (LIST_DEPINFO) + sizeof (DEPENDENCY_INFO) * vec.size ();
|
||||
HLIST_DEPINFO hList = (HLIST_DEPINFO)malloc (len);
|
||||
ZeroMemory (hList, len);
|
||||
hList->dwSize = 0;
|
||||
for (auto &it : vec)
|
||||
{
|
||||
auto &dep = hList->aDepInfo [hList->dwSize ++];
|
||||
dep.lpName = _wcsdup (it.name.c_str ());
|
||||
dep.lpPublisher = _wcsdup (it.publisher.c_str ());
|
||||
dep.verMin = VersionClassToStruct (it.minversion);
|
||||
}
|
||||
return hList;
|
||||
}
|
||||
// Capabilities
|
||||
HLIST_PVOID GetManifestCapabilitiesList (_In_ HPKGMANIFESTREAD hReader)
|
||||
{
|
||||
auto ptr = ToPtrManifest (hReader);
|
||||
if (!ptr) return nullptr;
|
||||
std::vector <std::wnstring> caps;
|
||||
switch (ptr->type ())
|
||||
{
|
||||
case PackageType::single: {
|
||||
auto reader = ptr->appx_reader ();
|
||||
auto cap = reader.capabilities ();
|
||||
std::vector <std::wstring> vec;
|
||||
cap.capabilities_names (vec);
|
||||
for (auto &it : vec)
|
||||
{
|
||||
auto cname = std::wnstring (it.c_str ());
|
||||
if (cname.empty ()) continue;
|
||||
push_unique (caps, cname);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
size_t len = sizeof (LIST_PVOID) + sizeof (LPWSTR) * caps.size ();
|
||||
HLIST_PVOID hList = (HLIST_PVOID)malloc (len);
|
||||
ZeroMemory (hList, len);
|
||||
hList->dwSize = 0;
|
||||
for (auto &it : caps)
|
||||
{
|
||||
hList->alpVoid [hList->dwSize ++] = (LPVOID)_wcsdup (it.c_str ());
|
||||
}
|
||||
return hList;
|
||||
}
|
||||
HLIST_PVOID GetManifestDeviceCapabilitiesList (_In_ HPKGMANIFESTREAD hReader)
|
||||
{
|
||||
auto ptr = ToPtrManifest (hReader);
|
||||
if (!ptr) return nullptr;
|
||||
std::vector <std::wnstring> caps;
|
||||
switch (ptr->type ())
|
||||
{
|
||||
case PackageType::single: {
|
||||
auto reader = ptr->appx_reader ();
|
||||
auto cap = reader.capabilities ();
|
||||
std::vector <std::wstring> vec;
|
||||
cap.device_capabilities (vec);
|
||||
for (auto &it : vec)
|
||||
{
|
||||
auto cname = std::wnstring (it.c_str ());
|
||||
if (cname.empty ()) continue;
|
||||
push_unique (caps, cname);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
size_t len = sizeof (LIST_PVOID) + sizeof (LPWSTR) * caps.size ();
|
||||
HLIST_PVOID hList = (HLIST_PVOID)malloc (len);
|
||||
ZeroMemory (hList, len);
|
||||
hList->dwSize = 0;
|
||||
for (auto &it : caps)
|
||||
{
|
||||
hList->alpVoid [hList->dwSize ++] = (LPVOID)_wcsdup (it.c_str ());
|
||||
}
|
||||
return hList;
|
||||
}
|
||||
// Prerequisite
|
||||
BOOL GetManifestPrerequisite (_In_ HPKGMANIFESTREAD hReader, _In_ LPCWSTR lpName, _Outptr_ VERSION *pVerRet)
|
||||
{
|
||||
auto ptr = ToPtrManifest (hReader);
|
||||
if (!ptr) return FALSE;
|
||||
switch (ptr->type ())
|
||||
{
|
||||
case PackageType::single: {
|
||||
auto reader = ptr->appx_reader ();
|
||||
auto pre = reader.prerequisites ();
|
||||
auto ver = pre.get_version (lpName ? lpName : L"");
|
||||
*pVerRet = VersionClassToStruct (ver);
|
||||
return !ver.empty ();
|
||||
} break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ extern "C"
|
||||
#define PKGROLE_APPLICATION 1
|
||||
#define PKGROLE_FRAMEWORK 2
|
||||
#define PKGROLE_RESOURCE 3
|
||||
// 创建包读取器
|
||||
// 创建包读取器
|
||||
PKGREAD_API HPKGREAD CreatePackageReader ();
|
||||
// 通过包读取器打开包
|
||||
PKGREAD_API BOOL LoadPackageFromFile (_In_ HPKGREAD hReader, _In_ LPCWSTR lpFilePath);
|
||||
@@ -286,6 +286,155 @@ extern "C"
|
||||
// 获取功能名的显示名,如 internetClient 对应“访问您的 Internet 连接”。返回的是适应于系统区域语言的文本。
|
||||
// 注意:返回的字符串一定要通过 free 释放。
|
||||
PKGREAD_API LPWSTR GetPackageCapabilityDisplayName (LPCWSTR lpCapabilityName);
|
||||
// 释放从本库中返回的字符串
|
||||
// 其实通过 free 释放即可,但考虑到环境问题,那么另写了个函数
|
||||
PKGREAD_API void PackageReaderFreeString (LPWSTR lpStrFromThisDll);
|
||||
|
||||
// ========= 以下是针对于应用清单的读取器,一些常量和类型等是复用的 =========
|
||||
|
||||
TEMPLATE_STRUCT (PKGMANIFESTREAD);
|
||||
typedef PKGMANIFESTREAD *HPKGMANIFESTREAD;
|
||||
// 创建 Manifest 读取器。
|
||||
// 返回一个 Manifest Reader 句柄,初始状态未加载任何文件。
|
||||
PKGREAD_API HPKGMANIFESTREAD CreateManifestReader ();
|
||||
// 从文件加载 Manifest。
|
||||
// 支持的输入:
|
||||
// - AppxManifest.xml
|
||||
// - .appx / .msix
|
||||
// - .appxbundle / .msixbundle
|
||||
// 加载成功后,读取器会自动识别 Manifest 类型。
|
||||
PKGREAD_API BOOL LoadManifestFromFile (_In_ HPKGMANIFESTREAD hReader, _In_ LPCWSTR lpFilePath);
|
||||
// 从文件加载 Manifest。
|
||||
// 支持的输入:
|
||||
// - AppxManifest.xml
|
||||
// - .appx / .msix
|
||||
// - .appxbundle / .msixbundle
|
||||
// 加载成功后,读取器会自动识别 Manifest 类型。
|
||||
PKGREAD_API BOOL LoadManifestFromFile (_In_ HPKGMANIFESTREAD hReader, _In_ LPCWSTR lpFilePath);
|
||||
// 销毁 Manifest 读取器(必须调用)。
|
||||
// 释放内部所有资源,句柄在此之后不可再使用。
|
||||
PKGREAD_API void DestroyManifestReader (_In_ HPKGMANIFESTREAD hReader);
|
||||
// 获取 Manifest 的类型。
|
||||
// 返回值:
|
||||
// - PKGTYPE_APPX :单一 Appx / Msix 包
|
||||
// - PKGTYPE_BUNDLE :AppxBundle / MsixBundle
|
||||
// - PKGTYPE_UNKNOWN :未知或未加载
|
||||
PKGREAD_API WORD GetManifestType (_In_ HPKGMANIFESTREAD hReader);
|
||||
// 获取 Manifest 的类型。
|
||||
// 返回值:
|
||||
// - PKGTYPE_APPX :单一 Appx / Msix 包
|
||||
// - PKGTYPE_BUNDLE :AppxBundle / MsixBundle
|
||||
// - PKGTYPE_UNKNOWN :未知或未加载
|
||||
PKGREAD_API WORD GetManifestType (_In_ HPKGMANIFESTREAD hReader);
|
||||
// 判断 Manifest 是否有效。
|
||||
// 如果 Manifest 解析失败、结构非法或未加载,返回 FALSE。
|
||||
PKGREAD_API BOOL IsManifestValid (_In_ HPKGMANIFESTREAD hReader);
|
||||
// 获取 Manifest 所表示包的角色。
|
||||
// 返回值:
|
||||
// - PKGROLE_APPLICATION :应用包
|
||||
// - PKGROLE_FRAMEWORK :框架包
|
||||
// - PKGROLE_RESOURCE :资源包
|
||||
// - PKGROLE_UNKNOWN :未知
|
||||
//
|
||||
// 说明:
|
||||
// - 对于 AppxBundle,永远返回 PKGROLE_APPLICATION。
|
||||
PKGREAD_API WORD GetManifestRole (_In_ HPKGMANIFESTREAD hReader);
|
||||
// 获取 Identity 的字符串字段。
|
||||
// dwName 可取值:
|
||||
// - PKG_IDENTITY_NAME
|
||||
// - PKG_IDENTITY_PUBLISHER
|
||||
// - PKG_IDENTITY_PACKAGEFAMILYNAME
|
||||
// - PKG_IDENTITY_PACKAGEFULLNAME
|
||||
// - PKG_IDENTITY_RESOURCEID
|
||||
//
|
||||
// 返回值:
|
||||
// - 成功:返回新分配的字符串(调用者负责释放)
|
||||
// - 失败:返回 NULL
|
||||
PKGREAD_API LPWSTR GetManifestIdentityStringValue (_In_ HPKGMANIFESTREAD hReader, _In_ DWORD dwName);
|
||||
#define GetManifestIdentityName(_In_hReader_) GetManifestIdentityStringValue (_In_hReader_, PKG_IDENTITY_NAME)
|
||||
#define GetManifestIdentityPublisher(_In_hReader_) GetManifestIdentityStringValue (_In_hReader_, PKG_IDENTITY_PUBLISHER)
|
||||
#define GetManifestIdentityPackageFamilyName(_In_hReader_) GetManifestIdentityStringValue (_In_hReader_, PKG_IDENTITY_PACKAGEFAMILYNAME)
|
||||
#define GetManifestIdentityPackageFullName(_In_hReader_) GetManifestIdentityStringValue (_In_hReader_, PKG_IDENTITY_PACKAGEFULLNAME)
|
||||
#define GetManifestIdentityResourceId(_In_hReader_) GetManifestIdentityStringValue (_In_hReader_, PKG_IDENTITY_RESOURCEID)
|
||||
// 获取 Identity 的版本号。
|
||||
//
|
||||
// pVersion 返回格式化后的 VERSION 结构。
|
||||
// 返回值:
|
||||
// - TRUE :成功
|
||||
// - FALSE :失败或版本不存在
|
||||
PKGREAD_API BOOL GetManifestIdentityVersion (_In_ HPKGMANIFESTREAD hReader, _Out_ VERSION *pVersion);
|
||||
// 获取包支持的架构信息。
|
||||
// 对于单一 Appx 包,返回单一架构;
|
||||
// 对于 Bundle,返回所有子包架构的组合(按位或)。
|
||||
//
|
||||
// 返回值通过 pdwArchi 输出,取值为 PKG_ARCHITECTURE_* 宏。
|
||||
PKGREAD_API BOOL GetManifestIdentityArchitecture (_In_ HPKGMANIFESTREAD hReader, _Out_ DWORD *pdwArchi);
|
||||
// 获取 Properties 中的字符串值。
|
||||
// lpName 为属性名(如 "DisplayName")。
|
||||
// 返回值:
|
||||
// - 成功:返回新分配的字符串(调用者负责释放)
|
||||
// - 失败:返回 NULL
|
||||
//
|
||||
// 说明:
|
||||
// - 仅适用于单一 Appx 包。
|
||||
PKGREAD_API LPWSTR GetManifestPropertiesStringValue (_In_ HPKGMANIFESTREAD hReader, _In_ LPCWSTR lpName);
|
||||
// 获取 Properties 中的布尔值。
|
||||
//
|
||||
// pRet 返回布尔结果。
|
||||
// 返回 HRESULT,便于区分失败原因。
|
||||
//
|
||||
// 说明:
|
||||
// - 仅适用于单一 Appx 包。
|
||||
PKGREAD_API HRESULT GetManifestPropertiesBoolValue (_In_ HPKGMANIFESTREAD hReader, _In_ LPCWSTR lpName, _Outptr_ BOOL *pRet);
|
||||
// 向应用枚举器中添加需要读取的 Application 属性名。
|
||||
// 返回 FALSE 表示属性名非法或重复。
|
||||
PKGREAD_API BOOL AddManifestApplicationItemGetName (_In_ LPCWSTR lpName);
|
||||
// 从应用枚举器中移除指定的 Application 属性名。
|
||||
PKGREAD_API BOOL RemoveManifestApplicationItemGetName (_In_ LPCWSTR lpName);
|
||||
// 获取 Applications 枚举器。
|
||||
// 返回一个应用枚举器句柄,调用者需手动销毁。
|
||||
//
|
||||
// 说明:
|
||||
// - 仅适用于单一 Appx 包。
|
||||
PKGREAD_API HAPPENUMERATOR GetManifestApplications (_In_ HPKGMANIFESTREAD hReader);
|
||||
// 销毁 Applications 枚举器。
|
||||
PKGREAD_API void DestroyManifestApplications (_In_ HAPPENUMERATOR hEnumerator);
|
||||
// 获取资源支持的语言列表(字符串形式)。
|
||||
// 返回 HLIST_PVOID,内部元素为 LPWSTR。
|
||||
PKGREAD_API HLIST_PVOID GetManifestResourcesLanguages (_In_ HPKGMANIFESTREAD hReader);
|
||||
// 获取资源支持的语言列表(LCID 形式)。
|
||||
// 返回 HLIST_LCID。
|
||||
PKGREAD_API HLIST_LCID GetManifestResourcesLanguagesToLcid (_In_ HPKGMANIFESTREAD hReader);
|
||||
// 获取资源支持的缩放比例(Scale)。
|
||||
// 返回 HLIST_UINT32。
|
||||
PKGREAD_API HLIST_UINT32 GetManifestResourcesScales (_In_ HPKGMANIFESTREAD hReader);
|
||||
// 获取资源支持的 DirectX Feature Level。
|
||||
// 返回值为 PKG_RESOURCES_DXFEATURE_LEVEL* 位掩码组合。
|
||||
PKGREAD_API DWORD GetManifestResourcesDxFeatureLevels (_In_ HPKGMANIFESTREAD hReader);
|
||||
// 获取依赖包信息列表。
|
||||
// 返回 HLIST_DEPINFO,其中包含名称、发布者及最低版本。
|
||||
//
|
||||
// 说明:
|
||||
// - 仅适用于单一 Appx 包。
|
||||
PKGREAD_API HLIST_DEPINFO GetManifestDependencesInfoList (_In_ HPKGMANIFESTREAD hReader);
|
||||
// 获取 Capability 列表(Capability)。
|
||||
// 返回的列表元素为 LPWSTR。
|
||||
//
|
||||
// 说明:
|
||||
// - 仅适用于单一 Appx 包。
|
||||
PKGREAD_API HLIST_PVOID GetManifestCapabilitiesList (_In_ HPKGMANIFESTREAD hReader);
|
||||
// 获取 Device Capability 列表。
|
||||
// 返回的列表元素为 LPWSTR。
|
||||
//
|
||||
// 说明:
|
||||
// - 仅适用于单一 Appx 包。
|
||||
PKGREAD_API HLIST_PVOID GetManifestDeviceCapabilitiesList (_In_ HPKGMANIFESTREAD hReader);
|
||||
// 获取指定前置条件的最低版本要求。
|
||||
// lpName 为前置组件名称。
|
||||
// pVerRet 返回版本结构。
|
||||
// 返回 TRUE 表示存在该前置条件。
|
||||
PKGREAD_API BOOL GetManifestPrerequisite (_In_ HPKGMANIFESTREAD hReader, _In_ LPCWSTR lpName, _Outptr_ VERSION *pVerRet);
|
||||
|
||||
#ifdef _DEFAULT_INIT_VALUE_
|
||||
#undef _DEFAULT_INIT_VALUE_
|
||||
#endif
|
||||
|
||||
@@ -1336,3 +1336,202 @@ class package
|
||||
appxreader appx_reader () const { return appxreader (*(IAppxPackageReader **)&this->appx); }
|
||||
bundlereader bundle_reader () const { return bundlereader (*(IAppxBundleReader **)&this->bundle); }
|
||||
};
|
||||
|
||||
class appxmanifest: virtual public com_info_quote <IAppxManifestReader>
|
||||
{
|
||||
using Base = com_info_quote <IAppxManifestReader>;
|
||||
template <typename IComPtr, typename ReturnType, typename Fn> HRESULT get (IComPtr iptr, Fn func, ReturnType *retvalue) const { if (!iptr) return E_FAIL; return (iptr->*func) (retvalue); }
|
||||
using Manifest = IAppxManifestReader;
|
||||
public:
|
||||
using Base::Base;
|
||||
Manifest *manifest () { return pointer (); }
|
||||
template <class IComPtr, class Func> HRESULT get_from_manifest (Func fn, _Outptr_ IComPtr *output) const
|
||||
{
|
||||
if (!pointer ()) return E_FAIL;
|
||||
return get (pointer (), fn, output);
|
||||
}
|
||||
HRESULT get_identity (_Outptr_ IAppxManifestPackageId **output) const { return get_from_manifest <IAppxManifestPackageId *> (&Manifest::GetPackageId, output); }
|
||||
appx_info::appx_id identity () const
|
||||
{
|
||||
IAppxManifestPackageId *ip = nullptr;
|
||||
get_identity (&ip);
|
||||
return appx_info::appx_id (ip);
|
||||
}
|
||||
appx_info::appx_res resources () const
|
||||
{
|
||||
return appx_info::appx_res (pointer ());
|
||||
}
|
||||
HRESULT get_properties (_Outptr_ IAppxManifestProperties **output) const { return get_from_manifest <IAppxManifestProperties *> (&Manifest::GetProperties, output); }
|
||||
appx_info::appx_prop properties () const
|
||||
{
|
||||
IAppxManifestProperties *ip = nullptr;
|
||||
HRESULT hr = get_properties (&ip);
|
||||
return appx_info::appx_prop (ip);
|
||||
}
|
||||
appx_info::appx_preq prerequisites () const
|
||||
{
|
||||
return appx_info::appx_preq (pointer ());
|
||||
}
|
||||
HRESULT get_applications (_Outptr_ IAppxManifestApplicationsEnumerator **output) const { return get_from_manifest <IAppxManifestApplicationsEnumerator *> (&Manifest::GetApplications, output); }
|
||||
appx_info::appx_apps applications () const
|
||||
{
|
||||
IAppxManifestApplicationsEnumerator *ip = nullptr;
|
||||
get_applications (&ip);
|
||||
return appx_info::appx_apps (ip);
|
||||
}
|
||||
HRESULT get_capabilities (_Outptr_ APPX_CAPABILITIES *output) const { return get_from_manifest <APPX_CAPABILITIES> (&Manifest::GetCapabilities, output); }
|
||||
HRESULT get_device_capabilities (_Outptr_ IAppxManifestDeviceCapabilitiesEnumerator **output) const { return get_from_manifest <IAppxManifestDeviceCapabilitiesEnumerator *> (&Manifest::GetDeviceCapabilities, output); }
|
||||
appx_info::appx_capabs capabilities () const
|
||||
{
|
||||
APPX_CAPABILITIES caps;
|
||||
IAppxManifestDeviceCapabilitiesEnumerator *ip = nullptr;
|
||||
if (pointer ()) pointer ()->GetDeviceCapabilities (&ip);
|
||||
auto im = pointer ();
|
||||
if (SUCCEEDED (get_capabilities (&caps))) return appx_info::appx_capabs (ip, caps, im);
|
||||
return appx_info::appx_capabs (ip);
|
||||
}
|
||||
HRESULT get_dependencies (_Outptr_ IAppxManifestPackageDependenciesEnumerator **output) const { return get_from_manifest <IAppxManifestPackageDependenciesEnumerator *> (&Manifest::GetPackageDependencies, output); }
|
||||
appx_info::appx_deps dependencies () const
|
||||
{
|
||||
IAppxManifestPackageDependenciesEnumerator *ip = nullptr;
|
||||
get_dependencies (&ip);
|
||||
return appx_info::appx_deps (ip);
|
||||
}
|
||||
PackageRole package_role () const
|
||||
{
|
||||
auto prop = properties ();
|
||||
if (prop.framework ()) return PackageRole::framework;
|
||||
try { if (prop.resource_package ()) return PackageRole::resource; }
|
||||
catch (const std::exception &e) {}
|
||||
auto app = applications ();
|
||||
std::vector <std::wstring> apps;
|
||||
if (app.app_user_model_ids (apps)) return PackageRole::application;
|
||||
else return PackageRole::unknown;
|
||||
}
|
||||
};
|
||||
class bundlemanifest: virtual public com_info_quote <IAppxBundleManifestReader>
|
||||
{
|
||||
using Base = com_info_quote <IAppxBundleManifestReader>;
|
||||
public:
|
||||
using Base::Base;
|
||||
template <typename IComPtr, typename ReturnType, typename Fn> HRESULT get (IComPtr iptr, Fn func, ReturnType *retvalue) const { if (!iptr) return E_FAIL; return (iptr->*func) (retvalue); }
|
||||
using Manifest = IAppxBundleManifestReader;
|
||||
Manifest *manifest () { return pointer (); }
|
||||
template <class IComPtr, class Func> HRESULT get_from_manifest (Func fn, _Outptr_ IComPtr *output) const
|
||||
{
|
||||
if (!pointer ()) return E_FAIL;
|
||||
return get (pointer (), fn, output);
|
||||
}
|
||||
HRESULT get_identity (_Outptr_ IAppxManifestPackageId **output) const { return get_from_manifest (&Manifest::GetPackageId, output); }
|
||||
appx_info::appx_id identity () const
|
||||
{
|
||||
IAppxManifestPackageId *ip = nullptr;
|
||||
get_identity (&ip);
|
||||
return appx_info::appx_id (ip);
|
||||
}
|
||||
HRESULT get_package_id_items (_Outptr_ IAppxBundleManifestPackageInfoEnumerator **output) const { return get_from_manifest (&Manifest::GetPackageInfoItems, output); }
|
||||
appx_info::appx_iditems package_id_items () const
|
||||
{
|
||||
IAppxBundleManifestPackageInfoEnumerator *ip = nullptr;
|
||||
get_package_id_items (&ip);
|
||||
return appx_info::appx_iditems (ip);
|
||||
}
|
||||
};
|
||||
|
||||
HRESULT GetAppxManifestReader (_In_ LPCWSTR inputPath, _Outptr_ IAppxManifestReader **manifestReader)
|
||||
{
|
||||
if (!manifestReader) return E_POINTER;
|
||||
*manifestReader = nullptr;
|
||||
HRESULT hr;
|
||||
CComPtr <IStream> stream;
|
||||
CComPtr <IAppxFactory> factory;
|
||||
CComPtr <IAppxPackageReader> packageReader;
|
||||
hr = SHCreateStreamOnFileEx (
|
||||
inputPath,
|
||||
STGM_READ | STGM_SHARE_DENY_NONE,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
FALSE,
|
||||
nullptr,
|
||||
&stream
|
||||
);
|
||||
if (FAILED (hr)) return hr;
|
||||
hr = CoCreateInstance (
|
||||
__uuidof (AppxFactory),
|
||||
nullptr,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
IID_PPV_ARGS (&factory)
|
||||
);
|
||||
if (FAILED (hr)) return hr;
|
||||
hr = factory->CreatePackageReader (stream, &packageReader);
|
||||
if (SUCCEEDED (hr))
|
||||
{
|
||||
return packageReader->GetManifest (manifestReader);
|
||||
}
|
||||
hr = factory->CreateManifestReader (stream, manifestReader);
|
||||
return hr;
|
||||
}
|
||||
HRESULT GetBundleManifestReader (_In_ LPCWSTR bundlePath, _Outptr_ IAppxBundleManifestReader **manifestReader)
|
||||
{
|
||||
if (!manifestReader) return E_POINTER;
|
||||
*manifestReader = nullptr;
|
||||
HRESULT hr;
|
||||
CComPtr <IStream> stream;
|
||||
CComPtr <IAppxBundleFactory> factory;
|
||||
CComPtr <IAppxBundleReader> bundleReader;
|
||||
hr = SHCreateStreamOnFileEx (
|
||||
bundlePath,
|
||||
STGM_READ | STGM_SHARE_DENY_NONE,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
FALSE,
|
||||
nullptr,
|
||||
&stream
|
||||
);
|
||||
if (FAILED (hr)) return hr;
|
||||
hr = CoCreateInstance (
|
||||
__uuidof(AppxBundleFactory),
|
||||
nullptr,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
IID_PPV_ARGS (&factory)
|
||||
);
|
||||
if (FAILED (hr)) return hr;
|
||||
hr = factory->CreateBundleReader (stream, &bundleReader);
|
||||
if (FAILED (hr)) return hr;
|
||||
hr = bundleReader->GetManifest (manifestReader);
|
||||
if (FAILED (hr)) return hr = factory->CreateBundleManifestReader (stream, manifestReader);
|
||||
return hr;
|
||||
}
|
||||
|
||||
class manifest
|
||||
{
|
||||
IAppxManifestReader *appx = nullptr;
|
||||
IAppxBundleManifestReader *bundle = nullptr;
|
||||
public:
|
||||
~manifest () { destroy (); }
|
||||
manifest (const std::wstring &filepath = L"") { create (filepath); }
|
||||
void destroy ()
|
||||
{
|
||||
if (appx) { appx->Release (); appx = nullptr; }
|
||||
if (bundle) { bundle->Release (); bundle = nullptr; }
|
||||
}
|
||||
bool create (const std::wstring &filepath)
|
||||
{
|
||||
destroy ();
|
||||
if (!IsFileExists (filepath)) return false;
|
||||
HRESULT hr = GetBundleManifestReader (filepath.c_str (), &bundle);
|
||||
if (SUCCEEDED (hr)) return true;
|
||||
if (bundle) { bundle->Release (); bundle = nullptr; }
|
||||
hr = GetAppxManifestReader (filepath.c_str (), &appx);
|
||||
if (SUCCEEDED (hr)) return true;
|
||||
if (appx) { appx->Release (); appx = nullptr; }
|
||||
return false;
|
||||
}
|
||||
bool valid () const { return (bool)appx ^ (bool)bundle; }
|
||||
PackageType type () const
|
||||
{
|
||||
if (appx) return PackageType::single;
|
||||
if (bundle) return PackageType::bundle;
|
||||
return PackageType::unknown;
|
||||
}
|
||||
appxmanifest appx_reader () const { return appxmanifest (*(IAppxManifestReader **)&this->appx); }
|
||||
bundlemanifest bundle_reader () const { return bundlemanifest (*(IAppxBundleManifestReader **)&this->bundle); }
|
||||
};
|
||||
@@ -915,4 +915,10 @@ BOOL IsMsResourceUri (LPCWSTR pResUri)
|
||||
try { Uri ^uri = gcnew Uri (gcnew String (pResUri ? pResUri : L"")); delete uri; }
|
||||
catch (Exception ^e) { return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
void PriFormatFreeString (LPWSTR lpStrFromThisDll)
|
||||
{
|
||||
if (!lpStrFromThisDll) return;
|
||||
free (lpStrFromThisDll);
|
||||
}
|
||||
@@ -73,6 +73,8 @@ extern "C" {
|
||||
PRIFORMATCLI_API BOOL IsMsResourceUriFull (LPCWSTR pResUri);
|
||||
// 工具函数,用于判断是否为 MS-Resource URI
|
||||
PRIFORMATCLI_API BOOL IsMsResourceUri (LPCWSTR pResUri);
|
||||
// 工具函数,用于释放本地 DLL 返回的字符串
|
||||
PRIFORMATCLI_API void PriFormatFreeString (LPWSTR lpStrFromThisDll);
|
||||
#ifdef _DEFAULT_VALUE_SET
|
||||
#undef _DEFAULT_VALUE_SET
|
||||
#endif
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
========================================================================
|
||||
动态链接库:priread 项目概述
|
||||
========================================================================
|
||||
|
||||
应用程序向导已为您创建了此 priread DLL。
|
||||
|
||||
本文件概要介绍组成 priread 应用程序的每个文件的内容。
|
||||
|
||||
|
||||
priread.vcxproj
|
||||
这是使用应用程序向导生成的 VC++ 项目的主项目文件,其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。
|
||||
|
||||
priread.vcxproj.filters
|
||||
这是使用“应用程序向导”生成的 VC++ 项目筛选器文件。它包含有关项目文件与筛选器之间的关联信息。在 IDE 中,通过这种关联,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。
|
||||
|
||||
priread.cpp
|
||||
这是主 DLL 源文件。
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
其他标准文件:
|
||||
|
||||
StdAfx.h, StdAfx.cpp
|
||||
这些文件用于生成名为 priread.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
其他注释:
|
||||
|
||||
应用程序向导使用“TODO:”注释来指示应添加或自定义的源代码部分。
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1,19 +0,0 @@
|
||||
// dllmain.cpp : 定义 DLL 应用程序的入口点。
|
||||
#include "stdafx.h"
|
||||
|
||||
BOOL APIENTRY DllMain( HMODULE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1,163 +0,0 @@
|
||||
#pragma once
|
||||
#include <WinNls.h>
|
||||
#include <string>
|
||||
static 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;
|
||||
}
|
||||
|
||||
#undef GetLocaleInfo
|
||||
std::string GetLocaleInfoA (LCID code, LCTYPE type)
|
||||
{
|
||||
char buf [LOCALE_NAME_MAX_LENGTH] = {0};
|
||||
GetLocaleInfoA (code, type, buf, LOCALE_NAME_MAX_LENGTH);
|
||||
return buf;
|
||||
}
|
||||
std::wstring GetLocaleInfoW (LCID code, LCTYPE type)
|
||||
{
|
||||
WCHAR buf [LOCALE_NAME_MAX_LENGTH] = {0};
|
||||
GetLocaleInfoW (code, type, buf, LOCALE_NAME_MAX_LENGTH);
|
||||
return buf;
|
||||
}
|
||||
void GetLocaleInfo (LCID code, LCTYPE type, std::wstring &output)
|
||||
{
|
||||
output = GetLocaleInfoW (code, type);
|
||||
}
|
||||
void GetLocaleInfo (LCID code, LCTYPE type, std::string &output)
|
||||
{
|
||||
output = GetLocaleInfoA (code, type);
|
||||
}
|
||||
int GetLocaleInfoEx (std::wstring lpLocaleName, LCTYPE type, std::wstring &output)
|
||||
{
|
||||
WCHAR buf [LOCALE_NAME_MAX_LENGTH] = {0};
|
||||
int res = GetLocaleInfoEx (lpLocaleName.c_str (), type, buf, LOCALE_NAME_MAX_LENGTH);
|
||||
if (&output) output = std::wstring (buf);
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef SetLocaleInfo
|
||||
BOOL SetLocaleInfoA (LCID code, LCTYPE type, const std::string &lcData)
|
||||
{
|
||||
return SetLocaleInfoA (code, type, lcData.c_str ());
|
||||
}
|
||||
BOOL SetLocaleInfoW (LCID code, LCTYPE type, const std::wstring &lcData)
|
||||
{
|
||||
return SetLocaleInfoW (code, type, lcData.c_str ());
|
||||
}
|
||||
BOOL SetLocaleInfo (LCID code, LCTYPE type, const std::wstring &lcData)
|
||||
{
|
||||
return SetLocaleInfoW (code, type, lcData);
|
||||
}
|
||||
BOOL SetLocaleInfo (LCID code, LCTYPE type, const std::string &lcData)
|
||||
{
|
||||
return SetLocaleInfoA (code, type, lcData);
|
||||
}
|
||||
|
||||
std::string GetLocaleRestrictedCodeFromLcidA (LCID lcid)
|
||||
{
|
||||
return GetLocaleInfoA (lcid, 89);
|
||||
}
|
||||
std::wstring GetLocaleRestrictedCodeFromLcidW (LCID lcid)
|
||||
{
|
||||
return GetLocaleInfoW (lcid, 89);
|
||||
}
|
||||
void GetLocaleRestrictedCodeFromLcid (LCID lcid, std::string &ret)
|
||||
{
|
||||
ret = GetLocaleRestrictedCodeFromLcidA (lcid);
|
||||
}
|
||||
void GetLocaleRestrictedCodeFromLcid (LCID lcid, std::wstring &ret)
|
||||
{
|
||||
ret = GetLocaleRestrictedCodeFromLcidW (lcid);
|
||||
}
|
||||
|
||||
std::string GetLocaleElaboratedCodeFromLcidA (LCID lcid)
|
||||
{
|
||||
return GetLocaleInfoA (lcid, 90);
|
||||
}
|
||||
std::wstring GetLocaleElaboratedCodeFromLcidW (LCID lcid)
|
||||
{
|
||||
return GetLocaleInfoW (lcid, 90);
|
||||
}
|
||||
void GetLocaleElaboratedCodeFromLcid (LCID lcid, std::wstring &ret)
|
||||
{
|
||||
ret = GetLocaleElaboratedCodeFromLcidW (lcid);
|
||||
}
|
||||
void GetLocaleElaboratedCodeFromLcid (LCID lcid, std::string &ret)
|
||||
{
|
||||
ret = GetLocaleElaboratedCodeFromLcidA (lcid);
|
||||
}
|
||||
|
||||
LCID LocaleCodeToLcidW (LPCWSTR localeCode)
|
||||
{
|
||||
BYTE buf [LOCALE_NAME_MAX_LENGTH * sizeof (WCHAR)] = {0};
|
||||
int res = GetLocaleInfoEx (localeCode, LOCALE_RETURN_NUMBER | LOCALE_ILANGUAGE, (LPWSTR)buf, LOCALE_NAME_MAX_LENGTH);
|
||||
LCID lcid = *((LCID *)buf);
|
||||
return lcid;
|
||||
}
|
||||
LCID LocaleCodeToLcidA (LPCSTR localeCode)
|
||||
{
|
||||
std::wstring lcWide = StringToWString (std::string (localeCode));
|
||||
return LocaleCodeToLcidW (lcWide.c_str ());
|
||||
}
|
||||
LCID LocaleCodeToLcid (const std::wstring &loccode)
|
||||
{
|
||||
return LocaleCodeToLcidW (loccode.c_str ());
|
||||
}
|
||||
LCID LocaleCodeToLcid (const std::string &loccode)
|
||||
{
|
||||
return LocaleCodeToLcidA (loccode.c_str ());
|
||||
}
|
||||
|
||||
std::string GetLocaleRestrictedCodeA (LPCSTR lc)
|
||||
{
|
||||
return GetLocaleInfoA (LocaleCodeToLcidA (lc), 89);
|
||||
}
|
||||
std::string GetLocaleRestrictedCodeA (const std::string &lc)
|
||||
{
|
||||
return GetLocaleInfoA (LocaleCodeToLcidA (lc.c_str ()), 89);
|
||||
}
|
||||
std::wstring GetLocaleRestrictedCodeW (LPCWSTR lc)
|
||||
{
|
||||
return GetLocaleInfoW (LocaleCodeToLcidW (lc), 89);
|
||||
}
|
||||
std::wstring GetLocaleRestrictedCodeW (const std::wstring &lc)
|
||||
{
|
||||
return GetLocaleInfoW (LocaleCodeToLcidW (lc.c_str ()), 89);
|
||||
}
|
||||
std::wstring GetLocaleRestrictedCode (const std::wstring &lc) { return GetLocaleRestrictedCodeW (lc); }
|
||||
std::string GetLocaleRestrictedCode (const std::string &lc) { return GetLocaleRestrictedCodeA (lc); }
|
||||
|
||||
std::string GetLocaleElaboratedCodeA (LPCSTR lc)
|
||||
{
|
||||
return GetLocaleInfoA (LocaleCodeToLcidA (lc), 90);
|
||||
}
|
||||
std::string GetLocaleElaboratedCodeA (const std::string &lc)
|
||||
{
|
||||
return GetLocaleInfoA (LocaleCodeToLcidA (lc.c_str ()), 90);
|
||||
}
|
||||
std::wstring GetLocaleElaboratedCodeW (LPCWSTR lc)
|
||||
{
|
||||
return GetLocaleInfoW (LocaleCodeToLcidW (lc), 90);
|
||||
}
|
||||
std::wstring GetLocaleElaboratedCodeW (const std::wstring &lc)
|
||||
{
|
||||
return GetLocaleInfoW (LocaleCodeToLcidW (lc.c_str ()), 90);
|
||||
}
|
||||
std::wstring GetLocaleElaboratedCode (const std::wstring &lc) { return GetLocaleElaboratedCodeW (lc); }
|
||||
std::string GetLocaleElaboratedCode (const std::string &lc) { return GetLocaleElaboratedCodeA (lc); }
|
||||
|
||||
std::string LcidToLocaleCodeA (LCID lcid, char divide = '-')
|
||||
{
|
||||
return GetLocaleRestrictedCodeFromLcidA (lcid) + divide + GetLocaleElaboratedCodeFromLcidA (lcid);
|
||||
}
|
||||
std::wstring LcidToLocaleCodeW (LCID lcid, WCHAR divide = L'-')
|
||||
{
|
||||
return GetLocaleRestrictedCodeFromLcidW (lcid) + divide + GetLocaleElaboratedCodeFromLcidW (lcid);
|
||||
}
|
||||
std::wstring LcidToLocaleCode (LCID lcid, WCHAR divide = L'-') { return LcidToLocaleCodeW (lcid, divide); }
|
||||
std::string LcidToLocaleCode (LCID lcid, char divide = '-') { return LcidToLocaleCodeA (lcid, divide); }
|
||||
@@ -1,456 +0,0 @@
|
||||
#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>
|
||||
{
|
||||
using base = std::basic_string <ct, tr, al>;
|
||||
bool default_upper = false, default_include_blank_in_str = false;
|
||||
public:
|
||||
using typename base::size_type;
|
||||
using typename base::value_type;
|
||||
using base::base;
|
||||
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) {}
|
||||
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); }
|
||||
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;
|
||||
}
|
||||
2671
priread/prifile.h
2671
priread/prifile.h
File diff suppressed because it is too large
Load Diff
@@ -1,22 +0,0 @@
|
||||
// priread.cpp : 定义 DLL 应用程序的导出函数。
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "priread.h"
|
||||
|
||||
|
||||
// 这是导出变量的一个示例
|
||||
PRIREAD_API int npriread=0;
|
||||
|
||||
// 这是导出函数的一个示例。
|
||||
PRIREAD_API int fnpriread(void)
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
||||
// 这是已导出类的构造函数。
|
||||
// 有关类定义的信息,请参阅 priread.h
|
||||
Cpriread::Cpriread()
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
// 下列 ifdef 块是创建使从 DLL 导出更简单的
|
||||
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 PRIREAD_EXPORTS
|
||||
// 符号编译的。在使用此 DLL 的
|
||||
// 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
|
||||
// PRIREAD_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
|
||||
// 符号视为是被导出的。
|
||||
#ifdef PRIREAD_EXPORTS
|
||||
#define PRIREAD_API __declspec(dllexport)
|
||||
#else
|
||||
#define PRIREAD_API __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
// 此类是从 priread.dll 导出的
|
||||
class PRIREAD_API Cpriread {
|
||||
public:
|
||||
Cpriread(void);
|
||||
// TODO: 在此添加您的方法。
|
||||
};
|
||||
|
||||
extern PRIREAD_API int npriread;
|
||||
|
||||
PRIREAD_API int fnpriread(void);
|
||||
@@ -1,182 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{99D714D9-F40D-425B-BAFA-8B41C17971A5}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>priread</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;PRIREAD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;PRIREAD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PRIREAD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;PRIREAD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="localeex.h" />
|
||||
<ClInclude Include="nstring.h" />
|
||||
<ClInclude Include="prifile.h" />
|
||||
<ClInclude Include="priread.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
<ClInclude Include="themeinfo.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</PrecompiledHeader>
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
</PrecompiledHeader>
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</PrecompiledHeader>
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="priread.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,54 +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>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="targetver.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="priread.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="prifile.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="nstring.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="localeex.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="themeinfo.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="priread.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,8 +0,0 @@
|
||||
// stdafx.cpp : 只包括标准包含文件的源文件
|
||||
// priread.pch 将作为预编译头
|
||||
// stdafx.obj 将包含预编译类型信息
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: 在 STDAFX.H 中引用任何所需的附加头文件,
|
||||
//而不是在此文件中引用
|
||||
@@ -1,20 +0,0 @@
|
||||
// stdafx.h : 标准系统包含文件的包含文件,
|
||||
// 或是经常使用但不常更改的
|
||||
// 特定于项目的包含文件
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "targetver.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // 从 Windows 头中排除极少使用的资料
|
||||
// Windows 头文件:
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 某些 CString 构造函数将是显式的
|
||||
|
||||
#include <atlbase.h>
|
||||
#include <atlstr.h>
|
||||
|
||||
// TODO: 在此处引用程序需要的其他头文件
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。
|
||||
|
||||
// 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并将
|
||||
// 将 _WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。
|
||||
|
||||
#include <SDKDDKVer.h>
|
||||
@@ -1,40 +0,0 @@
|
||||
#pragma once
|
||||
#include <Windows.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;
|
||||
}
|
||||
@@ -12,6 +12,18 @@
|
||||
DarkModeBackgroundColor='#001629' />
|
||||
</VisualElements>
|
||||
</Application>
|
||||
<Application Id='Manager'>
|
||||
<VisualElements
|
||||
DisplayName='Package Manager'
|
||||
Logo='Settings.Assets\Logo.png'
|
||||
SmallLogo='Settings.Assets\SmallLogo.png'
|
||||
ForegroundText='light'
|
||||
BackgroundColor='#159d9d'>
|
||||
<DefaultTile ShowName='allLogos' />
|
||||
<SplashScreen Image="VisualElements\splash\settings\splashscreen.png"
|
||||
BackgroundColor="#159d9d" DarkModeBackgroundColor='#2e1e5c' />
|
||||
</VisualElements>
|
||||
</Application>
|
||||
<Application Id='Settings'>
|
||||
<VisualElements
|
||||
DisplayName='Settings'
|
||||
|
||||
Binary file not shown.
@@ -170,7 +170,7 @@
|
||||
element.style.animation = generateAnimeString(swKeyFrames, uMillisecond, swTimingFunc, uDelayMs, swIteration, swDirection, swFillMode, swPlayState);
|
||||
element.addEventListener("animationend", function() {
|
||||
element.style.animation = "";
|
||||
complete();
|
||||
complete(element);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
396
shared/html/js/appbar.js
Normal file
396
shared/html/js/appbar.js
Normal file
@@ -0,0 +1,396 @@
|
||||
(function(global) {
|
||||
"use strict";
|
||||
|
||||
// 基类:提供 element 管理与基础 dispose 行为
|
||||
function PMAppBarBaseMember() {
|
||||
var _element = null;
|
||||
Object.defineProperty(this, "element", {
|
||||
configurable: true, // <- 关键:允许子类重定义该属性
|
||||
enumerable: false,
|
||||
get: function() { return _element; },
|
||||
set: function(value) {
|
||||
_element = value;
|
||||
try {
|
||||
if (_element) {
|
||||
// 让 DOM 节点可以反查到对应的 member
|
||||
_element.appBarMember = this;
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
});
|
||||
// 可被子类或外部调用来从 DOM 中移除自身
|
||||
this.dispose = function() {
|
||||
try {
|
||||
if (this.element && this.element.parentNode) {
|
||||
this.element.parentNode.removeChild(this.element);
|
||||
}
|
||||
} catch (e) {}
|
||||
};
|
||||
}
|
||||
|
||||
function PMAppBarCommand() {
|
||||
PMAppBarBaseMember.call(this);
|
||||
var _button = document.createElement("button");
|
||||
var _iconcontainer = document.createElement("span");
|
||||
var _iconnode = document.createElement("span");
|
||||
var _labelnode = document.createElement("span");
|
||||
_button.appendChild(_iconcontainer);
|
||||
_iconcontainer.appendChild(_iconnode);
|
||||
_button.appendChild(_labelnode);
|
||||
_button.classList.add("win-command");
|
||||
_button.setAttribute("role", "menuitem");
|
||||
_iconcontainer.classList.add("win-commandicon");
|
||||
_iconcontainer.classList.add("win-commandring");
|
||||
_iconnode.classList.add("win-commandimage");
|
||||
_labelnode.classList.add("win-label");
|
||||
_iconcontainer.tabIndex = -1;
|
||||
_iconnode.tabIndex = -1;
|
||||
_labelnode.tabIndex = -1;
|
||||
_button.classList.add("win-global");
|
||||
Windows.UI.Event.Util.addEvent(_button, "keydown", function(event) {
|
||||
if (event.keyCode === 13) {
|
||||
_button.click();
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "element", {
|
||||
get: function() { return _button; },
|
||||
set: function(value) { _button = value; }
|
||||
});
|
||||
Object.defineProperty(this, "icon", {
|
||||
get: function() { return _iconnode.innerHTML; },
|
||||
set: function(value) { _iconnode.innerHTML = value; }
|
||||
});
|
||||
Object.defineProperty(this, "label", {
|
||||
get: function() { return _labelnode.textContent; },
|
||||
set: function(value) { _labelnode.textContent = value; }
|
||||
});
|
||||
Object.defineProperty(this, "onclick", {
|
||||
get: function() { return _button.onclick; },
|
||||
set: function(value) { _button.onclick = value; }
|
||||
});
|
||||
Object.defineProperty(this, "selectable", {
|
||||
get: function() { return _button.classList.contains("win-selectable"); },
|
||||
set: function(value) {
|
||||
try { Windows.UI.Event.Util.removeEvent(this.element, "click", selectHandler); } catch (e) {}
|
||||
_button.classList.toggle("win-selectable", value);
|
||||
if (!value) {
|
||||
if (_button.classList.contains("win-selected")) {
|
||||
_button.classList.remove("win-selected");
|
||||
}
|
||||
}
|
||||
if (value) Windows.UI.Event.Util.addEvent(this.element, "click", selectHandler);
|
||||
else Windows.UI.Event.Util.removeEvent(this.element, "click", selectHandler);
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "selected", {
|
||||
get: function() { return _button.classList.contains("win-selected"); },
|
||||
set: function(value) { _button.classList.toggle("win-selected", value); }
|
||||
});
|
||||
Object.defineProperty(this, "disabled", {
|
||||
get: function() { try { return this.element.disabled; } catch (e) { return false; } },
|
||||
set: function(value) { try { this.element.disabled = value; } catch (e) {} }
|
||||
});
|
||||
// global 或 selection (始终显示或有选择时显示)
|
||||
Object.defineProperty(this, "section", {
|
||||
get: function() {
|
||||
if (_button.classList.contains("win-global")) return "global";
|
||||
if (_button.classList.contains("win-selection")) return "selection";
|
||||
return "none";
|
||||
},
|
||||
set: function(value) {
|
||||
_button.classList.remove("win-global");
|
||||
_button.classList.remove("win-selection");
|
||||
if (value == "global") _button.classList.add("win-global");
|
||||
if (value == "selection") _button.classList.add("win-selection");
|
||||
}
|
||||
});
|
||||
|
||||
function selectHandler(event) {
|
||||
_button.classList.toggle("win-selected");
|
||||
}
|
||||
this.addEventListener = function(type, listener) {
|
||||
try { Windows.UI.Event.Util.addEvent(this.element, type, listener); } catch (e) {}
|
||||
};
|
||||
this.removeEventListener = function(type, listener) {
|
||||
try { Windows.UI.Event.Util.removeEvent(this.element, type, listener); } catch (e) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
function PMAppBarSeparator() {
|
||||
PMAppBarBaseMember.call(this);
|
||||
var _hr = document.createElement("hr");
|
||||
_hr.classList.add("win-command");
|
||||
_hr.classList.add("win-global");
|
||||
_hr.setAttribute("role", "separator");
|
||||
Object.defineProperty(this, "element", {
|
||||
get: function() { return _hr; },
|
||||
set: function(value) { _hr = value; }
|
||||
});
|
||||
}
|
||||
|
||||
function PMAppBar(container) {
|
||||
var _container = container;
|
||||
var _enable = true;
|
||||
|
||||
function init(node) {
|
||||
var classNames = [
|
||||
"win-overlay",
|
||||
"win-commandlayout",
|
||||
"win-appbar",
|
||||
"appbar"
|
||||
]
|
||||
try {
|
||||
for (var i = 0; i < classNames.length; i++) {
|
||||
if (!node.classList.contains(classNames[i]))
|
||||
node.classList.add(classNames[i]);
|
||||
}
|
||||
} catch (e) {}
|
||||
try {
|
||||
node.appBarControl = this;
|
||||
} catch (e) {}
|
||||
}
|
||||
Object.defineProperty(this, "element", {
|
||||
get: function() { return _container; },
|
||||
set: function(value) {
|
||||
_container = value;
|
||||
init(value);
|
||||
// 将已有成员渲染到新的容器中
|
||||
try {
|
||||
// 先移除所有成员 DOM(如果之前挂载过)
|
||||
for (var i = 0; i < this._members.length; i++) {
|
||||
try {
|
||||
var mEl = this._members[i].element;
|
||||
if (mEl && mEl.parentNode === _container) {
|
||||
_container.removeChild(mEl);
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
// 重新挂载所有成员,按数组顺序
|
||||
for (i = 0; i < this._members.length; i++) {
|
||||
try {
|
||||
var el = this._members[i].element;
|
||||
if (el) _container.appendChild(el);
|
||||
} catch (e) {}
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
});
|
||||
|
||||
// 成员管理
|
||||
this._members = [];
|
||||
|
||||
// 返回内部数组引用(只读语义上)
|
||||
Object.defineProperty(this, "members", {
|
||||
get: function() { return this._members; }
|
||||
});
|
||||
|
||||
// 添加成员到末尾,返回索引;若失败返回 -1
|
||||
this.add = function(member) {
|
||||
if (!member || !member.element) return -1;
|
||||
this._members.push(member);
|
||||
try {
|
||||
if (_container) _container.appendChild(member.element);
|
||||
} catch (e) {}
|
||||
this._updateSelectionVisibility();
|
||||
return this._members.length - 1;
|
||||
};
|
||||
this.addMember = this.add; // alias
|
||||
|
||||
// 在指定索引处插入(如果 index 为 undefined 或超范围,则 append)
|
||||
this.insertAt = function(member, index) {
|
||||
if (!member || !member.element) return -1;
|
||||
var len = this._members.length;
|
||||
if (typeof index !== "number" || index < 0 || index > len) {
|
||||
return this.add(member);
|
||||
}
|
||||
this._members.splice(index, 0, member);
|
||||
try {
|
||||
if (_container) {
|
||||
var refNode = _container.childNodes[index] || null;
|
||||
_container.insertBefore(member.element, refNode);
|
||||
}
|
||||
} catch (e) {}
|
||||
this._updateSelectionVisibility();
|
||||
return index;
|
||||
};
|
||||
|
||||
// remove 接受成员对象或索引
|
||||
this.remove = function(memberOrIndex) {
|
||||
var idx = -1;
|
||||
if (typeof memberOrIndex === "number") {
|
||||
idx = memberOrIndex;
|
||||
} else {
|
||||
idx = this._members.indexOf(memberOrIndex);
|
||||
}
|
||||
if (idx < 0 || idx >= this._members.length) return false;
|
||||
var removed = this._members.splice(idx, 1)[0];
|
||||
try {
|
||||
if (removed && removed.element && removed.element.parentNode) {
|
||||
removed.element.parentNode.removeChild(removed.element);
|
||||
}
|
||||
} catch (e) {}
|
||||
this._updateSelectionVisibility();
|
||||
return true;
|
||||
};
|
||||
|
||||
// 替换指定索引的成员,返回 true/false
|
||||
this.replaceAt = function(index, member) {
|
||||
if (!member || !member.element) return false;
|
||||
if (typeof index !== "number" || index < 0 || index >= this._members.length) return false;
|
||||
var old = this._members[index];
|
||||
this._members[index] = member;
|
||||
try {
|
||||
if (_container && old && old.element) {
|
||||
// 如果 old.element 在容器中,直接 replaceChild
|
||||
if (old.element.parentNode === _container) {
|
||||
_container.replaceChild(member.element, old.element);
|
||||
} else {
|
||||
// 备用:在位置 index 插入
|
||||
var ref = _container.childNodes[index] || null;
|
||||
_container.insertBefore(member.element, ref);
|
||||
}
|
||||
} else if (_container) {
|
||||
// 没有 old 元素,直接 append
|
||||
_container.appendChild(member.element);
|
||||
}
|
||||
} catch (e) {}
|
||||
this._updateSelectionVisibility();
|
||||
return true;
|
||||
};
|
||||
|
||||
this.getMember = function(index) {
|
||||
return this._members[index];
|
||||
};
|
||||
|
||||
this.indexOf = function(member) {
|
||||
return this._members.indexOf(member);
|
||||
};
|
||||
|
||||
this.clear = function() {
|
||||
while (this._members.length) {
|
||||
var m = this._members.shift();
|
||||
try {
|
||||
if (m && m.element && m.element.parentNode) {
|
||||
m.element.parentNode.removeChild(m.element);
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
};
|
||||
|
||||
var timer = null;
|
||||
var isupdating = false;
|
||||
|
||||
function waitTimer(ms) {
|
||||
clearTimeout(timer);
|
||||
isupdating = true;
|
||||
timer = setTimeout(function(t) {
|
||||
isupdating = false;
|
||||
t = null;
|
||||
}, ms, timer);
|
||||
}
|
||||
Object.defineProperty(this, "isupdating", {
|
||||
get: function() { return isupdating; }
|
||||
});
|
||||
var touchHide = document.createElement("div");
|
||||
touchHide.classList.add("appbar-touchhide");
|
||||
touchHide.style.display = "none";
|
||||
Windows.UI.Event.Util.addEvent(touchHide, "click", function(event) {
|
||||
touchHide.style.display = "none";
|
||||
this.hide();
|
||||
}.bind(this));
|
||||
document.body.appendChild(touchHide);
|
||||
|
||||
function showTouchHide() {
|
||||
if (touchHide == null || touchHide == void 0) {
|
||||
touchHide = document.createElement("div");
|
||||
touchHide.classList.add("appbar-touchhide");
|
||||
}
|
||||
touchHide.style.display = "";
|
||||
}
|
||||
|
||||
function hideTouchHide() {
|
||||
touchHide.style.display = "none";
|
||||
}
|
||||
this.show = function() {
|
||||
try {
|
||||
if (!_enable) return;
|
||||
if (!this.element.classList.contains("show"))
|
||||
this.element.classList.add("show");
|
||||
waitTimer(500);
|
||||
showTouchHide();
|
||||
} catch (e) {}
|
||||
};
|
||||
this.hide = function() {
|
||||
try {
|
||||
if (this.element.classList.contains("show"))
|
||||
this.element.classList.remove("show");
|
||||
waitTimer(500);
|
||||
hideTouchHide();
|
||||
} catch (e) {}
|
||||
};
|
||||
this.setSelectionActive = function(active) {
|
||||
this._hasSelection = !!active;
|
||||
this._updateSelectionVisibility();
|
||||
};
|
||||
this._updateSelectionVisibility = function() {
|
||||
for (var i = 0; i < this._members.length; i++) {
|
||||
var el = this._members[i].element;
|
||||
if (el && el.classList && el.classList.contains("win-selection")) {
|
||||
el.style.display = this._hasSelection ? "" : "none";
|
||||
}
|
||||
}
|
||||
};
|
||||
Object.defineProperty(this, "enabled", {
|
||||
get: function() { return _enable; },
|
||||
set: function(value) {
|
||||
_enable = value;
|
||||
if (!value) {
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "isshowing", {
|
||||
get: function() { return this.element.classList.contains("show"); },
|
||||
set: function(value) {
|
||||
if (value) {
|
||||
this.show();
|
||||
} else {
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
this._eventShowHandler = function(event) {
|
||||
if (!this.isshowing) this.show();
|
||||
else this.hide();
|
||||
};
|
||||
this._eventHideHandler = function(event) {
|
||||
this.hide();
|
||||
};
|
||||
var EventUtil = Windows.UI.Event.Util;
|
||||
var self = this;
|
||||
EventUtil.addEvent(document, "contextmenu", function(event) {
|
||||
self._eventShowHandler(event);
|
||||
event.preventDefault();
|
||||
});
|
||||
var pressTimer = null;
|
||||
|
||||
EventUtil.addEvent(document, "mousedown", function(event) {
|
||||
if (!self._enable) return;
|
||||
pressTimer = setTimeout(function(e) {
|
||||
self._eventShowHandler(e);
|
||||
event.preventDefault();
|
||||
}, 600, event);
|
||||
});
|
||||
|
||||
EventUtil.addEvent(document, "mouseup", function() {
|
||||
clearTimeout(pressTimer);
|
||||
});
|
||||
}
|
||||
global.AppBar = {
|
||||
AppBar: PMAppBar,
|
||||
Command: PMAppBarCommand,
|
||||
Separator: PMAppBarSeparator,
|
||||
BaseMember: PMAppBarBaseMember
|
||||
};
|
||||
})(this);
|
||||
479
shared/html/js/datasrc.js
Normal file
479
shared/html/js/datasrc.js
Normal file
@@ -0,0 +1,479 @@
|
||||
(function(global) {
|
||||
"use strict";
|
||||
global.DataView = {
|
||||
ChangeType: {
|
||||
add: "add",
|
||||
remove: "remove",
|
||||
change: "change",
|
||||
clear: "clear",
|
||||
move: "move",
|
||||
sort: "sort",
|
||||
},
|
||||
};
|
||||
var childAnimeDuration = 120;
|
||||
var parentAnimeDuration = 400;
|
||||
|
||||
function showItemAmine(node) {
|
||||
return Windows.UI.Animation.runAsync(node, [
|
||||
Windows.UI.Animation.Keyframes.Scale.up,
|
||||
Windows.UI.Animation.Keyframes.Opacity.visible,
|
||||
], childAnimeDuration);
|
||||
}
|
||||
|
||||
function hideItemAmine(node) {
|
||||
return Windows.UI.Animation.runAsync(node, [
|
||||
Windows.UI.Animation.Keyframes.Scale.down,
|
||||
Windows.UI.Animation.Keyframes.Opacity.hidden,
|
||||
], childAnimeDuration);
|
||||
}
|
||||
|
||||
function updateItemAmine(node, updateCallback) {
|
||||
return Windows.UI.Animation.runAsync(node, [
|
||||
Windows.UI.Animation.Keyframes.Opacity.hidden,
|
||||
Windows.UI.Animation.Keyframes.Scale.down
|
||||
], 120).then(function() {
|
||||
if (updateCallback && typeof updateCallback === 'function') {
|
||||
updateCallback(node);
|
||||
}
|
||||
return Windows.UI.Animation.runAsync(node, [
|
||||
Windows.UI.Animation.Keyframes.Opacity.visible,
|
||||
Windows.UI.Animation.Keyframes.Scale.up
|
||||
], 120);
|
||||
}).then(function() {
|
||||
return node;
|
||||
});
|
||||
}
|
||||
|
||||
function PMChangeEvent(type, datas, detailOperation) {
|
||||
this.type = type; // ChangeType
|
||||
this.datas = datas || []; // 受影响的数据
|
||||
this.detail = detailOperation || null;
|
||||
}
|
||||
|
||||
function PMDataSource() {
|
||||
var _list = [];
|
||||
var _listeners = [];
|
||||
this.subscribe = function(fn) {
|
||||
if (typeof fn === "function") {
|
||||
_listeners.push(fn);
|
||||
}
|
||||
};
|
||||
|
||||
function emit(evt) {
|
||||
for (var i = 0; i < _listeners.length; i++) {
|
||||
_listeners[i](evt);
|
||||
}
|
||||
}
|
||||
this.add = function(item) {
|
||||
_list.push(item);
|
||||
emit(new PMChangeEvent(
|
||||
DataView.ChangeType.add, [item], { index: _list.length - 1 }
|
||||
));
|
||||
};
|
||||
this.removeAt = function(index) {
|
||||
if (index < 0 || index >= _list.length) return;
|
||||
var item = _list.splice(index, 1)[0];
|
||||
emit(new PMChangeEvent(
|
||||
DataView.ChangeType.remove, [item], { index: index }
|
||||
));
|
||||
};
|
||||
this.changeAt = function(index, newItem) {
|
||||
if (index < 0 || index >= _list.length) return;
|
||||
_list[index] = newItem;
|
||||
emit(new PMChangeEvent(
|
||||
DataView.ChangeType.change, [newItem], { index: index }
|
||||
));
|
||||
};
|
||||
this.clear = function() {
|
||||
_list.length = 0;
|
||||
emit(new PMChangeEvent(
|
||||
DataView.ChangeType.clear
|
||||
));
|
||||
};
|
||||
this.move = function(from, to) {
|
||||
if (from === to ||
|
||||
from < 0 || to < 0 ||
|
||||
from >= _list.length || to >= _list.length) {
|
||||
return;
|
||||
}
|
||||
var item = _list.splice(from, 1)[0];
|
||||
_list.splice(to, 0, item);
|
||||
emit(new PMChangeEvent(
|
||||
DataView.ChangeType.move, [item], { from: from, to: to }
|
||||
));
|
||||
};
|
||||
this.sort = function(compareFn) {
|
||||
_list.sort(compareFn);
|
||||
emit(new PMChangeEvent(
|
||||
DataView.ChangeType.sort,
|
||||
_list.slice(0), { compare: compareFn }
|
||||
));
|
||||
};
|
||||
this.get = function() {
|
||||
return _list.slice(0);
|
||||
};
|
||||
this.addList = function(list, keySelector) {
|
||||
if (!list || !list.length) return;
|
||||
|
||||
var added = [];
|
||||
var changed = [];
|
||||
|
||||
var useKey = keySelector !== void 0;
|
||||
var getKey;
|
||||
|
||||
if (keySelector === null) {
|
||||
getKey = function(item) {
|
||||
return item && item.id;
|
||||
};
|
||||
} else if (typeof keySelector === "function") {
|
||||
getKey = keySelector;
|
||||
}
|
||||
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
var item = list[i];
|
||||
|
||||
if (!useKey) {
|
||||
_list.push(item);
|
||||
added.push({ item: item, index: _list.length - 1 });
|
||||
continue;
|
||||
}
|
||||
|
||||
var key = getKey(item);
|
||||
if (key === void 0) {
|
||||
_list.push(item);
|
||||
added.push({ item: item, index: _list.length - 1, key: key });
|
||||
continue;
|
||||
}
|
||||
|
||||
var found = -1;
|
||||
for (var j = 0; j < _list.length; j++) {
|
||||
if (getKey(_list[j]) === key) {
|
||||
found = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found >= 0) {
|
||||
_list[found] = item;
|
||||
changed.push({ item: item, index: found, key: key });
|
||||
} else {
|
||||
_list.push(item);
|
||||
added.push({ item: item, index: _list.length - 1, key: key });
|
||||
}
|
||||
}
|
||||
|
||||
// 统一发出一个事件
|
||||
if (added.length > 0) {
|
||||
emit(new PMChangeEvent(DataView.ChangeType.add, added));
|
||||
}
|
||||
if (changed.length > 0) {
|
||||
emit(new PMChangeEvent(DataView.ChangeType.change, changed));
|
||||
}
|
||||
};
|
||||
this.updateList = function(list, fnGetKey) {
|
||||
if (!list) list = [];
|
||||
|
||||
var getKey;
|
||||
|
||||
if (fnGetKey === null) {
|
||||
getKey = function(item) {
|
||||
return item && item.id;
|
||||
};
|
||||
} else if (typeof fnGetKey === "function") {
|
||||
getKey = fnGetKey;
|
||||
} else {
|
||||
// 不提供 key:直接整体替换
|
||||
_list = list.slice(0);
|
||||
emit(new PMChangeEvent(
|
||||
DataView.ChangeType.clear
|
||||
));
|
||||
emit(new PMChangeEvent(
|
||||
DataView.ChangeType.add,
|
||||
list.map(function(item, index) {
|
||||
return { item: item, index: index };
|
||||
})
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
var oldList = _list;
|
||||
var newList = list;
|
||||
|
||||
var oldKeyIndex = {};
|
||||
var newKeyIndex = {};
|
||||
|
||||
var i;
|
||||
|
||||
// 建立旧列表 key → index
|
||||
for (i = 0; i < oldList.length; i++) {
|
||||
var ok = getKey(oldList[i]);
|
||||
if (ok !== void 0) {
|
||||
oldKeyIndex[ok] = i;
|
||||
}
|
||||
}
|
||||
|
||||
// 建立新列表 key → index
|
||||
for (i = 0; i < newList.length; i++) {
|
||||
var nk = getKey(newList[i]);
|
||||
if (nk !== void 0) {
|
||||
newKeyIndex[nk] = i;
|
||||
}
|
||||
}
|
||||
|
||||
var added = [];
|
||||
var changed = [];
|
||||
var removed = [];
|
||||
|
||||
// 1️⃣ 找 remove
|
||||
for (i = oldList.length - 1; i >= 0; i--) {
|
||||
var oldItem = oldList[i];
|
||||
var oldKey = getKey(oldItem);
|
||||
|
||||
if (oldKey === void 0 || newKeyIndex[oldKey] === void 0) {
|
||||
removed.push({
|
||||
item: oldItem,
|
||||
index: i,
|
||||
key: oldKey
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 2️⃣ 找 add / change
|
||||
for (i = 0; i < newList.length; i++) {
|
||||
var newItem = newList[i];
|
||||
var newKey = getKey(newItem);
|
||||
|
||||
if (newKey === void 0 || oldKeyIndex[newKey] === void 0) {
|
||||
added.push({
|
||||
item: newItem,
|
||||
index: i,
|
||||
key: newKey
|
||||
});
|
||||
} else {
|
||||
var oldIndex = oldKeyIndex[newKey];
|
||||
var oldItem2 = oldList[oldIndex];
|
||||
|
||||
if (oldItem2 !== newItem) {
|
||||
changed.push({
|
||||
item: newItem,
|
||||
index: oldIndex,
|
||||
key: newKey
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3️⃣ 执行 remove(从后往前)
|
||||
if (removed.length > 0) {
|
||||
for (i = 0; i < removed.length; i++) {
|
||||
_list.splice(removed[i].index, 1);
|
||||
}
|
||||
emit(new PMChangeEvent(
|
||||
DataView.ChangeType.remove,
|
||||
removed
|
||||
));
|
||||
}
|
||||
|
||||
// 4️⃣ 执行 add / change(重建顺序)
|
||||
_list = newList.slice(0);
|
||||
|
||||
if (added.length > 0) {
|
||||
emit(new PMChangeEvent(
|
||||
DataView.ChangeType.add,
|
||||
added
|
||||
));
|
||||
}
|
||||
|
||||
if (changed.length > 0) {
|
||||
emit(new PMChangeEvent(
|
||||
DataView.ChangeType.change,
|
||||
changed
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
function PMDataListView(container, templateFn) {
|
||||
this.container = container;
|
||||
this.templateFn = templateFn;
|
||||
this.listViewControl = this;
|
||||
}
|
||||
PMDataListView.prototype.bind = function(ds) {
|
||||
var self = this;
|
||||
var items = ds.get();
|
||||
self.container.innerHTML = "";
|
||||
|
||||
// 动画队列,保证异步操作不会乱序
|
||||
var queue = Promise.resolve();
|
||||
|
||||
function renderItem(data, index) {
|
||||
var el = self.templateFn(data, index);
|
||||
|
||||
el.addEventListener("click", function() {
|
||||
self._toggleSelect(el);
|
||||
});
|
||||
|
||||
return el;
|
||||
}
|
||||
|
||||
// 初始化渲染
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
self.container.appendChild(renderItem(items[i], i));
|
||||
}
|
||||
|
||||
ds.subscribe(function(evt) {
|
||||
|
||||
// 把每次事件放进队列,保证顺序执行
|
||||
queue = queue.then(function() {
|
||||
switch (evt.type) {
|
||||
|
||||
case DataView.ChangeType.add:
|
||||
{
|
||||
// evt.datas = [{item, index}, ...]
|
||||
var datas = evt.datas;
|
||||
|
||||
// 先批量 append 到 DOM(顺序必须保持)
|
||||
var nodes = [];
|
||||
for (var i = 0; i < datas.length; i++) {
|
||||
var n = renderItem(datas[i].item, datas[i].index);
|
||||
nodes.push(n);
|
||||
self.container.appendChild(n);
|
||||
}
|
||||
|
||||
// 如果数量>=20,动画并行,否则串行
|
||||
if (datas.length >= 20) {
|
||||
var promises = [];
|
||||
for (var j = 0; j < nodes.length; j++) {
|
||||
promises.push(showItemAmine(nodes[j]));
|
||||
}
|
||||
return Promise.all(promises);
|
||||
} else {
|
||||
// 串行
|
||||
var p = Promise.resolve();
|
||||
for (var k = 0; k < nodes.length; k++) {
|
||||
(function(node) {
|
||||
p = p.then(function() {
|
||||
return showItemAmine(node);
|
||||
});
|
||||
})(nodes[k]);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
case DataView.ChangeType.remove:
|
||||
{
|
||||
var node = self.container.children[evt.detail.index];
|
||||
if (!node) return;
|
||||
|
||||
// 隐藏动画完成后再移除
|
||||
return hideItemAmine(node).then(function() {
|
||||
self.container.removeChild(node);
|
||||
});
|
||||
}
|
||||
|
||||
case DataView.ChangeType.change:
|
||||
{
|
||||
var oldNode = self.container.children[evt.detail.index];
|
||||
if (!oldNode) return;
|
||||
|
||||
// 先淡出旧节点
|
||||
return hideItemAmine(oldNode).then(function() {
|
||||
// 替换节点
|
||||
var newNode = renderItem(evt.datas[0], evt.detail.index);
|
||||
self.container.replaceChild(newNode, oldNode);
|
||||
|
||||
// 再淡入新节点
|
||||
return showItemAmine(newNode);
|
||||
});
|
||||
}
|
||||
|
||||
case DataView.ChangeType.clear:
|
||||
self.container.innerHTML = "";
|
||||
return Promise.resolve();
|
||||
|
||||
case DataView.ChangeType.move:
|
||||
{
|
||||
var node = self.container.children[evt.detail.from];
|
||||
var ref = self.container.children[evt.detail.to] || null;
|
||||
if (node) self.container.insertBefore(node, ref);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
case DataView.ChangeType.sort:
|
||||
{
|
||||
self.container.innerHTML = "";
|
||||
for (var i = 0; i < evt.datas.length; i++) {
|
||||
self.container.appendChild(renderItem(evt.datas[i], i));
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
PMDataListView.prototype._toggleSelect = function(ele) {
|
||||
// 如果选择模式为 none,则不处理
|
||||
if (this.selectionMode === "none") return;
|
||||
|
||||
var isSelected = ele.classList.contains("selected");
|
||||
|
||||
if (this.selectionMode === "single") {
|
||||
// 单选:先取消所有选中
|
||||
this._clearSelected();
|
||||
if (!isSelected) {
|
||||
ele.classList.add("selected");
|
||||
}
|
||||
} else if (this.selectionMode === "multiple") {
|
||||
// 多选:点一次切换状态
|
||||
if (isSelected) {
|
||||
ele.classList.remove("selected");
|
||||
} else {
|
||||
ele.classList.add("selected");
|
||||
}
|
||||
}
|
||||
};
|
||||
PMDataListView.prototype._clearSelected = function() {
|
||||
var selected = this.container.querySelectorAll(".selected");
|
||||
for (var i = 0; i < selected.length; i++) {
|
||||
selected[i].classList.remove("selected");
|
||||
}
|
||||
};
|
||||
Object.defineProperty(PMDataListView.prototype, "selectionMode", {
|
||||
get: function() {
|
||||
return this._selectionMode || "none";
|
||||
},
|
||||
set: function(value) {
|
||||
var mode = String(value).toLowerCase();
|
||||
if (mode !== "none" && mode !== "single" && mode !== "multiple") {
|
||||
mode = "none";
|
||||
}
|
||||
this._selectionMode = mode;
|
||||
|
||||
// 切换模式时,清空选中状态(可选)
|
||||
if (mode === "none") {
|
||||
this._clearSelected();
|
||||
}
|
||||
if (mode === "single") {
|
||||
// 单选模式:如果多选了多个,保留第一个
|
||||
var selected = this.container.querySelectorAll(".selected");
|
||||
if (selected.length > 1) {
|
||||
for (var i = 1; i < selected.length; i++) {
|
||||
selected[i].classList.remove("selected");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
Object.defineProperty(PMDataListView.prototype, "selectedItems", {
|
||||
get: function() {
|
||||
return Array.prototype.slice.call(this.container.querySelectorAll(".selected"));
|
||||
}
|
||||
});
|
||||
|
||||
global.DataView.ChangeEvent = PMChangeEvent;
|
||||
global.DataView.DataSource = PMDataSource;
|
||||
global.DataView.ListView = PMDataListView;
|
||||
})(this);
|
||||
50
shared/html/js/manager/pages.js
Normal file
50
shared/html/js/manager/pages.js
Normal file
@@ -0,0 +1,50 @@
|
||||
(function(global) {
|
||||
"use strict";
|
||||
var pkg_ns = external.Package;
|
||||
|
||||
function archsToStr(archs) {
|
||||
var arr = [];
|
||||
for (var i = 0; i < archs.length; i++) {
|
||||
switch (archs[i]) {
|
||||
case 0:
|
||||
arr.push("x86");
|
||||
break;
|
||||
case 5:
|
||||
arr.push("ARM");
|
||||
break;
|
||||
case 9:
|
||||
arr.push("x64");
|
||||
break;
|
||||
case 11:
|
||||
arr.push("Neutral");
|
||||
break;
|
||||
case 12:
|
||||
arr.push("ARM64");
|
||||
break;
|
||||
case 65535:
|
||||
arr.push("Unknown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return arr.join(", ");
|
||||
}
|
||||
|
||||
function setAppInfoPageContent(info) {
|
||||
var page = document.getElementById("page-appinfo");
|
||||
page.querySelector(".display-name").textContent = info.Properties.DisplayName;
|
||||
page.querySelector(".publisher-display-name").textContent = info.Properties.Publisher;
|
||||
page.querySelector(".version").textContent = info.Identity.Version.Expression;
|
||||
page.querySelector(".description").textContent = info.Properties.Description;
|
||||
page.querySelector(".identity .name").textContent = info.Identity.Name;
|
||||
page.querySelector(".identity .publisher").textContent = info.Identity.Publisher;
|
||||
page.querySelector(".identity .publisher-id").textContent = info.Identity.PublisherId;
|
||||
page.querySelector(".identity .family-name").textContent = info.Identity.FamilyName;
|
||||
page.querySelector(".identity .full-name").textContent = info.Identity.FullName;
|
||||
page.querySelector(".identity .architecture").textContent = archsToStr(info.Identity.ProcessArchitecture);
|
||||
var il = info.InstallLocation;
|
||||
var pkg = pkg_ns.fromInstallLocation(il);
|
||||
var json = pkg.jsonText;
|
||||
console.log(JSON.parse(json));
|
||||
}
|
||||
global.setAppInfoPageContent = setAppInfoPageContent;
|
||||
})(this);
|
||||
524
shared/html/js/mgrinit.js
Normal file
524
shared/html/js/mgrinit.js
Normal file
@@ -0,0 +1,524 @@
|
||||
(function(global) {
|
||||
function _createImage(src, onload, onerror) {
|
||||
var img = new Image();
|
||||
|
||||
img.onload = function() {
|
||||
onload(img);
|
||||
};
|
||||
|
||||
img.onerror = function() {
|
||||
onerror && onerror();
|
||||
};
|
||||
|
||||
img.src = src;
|
||||
}
|
||||
|
||||
function getSolidOpaqueBackgroundColor(source, callback) {
|
||||
|
||||
function processImage(img) {
|
||||
if (!img || !img.complete) {
|
||||
callback(null);
|
||||
return;
|
||||
}
|
||||
|
||||
var canvas = document.createElement("canvas");
|
||||
var ctx = canvas.getContext("2d");
|
||||
|
||||
canvas.width = img.naturalWidth || img.width;
|
||||
canvas.height = img.naturalHeight || img.height;
|
||||
|
||||
ctx.drawImage(img, 0, 0);
|
||||
|
||||
try {
|
||||
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||
} catch (e) {
|
||||
// 跨域导致的安全异常
|
||||
callback(null);
|
||||
return;
|
||||
}
|
||||
|
||||
var data = imageData.data;
|
||||
var w = canvas.width;
|
||||
var h = canvas.height;
|
||||
|
||||
var colors = {};
|
||||
var total = 0;
|
||||
|
||||
function pushColor(r, g, b, a) {
|
||||
if (a !== 255) return;
|
||||
var key = r + "," + g + "," + b;
|
||||
colors[key] = (colors[key] || 0) + 1;
|
||||
total++;
|
||||
}
|
||||
|
||||
// top + bottom
|
||||
for (var x = 0; x < w; x++) {
|
||||
var topIndex = (0 * w + x) * 4;
|
||||
var botIndex = ((h - 1) * w + x) * 4;
|
||||
pushColor(data[topIndex], data[topIndex + 1], data[topIndex + 2], data[topIndex + 3]);
|
||||
pushColor(data[botIndex], data[botIndex + 1], data[botIndex + 2], data[botIndex + 3]);
|
||||
}
|
||||
|
||||
// left + right
|
||||
for (var y = 1; y < h - 1; y++) {
|
||||
var leftIndex = (y * w + 0) * 4;
|
||||
var rightIndex = (y * w + (w - 1)) * 4;
|
||||
pushColor(data[leftIndex], data[leftIndex + 1], data[leftIndex + 2], data[leftIndex + 3]);
|
||||
pushColor(data[rightIndex], data[rightIndex + 1], data[rightIndex + 2], data[rightIndex + 3]);
|
||||
}
|
||||
|
||||
if (total === 0) {
|
||||
callback(null);
|
||||
return;
|
||||
}
|
||||
|
||||
var bestKey = null;
|
||||
var bestCount = 0;
|
||||
|
||||
for (var key in colors) {
|
||||
if (colors.hasOwnProperty(key)) {
|
||||
if (colors[key] > bestCount) {
|
||||
bestCount = colors[key];
|
||||
bestKey = key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 95% 纯色阈值
|
||||
if (bestCount / total < 0.95) {
|
||||
callback(null);
|
||||
return;
|
||||
}
|
||||
|
||||
callback(bestKey);
|
||||
}
|
||||
|
||||
// 如果传入的是 img 元素
|
||||
if (source && source.tagName && source.tagName.toLowerCase() === "img") {
|
||||
processImage(source);
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果传入的是 data url 或普通 url
|
||||
if (typeof source === "string") {
|
||||
_createImage(source, processImage, function() {
|
||||
callback(null);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null);
|
||||
}
|
||||
|
||||
function getHamonyColor(source, callback) {
|
||||
|
||||
function _createImage(src, onload, onerror) {
|
||||
var img = new Image();
|
||||
img.onload = function() { onload(img); };
|
||||
img.onerror = function() { onerror && onerror(); };
|
||||
img.src = src;
|
||||
}
|
||||
|
||||
function _toKey(r, g, b) {
|
||||
return r + "," + g + "," + b;
|
||||
}
|
||||
|
||||
function _rgbToHsl(r, g, b) {
|
||||
r /= 255;
|
||||
g /= 255;
|
||||
b /= 255;
|
||||
var max = Math.max(r, g, b);
|
||||
var min = Math.min(r, g, b);
|
||||
var h, s, l = (max + min) / 2;
|
||||
|
||||
if (max === min) {
|
||||
h = s = 0;
|
||||
} 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: h, s: s, l: l };
|
||||
}
|
||||
|
||||
function _hslToRgb(h, s, l) {
|
||||
var r, g, b;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (s === 0) {
|
||||
r = g = b = l;
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
|
||||
return {
|
||||
r: Math.round(r * 255),
|
||||
g: Math.round(g * 255),
|
||||
b: Math.round(b * 255)
|
||||
};
|
||||
}
|
||||
|
||||
function _lum(r, g, b) {
|
||||
function f(x) {
|
||||
x = x / 255;
|
||||
return x <= 0.03928 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
|
||||
}
|
||||
return 0.2126 * f(r) + 0.7152 * f(g) + 0.0722 * f(b);
|
||||
}
|
||||
|
||||
function _contrast(a, b) {
|
||||
var L1 = _lum(a.r, a.g, a.b);
|
||||
var L2 = _lum(b.r, b.g, b.b);
|
||||
var lighter = Math.max(L1, L2);
|
||||
var darker = Math.min(L1, L2);
|
||||
return (lighter + 0.05) / (darker + 0.05);
|
||||
}
|
||||
|
||||
function _tryPureBackground(data, w, h) {
|
||||
var edgeColors = {};
|
||||
var edgeTotal = 0;
|
||||
|
||||
function push(r, g, b, a) {
|
||||
if (a !== 255) return;
|
||||
var k = _toKey(r, g, b);
|
||||
edgeColors[k] = (edgeColors[k] || 0) + 1;
|
||||
edgeTotal++;
|
||||
}
|
||||
|
||||
for (var x = 0; x < w; x++) {
|
||||
var top = (0 * w + x) * 4;
|
||||
var bot = ((h - 1) * w + x) * 4;
|
||||
push(data[top], data[top + 1], data[top + 2], data[top + 3]);
|
||||
push(data[bot], data[bot + 1], data[bot + 2], data[bot + 3]);
|
||||
}
|
||||
for (var y = 1; y < h - 1; y++) {
|
||||
var left = (y * w + 0) * 4;
|
||||
var right = (y * w + (w - 1)) * 4;
|
||||
push(data[left], data[left + 1], data[left + 2], data[left + 3]);
|
||||
push(data[right], data[right + 1], data[right + 2], data[right + 3]);
|
||||
}
|
||||
|
||||
if (edgeTotal === 0) return null;
|
||||
|
||||
var best = null,
|
||||
bestCount = 0;
|
||||
for (var k in edgeColors) {
|
||||
if (edgeColors.hasOwnProperty(k) && edgeColors[k] > bestCount) {
|
||||
bestCount = edgeColors[k];
|
||||
best = k;
|
||||
}
|
||||
}
|
||||
if (best && bestCount / edgeTotal >= 0.95) return best;
|
||||
return null;
|
||||
}
|
||||
|
||||
function _process(img) {
|
||||
if (!img || !img.complete) { callback(null); return; }
|
||||
|
||||
var canvas = document.createElement("canvas");
|
||||
var ctx = canvas.getContext("2d");
|
||||
canvas.width = img.naturalWidth || img.width;
|
||||
canvas.height = img.naturalHeight || img.height;
|
||||
ctx.drawImage(img, 0, 0);
|
||||
|
||||
var imageData;
|
||||
try {
|
||||
imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||
} catch (e) {
|
||||
callback(null);
|
||||
return;
|
||||
}
|
||||
|
||||
var data = imageData.data;
|
||||
var w = canvas.width,
|
||||
h = canvas.height;
|
||||
|
||||
// 1) 尝试纯色背景
|
||||
var pure = _tryPureBackground(data, w, h);
|
||||
if (pure) { callback(pure); return; }
|
||||
|
||||
// 2) 统计不透明像素(抽样)
|
||||
var sumR = 0,
|
||||
sumG = 0,
|
||||
sumB = 0,
|
||||
count = 0;
|
||||
var samples = 0;
|
||||
var step = 4; // 4x抽样,减少性能消耗
|
||||
for (var y = 0; y < h; y += step) {
|
||||
for (var x = 0; x < w; x += step) {
|
||||
var i = (y * w + x) * 4;
|
||||
var a = data[i + 3];
|
||||
if (a === 255) {
|
||||
sumR += data[i];
|
||||
sumG += data[i + 1];
|
||||
sumB += data[i + 2];
|
||||
count++;
|
||||
}
|
||||
samples++;
|
||||
}
|
||||
}
|
||||
if (count === 0) { callback(null); return; }
|
||||
|
||||
var avgR = sumR / count,
|
||||
avgG = sumG / count,
|
||||
avgB = sumB / count;
|
||||
|
||||
// 3) 生成候选色(借鉴流行配色)
|
||||
var base = _rgbToHsl(avgR, avgG, avgB);
|
||||
|
||||
function clamp(v, min, max) { return Math.max(min, Math.min(max, v)); }
|
||||
|
||||
var candidates = [];
|
||||
|
||||
// 中性色(低饱和)
|
||||
candidates.push(_hslToRgb(base.h, 0.05, 0.5));
|
||||
candidates.push(_hslToRgb(base.h, 0.1, 0.6));
|
||||
candidates.push(_hslToRgb(base.h, 0.1, 0.4));
|
||||
|
||||
// 平均色去饱和
|
||||
candidates.push(_hslToRgb(base.h, clamp(base.s * 0.4, 0.05, 0.2), clamp(base.l, 0.2, 0.8)));
|
||||
|
||||
// 互补色(活泼)
|
||||
candidates.push(_hslToRgb((base.h + 0.5) % 1, clamp(base.s * 0.6, 0.1, 0.8), clamp(base.l, 0.35, 0.7)));
|
||||
|
||||
// 类似色
|
||||
candidates.push(_hslToRgb((base.h + 0.083) % 1, clamp(base.s * 0.5, 0.1, 0.8), clamp(base.l, 0.35, 0.7)));
|
||||
candidates.push(_hslToRgb((base.h - 0.083 + 1) % 1, clamp(base.s * 0.5, 0.1, 0.8), clamp(base.l, 0.35, 0.7)));
|
||||
|
||||
// 三分色
|
||||
candidates.push(_hslToRgb((base.h + 0.333) % 1, clamp(base.s * 0.6, 0.1, 0.8), clamp(base.l, 0.35, 0.7)));
|
||||
candidates.push(_hslToRgb((base.h - 0.333 + 1) % 1, clamp(base.s * 0.6, 0.1, 0.8), clamp(base.l, 0.35, 0.7)));
|
||||
|
||||
// 4) 计算最小对比度(与所有不透明像素)
|
||||
function minContrastWithImage(bg) {
|
||||
var bgObj = { r: bg.r, g: bg.g, b: bg.b };
|
||||
var minC = Infinity;
|
||||
|
||||
for (var y = 0; y < h; y += step) {
|
||||
for (var x = 0; x < w; x += step) {
|
||||
var i = (y * w + x) * 4;
|
||||
if (data[i + 3] !== 255) continue;
|
||||
var px = { r: data[i], g: data[i + 1], b: data[i + 2] };
|
||||
var c = _contrast(bgObj, px);
|
||||
if (c < minC) minC = c;
|
||||
}
|
||||
}
|
||||
return minC;
|
||||
}
|
||||
|
||||
var best = null;
|
||||
for (var i = 0; i < candidates.length; i++) {
|
||||
var c = candidates[i];
|
||||
var minC = minContrastWithImage(c);
|
||||
if (minC >= 4.5) {
|
||||
best = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (best) {
|
||||
callback(_toKey(best.r, best.g, best.b));
|
||||
} else {
|
||||
callback(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (source && source.tagName && source.tagName.toLowerCase() === "img") {
|
||||
_process(source);
|
||||
} else if (typeof source === "string") {
|
||||
_createImage(source, _process, function() { callback(null); });
|
||||
} else {
|
||||
callback(null);
|
||||
}
|
||||
}
|
||||
|
||||
function getSuitableBackgroundColor(source, callback) {
|
||||
getSolidOpaqueBackgroundColor(source, function(color) {
|
||||
if (color) {
|
||||
callback(color);
|
||||
} else {
|
||||
getHamonyColor(source, callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function createLocalizedCompare(locale) {
|
||||
return function(a, b) {
|
||||
a = a || "";
|
||||
b = b || "";
|
||||
|
||||
return a.localeCompare(b, locale, {
|
||||
numeric: true, // 2 < 10
|
||||
sensitivity: "base" // 不区分大小写 / 重音
|
||||
});
|
||||
};
|
||||
}
|
||||
var pagemgr = new PageManager();
|
||||
OnLoad.add(function() {
|
||||
var listContainer = document.getElementById("applist");
|
||||
var appItemTemplate = document.getElementById("appitem-template");
|
||||
var mgr = Package.manager;
|
||||
var nstr = Bridge.NString;
|
||||
var datasrc = new DataView.DataSource();
|
||||
var themeColor = Bridge.UI.themeColor;
|
||||
var loadingDisplay = document.getElementById("applist-loading");
|
||||
var loadingStatus = loadingDisplay.querySelector(".title");
|
||||
var listView = new DataView.ListView(listContainer, function(item) {
|
||||
var appItem = appItemTemplate.cloneNode(true);
|
||||
appItem.id = "";
|
||||
appItem.style.display = "";
|
||||
var logoimg = appItem.querySelector("img");
|
||||
logoimg.src = item.Properties.LogoBase64 || logoimg.src;
|
||||
logoimg.parentElement.style.backgroundColor = themeColor;
|
||||
var appName = appItem.querySelector(".displayName");
|
||||
appName.textContent = item.Properties.DisplayName || item.Identity.Name;
|
||||
var appPub = appItem.querySelector(".publisher");
|
||||
appPub.textContent = item.Properties.Publisher;
|
||||
appItem.data = item;
|
||||
appItem.setAttribute("data-install-location", item.InstallLocation);
|
||||
appItem.setAttribute("data-development-mode", item.DevelopmentMode);
|
||||
appItem.setAttribute("data-is-bundle", item.IsBundle);
|
||||
appItem.setAttribute("data-is-framework", item.Properties.Framework);
|
||||
appItem.setAttribute("data-family-name", item.Identity.FamilyName);
|
||||
appItem.setAttribute("data-full-name", item.Identity.FullName);
|
||||
appItem.setAttribute("data-version", item.Identity.Version.Expression);
|
||||
appItem.setAttribute("data-users", item.Users);
|
||||
appItem.setAttribute("data-publisher-id", item.Identity.PublisherId);
|
||||
setTimeout(function(a, b) {
|
||||
getSolidOpaqueBackgroundColor(a, function(color) {
|
||||
try {
|
||||
var pipes = color.split(",");
|
||||
var colorobj = new Color(parseInt(pipes[0]), parseInt(pipes[1]), parseInt(pipes[2]));
|
||||
if (colorobj.hex == "#ffffff" || colorobj.hex == "#000000") throw "too white or black";
|
||||
var rgbstr = colorobj.RGB.toString();
|
||||
b.style.backgroundColor = rgbstr;
|
||||
} catch (e) {}
|
||||
});
|
||||
}, 0, item.Properties.LogoBase64, logoimg.parentElement);
|
||||
Windows.UI.Event.Util.addEvent(appItem.querySelector("div[role=advance] a"), "click", function(e) {
|
||||
e.stopPropagation();
|
||||
try {
|
||||
pagemgr.go("appinfo", this.parentNode.parentNode.parentNode.data);
|
||||
} catch (ex) {}
|
||||
});
|
||||
return appItem;
|
||||
});
|
||||
listView.selectionMode = "single";
|
||||
listView.bind(datasrc);
|
||||
var timer = null;
|
||||
|
||||
function refreshAppList() {
|
||||
function update(datas) {
|
||||
var newDatas = [];
|
||||
for (var i = 0; i < datas.length; i++) {
|
||||
var data = datas[i];
|
||||
if (data.Properties.Framework) continue; // 过滤依赖项
|
||||
var isfind = false; // 过滤系统应用
|
||||
for (var j = 0; data && data.Users && j < data.Users.length; j++) {
|
||||
if (Bridge.NString.equals(data.Users[j], "NT AUTHORITY\\SYSTEM")) {
|
||||
isfind = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isfind) continue;
|
||||
newDatas.push(data);
|
||||
}
|
||||
datasrc.updateList(newDatas, function(item) {
|
||||
return item.Identity.FullName || "";
|
||||
});
|
||||
var compare = function(a, b) { return a - b; };
|
||||
try {
|
||||
compare = createLocalizedCompare(external.System.Locale.currentLocale);
|
||||
} catch (e) {
|
||||
try {
|
||||
compare = createLocalizedCompare(navigator.language);
|
||||
} catch (e) {
|
||||
compare = function(a, b) {
|
||||
if (a < b) return -1;
|
||||
if (a > b) return 1;
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
datasrc.sort(function(a, b) {
|
||||
return compare(a.Properties.DisplayName, b.Properties.DisplayName);
|
||||
});
|
||||
}
|
||||
if (timer) clearTimeout(timer);
|
||||
timer = null;
|
||||
loadingDisplay.style.display = "";
|
||||
loadingDisplay.classList.remove("noloading");
|
||||
|
||||
function waitAndHide() {
|
||||
if (timer) clearTimeout(timer);
|
||||
timer = null;
|
||||
timer = setTimeout(function() {
|
||||
loadingDisplay.style.display = "none";
|
||||
}, 10000);
|
||||
}
|
||||
loadingStatus.textContent = "正在加载数据...";
|
||||
return mgr.get().then(function(result) {
|
||||
loadingDisplay.classList.add("noloading");
|
||||
loadingStatus.textContent = "已经加载了所有数据";
|
||||
update(result.list);
|
||||
waitAndHide();
|
||||
}, function(error) {
|
||||
loadingDisplay.classList.add("noloading");
|
||||
loadingStatus.textContent = "更新时出错: " + (error.result ? (error.result.message || error.result.ErrorCode || "获取失败") : (error.message || error.error || error));
|
||||
try { update(error.list); } catch (e) {}
|
||||
waitAndHide();
|
||||
})
|
||||
}
|
||||
var appbar = document.getElementById("appBar");
|
||||
var appbarControl = new AppBar.AppBar(appbar);
|
||||
var refreshButton = new AppBar.Command();
|
||||
refreshButton.icon = "";
|
||||
refreshButton.label = "刷新";
|
||||
global.refreshAppList2 = function refreshAppList2() {
|
||||
appbarControl.hide();
|
||||
refreshButton.disabled = true;
|
||||
refreshAppList().done(function() {
|
||||
refreshButton.disabled = false;
|
||||
}, function(error) {
|
||||
refreshButton.disabled = false;
|
||||
});
|
||||
}
|
||||
refreshButton.addEventListener("click", refreshAppList2);
|
||||
appbarControl.add(refreshButton);
|
||||
refreshAppList2();
|
||||
pagemgr.register("manager", document.getElementById("tag-manager"), document.getElementById("page-manager"));
|
||||
pagemgr.register("appinfo", document.getElementById("tag-appinfo"), document.getElementById("page-appinfo"), setAppInfoPageContent);
|
||||
var appinfoBackPage = document.getElementById("page-appinfo").querySelector(".win-backbutton");
|
||||
Windows.UI.Event.Util.addEvent(appinfoBackPage, "click", function(e) {
|
||||
pagemgr.back();
|
||||
});
|
||||
pagemgr.addEventListener("load", function(e) {
|
||||
appbarControl.enabled = e == "manager";
|
||||
refreshButton.style.display = e == "manager" ? "" : "none";
|
||||
});
|
||||
pagemgr.go("manager");
|
||||
});
|
||||
})(this);
|
||||
359
shared/html/js/pagemgr.js
Normal file
359
shared/html/js/pagemgr.js
Normal file
@@ -0,0 +1,359 @@
|
||||
(function(global) {
|
||||
"use strict";
|
||||
var eu = Windows.UI.Event.Util;
|
||||
var anime = Windows.UI.Animation;
|
||||
|
||||
function PagePair(guideNode, pageNode, respHandler) {
|
||||
var _guide = guideNode;
|
||||
var _page = pageNode;
|
||||
var _handler = respHandler || null;
|
||||
Object.defineProperty(this, "guide", {
|
||||
get: function() { return _guide; },
|
||||
set: function(value) { _guide = value; }
|
||||
});
|
||||
Object.defineProperty(this, "page", {
|
||||
get: function() { return _page; },
|
||||
set: function(value) { _page = value; }
|
||||
});
|
||||
Object.defineProperty(this, "handler", {
|
||||
get: function() { return _handler; },
|
||||
set: function(value) { _handler = value; }
|
||||
});
|
||||
}
|
||||
|
||||
function PageManager() {
|
||||
var dict = {};
|
||||
var stack = [];
|
||||
var current = -1;
|
||||
var record = {}; // 记录哪些界面已经第一次加载过
|
||||
var paramStack = [];
|
||||
// scrollStack 与 stack 对齐:scrollStack[i] 对应 stack[i]
|
||||
var scrollStack = [];
|
||||
var nowScroll = 0;
|
||||
var events = {
|
||||
firstload: [],
|
||||
beforeload: [],
|
||||
load: [],
|
||||
afterload: [],
|
||||
willunload: [],
|
||||
unload: []
|
||||
};
|
||||
|
||||
function addHandler(type, fn) {
|
||||
if (typeof fn !== "function") return;
|
||||
events[type].push(fn);
|
||||
}
|
||||
|
||||
function removeHandler(type, fn) {
|
||||
var list = events[type];
|
||||
for (var i = list.length - 1; i >= 0; i--) {
|
||||
if (list[i] === fn) {
|
||||
list.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emit(type, arg) {
|
||||
var list = events[type];
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
try {
|
||||
list[i](arg);
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
|
||||
function emitCancelable(type, arg) {
|
||||
var list = events[type];
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
try {
|
||||
var r = list[i](arg);
|
||||
if (r === false) return false;
|
||||
} catch (e) {}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* 添加载入事件
|
||||
* @param {string} type 支持:"firstload"
|
||||
"beforeload"
|
||||
"load"
|
||||
"afterload"
|
||||
"willunload"
|
||||
"unload"
|
||||
|
||||
* @param {function} fn
|
||||
*/
|
||||
this.addEventListener = function(type, fn) {
|
||||
addHandler(type, fn);
|
||||
};
|
||||
/**
|
||||
* 移除载入事件
|
||||
* @param {string} type 支持:"firstload"
|
||||
"beforeload"
|
||||
"load"
|
||||
"afterload"
|
||||
"willunload"
|
||||
"unload"
|
||||
|
||||
* @param {function} fn
|
||||
*/
|
||||
this.removeEventListener = function(type, fn) {
|
||||
removeHandler(type, fn);
|
||||
};
|
||||
|
||||
|
||||
function guideClickHandler(e) {
|
||||
var tag = this.__pageTag;
|
||||
if (!tag) return;
|
||||
if (this.classList.contains("selected")) return;
|
||||
self.go(tag);
|
||||
return;
|
||||
var keys = Object.keys(dict);
|
||||
var promises = [];
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
var pair = dict[key];
|
||||
if (pair.guide.classList.contains("selected")) {
|
||||
promises.push(anime.runAsync(
|
||||
pair.page, [
|
||||
anime.Keyframes.Opacity.hidden,
|
||||
anime.Keyframes.Scale.down
|
||||
]
|
||||
).then(function(el) {
|
||||
el.style.display = "none";
|
||||
}));
|
||||
}
|
||||
}
|
||||
this.classList.add("selected");
|
||||
var after = Promise.join(promises);
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
var pair = dict[key];
|
||||
if (pair.guide.classList.contains("selected")) {
|
||||
pair.page.style.display = "";
|
||||
after.then(function() {
|
||||
anime.runAsync(
|
||||
pair.page, [
|
||||
anime.Keyframes.Opacity.visible,
|
||||
anime.Keyframes.Flyout.toLeft
|
||||
]
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
var self = this;
|
||||
|
||||
function _activate(tag, args, fromHistory) {
|
||||
var pair = dict[tag];
|
||||
if (!pair) throw "Page not found: " + tag;
|
||||
if (!emitCancelable("beforeload", tag)) {
|
||||
return;
|
||||
}
|
||||
var keys = Object.keys(dict);
|
||||
var promises = [];
|
||||
var oldTags = [];
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var k = keys[i];
|
||||
var p = dict[k];
|
||||
if (p.guide.classList.contains("selected") && k !== tag) {
|
||||
if (!emitCancelable("willunload", k)) {
|
||||
return;
|
||||
}
|
||||
oldTags.push(k);
|
||||
promises.push(
|
||||
anime.runAsync(p.page, [
|
||||
anime.Keyframes.Opacity.hidden
|
||||
]).then((function(page, key) {
|
||||
return function() {
|
||||
page.style.display = "none";
|
||||
page.style.opacity = 0;
|
||||
emit("unload", key);
|
||||
};
|
||||
})(p.page, k))
|
||||
);
|
||||
p.guide.classList.remove("selected");
|
||||
}
|
||||
}
|
||||
pair.guide.classList.add("selected");
|
||||
pair.page.style.display = "";
|
||||
emit("load", tag);
|
||||
var after = Promise.join(promises);
|
||||
after.then(function() {
|
||||
if (!record[tag]) {
|
||||
record[tag] = true;
|
||||
emit("firstload", tag);
|
||||
}
|
||||
pair.page.style.opacity = 1;
|
||||
if (pair.handler) {
|
||||
// fix: use pair.handler
|
||||
pair.handler(args);
|
||||
}
|
||||
try {
|
||||
setTimeout(function(tnode) {
|
||||
try {
|
||||
tnode.scrollTop = nowScroll || 0;
|
||||
} catch (ex) {}
|
||||
}, 10, pair.page.parentNode);
|
||||
} catch (ex) {}
|
||||
return anime.runAsync(pair.page, [
|
||||
anime.Keyframes.Opacity.visible,
|
||||
anime.Keyframes.Flyout.toLeft
|
||||
]).then(function() {
|
||||
|
||||
});
|
||||
}).then(function() {
|
||||
emit("afterload", tag);
|
||||
});
|
||||
}
|
||||
this.register = function(tag, guideNode, pageNode, respHandler) {
|
||||
dict[tag] = new PagePair(guideNode, pageNode, respHandler);
|
||||
guideNode.__pageTag = tag;
|
||||
try {
|
||||
eu.removeEvent(guideNode, "click", guideClickHandler);
|
||||
eu.addEvent(guideNode, "click", guideClickHandler);
|
||||
} catch (e) {}
|
||||
};
|
||||
this.edit = function(tag, pagePair) {
|
||||
try {
|
||||
if (dict[tag] && dict[tag].guide) {
|
||||
dict[tag].guide.__pageTag = null;
|
||||
}
|
||||
} catch (e) {}
|
||||
dict[tag] = pagePair;
|
||||
try {
|
||||
pagePair.guide.__pageTag = tag;
|
||||
eu.removeEvent(pagePair.guide, "click", guideClickHandler);
|
||||
eu.addEvent(pagePair.guide, "click", guideClickHandler);
|
||||
} catch (e) {}
|
||||
};
|
||||
this.get = function(tag) {
|
||||
return dict[tag];
|
||||
};
|
||||
this.getGuide = function(tag) {
|
||||
return dict[tag].guide;
|
||||
};
|
||||
this.getPage = function(tag) {
|
||||
return dict[tag].page;
|
||||
};
|
||||
this.getHandler = function(tag) {
|
||||
return dict[tag].handler;
|
||||
};
|
||||
this.setGuide = function(tag, guideNode) {
|
||||
try {
|
||||
if (dict[tag] && dict[tag].guide) {
|
||||
eu.removeEvent(dict[tag].guide, "click", guideClickHandler);
|
||||
dict[tag].guide.__pageTag = null;
|
||||
}
|
||||
} catch (e) {}
|
||||
dict[tag].guide = guideNode;
|
||||
try {
|
||||
guideNode.__pageTag = tag;
|
||||
eu.removeEvent(guideNode, "click", guideClickHandler);
|
||||
eu.addEvent(guideNode, "click", guideClickHandler);
|
||||
} catch (e) {}
|
||||
};
|
||||
this.setPage = function(tag, pageNode) {
|
||||
dict[tag].page = pageNode;
|
||||
};
|
||||
this.setHandler = function(tag, handler) {
|
||||
dict[tag].handler = handler;
|
||||
};
|
||||
this.remove = function(tag) {
|
||||
try {
|
||||
try {
|
||||
if (dict[tag] && dict[tag].guide) {
|
||||
eu.removeEvent(dict[tag].guide, "click", guideClickHandler);
|
||||
}
|
||||
} catch (e) {}
|
||||
delete dict[tag];
|
||||
} catch (e) {}
|
||||
};
|
||||
this.clear = function() {
|
||||
try {
|
||||
var keys = Object.keys(dict);
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
this.remove(keys[i]);
|
||||
}
|
||||
} catch (e) {}
|
||||
};
|
||||
this.jump = function(tag, args) {
|
||||
_activate(tag, args, true);
|
||||
};
|
||||
this.go = function(tag, params) {
|
||||
// limit history
|
||||
if (stack.length > 300) {
|
||||
stack.length = 0;
|
||||
paramStack.length = 0;
|
||||
scrollStack.length = 0;
|
||||
current = -1;
|
||||
}
|
||||
// if we are in the middle, truncate forward history
|
||||
if (current < stack.length - 1) {
|
||||
stack.splice(current + 1);
|
||||
paramStack.splice(current + 1);
|
||||
scrollStack.splice(current + 1);
|
||||
}
|
||||
// save current page scrollTop
|
||||
try {
|
||||
if (current >= 0 && stack[current] && dict[stack[current]] && dict[stack[current]].page && dict[stack[current]].page.parentNode) {
|
||||
scrollStack[current] = dict[stack[current]].page.parentNode.scrollTop;
|
||||
}
|
||||
} catch (e) {}
|
||||
// push new entry
|
||||
stack.push(tag);
|
||||
paramStack.push(params);
|
||||
// initialize scroll value for the new page (will be used if user goes back to it later)
|
||||
scrollStack.push(0);
|
||||
current++;
|
||||
_activate(tag, params, false);
|
||||
};
|
||||
this.back = function() {
|
||||
if (current <= 0) return false;
|
||||
// save scroll of current page
|
||||
try {
|
||||
if (stack[current] && dict[stack[current]] && dict[stack[current]].page && dict[stack[current]].page.parentNode) {
|
||||
scrollStack[current] = dict[stack[current]].page.parentNode.scrollTop;
|
||||
}
|
||||
} catch (e) {}
|
||||
// move back
|
||||
current--;
|
||||
// restore scroll for new current
|
||||
nowScroll = scrollStack[current] || 0;
|
||||
_activate(stack[current], paramStack[current], true);
|
||||
return true;
|
||||
};
|
||||
this.next = function() {
|
||||
if (current >= stack.length - 1) return false;
|
||||
// save scroll of current page
|
||||
try {
|
||||
if (stack[current] && dict[stack[current]] && dict[stack[current]].page && dict[stack[current]].page.parentNode) {
|
||||
scrollStack[current] = dict[stack[current]].page.parentNode.scrollTop;
|
||||
}
|
||||
} catch (e) {}
|
||||
// move forward
|
||||
current++;
|
||||
// restore scroll for new current
|
||||
nowScroll = scrollStack[current] || 0;
|
||||
_activate(stack[current], paramStack[current], true);
|
||||
return true;
|
||||
};
|
||||
Object.defineProperty(this, "current", {
|
||||
get: function() { return stack[current]; },
|
||||
set: function(value) {
|
||||
if (value < 0 || value >= stack.length) return;
|
||||
current = value;
|
||||
// restore scroll for assigned current
|
||||
nowScroll = scrollStack[current] || 0;
|
||||
_activate(stack[current], paramStack[current], true);
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "canback", {
|
||||
get: function() { return current > 0; }
|
||||
});
|
||||
Object.defineProperty(this, "cannext", {
|
||||
get: function() { return current < stack.length - 1; }
|
||||
});
|
||||
}
|
||||
global.PageManager = PageManager;
|
||||
})(this);
|
||||
128
shared/html/js/pkginfo.js
Normal file
128
shared/html/js/pkginfo.js
Normal file
@@ -0,0 +1,128 @@
|
||||
(function(global) {
|
||||
"use strict";
|
||||
var mgr = external.Package.manager;
|
||||
|
||||
function parseJsonCallback(swJson, callback) {
|
||||
var ret = swJson;
|
||||
try {
|
||||
if (swJson) ret = JSON.parse(swJson);
|
||||
} catch (e) {}
|
||||
if (callback) callback(ret);
|
||||
}
|
||||
global.Package = {
|
||||
reader: function(pkgPath) { external.Package.reader(pkgPath); },
|
||||
manager: {
|
||||
add: function(swPkgPath, uOptions) {
|
||||
return new Promise(function(resolve, reject, progress) {
|
||||
mgr.addPackage(swPkgPath, uOptions, function(result) {
|
||||
parseJsonCallback(result, resolve);
|
||||
}, function(result) {
|
||||
parseJsonCallback(result, reject);
|
||||
}, progress);
|
||||
})
|
||||
},
|
||||
get: function() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
mgr.getPackages(function(result) {
|
||||
parseJsonCallback(result, resolve);
|
||||
}, function(result) {
|
||||
parseJsonCallback(result, reject);
|
||||
});
|
||||
});
|
||||
},
|
||||
remove: function(swPkgFullName) {
|
||||
return new Promise(function(resolve, reject, progress) {
|
||||
mgr.removePackage(swPkgFullName, function(result) {
|
||||
parseJsonCallback(result, resolve);
|
||||
}, function(result) {
|
||||
parseJsonCallback(result, reject);
|
||||
}, progress);
|
||||
});
|
||||
},
|
||||
clearup: function(swPkgName, swUserSID) {
|
||||
return new Promise(function(resolve, reject, progress) {
|
||||
mgr.clearupPackage(swPkgName, swUserSID, function(result) {
|
||||
parseJsonCallback(result, resolve);
|
||||
}, function(result) {
|
||||
parseJsonCallback(result, reject);
|
||||
}, progress);
|
||||
});
|
||||
},
|
||||
register: function(swPkgPath, uOptions) {
|
||||
return new Promise(function(resolve, reject, progress) {
|
||||
mgr.registerPackage(swPkgPath, uOptions, function(result) {
|
||||
parseJsonCallback(result, resolve);
|
||||
}, function(result) {
|
||||
parseJsonCallback(result, reject);
|
||||
}, progress);
|
||||
});
|
||||
},
|
||||
registerByFullName: function(swPkgFullName, uOptions) {
|
||||
return new Promise(function(resolve, reject, progress) {
|
||||
mgr.registerPackageByFullName(swPkgFullName, uOptions, function(result) {
|
||||
parseJsonCallback(result, resolve);
|
||||
}, function(result) {
|
||||
parseJsonCallback(result, reject);
|
||||
}, progress);
|
||||
});
|
||||
},
|
||||
setStatus: function(swPkgFullName, uStatus) {
|
||||
mgr.setPackageStatus(swPkgFullName, uStatus);
|
||||
},
|
||||
stage: function(swPkgPath, uOptions) {
|
||||
return new Promise(function(resolve, reject, progress) {
|
||||
mgr.stagePackage(swPkgPath, uOptions, function(result) {
|
||||
parseJsonCallback(result, resolve);
|
||||
}, function(result) {
|
||||
parseJsonCallback(result, reject);
|
||||
}, progress);
|
||||
});
|
||||
},
|
||||
stageUserData: function(swPkgFullName) {
|
||||
return new Promise(function(resolve, reject, progress) {
|
||||
mgr.stagePackageUserData(swPkgFullName, function(result) {
|
||||
parseJsonCallback(result, resolve);
|
||||
}, function(result) {
|
||||
parseJsonCallback(result, reject);
|
||||
}, progress);
|
||||
});
|
||||
},
|
||||
update: function(swPkgPath, uOptions) {
|
||||
return new Promise(function(resolve, reject, progress) {
|
||||
mgr.updatePackage(swPkgPath, uOptions, function(result) {
|
||||
parseJsonCallback(result, resolve);
|
||||
}, function(result) {
|
||||
parseJsonCallback(result, reject);
|
||||
}, progress);
|
||||
});
|
||||
},
|
||||
findByIdentity: function(swIdName, swIdPublisher) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
mgr.findPackageByIdentity(swIdName, swIdPublisher, function(result) {
|
||||
parseJsonCallback(result, resolve);
|
||||
}, function(result) {
|
||||
parseJsonCallback(result, reject);
|
||||
});
|
||||
});
|
||||
},
|
||||
findByFamilyName: function(swFamilyName) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
mgr.findPackageByFamilyName(swFamilyName, function(result) {
|
||||
parseJsonCallback(result, resolve);
|
||||
}, function(result) {
|
||||
parseJsonCallback(result, reject);
|
||||
});
|
||||
});
|
||||
},
|
||||
findByFullName: function(swPkgFullName) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
mgr.findPackageByFullName(swPkgFullName, function(result) {
|
||||
parseJsonCallback(result, resolve);
|
||||
}, function(result) {
|
||||
parseJsonCallback(result, reject);
|
||||
});
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
})(this);
|
||||
@@ -380,4 +380,153 @@ function messageBoxAsync(swText, swTitle, uType, swColor, pfCallback) {
|
||||
if (reject) reject(ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function MessageBoxButton(swDisplayName, nValueReturn) {
|
||||
this.displayName = swDisplayName;
|
||||
this.value = nValueReturn;
|
||||
}
|
||||
|
||||
function messageBoxAdvance(swText, swCaption, aCommands, swColor, pfCallback) {
|
||||
var _lpText = swText;
|
||||
var _lpCaption = swCaption;
|
||||
var msgbox = document.createElement("div");
|
||||
msgbox.classList.add("notice-back");
|
||||
msgbox.classList.add("win-ui-dark");
|
||||
var uniqueId = "msgbox_" + new Date().getTime();
|
||||
msgbox.id = uniqueId;
|
||||
var msgbody = document.createElement("div");
|
||||
msgbody.classList.add("notice-body");
|
||||
if (!IsBlackLabel(swColor)) {
|
||||
msgbody.style.backgroundColor = swColor;
|
||||
}
|
||||
msgbox.appendChild(msgbody);
|
||||
var msgcontainter = document.createElement("div");
|
||||
msgcontainter.style.height = "100%";
|
||||
msgcontainter.style.width = "100%";
|
||||
msgcontainter.style.maxHeight = "100%";
|
||||
msgcontainter.style.minHeight = "0px";
|
||||
msgcontainter.style.boxSizing = "border-box";
|
||||
msgbody.appendChild(msgcontainter);
|
||||
var msgcaption = document.createElement("div");
|
||||
msgcontainter.appendChild(msgcaption);
|
||||
msgcontainter.style.display = "flex";
|
||||
msgcontainter.style.flexDirection = "column";
|
||||
var msgcontent = document.createElement("div");
|
||||
msgcontent.style.flex = "1 1 auto";
|
||||
msgcontent.style.marginRight = "3px";
|
||||
msgcontent.style.overflowX = "hidden";
|
||||
msgcontent.style.overflowY = "auto";
|
||||
msgcontent.style.minHeight = "0px";
|
||||
msgcontainter.appendChild(msgcontent);
|
||||
if (_lpCaption instanceof HTMLElement) {
|
||||
msgcaption.appendChild(_lpCaption);
|
||||
msgcaption.classList.add("notice-title");
|
||||
} else {
|
||||
if (!IsBlackLabel(_lpCaption)) {
|
||||
var msgtitle = document.createElement("h2");
|
||||
msgtitle.textContent = _lpCaption;
|
||||
msgtitle.classList.add("notice-title");
|
||||
msgcaption.appendChild(msgtitle);
|
||||
} else {
|
||||
var msgtitle = document.createElement("h2");
|
||||
msgtitle.textContent = "";
|
||||
msgtitle.classList.add("notice-title");
|
||||
msgcaption.appendChild(msgtitle);
|
||||
}
|
||||
}
|
||||
if (_lpText instanceof HTMLElement || _lpText instanceof HTMLDivElement || typeof _lpText !== "string") {
|
||||
try {
|
||||
_lpText.classList.add("notice-text");
|
||||
msgcontent.appendChild(_lpText);
|
||||
} catch (e) {
|
||||
if (!IsBlackLabel(_lpText)) {
|
||||
var msgtext = document.createElement("p");
|
||||
msgtext.textContent = _lpText;
|
||||
msgtext.classList.add("notice-text");
|
||||
if (IsBlackLabel(_lpCaption)) {
|
||||
msgtext.style.marginTop = "0";
|
||||
}
|
||||
msgcontent.appendChild(msgtext);
|
||||
} else {
|
||||
var msgtext = document.createElement("p");
|
||||
msgtext.innerText = "";
|
||||
msgtext.classList.add("notice-text");
|
||||
if (IsBlackLabel(_lpCaption)) {
|
||||
msgtext.style.marginTop = "0";
|
||||
}
|
||||
msgcontent.appendChild(msgtext);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!IsBlackLabel(_lpText)) {
|
||||
var msgtext = document.createElement("p");
|
||||
msgtext.textContent = _lpText;
|
||||
msgtext.classList.add("notice-text");
|
||||
if (IsBlackLabel(_lpCaption)) {
|
||||
msgtext.style.marginTop = "0";
|
||||
}
|
||||
msgcontent.appendChild(msgtext);
|
||||
} else {
|
||||
var msgtext = document.createElement("p");
|
||||
msgtext.innerText = "";
|
||||
msgtext.classList.add("notice-text");
|
||||
if (IsBlackLabel(_lpCaption)) {
|
||||
msgtext.style.marginTop = "0";
|
||||
}
|
||||
msgcontent.appendChild(msgtext);
|
||||
}
|
||||
}
|
||||
var msgctrls = document.createElement("div");
|
||||
msgctrls.classList.add("notice-controls");
|
||||
msgcontainter.appendChild(msgctrls);
|
||||
if (aCommands.length <= 0) {
|
||||
aCommands.push(new MessageBoxButton(GetLocaleStringFromResId(800) || "OK", MBRET.IDOK));
|
||||
}
|
||||
for (var i = 0; i < aCommands.length; i++) {
|
||||
var cmd = aCommands[i];
|
||||
var btn = document.createElement("button");
|
||||
btn.textContent = cmd.displayName;
|
||||
btn.setAttribute("data-msgbox-value", cmd.value);
|
||||
Windows.UI.Event.Util.addEvent(btn, "click", function(event) {
|
||||
var btns = this.parentNode.querySelectorAll("button");
|
||||
var lastbtnstatus = [];
|
||||
for (var j = 0; j < btns.length; j++) {
|
||||
lastbtnstatus.push(btns[j].disabled);
|
||||
btns[j].disabled = true;
|
||||
}
|
||||
try {
|
||||
pfCallback(this.getAttribute("data-msgbox-value"));
|
||||
} catch (e) {}
|
||||
msgbox.style.opacity = 0;
|
||||
setTimeout(function(nodes, laststatus) {
|
||||
for (var k = 0; k < nodes.length; k++) {
|
||||
nodes[k].disabled = laststatus[k];
|
||||
}
|
||||
document.body.removeChild(msgbox);
|
||||
}, 500, btns, lastbtnstatus);
|
||||
});
|
||||
msgctrls.appendChild(btn);
|
||||
}
|
||||
document.body.appendChild(msgbox);
|
||||
setTimeout(function() {
|
||||
msgbox.style.opacity = 1;
|
||||
}, 1);
|
||||
return msgbox.id;
|
||||
}
|
||||
|
||||
function messageBoxAdvanceAsync(swText, swCaption, aCommands, swColor) {
|
||||
if (typeof Promise === "undefined") {
|
||||
console.error("Promise is not supported in this environment.");
|
||||
messageBoxAdvance(swText, swCaption, aCommands, swColor);
|
||||
}
|
||||
return new Promise(function(resolve, reject) {
|
||||
try {
|
||||
messageBoxAdvance(swText, swCaption, aCommands, swColor, function(valueReturn) {
|
||||
if (resolve) resolve(valueReturn);
|
||||
});
|
||||
} catch (ex) {
|
||||
if (reject) reject(ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
<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/1.0/css/ui-light.css" id="winjs-style-1">
|
||||
<link rel="stylesheet" href="libs/winjs/2.0/css/ui-light.css" id="winjs-style">
|
||||
<script type="text/javascript" src="libs/winjs/1.0/js/base.js"></script>
|
||||
<script type="text/javascript" src="libs/winjs/1.0/js/ui.js"></script>
|
||||
@@ -21,38 +22,77 @@
|
||||
<link rel="stylesheet" href="fonts/segx.css">
|
||||
<link rel="stylesheet" href="manager/page.css">
|
||||
<link rel="stylesheet" href="manager/appitem.css">
|
||||
<link rel="stylesheet" href="manager/appbar.css">
|
||||
<script type="text/javascript" src="js/event.js"></script>
|
||||
<script type="text/javascript" src="js/tileback.js"></script>
|
||||
<script type="text/javascript" src="js/load.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="libs/msgbox/msgbox.css">
|
||||
<script type="text/javascript" src="libs/msgbox/msgbox.js"></script>
|
||||
<script type="text/javascript" src="js/init.js"></script>
|
||||
<script type="text/javascript" src="js/pkginfo.js"></script>
|
||||
<script type="text/javascript" src="js/datasrc.js"></script>
|
||||
<script type="text/javascript" src="js/appbar.js"></script>
|
||||
<script type="text/javascript" src="js/pagemgr.js"></script>
|
||||
<script type="text/javascript" src="js/manager/pages.js"></script>
|
||||
<script type="text/javascript" src="js/mgrinit.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="settingpage" class="pagecontainer full">
|
||||
<div id="managerpage" class="pagecontainer full">
|
||||
<div class="page full guide fold">
|
||||
<main class="main padding">
|
||||
<div id="page-manager">
|
||||
<div id="page-manager" style="display: none;" class="ispage">
|
||||
<h2>应用</h2>
|
||||
<p>在这里,可以对安装的 Windows 商店应用进行管理。</p>
|
||||
<h3>安装的应用</h3>
|
||||
<template id="appitem-template">
|
||||
|
||||
</template>
|
||||
<div class="appitem selected">
|
||||
<div role="img">
|
||||
<img width="24" height="24" src="images/applogo.default.png" />
|
||||
<br>
|
||||
<div class="app-loading" id="applist-loading" style="display: none;">
|
||||
<progress class="win-ring"></progress>
|
||||
<span class="win-label title">正在加载应用...</span>
|
||||
<br>
|
||||
</div>
|
||||
<div class="appitem" id="appitem-template" style="display: none;">
|
||||
<div role="img" style="pointer-events: none;">
|
||||
<img width="" height="" src="images/applogo.default.png" />
|
||||
</div>
|
||||
<div role="divide"></div>
|
||||
<div role="divide" style="pointer-events: none;"></div>
|
||||
<div role="excepticon">
|
||||
<div role="title" class="win-type-x-small"><span>App Name</span></div>
|
||||
<div role="control"><button>卸载</button></div>
|
||||
<div role="title" class="win-type-x-small" style="pointer-events: none;">
|
||||
<span class="displayName">App Name</span><br>
|
||||
<span class="publisher">Publisher</span>
|
||||
</div>
|
||||
<div role="advance">
|
||||
<a>高级选项</a>
|
||||
</div>
|
||||
<div role="control">
|
||||
<button name="uninstall">卸载</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ul>
|
||||
<li></li>
|
||||
</ul>
|
||||
<div id="applist" class="appitem-list" style="width: 100%; height: auto;">
|
||||
</div>
|
||||
<div class="bottom-compensate"></div>
|
||||
</div>
|
||||
<div id="page-appinfo" class="ispage app-detailpage">
|
||||
<header>
|
||||
<button class="win-backbutton"></button>
|
||||
<h2 class="display-name">App DisplayName</h2>
|
||||
</header>
|
||||
<span class="publisher-display-name">App PublisherDisplayName</span><br>
|
||||
<span class="version">App Version</span><br>
|
||||
<span class="description">App Description</span>
|
||||
<p><strong>应用身份</strong></p>
|
||||
<div class="identity win-type-body" style="width: 100%; max-width: 100%; box-sizing: border-box; -ms-user-select: element;">
|
||||
<span style="font-weight: bold;">名称</span><span>: </span><span class="name"></span><br>
|
||||
<span style="font-weight: bold;">发布者</span><span>: </span><span class="publisher"></span><br>
|
||||
<span style="font-weight: bold;">发布者 ID</span><span>: </span><span class="publisher-id"></span><br>
|
||||
<span style="font-weight: bold;">系列名</span><span>: </span><span class="family-name"></span><br>
|
||||
<span style="font-weight: bold;">全名</span><span>: </span><span class="full-name"></span><br>
|
||||
<span style="font-weight: bold;">支持的处理器架构</span><span>: </span><span class="architecture"></span><br>
|
||||
</div>
|
||||
<p><strong>卸载</strong></p>
|
||||
<p>卸载此应用及其设置。</p>
|
||||
<button id="detail-uninstall-btn" data-app-fullname="">卸载</button>
|
||||
</div>
|
||||
</main>
|
||||
<aside class="win-ui-dark">
|
||||
@@ -75,10 +115,14 @@
|
||||
</ul>
|
||||
<hr>
|
||||
<ul class="list">
|
||||
<li>
|
||||
<li id="tag-manager">
|
||||
<div role="img"></div>
|
||||
<span class="win-type-base">管理</span>
|
||||
</li>
|
||||
<li id="tag-appinfo" class="subitem">
|
||||
<div role="img"></div>
|
||||
<span class="win-type-base">应用信息</span>
|
||||
</li>
|
||||
<li>
|
||||
<div role="img"></div>
|
||||
<span class="win-type-base">Manager</span>
|
||||
@@ -88,6 +132,8 @@
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win-overlay win-commandlayout win-appbar win-bottom appbar win-ui-dark" id="appBar" role="menubar">
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
49
shared/html/manager/appbar.css
Normal file
49
shared/html/manager/appbar.css
Normal file
@@ -0,0 +1,49 @@
|
||||
.win-bottom {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
top: auto;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.appbar {
|
||||
-ms-transform: translateY(100%);
|
||||
transform: translateY(100%);
|
||||
transition: all 0.5s cubic-bezier(0.1, 0.9, 0.2, 1);
|
||||
}
|
||||
|
||||
.appbar.show {
|
||||
-ms-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.appbar.win-ui-dark .win-label {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.appbar-touchhide {
|
||||
background-color: transparent;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 88px;
|
||||
}
|
||||
|
||||
.appbar button.win-command,
|
||||
.win-appbar .win-commandlayout button.win-command {
|
||||
box-sizing: border-box;
|
||||
/* 含 padding/border 计算宽度 */
|
||||
min-width: 100px;
|
||||
/* 强制最小宽度 100px */
|
||||
}
|
||||
|
||||
|
||||
/* 同时覆盖在窄屏 media query 中的行为(确保在 @media (max-width:1023px) 之后或在文件末尾定义) */
|
||||
|
||||
@media (max-width: 1023px) {
|
||||
.appbar button.win-command,
|
||||
.win-appbar .win-commandlayout button.win-command {
|
||||
min-width: 100px;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
height: 60px;
|
||||
width: 450px;
|
||||
width: 460px;
|
||||
max-width: 100%;
|
||||
display: -ms-flexbox;
|
||||
/* IE10 */
|
||||
@@ -53,6 +53,14 @@
|
||||
-ms-flex-line-pack: center;
|
||||
/* IE10 -> align-content */
|
||||
align-content: center;
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
transition: all 0.3s cubic-bezier(0.1, 0.9, 0.2, 1);
|
||||
}
|
||||
|
||||
.appitem div[role=img] img {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.appitem div[role=divide] {
|
||||
@@ -65,6 +73,23 @@
|
||||
font-weight: normal;
|
||||
flex: 1;
|
||||
-ms-flex: 1;
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.appitem div[role=excepticon] div[role=advance] {
|
||||
display: none;
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
transition: all 0.3s cubic-bezier(0.1, 0.9, 0.2, 1);
|
||||
}
|
||||
|
||||
.appitem.selected div[role=excepticon] div[role=advance] {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.appitem div[role=excepticon] {
|
||||
@@ -85,12 +110,12 @@
|
||||
-ms-flex-pack: start;
|
||||
/* IE10 -> justify-content */
|
||||
justify-content: flex-start;
|
||||
width: calc(100% - 40px - 10px);
|
||||
}
|
||||
|
||||
.appitem div[role=excepticon] div[role=control] {
|
||||
display: none;
|
||||
/* IE10 */
|
||||
display: flex;
|
||||
-ms-flex-direction: row-reverse;
|
||||
/* IE10 */
|
||||
flex-direction: row-reverse;
|
||||
@@ -106,13 +131,95 @@
|
||||
-ms-flex-align: center;
|
||||
/* IE10 -> align-items */
|
||||
align-items: center;
|
||||
transition: all 0.3s cubic-bezier(0.1, 0.9, 0.2, 1);
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.appitem.selected {
|
||||
height: 119px;
|
||||
background-color: rgba(232, 232, 232, 1);
|
||||
}
|
||||
|
||||
.appitem.selected div[role=excepticon] div[role=control] {
|
||||
display: flex;
|
||||
display: -ms-flexbox;
|
||||
opacity: 1;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
ul.appitem-list,
|
||||
ul.appitem-list li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.appitem .displayName,
|
||||
.appitem .publisher {
|
||||
text-overflow: ellipsis;
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
white-space: nowrap;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.appitem .publisher {
|
||||
color: rgb(102, 102, 102);
|
||||
}
|
||||
|
||||
.app-loading {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-content: center;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.app-loading.noloading progress {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.app-loading .title {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.app-loading.noloading .title {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.app-detailpage header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
align-content: flex-start;
|
||||
justify-content: flex-start;
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 100%;
|
||||
height: 67px;
|
||||
box-sizing: border-box;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.app-detailpage header .win-backbutton {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
font-size: 11.9pt;
|
||||
line-height: 32px;
|
||||
min-width: 35px;
|
||||
min-height: 35px;
|
||||
}
|
||||
|
||||
.app-detailpage header .display-name {
|
||||
padding-left: 10px;
|
||||
box-sizing: border-box;
|
||||
width: calc(100% - 35px - 10px);
|
||||
overflow-y: hidden;
|
||||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
@@ -168,6 +168,7 @@ aside>nav ul li {
|
||||
|
||||
.page.fold>aside>nav ul li {
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
aside>nav ul li div[role=img] {
|
||||
@@ -189,6 +190,33 @@ aside>nav ul li div[role=img] {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.page>aside>nav ul li.selected {
|
||||
background-color: #159d9d;
|
||||
}
|
||||
|
||||
.page>aside>nav ul li.selected:hover {
|
||||
background-color: rgb(23, 187, 187);
|
||||
}
|
||||
|
||||
.page>aside>nav ul li.selected:active {
|
||||
background-color: rgb(29, 224, 224);
|
||||
}
|
||||
|
||||
.page>aside>nav ul li.subitem {
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.page>aside>nav ul li.subitem.selected {
|
||||
opacity: 1;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.page.fold>aside>nav ul li * {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.page.fold>aside>nav ul li div[role=img] {
|
||||
min-width: 90px;
|
||||
width: 90px;
|
||||
@@ -213,7 +241,8 @@ aside>nav ul li div[role=img] {
|
||||
|
||||
.page>aside>nav ul li div[role=img] {
|
||||
font-size: 15pt;
|
||||
margin-right: 5px;
|
||||
margin-right: 10px;
|
||||
width: 1em;
|
||||
}
|
||||
|
||||
.page>aside>nav ul li.title div[role=img] {
|
||||
@@ -256,7 +285,7 @@ aside>nav ul li div[role=img] {
|
||||
|
||||
.page.fold>aside>nav ul li:hover div[role=img] {
|
||||
min-width: 0;
|
||||
width: auto;
|
||||
width: 1em;
|
||||
}
|
||||
|
||||
.page.fold>aside>nav ul li:hover span {
|
||||
@@ -292,6 +321,10 @@ aside>nav ul li div[role=img] {
|
||||
overflow-y: visible;
|
||||
}
|
||||
|
||||
.main {
|
||||
transition: all 0.3s cubic-bezier(0.1, 0.9, 0.2, 1);
|
||||
}
|
||||
|
||||
.main.padding {
|
||||
padding: 44px 60px;
|
||||
}
|
||||
@@ -307,12 +340,18 @@ aside>nav ul li div[role=img] {
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
background-color: white;
|
||||
transition: all 0.3s cubic-bezier(0.1, 0.9, 0.2, 1);
|
||||
}
|
||||
|
||||
.section.padding {
|
||||
padding: 44px 60px;
|
||||
}
|
||||
|
||||
.section.padding .bottom-compensate {
|
||||
.bottom-compensate {
|
||||
padding-bottom: 44px;
|
||||
}
|
||||
|
||||
.ispage {
|
||||
opacity: 1;
|
||||
transition: all 0.4s cubic-bezier(0.1, 0.9, 0.2, 1);
|
||||
}
|
||||
Reference in New Issue
Block a user