mirror of
https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git
synced 2026-04-11 17:57:19 +10:00
Update Shell
Fix Package Store Logo Read
This commit is contained in:
Binary file not shown.
@@ -183,7 +183,7 @@ public ref class SplashForm: public System::Windows::Forms::Form
|
||||
picbox->Image = img;
|
||||
}
|
||||
}
|
||||
catch (...) { }
|
||||
catch (...) {}
|
||||
if (splashimg) picbox->Image = splashimg;
|
||||
if (backcolor != Drawing::Color::Transparent)
|
||||
{
|
||||
@@ -434,6 +434,512 @@ HRESULT UpdateAppxPackageFromPath (
|
||||
detailmsg = lpmsg ? lpmsg : L"";
|
||||
return hr;
|
||||
}
|
||||
bool IsWindows10 ()
|
||||
{
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4996)
|
||||
OSVERSIONINFOEX osvi = {0};
|
||||
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
|
||||
osvi.dwMajorVersion = 10;
|
||||
DWORDLONG conditionMask = 0;
|
||||
VER_SET_CONDITION (conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||
if (VerifyVersionInfoW (&osvi, VER_MAJORVERSION, conditionMask)) return TRUE;
|
||||
DWORD error = GetLastError ();
|
||||
return (error == ERROR_OLD_WIN_VERSION) ? FALSE : FALSE;
|
||||
#pragma warning(pop)
|
||||
}
|
||||
void ActivateApp (Object ^appid)
|
||||
{
|
||||
auto res = ActivateAppxApplication (MPStringToStdW (appid->ToString ()));
|
||||
}
|
||||
[ComVisible (true)]
|
||||
public ref class AppListWnd: public System::Windows::Forms::Form
|
||||
{
|
||||
public:
|
||||
using WebBrowser = System::Windows::Forms::WebBrowser;
|
||||
using Timer = System::Windows::Forms::Timer;
|
||||
[ComVisible (true)]
|
||||
ref class IBridge
|
||||
{
|
||||
private:
|
||||
AppListWnd ^wndinst = nullptr;
|
||||
public:
|
||||
IBridge (AppListWnd ^wnd): wndinst (wnd) {}
|
||||
ref class _I_HResult
|
||||
{
|
||||
private:
|
||||
HRESULT hr = S_OK;
|
||||
String ^errorcode = "";
|
||||
String ^detailmsg = "";
|
||||
public:
|
||||
_I_HResult (HRESULT hres)
|
||||
{
|
||||
hr = hres;
|
||||
detailmsg = CStringToMPString (HResultToMessage (hres));
|
||||
}
|
||||
_I_HResult (HRESULT hres, String ^error, String ^message)
|
||||
{
|
||||
hr = hres;
|
||||
errorcode = error;
|
||||
detailmsg = message;
|
||||
}
|
||||
property HRESULT HResult { HRESULT get () { return hr; }}
|
||||
property String ^ErrorCode { String ^get () { return errorcode; }}
|
||||
property String ^Message { String ^get () { return detailmsg; }}
|
||||
property bool Succeeded { bool get () { return SUCCEEDED (hr); }}
|
||||
property bool Failed { bool get () { return FAILED (hr); }}
|
||||
};
|
||||
ref class _I_System
|
||||
{
|
||||
private:
|
||||
AppListWnd ^wndinst = nullptr;
|
||||
public:
|
||||
ref class _I_UI
|
||||
{
|
||||
private:
|
||||
AppListWnd ^wndinst = nullptr;
|
||||
public:
|
||||
ref struct _I_UI_Size
|
||||
{
|
||||
private:
|
||||
int m_width = 0;
|
||||
int m_height = 0;
|
||||
public:
|
||||
property int width { int get () { return m_width; } }
|
||||
property int height { int get () { return m_height; }}
|
||||
property int Width { int get () { return m_width; } }
|
||||
property int Height { int get () { return m_height; }}
|
||||
int getWidth () { return m_width; }
|
||||
int getHeight () { return m_height; }
|
||||
_I_UI_Size (int w, int h): m_width (w), m_height (h) {}
|
||||
};
|
||||
_I_UI (AppListWnd ^wnd): wndinst (wnd) {}
|
||||
property int DPIPercent { int get () { return GetDPI (); }}
|
||||
property double DPI { double get () { return DPIPercent * 0.01; }}
|
||||
property _I_UI_Size ^WndSize { _I_UI_Size ^get () { return gcnew _I_UI_Size (wndinst->Width, wndinst->Height); } }
|
||||
property _I_UI_Size ^ClientSize { _I_UI_Size ^get () { auto cs = wndinst->ClientSize; return gcnew _I_UI_Size (cs.Width, cs.Height); } }
|
||||
property String ^ThemeColor { String ^get () { return ColorToHtml (GetDwmThemeColor ()); } }
|
||||
property bool DarkMode { bool get () { return IsAppInDarkMode (); }}
|
||||
property String ^HighContrast
|
||||
{
|
||||
String ^get ()
|
||||
{
|
||||
auto highc = GetHighContrastTheme ();
|
||||
switch (highc)
|
||||
{
|
||||
case HighContrastTheme::None: return "none";
|
||||
break;
|
||||
case HighContrastTheme::Black: return "black";
|
||||
break;
|
||||
case HighContrastTheme::White: return "white";
|
||||
break;
|
||||
case HighContrastTheme::Other: return "high";
|
||||
break;
|
||||
default: return "none";
|
||||
break;
|
||||
}
|
||||
return "none";
|
||||
}
|
||||
}
|
||||
};
|
||||
ref class _I_Resources
|
||||
{
|
||||
public:
|
||||
String ^GetById (unsigned int uiResId) { return GetRCStringCli (uiResId); }
|
||||
unsigned ToId (String ^lpResName)
|
||||
{
|
||||
auto it = g_nameToId.find (MPStringToStdA (lpResName));
|
||||
return (it != g_nameToId.end ()) ? it->second : 0;
|
||||
}
|
||||
String ^ToName (unsigned int ulResId)
|
||||
{
|
||||
for (auto &it : g_nameToId) { if (it.second == ulResId) return CStringToMPString (it.first); }
|
||||
return "";
|
||||
}
|
||||
String ^GetByName (String ^lpResId) { return GetById (ToId (lpResId)); }
|
||||
String ^operator [] (unsigned int uiResId) { return GetRCStringCli (uiResId); }
|
||||
};
|
||||
private:
|
||||
_I_UI ^ui = gcnew _I_UI (wndinst);
|
||||
_I_Resources ^ires = gcnew _I_Resources ();
|
||||
public:
|
||||
_I_System (AppListWnd ^wnd): wndinst (wnd) {}
|
||||
property _I_UI ^UI { _I_UI ^get () { return ui; } }
|
||||
property _I_Resources ^Resources { _I_Resources ^get () { return ires; } }
|
||||
property bool IsWindows10
|
||||
{
|
||||
bool get ()
|
||||
{
|
||||
OSVERSIONINFOEX osvi = {0};
|
||||
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
|
||||
osvi.dwMajorVersion = 10;
|
||||
DWORDLONG conditionMask = 0;
|
||||
VER_SET_CONDITION (conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||
if (VerifyVersionInfoW (&osvi, VER_MAJORVERSION, conditionMask)) return TRUE;
|
||||
DWORD error = GetLastError ();
|
||||
return (error == ERROR_OLD_WIN_VERSION) ? FALSE : FALSE;
|
||||
}
|
||||
}
|
||||
};
|
||||
ref class _I_IEFrame
|
||||
{
|
||||
private:
|
||||
AppListWnd ^wndinst = nullptr;
|
||||
public:
|
||||
_I_IEFrame (AppListWnd ^wnd): wndinst (wnd) {}
|
||||
property int Scale
|
||||
{
|
||||
int get () { return wndinst->PageScale; }
|
||||
void set (int value) { return wndinst->PageScale = value; }
|
||||
}
|
||||
property int Version { int get () { return GetInternetExplorerVersionMajor (); }}
|
||||
String ^ParseHtmlColor (String ^color)
|
||||
{
|
||||
auto dcolor = Drawing::ColorTranslator::FromHtml (color);
|
||||
{
|
||||
rapidjson::Document doc;
|
||||
doc.SetObject ();
|
||||
auto &alloc = doc.GetAllocator ();
|
||||
doc.AddMember ("r", (uint16_t)dcolor.R, alloc);
|
||||
doc.AddMember ("g", (uint16_t)dcolor.G, alloc);
|
||||
doc.AddMember ("b", (uint16_t)dcolor.B, alloc);
|
||||
doc.AddMember ("a", (uint16_t)dcolor.A, alloc);
|
||||
rapidjson::StringBuffer buffer;
|
||||
rapidjson::Writer <rapidjson::StringBuffer> writer (buffer);
|
||||
doc.Accept (writer);
|
||||
std::string utf8 = buffer.GetString ();
|
||||
std::wstring_convert <std::codecvt_utf8 <wchar_t>> conv;
|
||||
return CStringToMPString (conv.from_bytes (utf8));
|
||||
}
|
||||
return "{}";
|
||||
}
|
||||
};
|
||||
ref class _I_String
|
||||
{
|
||||
public:
|
||||
ref class _I_NString
|
||||
{
|
||||
public:
|
||||
bool NEquals (String ^l, String ^r) { return IsNormalizeStringEquals (MPStringToPtrW (l), MPStringToPtrW (r)); }
|
||||
bool Empty (String ^l) { return IsNormalizeStringEmpty (MPStringToStdW (l)); }
|
||||
int Compare (String ^l, String ^r) { return NormalizeStringCompare (MPStringToPtrW (l), MPStringToPtrW (r)); }
|
||||
int Length (String ^l) { return GetNormalizeStringLength (MPStringToStdW (l)); }
|
||||
};
|
||||
private:
|
||||
_I_NString ^nstr = gcnew _I_NString ();
|
||||
public:
|
||||
property _I_NString ^NString { _I_NString ^get () { return nstr; }}
|
||||
String ^Trim (String ^src)
|
||||
{
|
||||
std::wstring csrc = MPStringToStdW (src);
|
||||
return CStringToMPString (::StringTrim (csrc));
|
||||
}
|
||||
String ^ToLower (String ^src) { return CStringToMPString (StringToLower (MPStringToStdW (src))); }
|
||||
String ^ToUpper (String ^src) { return CStringToMPString (StringToUpper (MPStringToStdW (src))); }
|
||||
String ^Format (String ^fmt, ... array <Object ^> ^args) { return FormatString (fmt, args); }
|
||||
String ^FormatInnerHTML (String ^fmt, ... array <Object ^> ^args)
|
||||
{
|
||||
std::wstring ihtml = EscapeToInnerXml (MPStringToStdW (fmt));
|
||||
auto pih = CStringToMPString (ihtml);
|
||||
auto newargs = gcnew array <Object ^> (args->Length);
|
||||
for (size_t i = 0; i < args->Length; i ++)
|
||||
{
|
||||
auto %p = newargs [i];
|
||||
p = Format ("<span>{0}</span>", EscapeToInnerXml (Format ("{0}", args [i])));
|
||||
}
|
||||
return Format (pih, newargs);
|
||||
}
|
||||
};
|
||||
ref class _I_Package
|
||||
{
|
||||
public:
|
||||
String ^GetPackagesToJson ()
|
||||
{
|
||||
rapidjson::Document doc;
|
||||
doc.SetArray ();
|
||||
auto &alloc = doc.GetAllocator ();
|
||||
for (auto &it : g_pkginfo)
|
||||
{
|
||||
rapidjson::Value member (rapidjson::kStringType);
|
||||
member.SetString (ws2utf8 (it.filepath).c_str (), alloc);
|
||||
doc.PushBack (member, alloc);
|
||||
}
|
||||
rapidjson::StringBuffer buffer;
|
||||
rapidjson::Writer <rapidjson::StringBuffer> writer (buffer);
|
||||
doc.Accept (writer);
|
||||
std::string utf8 = buffer.GetString ();
|
||||
std::wstring_convert <std::codecvt_utf8 <wchar_t>> conv;
|
||||
return CStringToMPString (conv.from_bytes (utf8));
|
||||
}
|
||||
String ^GetPackageInfoToJson (String ^filepath)
|
||||
{
|
||||
std::wstring fpath = MPStringToStdW (filepath);
|
||||
for (auto &it : g_pkginfo)
|
||||
{
|
||||
if (PathEquals (it.filepath, fpath))
|
||||
{
|
||||
return CStringToMPString (it.parseJson ());
|
||||
}
|
||||
}
|
||||
return "{}";
|
||||
}
|
||||
String ^GetCapabilityDisplayName (String ^capabilityName)
|
||||
{
|
||||
return CStringToMPString (GetPackageCapabilityDisplayName (MPStringToStdW (capabilityName)));
|
||||
}
|
||||
_I_HResult ^GetPackageInstallResult (String ^filepath)
|
||||
{
|
||||
std::wstring path = MPStringToStdW (filepath);
|
||||
if (g_pkgresult.find (path) == g_pkgresult.end ()) return nullptr;
|
||||
auto &pres = g_pkgresult.at (path);
|
||||
return gcnew _I_HResult (
|
||||
pres.result,
|
||||
CStringToMPString (pres.error),
|
||||
CStringToMPString (pres.reason)
|
||||
);
|
||||
}
|
||||
void Activate (String ^appid) { ActivateApp (appid); }
|
||||
};
|
||||
ref class _I_Window
|
||||
{
|
||||
private:
|
||||
AppListWnd ^wndinst = nullptr;
|
||||
public:
|
||||
_I_Window (AppListWnd ^wnd): wndinst (wnd) {}
|
||||
Object ^CallEvent (String ^name, ... array <Object ^> ^args) { return wndinst->CallEvent (name, args [0]); }
|
||||
};
|
||||
private:
|
||||
_I_System ^system = gcnew _I_System (wndinst);
|
||||
_I_IEFrame ^ieframe = gcnew _I_IEFrame (wndinst);
|
||||
_I_String ^str = gcnew _I_String ();
|
||||
_I_Package ^pkg = gcnew _I_Package ();
|
||||
_I_Window ^wnd = gcnew _I_Window (wndinst);
|
||||
public:
|
||||
property _I_System ^System { _I_System ^get () { return system; }}
|
||||
property _I_IEFrame ^IEFrame { _I_IEFrame ^get () { return ieframe; }}
|
||||
property _I_String ^String { _I_String ^get () { return str; }}
|
||||
property _I_Package ^Package { _I_Package ^get () { return pkg; }}
|
||||
property _I_Window ^Window { _I_Window ^get () { return wnd; }}
|
||||
};
|
||||
private:
|
||||
WebBrowser ^webui = nullptr;
|
||||
Timer ^showtimer = gcnew Timer ();
|
||||
Timer ^hidetimer = gcnew Timer ();
|
||||
int aminedelay = 150;
|
||||
int framedelay = 25;
|
||||
double movelen = 10 * DPI;
|
||||
int frametotal = aminedelay / framedelay;
|
||||
double movestep = movelen / (double)frametotal;
|
||||
int framenow = 0;
|
||||
int finaltop = 0;
|
||||
public:
|
||||
property WebBrowser ^WebUI { WebBrowser ^get () { return this->webui; } }
|
||||
property int DPIPercent { int get () { return GetDPI (); }}
|
||||
property double DPI { double get () { return DPIPercent * 0.01; }}
|
||||
AppListWnd ()
|
||||
{
|
||||
this->Visible = false;
|
||||
this->DoubleBuffered = true;
|
||||
this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::None;
|
||||
this->ShowInTaskbar = false;
|
||||
this->TopMost = true;
|
||||
this->Size = System::Drawing::Size (392 * DPI, 494 * DPI);
|
||||
if (IsWindows10 ()) this->MinimumSize = System::Drawing::Size (392 * DPI, 226 * DPI);
|
||||
else this->MinimumSize = System::Drawing::Size (392 * DPI, 129 * DPI);
|
||||
if (IsWindows10 ()) this->MaximumSize = System::Drawing::Size (392 * DPI, 522 * DPI);
|
||||
else this->MaximumSize = System::Drawing::Size (368 * DPI, 394 * DPI);
|
||||
this->Text = GetRCStringCli (IDS_APPLIST_WINTITLE);
|
||||
webui = gcnew System::Windows::Forms::WebBrowser ();
|
||||
webui->Dock = System::Windows::Forms::DockStyle::Fill;
|
||||
this->Controls->Add (webui);
|
||||
webui->Visible = false;
|
||||
webui->ObjectForScripting = gcnew IBridge (this);
|
||||
this->webui->DocumentCompleted += gcnew System::Windows::Forms::WebBrowserDocumentCompletedEventHandler (this, &AppListWnd::OnDocumentCompleted);
|
||||
this->Load += gcnew EventHandler (this, &AppListWnd::OnCreate);
|
||||
this->StartPosition = System::Windows::Forms::FormStartPosition::CenterScreen;
|
||||
this->Deactivate += gcnew EventHandler (this, &AppListWnd::OnDeactivate);
|
||||
webui->Navigate (CStringToMPString (CombinePath (GetProgramRootDirectoryW (), L"html\\applist.html")));
|
||||
showtimer->Interval = framedelay;
|
||||
hidetimer->Interval = framedelay;
|
||||
showtimer->Tick += gcnew EventHandler (this, &AppListWnd::OnTick_ShowTimer);
|
||||
hidetimer->Tick += gcnew EventHandler (this, &AppListWnd::OnTick_HideTimer);
|
||||
this->Opacity = 0;
|
||||
}
|
||||
protected:
|
||||
void OnCreate (System::Object ^sender, System::EventArgs ^e) {}
|
||||
void OnDocumentCompleted (Object ^sender, System::Windows::Forms::WebBrowserDocumentCompletedEventArgs ^e)
|
||||
{
|
||||
if (e->Url->ToString () == webui->Url->ToString ())
|
||||
{
|
||||
|
||||
ExecScript ("Windows.UI.DPI.mode = 1");
|
||||
ExecScript ("Bridge.Frame.scale = Bridge.Frame.scale * Bridge.UI.dpi");
|
||||
InvokeCallScriptFunction ("setWindows10Style", IsWindows10 ());
|
||||
size_t cnt = 0;
|
||||
for (auto &it : g_pkginfo)
|
||||
{
|
||||
for (auto &app : it.applications)
|
||||
{
|
||||
std::wstring launchid = it.identity.package_family_name + L'!' + app [L"Id"];
|
||||
auto &color = app [L"BackgroundColor"];
|
||||
std::wnstring displayName = app [L"DisplayName"];
|
||||
if (displayName.empty ()) displayName = app [L"ShortName"];
|
||||
auto &logo = app [L"Square44x44Logo"];
|
||||
InvokeCallScriptFunction (
|
||||
"addAppToList",
|
||||
CStringToMPString (displayName),
|
||||
CStringToMPString (logo),
|
||||
CStringToMPString (launchid),
|
||||
CStringToMPString (color)
|
||||
);
|
||||
cnt ++;
|
||||
}
|
||||
}
|
||||
if (cnt == 0) this->Close ();
|
||||
{
|
||||
bool isWin10 = IsWindows10 ();
|
||||
size_t height = ((cnt) * (isWin10 ? 50 : 60) * DPI) + (isWin10 ? 206 : 120) * DPI;
|
||||
if (height < (isWin10 ? 522 : 394) * DPI) this->Height = height;
|
||||
else this->Height = 522 * DPI;
|
||||
this->Left = (GetScreenWidth () - this->Width) / 2;
|
||||
this->Top = (GetScreenHeight () - this->Height) / 2;
|
||||
}
|
||||
finaltop = this->Top;
|
||||
this->Top -= movelen;
|
||||
webui->Visible = true;
|
||||
this->Visible = true;
|
||||
}
|
||||
}
|
||||
void OnPress_Cancel ()
|
||||
{
|
||||
if (!this->IsHandleCreated) return;
|
||||
if (InvokeRequired) this->Invoke (gcnew Action (this, &AppListWnd::HideAmine));
|
||||
else this->HideAmine ();
|
||||
return;
|
||||
}
|
||||
void OnPress_AppItem ()
|
||||
{
|
||||
OnPress_Cancel ();
|
||||
}
|
||||
void OnDeactivate (Object ^sender, EventArgs ^e)
|
||||
{
|
||||
OnPress_Cancel ();
|
||||
}
|
||||
void OnTick_ShowTimer (Object ^sender, EventArgs ^e)
|
||||
{
|
||||
framenow ++;
|
||||
if (framenow > frametotal)
|
||||
{
|
||||
showtimer->Stop ();
|
||||
this->Top = finaltop;
|
||||
this->Opacity = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->Top = finaltop + movestep * (frametotal - framenow);
|
||||
this->Opacity = framenow / (double)frametotal;
|
||||
}
|
||||
}
|
||||
void OnTick_HideTimer (Object ^sender, EventArgs ^e)
|
||||
{
|
||||
framenow ++;
|
||||
if (framenow > frametotal)
|
||||
{
|
||||
showtimer->Stop ();
|
||||
this->Opacity = 0;
|
||||
this->Close ();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->Opacity = 1.0 - framenow / (double)frametotal;
|
||||
}
|
||||
}
|
||||
public:
|
||||
static void DisplayWindow ()
|
||||
{
|
||||
auto wnd = gcnew AppListWnd ();
|
||||
wnd->ShowAmine ();
|
||||
}
|
||||
Object ^CallScriptFunction (String ^lpFuncName, ... array <Object ^> ^alpParams)
|
||||
{
|
||||
try { return this->webui->Document->InvokeScript (lpFuncName, alpParams); }
|
||||
catch (Exception ^e) {}
|
||||
return nullptr;
|
||||
}
|
||||
Object ^CallScriptFunction (String ^lpScriptName)
|
||||
{
|
||||
try { return this->webui->Document->InvokeScript (lpScriptName); }
|
||||
catch (Exception ^e) {}
|
||||
return nullptr;
|
||||
}
|
||||
Object ^InvokeCallScriptFunction (String ^lpFuncName, ... array <Object ^> ^alpParams)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this->InvokeRequired) return (Object ^)this->Invoke (gcnew Func <String ^, array <Object ^> ^, Object ^> (this, &AppListWnd::CallScriptFunction), lpFuncName, alpParams);
|
||||
else return CallScriptFunction (lpFuncName, alpParams);
|
||||
}
|
||||
catch (Exception ^e) {}
|
||||
return nullptr;
|
||||
}
|
||||
Object ^InvokeCallScriptFunction (String ^lpScriptName)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this->InvokeRequired) return (Object ^)this->Invoke (gcnew Func <String ^, Object ^> (this, &AppListWnd::CallScriptFunction), lpScriptName);
|
||||
else return CallScriptFunction (lpScriptName);
|
||||
}
|
||||
catch (Exception ^e) {}
|
||||
return nullptr;
|
||||
}
|
||||
Object ^ExecScript (... array <Object ^> ^alpScript) { return InvokeCallScriptFunction ("eval", alpScript); }
|
||||
Object ^CallEvent (String ^funcName, Object ^e)
|
||||
{
|
||||
std::wstring fname = MPStringToStdW (funcName);
|
||||
if (IsNormalizeStringEquals (fname.c_str (), L"OnPress_CancelButton")) OnPress_Cancel ();
|
||||
else if (IsNormalizeStringEquals (fname.c_str (), L"OnPress_AppItem")) OnPress_AppItem ();
|
||||
return nullptr;
|
||||
}
|
||||
property int PageScale
|
||||
{
|
||||
int get ()
|
||||
{
|
||||
CComPtr <IWebBrowser2> web2;
|
||||
HRESULT hr = GetWebBrowser2Interface (webui, &web2);
|
||||
if (FAILED (hr)) return 0;
|
||||
VARIANT v;
|
||||
VariantInit (&v);
|
||||
hr = web2->ExecWB (OLECMDID_OPTICAL_ZOOM, OLECMDEXECOPT_DODEFAULT, nullptr, &v);
|
||||
if (FAILED (hr) || v.vt != VT_I4) return 0;
|
||||
int val = v.lVal;
|
||||
VariantClear (&v);
|
||||
return val;
|
||||
}
|
||||
void set (int value)
|
||||
{
|
||||
CComPtr <IWebBrowser2> web2;
|
||||
HRESULT hr = GetWebBrowser2Interface (webui, &web2);
|
||||
if (FAILED (hr)) return;
|
||||
VARIANT v;
|
||||
VariantInit (&v);
|
||||
v.vt = VT_I4;
|
||||
v.lVal = value;
|
||||
web2->ExecWB (OLECMDID_OPTICAL_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER, &v, nullptr);
|
||||
}
|
||||
}
|
||||
void ShowAmine ()
|
||||
{
|
||||
this->Show ();
|
||||
hidetimer->Stop ();
|
||||
showtimer->Start ();
|
||||
}
|
||||
void HideAmine ()
|
||||
{
|
||||
framenow = 0;
|
||||
showtimer->Stop ();
|
||||
hidetimer->Start ();
|
||||
}
|
||||
};
|
||||
[ComVisible (true)]
|
||||
public ref class MainHtmlWnd: public System::Windows::Forms::Form
|
||||
{
|
||||
@@ -506,13 +1012,13 @@ public ref class MainHtmlWnd: public System::Windows::Forms::Form
|
||||
property double DPI { double get () { return DPIPercent * 0.01; }}
|
||||
property _I_UI_Size ^WndSize { _I_UI_Size ^get () { return gcnew _I_UI_Size (wndinst->Width, wndinst->Height); } }
|
||||
property _I_UI_Size ^ClientSize { _I_UI_Size ^get () { auto cs = wndinst->ClientSize; return gcnew _I_UI_Size (cs.Width, cs.Height); } }
|
||||
property String ^SplashImage
|
||||
{
|
||||
String ^get ()
|
||||
{
|
||||
auto uri = gcnew Uri (CStringToMPString (wndinst->GetSuitSplashImage ()));
|
||||
property String ^SplashImage
|
||||
{
|
||||
String ^get ()
|
||||
{
|
||||
auto uri = gcnew Uri (CStringToMPString (wndinst->GetSuitSplashImage ()));
|
||||
return uri->AbsoluteUri;
|
||||
}
|
||||
}
|
||||
}
|
||||
property String ^SplashBackgroundColor { String ^get () { return CStringToMPString (g_vemani.splash_screen_backgroundcolor (L"App")); } }
|
||||
void ShowSplash () { if (wndinst->SplashScreen->IsHandleCreated) wndinst->SplashScreen->Show (); else wndinst->SplashScreen->ReInit (); }
|
||||
@@ -553,7 +1059,7 @@ public ref class MainHtmlWnd: public System::Windows::Forms::Form
|
||||
}
|
||||
String ^ToName (unsigned int ulResId)
|
||||
{
|
||||
for (auto &it : g_nameToId) {if (it.second == ulResId) return CStringToMPString (it.first);}
|
||||
for (auto &it : g_nameToId) { if (it.second == ulResId) return CStringToMPString (it.first); }
|
||||
return "";
|
||||
}
|
||||
String ^GetByName (String ^lpResId) { return GetById (ToId (lpResId)); }
|
||||
@@ -568,7 +1074,7 @@ public ref class MainHtmlWnd: public System::Windows::Forms::Form
|
||||
property UINT16 Minor { UINT16 get () { return minor; } void set (UINT16 value) { minor = value; } }
|
||||
property UINT16 Build { UINT16 get () { return build; } void set (UINT16 value) { build = value; } }
|
||||
property UINT16 Revision { UINT16 get () { return revision; } void set (UINT16 value) { revision = value; } }
|
||||
property array <UINT16> ^Data
|
||||
property array <UINT16> ^Data
|
||||
{
|
||||
array <UINT16> ^get ()
|
||||
{
|
||||
@@ -736,7 +1242,7 @@ public ref class MainHtmlWnd: public System::Windows::Forms::Form
|
||||
ref class _I_String
|
||||
{
|
||||
public:
|
||||
ref class _I_NString
|
||||
ref class _I_NString
|
||||
{
|
||||
public:
|
||||
bool NEquals (String ^l, String ^r) { return IsNormalizeStringEquals (MPStringToPtrW (l), MPStringToPtrW (r)); }
|
||||
@@ -764,7 +1270,7 @@ public ref class MainHtmlWnd: public System::Windows::Forms::Form
|
||||
for (size_t i = 0; i < args->Length; i ++)
|
||||
{
|
||||
auto %p = newargs [i];
|
||||
p = Format ("<span>{0}</span>", EscapeToInnerXml (Format ("{0}", args [i])));
|
||||
p = Format ("<span>{0}</span>", EscapeToInnerXml (Format ("{0}", args [i])));
|
||||
}
|
||||
return Format (pih, newargs);
|
||||
}
|
||||
@@ -831,7 +1337,7 @@ public ref class MainHtmlWnd: public System::Windows::Forms::Form
|
||||
{
|
||||
private:
|
||||
MainHtmlWnd ^wndinst = nullptr;
|
||||
public:
|
||||
public:
|
||||
_I_Window (MainHtmlWnd ^wnd): wndinst (wnd) {}
|
||||
Object ^CallEvent (String ^name, ... array <Object ^> ^args) { return wndinst->CallEvent (name, args [0]); }
|
||||
};
|
||||
@@ -900,7 +1406,7 @@ public ref class MainHtmlWnd: public System::Windows::Forms::Form
|
||||
try { this->Icon = System::Drawing::Icon::FromHandle (IntPtr (g_hIconMain.hIcon)); }
|
||||
catch (...) {}
|
||||
}
|
||||
this->Text = rcString (IDS_WINTITLE);
|
||||
this->Text = GetRCStringCli (IDS_WINTITLE);
|
||||
this->ResumeLayout (false);
|
||||
webui->ObjectForScripting = gcnew IBridge (this);
|
||||
this->webui->DocumentCompleted += gcnew System::Windows::Forms::WebBrowserDocumentCompletedEventHandler (this, &MainHtmlWnd::OnDocumentCompleted);
|
||||
@@ -988,7 +1494,7 @@ public ref class MainHtmlWnd: public System::Windows::Forms::Form
|
||||
String ^btn2 = GetRCStringCli (IDS_PREINSTALL_CANCEL);
|
||||
if (g_pkginfo.size () == 1)
|
||||
{
|
||||
try
|
||||
try
|
||||
{
|
||||
const auto &pi = *g_pkginfo.begin ();
|
||||
const std::wstring
|
||||
@@ -1204,7 +1710,7 @@ public ref class MainHtmlWnd: public System::Windows::Forms::Form
|
||||
auto &it = g_pkginfo.at (nowinstall);
|
||||
InvokeCallScriptFunction ("setInstallingPackageInfoMultiple", CStringToMPString (it.filepath));
|
||||
InvokeCallScriptFunction (
|
||||
"setInstallingStatus",
|
||||
"setInstallingStatus",
|
||||
String::Format (
|
||||
GetRCStringCli (IDS_INSTALLING_MLOADCER),
|
||||
nowinstall + 1,
|
||||
@@ -1222,11 +1728,11 @@ public ref class MainHtmlWnd: public System::Windows::Forms::Form
|
||||
);
|
||||
package_installresult pir;
|
||||
pir.result = AddAppxPackageFromPath (
|
||||
it.filepath,
|
||||
blankdeplist,
|
||||
DEPOLYOPTION_NONE,
|
||||
it.filepath,
|
||||
blankdeplist,
|
||||
DEPOLYOPTION_NONE,
|
||||
gcnew InstallProgressCallbackDelegate (this, &MainHtmlWnd::InstallProgressCallbackMultiple),
|
||||
pir.error,
|
||||
pir.error,
|
||||
pir.reason
|
||||
);
|
||||
g_pkgresult [it.filepath] = pir;
|
||||
@@ -1261,6 +1767,7 @@ public ref class MainHtmlWnd: public System::Windows::Forms::Form
|
||||
}
|
||||
void PackageSuccessInstallCountTask ()
|
||||
{
|
||||
return;
|
||||
System::Threading::Thread::Sleep (System::TimeSpan (0, 0, 5));
|
||||
this->InvokeClose ();
|
||||
}
|
||||
@@ -1325,7 +1832,19 @@ public ref class MainHtmlWnd: public System::Windows::Forms::Form
|
||||
}
|
||||
else if (nequals (current, L"installsuccess"))
|
||||
{
|
||||
|
||||
std::vector <std::wnstring> appids;
|
||||
for (auto &it : g_pkginfo)
|
||||
for (auto &it_s : it.applications)
|
||||
if (!it_s [L"Id"].empty ())
|
||||
appids.emplace_back (it.identity.package_family_name + L'!' + it_s [L"Id"]);
|
||||
if (appids.size () == 1)
|
||||
{
|
||||
ActivateAppxApplication (appids.at (0));
|
||||
}
|
||||
else if (appids.size () > 1)
|
||||
{
|
||||
AppListWnd::DisplayWindow ();
|
||||
}
|
||||
}
|
||||
else if (nequals (current, L"installfailed")) this->Close ();
|
||||
return;
|
||||
@@ -1348,7 +1867,7 @@ public ref class MainHtmlWnd: public System::Windows::Forms::Form
|
||||
case InstallType::reinstall: {
|
||||
auto &pi = *g_pkginfo.begin ();
|
||||
if (pi.applications.size () == 1) ActivateAppxApplication (pi.identity.package_family_name + L"!" + pi.applications.at (0).at (L"Id"));
|
||||
|
||||
else AppListWnd::DisplayWindow ();
|
||||
} break;
|
||||
default:
|
||||
case InstallType::normal:
|
||||
@@ -1357,10 +1876,7 @@ public ref class MainHtmlWnd: public System::Windows::Forms::Form
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->Close ();
|
||||
}
|
||||
else this->Close ();
|
||||
return;
|
||||
}
|
||||
else if (nequals (current, L"installfailed")) this->Close ();
|
||||
@@ -1576,7 +2092,7 @@ int APIENTRY wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCm
|
||||
{
|
||||
if (pair.first.key == std::wnstring (L"help"))
|
||||
{
|
||||
MessageBox (nullptr, GenerateCmdHelper ().c_str (), GetRCStringSW (IDS_WINTITLE).c_str (), 0);
|
||||
MessageBoxW (nullptr, GenerateCmdHelper ().c_str (), GetRCStringSW (IDS_WINTITLE).c_str (), 0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,10 @@ std::map <std::string, unsigned> g_nameToId = {
|
||||
MAKENAMEIDMAP (IDS_MINHIEHGT),
|
||||
MAKENAMEIDMAP (IDS_INSTALLING_MLOADCER),
|
||||
MAKENAMEIDMAP (IDS_FAILED_MSUCCESS),
|
||||
MAKENAMEIDMAP (IDS_FAILED_STITLE)
|
||||
MAKENAMEIDMAP (IDS_FAILED_STITLE),
|
||||
MAKENAMEIDMAP (IDS_APPLIST_WINTITLE),
|
||||
MAKENAMEIDMAP (IDS_APPLIST_TITLE),
|
||||
MAKENAMEIDMAP (IDS_APPLIST_CANCEL)
|
||||
};
|
||||
|
||||
#ifdef MAKENAMEIDMAP
|
||||
|
||||
Binary file not shown.
@@ -539,44 +539,63 @@ HRESULT CreateToastNoticeWithIStream (LPCWSTR lpIdName, LPCWSTR lpText, HANDLE p
|
||||
}
|
||||
HRESULT NoticeGetLastHResult () { return g_lasthr; }
|
||||
LPCWSTR NoticeGetLastDetailMessage () { return g_lastexc.c_str (); }
|
||||
HRESULT CreateShortcutWithAppIdW (LPCWSTR pszShortcutPath, LPCWSTR pszTargetPath, LPCWSTR pszAppId)
|
||||
HRESULT CreateShortcutWithAppIdW (LPCWSTR pszShortcutPath, LPCWSTR pszTargetPath, LPCWSTR pszAppId, LPWSTR *lpException)
|
||||
{
|
||||
HRESULT hr;
|
||||
if (FAILED (hr)) return hr;
|
||||
IShellLinkW *pShellLinkW = nullptr;
|
||||
raii reltask1 ([&] () {
|
||||
if (pShellLinkW) pShellLinkW->Release ();
|
||||
pShellLinkW = nullptr;
|
||||
HRESULT &hr = g_lasthr;
|
||||
destruct relt ([&] () {
|
||||
if (FAILED (hr))
|
||||
{
|
||||
if (lpException && !*lpException)
|
||||
{
|
||||
_com_error ex (hr);
|
||||
g_lastexc = ex.ErrorMessage () ? ex.ErrorMessage () : L"";
|
||||
*lpException = _wcsdup (g_lastexc.c_str ());
|
||||
}
|
||||
}
|
||||
});
|
||||
hr = CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (void **)&pShellLinkW);
|
||||
if (FAILED (hr)) return hr;
|
||||
hr = pShellLinkW->SetPath (pszTargetPath); return hr;
|
||||
IPropertyStore *pPropStore = nullptr;
|
||||
raii reltask2 ([&] () {
|
||||
if (pPropStore) pPropStore->Release ();
|
||||
pPropStore = nullptr;
|
||||
});
|
||||
hr = pShellLinkW->QueryInterface (IID_IPropertyStore, (void **)&pPropStore);
|
||||
if (SUCCEEDED (hr))
|
||||
if (lpException) *lpException = nullptr;
|
||||
try
|
||||
{
|
||||
PROPVARIANT propvar;
|
||||
hr = InitPropVariantFromString (pszAppId, &propvar);
|
||||
hr = CoInitialize (NULL);
|
||||
if (FAILED (hr)) return hr;
|
||||
IShellLinkW *pShellLinkW = nullptr;
|
||||
raii reltask1 ([&] () {
|
||||
if (pShellLinkW) pShellLinkW->Release ();
|
||||
pShellLinkW = nullptr;
|
||||
});
|
||||
hr = CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (void **)&pShellLinkW);
|
||||
if (FAILED (hr)) return hr;
|
||||
hr = pShellLinkW->SetPath (pszTargetPath);
|
||||
if (FAILED (hr)) return hr;
|
||||
IPropertyStore *pPropStore = nullptr;
|
||||
raii reltask2 ([&] () {
|
||||
if (pPropStore) pPropStore->Release ();
|
||||
pPropStore = nullptr;
|
||||
});
|
||||
hr = pShellLinkW->QueryInterface (IID_IPropertyStore, (void **)&pPropStore);
|
||||
if (SUCCEEDED (hr))
|
||||
{
|
||||
hr = pPropStore->SetValue (PKEY_AppUserModel_ID, propvar);
|
||||
if (SUCCEEDED (hr)) hr = pPropStore->Commit ();
|
||||
PropVariantClear (&propvar);
|
||||
PROPVARIANT propvar;
|
||||
hr = InitPropVariantFromString (pszAppId, &propvar);
|
||||
if (SUCCEEDED (hr))
|
||||
{
|
||||
hr = pPropStore->SetValue (PKEY_AppUserModel_ID, propvar);
|
||||
if (SUCCEEDED (hr)) hr = pPropStore->Commit ();
|
||||
PropVariantClear (&propvar);
|
||||
}
|
||||
}
|
||||
else pPropStore = nullptr;
|
||||
IPersistFile *pPersistFile = nullptr;
|
||||
raii reltask3 ([&] () {
|
||||
if (pPersistFile) pPersistFile->Release ();
|
||||
pPersistFile = nullptr;
|
||||
});
|
||||
hr = pShellLinkW->QueryInterface (IID_IPersistFile, (void **)&pPersistFile);
|
||||
if (SUCCEEDED (hr)) hr = pPersistFile->Save (pszShortcutPath, TRUE);
|
||||
else pPersistFile = nullptr;
|
||||
return hr;
|
||||
}
|
||||
else pPropStore = nullptr;
|
||||
IPersistFile *pPersistFile = nullptr;
|
||||
raii reltask3 ([&] () {
|
||||
if (pPersistFile) pPersistFile->Release ();
|
||||
pPersistFile = nullptr;
|
||||
});
|
||||
hr = pShellLinkW->QueryInterface (IID_IPersistFile, (void **)&pPersistFile);
|
||||
if (SUCCEEDED (hr)) hr = pPersistFile->Save (pszShortcutPath, TRUE);
|
||||
else pPersistFile = nullptr;
|
||||
catch_lasterr (&hr, lpException);
|
||||
return hr;
|
||||
}
|
||||
|
||||
@@ -646,4 +665,51 @@ HRESULT CreateToastNotice2WithImgBase64 (LPCWSTR lpIdName, LPCWSTR lpTitle, LPCW
|
||||
if (bytes.size ())
|
||||
{ if (FAILED (BytesToIStream (bytes, &ist))) ist = nullptr; }
|
||||
return CreateToastNoticeWithIStream2 (lpIdName, lpTitle, lpText, ist, pfCallback, pCustom, lpExceptMsg);
|
||||
}
|
||||
|
||||
HRESULT CreateMessageDialog (const std::wstring &content, const std::wstring &title, LPWSTR *lpException)
|
||||
{
|
||||
auto &hr = g_lasthr;
|
||||
try
|
||||
{
|
||||
auto refcon = ref new Platform::String (content.c_str ());
|
||||
auto reftit = ref new Platform::String (title.c_str ());
|
||||
Windows::UI::Popups::MessageDialog ^msgdlg = nullptr;
|
||||
if (IsNormalizeStringEmpty (title)) msgdlg = ref new Windows::UI::Popups::MessageDialog (refcon);
|
||||
else msgdlg = ref new Windows::UI::Popups::MessageDialog (refcon, reftit);
|
||||
msgdlg->ShowAsync ();
|
||||
return S_OK;
|
||||
}
|
||||
catch_lasterr (&hr, lpException);
|
||||
return hr;
|
||||
}
|
||||
HRESULT SimpleMessageDialog (LPCWSTR lpContent, LPCWSTR lpTitle, LPWSTR *lpException)
|
||||
{
|
||||
auto &hr = g_lasthr;
|
||||
try
|
||||
{
|
||||
return CreateMessageDialog (
|
||||
lpContent ? lpContent : L"",
|
||||
lpTitle ? lpTitle : L"",
|
||||
lpException
|
||||
);
|
||||
}
|
||||
catch_lasterr (&hr, lpException);
|
||||
return hr;
|
||||
}
|
||||
HRESULT CreateTileNoticifation (LPCWSTR lpAppId, LPCWSTR lpXmlDoc, LPWSTR *lpExMsg)
|
||||
{
|
||||
auto &hr = g_lasthr;
|
||||
try
|
||||
{
|
||||
auto refcon = ref new Platform::String (lpXmlDoc ? lpXmlDoc : L"");
|
||||
auto xmldoc = ref new Windows::Data::Xml::Dom::XmlDocument ();
|
||||
xmldoc->LoadXml (ref new Platform::String (lpXmlDoc ? lpXmlDoc : L""));
|
||||
auto tile = ref new Windows::UI::Notifications::TileNotification (xmldoc);
|
||||
auto tilemgr = Windows::UI::Notifications::TileUpdateManager::CreateTileUpdaterForApplication (ref new Platform::String (lpAppId ? lpAppId : L""));
|
||||
tilemgr->Update (tile);
|
||||
return S_OK;
|
||||
}
|
||||
catch_lasterr (&hr, lpExMsg);
|
||||
return hr;
|
||||
}
|
||||
@@ -70,7 +70,7 @@ extern "C"
|
||||
NOTICE_API LPCWSTR NoticeGetLastDetailMessage ();
|
||||
// 创建快捷方式
|
||||
// (不用安装程序原生的创建,因为需要 AppUserID 才能使用 Toast 通知,当然这个限制只有 Windows 8.x 有,Windows 10 没有这个限制了)
|
||||
NOTICE_API HRESULT CreateShortcutWithAppIdW (LPCWSTR pszShortcutPath, LPCWSTR pszTargetPath, LPCWSTR pszAppId);
|
||||
NOTICE_API HRESULT CreateShortcutWithAppIdW (LPCWSTR pszShortcutPath, LPCWSTR pszTargetPath, LPCWSTR pszAppId, LPWSTR *lpException);
|
||||
// 由 notice.dll 获取到的动态字符串必须由此释放。
|
||||
NOTICE_API void NoticeApiFreeString (LPWSTR lpstr);
|
||||
// 创建一个简单的 Toast 通知。支持两段文本和一张图片(图片是 data uri 或者只是 Base64 编码后的字符串,如果不想设置则置 NULL)
|
||||
@@ -80,6 +80,7 @@ extern "C"
|
||||
// lpText 可以设置为 NULL 或空文本。此时函数的作用与 CreateToastNoticeWithIStream 一致。
|
||||
// 一些参数作用与 CreateToastNoticeFromXmlDocument 中的同名参数作用一致。
|
||||
NOTICE_API HRESULT CreateToastNotice2WithImgBase64 (LPCWSTR lpIdName, LPCWSTR lpTitle, LPCWSTR lpText, LPCWSTR lpImgBase64, NOTICE_ACTIVECALLBACK pfCallback, void *pCustom, LPWSTR *lpExceptMsg);
|
||||
|
||||
#ifdef _DEFAULT_INIT_VALUE_
|
||||
#undef _DEFAULT_INIT_VALUE_
|
||||
#endif
|
||||
@@ -185,7 +186,14 @@ notice::hresult CreateToastNoticeWithIStream (notice::qcwstring idname, notice::
|
||||
notice::hresult CreateToastNotice (notice::qcwstring idname, notice::qcwstring xmlstring, std::function <void ()> callback) { return CreateToastNoticeFromXmlDocument (idname, xmlstring, callback); }
|
||||
notice::hresult CreateToastNotice (notice::qcwstring idname, notice::qcwstring text, IStream *imgstream, std::function <void ()> callback = nullptr) { return CreateToastNoticeWithIStream (idname, text, imgstream, callback); }
|
||||
notice::hresult CreateToastNotice (notice::qcwstring idname, notice::qcwstring title, notice::qcwstring text, IStream *imgstream, std::function <void ()> callback = nullptr) { return CreateToastNoticeWithIStream2 (idname, title, text, imgstream, callback); }
|
||||
HRESULT CreateShortcutWithAppIdW (notice::qcwstring shortcut_path, notice::qcwstring targetpath, notice::qcwstring appid) { return CreateShortcutWithAppIdW (shortcut_path.c_str (), targetpath.c_str (), appid.c_str ()); }
|
||||
notice::hresult CreateShortcutWithAppIdW (notice::qcwstring shortcut_path, notice::qcwstring targetpath, notice::qcwstring appid)
|
||||
{
|
||||
notice::autostr exp;
|
||||
notice::hresult hr;
|
||||
hr.hr = CreateShortcutWithAppIdW (shortcut_path.c_str (), targetpath.c_str (), appid.c_str (), &exp.lpstr);
|
||||
hr.message = exp.get_string ();
|
||||
return hr;
|
||||
}
|
||||
HRESULT CreateToastNoticeWithImgBase64 (notice::qcwstring idname, notice::qcwstring text, notice::qcwstring imgbase64, std::function <void ()> callback = nullptr)
|
||||
{
|
||||
notice::autostr exp;
|
||||
@@ -202,4 +210,6 @@ HRESULT CreateToastNotice2WithImgBase64 (notice::qcwstring idname, notice::qcwst
|
||||
hr.message = exp.get_string ();
|
||||
return hr;
|
||||
}
|
||||
// WinRT API 测试用
|
||||
|
||||
#endif
|
||||
@@ -53,7 +53,7 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalOptions>/ZW:nostdlib /FUplatform.winmd /FUwindows.winmd %(AdditionalOptions)</AdditionalOptions>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;NOTICE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;NOTICE_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<CompileAsWinRT>true</CompileAsWinRT>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
</ClCompile>
|
||||
@@ -72,7 +72,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalOptions>/ZW:nostdlib /FUplatform.winmd /FUWindows.winmd %(AdditionalOptions)</AdditionalOptions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;NOTICE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;NOTICE_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<CompileAsWinRT>true</CompileAsWinRT>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <shlobj.h>
|
||||
#include <stdio.h>
|
||||
#include <shobjidl.h>
|
||||
#include <comdef.h>
|
||||
using namespace Platform;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::Management::Deployment;
|
||||
|
||||
@@ -611,6 +611,23 @@ class package_reader
|
||||
lpstr = nullptr;
|
||||
});
|
||||
lpstr = StreamToBase64W (pic, nullptr, 0, nullptr);
|
||||
if (!(lpstr && *lpstr))
|
||||
{
|
||||
if (lpstr) free (lpstr);
|
||||
HANDLE pkg1 = nullptr, pic1 = nullptr;
|
||||
destruct relp1 ([&pic1, &pkg1] () {
|
||||
if (pic1) DestroyAppxFileStream (pic1);
|
||||
if (pkg1) DestroyAppxFileStream (pkg1);
|
||||
pkg1 = nullptr;
|
||||
pic1 = nullptr;
|
||||
});
|
||||
pkg1 = GetAppxBundleApplicationPackageFile (hReader);
|
||||
if (pkg1)
|
||||
{
|
||||
pic1 = GetFileFromPayloadPackage (pkg1, logo ().c_str ());
|
||||
lpstr = StreamToBase64W (pic1, nullptr, 0, nullptr);
|
||||
}
|
||||
}
|
||||
return lpstr ? lpstr : L"";
|
||||
} break;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,14 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" type="text/css" href="libs/winjs/2.0/css/ui-light.css">
|
||||
<script src="js/bridge.js"></script>
|
||||
<script type="text/javascript" src="js/module.js"></script>
|
||||
<script type="text/javascript" src="js/polyfill-ie.js"></script>
|
||||
<script type="text/javascript" src="js/bridge.js"></script>
|
||||
<script type="text/javascript" src="js/dpimodes.js"></script>
|
||||
<script type="text/javascript" src="js/resources.js"></script>
|
||||
<script type="text/javascript" src="js/event.js"></script>
|
||||
<script type="text/javascript" src="js/load.js"></script>
|
||||
<script type="text/javascript" src="js/init.js"></script>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
@@ -35,6 +42,7 @@
|
||||
.applist-font-title {
|
||||
color: black;
|
||||
font-size: 11pt;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.applist-font-text {
|
||||
@@ -42,6 +50,7 @@
|
||||
font-size: 11pt;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.applist-window {
|
||||
@@ -131,6 +140,7 @@
|
||||
|
||||
.applist-item-divide {
|
||||
width: 12px;
|
||||
min-width: 12px;
|
||||
height: 100%;
|
||||
background-color: transparent;
|
||||
}
|
||||
@@ -167,6 +177,7 @@
|
||||
text-overflow: ellipsis;
|
||||
max-height: 3.9em;
|
||||
line-height: 1.3em;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.applist-btn-cancel {
|
||||
@@ -192,6 +203,7 @@
|
||||
|
||||
.win10 .applist-font-title {
|
||||
font-size: 13pt;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.win10.applist-window {
|
||||
@@ -225,10 +237,12 @@
|
||||
|
||||
.win10 .applist-item-divide {
|
||||
width: 12px;
|
||||
min-width: 12px;
|
||||
}
|
||||
|
||||
.win10 .applist-item-title {
|
||||
padding-top: 5pt;
|
||||
font-weight: normal;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -247,12 +261,12 @@
|
||||
</div>
|
||||
<div class="applist-window win10">
|
||||
<div class="applist-title">
|
||||
<span class="applist-font-title">你要如何打开这个文件?</span>
|
||||
<span class="applist-font-title" data-res-byname="IDS_APPLIST_TITLE"></span>
|
||||
</div>
|
||||
<div class="applist-listview">
|
||||
</div>
|
||||
<div class="applist-control">
|
||||
<button class="applist-btn-cancel win-commandbutton div-button-size div-std-button-center" onclick="EventCancelWindow()" tabindex="0">Cancel</button>
|
||||
<button class="applist-btn-cancel win-commandbutton div-button-size div-std-button-center" onclick="Bridge.Frame.callEvent ('OnPress_CancelButton')" tabindex="0" data-res-byname="IDS_APPLIST_CANCEL"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -336,6 +350,13 @@
|
||||
inode.logo = logo;
|
||||
inode.appid = appid;
|
||||
inode.color = color;
|
||||
item.itemInfo = inode;
|
||||
item.addEventListener("click", function() {
|
||||
setTimeout(function() {
|
||||
external.Package.activate(appid);
|
||||
Bridge.Frame.callEvent("OnPress_AppItem", appid);
|
||||
});
|
||||
});
|
||||
return item;
|
||||
}
|
||||
|
||||
@@ -350,6 +371,20 @@
|
||||
add: addItem
|
||||
}
|
||||
};
|
||||
global.addAppToList = function(title, logo, appid, color) {
|
||||
var item = createItem(title, logo, appid, color);
|
||||
addItem(item);
|
||||
};
|
||||
|
||||
function setWindows10Style(bIsSet) {
|
||||
var applist = document.querySelector(".applist-window");
|
||||
if (bIsSet) {
|
||||
if (!applist.classList.contains("win10")) applist.classList.add("win10");
|
||||
} else {
|
||||
if (applist.classList.contains("win10")) applist.classList.remove("win10");
|
||||
}
|
||||
}
|
||||
global.setWindows10Style = setWindows10Style;
|
||||
})(this);
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@@ -1,376 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>动画效果测试</title>
|
||||
<script type="text/javascript" src="js/module.js"></script>
|
||||
<script type="text/javascript" src="js/polyfill-ie.js"></script>
|
||||
<link rel="stylesheet" href="libs/winjs/2.0/css/ui-light.css">
|
||||
<script type="text/javascript" src="libs/winjs/2.0/js/base.js"></script>
|
||||
<script type="text/javascript" src="libs/winjs/2.0/js/ui.js"></script>
|
||||
<script type="text/javascript" src="js/animation.js"></script>
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
background-color: #f5f5f5;
|
||||
padding: 20px;
|
||||
overflow-x: auto;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
header {
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
padding: 20px;
|
||||
background: linear-gradient(135deg, #0067b8, #004e8c);
|
||||
color: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.description {
|
||||
font-size: 1.1rem;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.controls {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
gap: 20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.control-group {
|
||||
background: white;
|
||||
padding: 15px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.control-group h3 {
|
||||
margin-bottom: 15px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
color: #0067b8;
|
||||
}
|
||||
.demo-area {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin: 15px 0;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.demo-element {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: linear-gradient(135deg, #0067b8, #00a4ef);
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
margin-bottom: 15px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||
position: relative;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.demo-element::after {
|
||||
content: "动画元素";
|
||||
font-size: 0.9rem;
|
||||
text-align: center;
|
||||
padding: 5px;
|
||||
}
|
||||
.animation-buttons {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
button {
|
||||
background-color: #0067b8;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 12px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s;
|
||||
font-size: 14px;
|
||||
width: 100%;
|
||||
}
|
||||
button:hover {
|
||||
background-color: #004e8c;
|
||||
}
|
||||
.animation-status {
|
||||
background: #f8f8f8;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
min-height: 60px;
|
||||
white-space: pre-wrap;
|
||||
margin-top: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
footer {
|
||||
text-align: center;
|
||||
margin-top: 40px;
|
||||
padding: 20px;
|
||||
color: #666;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.controls {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>动画效果测试</h1>
|
||||
<p class="description">此页面展示animation.js中定义的所有动画效果。点击每个动画类别下的按钮来测试对应的动画。</p>
|
||||
</header>
|
||||
|
||||
<div class="controls">
|
||||
<div class="control-group">
|
||||
<h3>弹出动画 (Flyout)</h3>
|
||||
<div class="demo-area">
|
||||
<div class="demo-element" id="flyoutElement"></div>
|
||||
<div class="animation-buttons">
|
||||
<button onclick="runAnimation('Flyout.toTop', 'flyoutElement')">向顶端</button>
|
||||
<button onclick="runAnimation('Flyout.toBottom', 'flyoutElement')">向底端</button>
|
||||
<button onclick="runAnimation('Flyout.toLeft', 'flyoutElement')">向左</button>
|
||||
<button onclick="runAnimation('Flyout.toRight', 'flyoutElement')">向右</button>
|
||||
<button onclick="runAnimation('Flyout.fromBottom', 'flyoutElement')">从底端</button>
|
||||
<button onclick="runAnimation('Flyout.fromTop', 'flyoutElement')">从顶端</button>
|
||||
<button onclick="runAnimation('Flyout.fromLeft', 'flyoutElement')">从左侧</button>
|
||||
<button onclick="runAnimation('Flyout.fromRight', 'flyoutElement')">从右侧</button>
|
||||
</div>
|
||||
<div class="animation-status" id="flyoutStatus">等待动画执行...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<h3>渐变动画 (Opacity)</h3>
|
||||
<div class="demo-area">
|
||||
<div class="demo-element" id="opacityElement"></div>
|
||||
<div class="animation-buttons">
|
||||
<button onclick="runAnimation('Opacity.visible', 'opacityElement')">显示</button>
|
||||
<button onclick="runAnimation('Opacity.hidden', 'opacityElement')">消失</button>
|
||||
</div>
|
||||
<div class="animation-status" id="opacityStatus">等待动画执行...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<h3>缩放动画 (Scale)</h3>
|
||||
<div class="demo-area">
|
||||
<div class="demo-element" id="scaleElement"></div>
|
||||
<div class="animation-buttons">
|
||||
<button onclick="runAnimation('Scale.up', 'scaleElement')">放大</button>
|
||||
<button onclick="runAnimation('Scale.down', 'scaleElement')">缩小</button>
|
||||
</div>
|
||||
<div class="animation-status" id="scaleStatus">等待动画执行...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<h3>默认动画 (Default)</h3>
|
||||
<div class="demo-area">
|
||||
<div class="demo-element" id="defaultElement"></div>
|
||||
<div class="animation-buttons">
|
||||
<button onclick="runAnimation('Default.remove', 'defaultElement')">从右返回</button>
|
||||
<button onclick="runAnimation('Default.removertl', 'defaultElement')">从左返回</button>
|
||||
<button onclick="runAnimation('Default.apply', 'defaultElement')">向右移动</button>
|
||||
<button onclick="runAnimation('Default.applyrtl', 'defaultElement')">向左移动</button>
|
||||
</div>
|
||||
<div class="animation-status" id="defaultStatus">等待动画执行...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<h3>边缘动画 (Edge)</h3>
|
||||
<div class="demo-area">
|
||||
<div class="demo-element" id="edgeElement"></div>
|
||||
<div class="animation-buttons">
|
||||
<button onclick="runAnimation('Edge.show', 'edgeElement')">从顶部显示</button>
|
||||
<button onclick="runAnimation('Edge.hide', 'edgeElement')">向顶部隐藏</button>
|
||||
</div>
|
||||
<div class="animation-status" id="edgeStatus">等待动画执行...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<h3>面板动画 (Panel)</h3>
|
||||
<div class="demo-area">
|
||||
<div class="demo-element" id="panelElement"></div>
|
||||
<div class="animation-buttons">
|
||||
<button onclick="runAnimation('Panel.show', 'panelElement')">从右侧显示</button>
|
||||
<button onclick="runAnimation('Panel.showrtl', 'panelElement')">从左侧显示</button>
|
||||
<button onclick="runAnimation('Panel.hide', 'panelElement')">向右侧隐藏</button>
|
||||
<button onclick="runAnimation('Panel.hidertl', 'panelElement')">向左侧隐藏</button>
|
||||
</div>
|
||||
<div class="animation-status" id="panelStatus">等待动画执行...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<h3>弹出动画 (Popup)</h3>
|
||||
<div class="demo-area">
|
||||
<div class="demo-element" id="popupElement"></div>
|
||||
<div class="animation-buttons">
|
||||
<button onclick="runAnimation('Popup.show', 'popupElement')">弹出显示</button>
|
||||
</div>
|
||||
<div class="animation-status" id="popupStatus">等待动画执行...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<h3>拖放动画 (Drag)</h3>
|
||||
<div class="demo-area">
|
||||
<div class="demo-element" id="dragElement"></div>
|
||||
<div class="animation-buttons">
|
||||
<button onclick="runAnimation('Drag.sourceEnd', 'dragElement')">从右复位</button>
|
||||
<button onclick="runAnimation('Drag.sourceEndRtl', 'dragElement')">从左复位</button>
|
||||
</div>
|
||||
<div class="animation-status" id="dragStatus">等待动画执行...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<h3>内容动画 (Content)</h3>
|
||||
<div class="demo-area">
|
||||
<div class="demo-element" id="contentElement"></div>
|
||||
<div class="animation-buttons">
|
||||
<button onclick="runAnimation('Content.enter', 'contentElement')">从右进入</button>
|
||||
<button onclick="runAnimation('Content.enterrtl', 'contentElement')">从左进入</button>
|
||||
</div>
|
||||
<div class="animation-status" id="contentStatus">等待动画执行...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<h3>页面动画 (Page)</h3>
|
||||
<div class="demo-area">
|
||||
<div class="demo-element" id="pageElement"></div>
|
||||
<div class="animation-buttons">
|
||||
<button onclick="runAnimation('Page.enter', 'pageElement')">从右进入</button>
|
||||
<button onclick="runAnimation('Page.enterrtl', 'pageElement')">从左进入</button>
|
||||
</div>
|
||||
<div class="animation-status" id="pageStatus">等待动画执行...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<h3>其他动画</h3>
|
||||
<div class="demo-area">
|
||||
<div class="demo-element" id="otherElement"></div>
|
||||
<div class="animation-buttons">
|
||||
<button onclick="runAnimation('Exit', 'otherElement')">退出</button>
|
||||
<button onclick="runAnimation('UpdateBadge', 'otherElement')">更新徽章</button>
|
||||
</div>
|
||||
<div class="animation-status" id="otherStatus">等待动画执行...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<p>动画效果测试页面 - 使用 WinJS 动画库</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 确保Windows对象存在
|
||||
if (typeof Windows === 'undefined') {
|
||||
console.error('Windows对象未定义,请确保已正确引入WinJS库');
|
||||
} else if (!Windows.UI || !Windows.UI.Animation) {
|
||||
console.error('Windows.UI.Animation未定义,请确保animation.js已正确加载');
|
||||
}
|
||||
|
||||
// 动画映射表
|
||||
const animationMap = {
|
||||
'Flyout.toTop': Windows.UI.Animation.Keyframes.Flyout.toTop,
|
||||
'Flyout.toBottom': Windows.UI.Animation.Keyframes.Flyout.toBottom,
|
||||
'Flyout.toLeft': Windows.UI.Animation.Keyframes.Flyout.toLeft,
|
||||
'Flyout.toRight': Windows.UI.Animation.Keyframes.Flyout.toRight,
|
||||
'Flyout.fromBottom': Windows.UI.Animation.Keyframes.Flyout.fromBottom,
|
||||
'Flyout.fromTop': Windows.UI.Animation.Keyframes.Flyout.fromTop,
|
||||
'Flyout.fromLeft': Windows.UI.Animation.Keyframes.Flyout.fromLeft,
|
||||
'Flyout.fromRight': Windows.UI.Animation.Keyframes.Flyout.fromRight,
|
||||
'Opacity.visible': Windows.UI.Animation.Keyframes.Opacity.visible,
|
||||
'Opacity.hidden': Windows.UI.Animation.Keyframes.Opacity.hidden,
|
||||
'Scale.up': Windows.UI.Animation.Keyframes.Scale.up,
|
||||
'Scale.down': Windows.UI.Animation.Keyframes.Scale.down,
|
||||
'Default.remove': Windows.UI.Animation.Keyframes.Default.remove,
|
||||
'Default.removertl': Windows.UI.Animation.Keyframes.Default.removertl,
|
||||
'Default.apply': Windows.UI.Animation.Keyframes.Default.apply,
|
||||
'Default.applyrtl': Windows.UI.Animation.Keyframes.Default.applyrtl,
|
||||
'Edge.show': Windows.UI.Animation.Keyframes.Edge.show,
|
||||
'Edge.hide': Windows.UI.Animation.Keyframes.Edge.hide,
|
||||
'Panel.show': Windows.UI.Animation.Keyframes.Panel.show,
|
||||
'Panel.showrtl': Windows.UI.Animation.Keyframes.Panel.showrtl,
|
||||
'Panel.hide': Windows.UI.Animation.Keyframes.Panel.hide,
|
||||
'Panel.hidertl': Windows.UI.Animation.Keyframes.Panel.hidertl,
|
||||
'Popup.show': Windows.UI.Animation.Keyframes.Popup.show,
|
||||
'Drag.sourceEnd': Windows.UI.Animation.Keyframes.Drag.sourceEnd,
|
||||
'Drag.sourceEndRtl': Windows.UI.Animation.Keyframes.Drag.sourceEndRtl,
|
||||
'Content.enter': Windows.UI.Animation.Keyframes.Content.enter,
|
||||
'Content.enterrtl': Windows.UI.Animation.Keyframes.Content.enterrtl,
|
||||
'Page.enter': Windows.UI.Animation.Keyframes.Page.enter,
|
||||
'Page.enterrtl': Windows.UI.Animation.Keyframes.Page.enterrtl,
|
||||
'Exit': Windows.UI.Animation.Keyframes.Exit,
|
||||
'UpdateBadge': Windows.UI.Animation.Keyframes.UpdateBadge
|
||||
};
|
||||
|
||||
// 运行动画的函数
|
||||
function runAnimation(animationKey, elementId) {
|
||||
const targetElement = document.getElementById(elementId);
|
||||
const statusElement = document.getElementById(elementId.replace('Element', 'Status'));
|
||||
|
||||
if (!animationMap[animationKey]) {
|
||||
statusElement.textContent = `错误:未找到动画键 "${animationKey}"`;
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取动画关键帧
|
||||
const keyFrame = animationMap[animationKey];
|
||||
|
||||
// 更新状态
|
||||
statusElement.textContent = `正在执行动画: ${animationKey}\n关键帧: ${keyFrame}\n开始时间: ${new Date().toLocaleTimeString()}`;
|
||||
|
||||
// 执行动画
|
||||
Windows.UI.Animation.RunAsync(targetElement, keyFrame, 1000)
|
||||
.then(function() {
|
||||
statusElement.textContent += `\n动画完成时间: ${new Date().toLocaleTimeString()}`;
|
||||
})
|
||||
.catch(function(error) {
|
||||
statusElement.textContent = `动画执行出错: ${error.message}`;
|
||||
});
|
||||
}
|
||||
|
||||
// 页面加载完成后显示提示
|
||||
window.addEventListener('DOMContentLoaded', function() {
|
||||
const statusElements = document.querySelectorAll('.animation-status');
|
||||
statusElements.forEach(element => {
|
||||
element.textContent = '页面已加载完成,点击按钮测试动画效果';
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -5,7 +5,8 @@
|
||||
function nextstep() {
|
||||
Resources.processAll();
|
||||
}
|
||||
WinJS.UI.processAll().done(nextstep);
|
||||
if (typeof WinJS !== "undefined") WinJS.UI.processAll().done(nextstep);
|
||||
else nextstep();
|
||||
}
|
||||
OnLoad.add(ready);
|
||||
})(this);
|
||||
Reference in New Issue
Block a user