Skip to content

Commit ed3da92

Browse files
committed
Update: Use desktop toast notifications on Windows 10
Use toast notification to announce new update on modern Windows versions. The advantage of toasts is that they look more natural and they are persistent. So one can find the information about new update in action center even after notification timed out.
1 parent 225d0ba commit ed3da92

File tree

3 files changed

+77
-44
lines changed

3 files changed

+77
-44
lines changed

Src/Setup/BuildBinaries.bat

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ copy /B ..\ClassicIE\Setup\ClassicIE_32.exe Output > nul
3838
copy /B ..\StartMenu\Setup\StartMenu.exe Output > nul
3939
copy /B ..\StartMenu\Setup\StartMenuDLL.dll Output > nul
4040
copy /B ..\Update\Release\Update.exe Output > nul
41+
copy /B ..\Update\DesktopToasts\Release\DesktopToasts.dll Output > nul
4142
copy /B ..\StartMenu\StartMenuHelper\Setup\StartMenuHelper32.dll Output > nul
4243
copy /B ..\Setup\SetupHelper\Release\SetupHelper.exe Output > nul
4344

@@ -99,6 +100,8 @@ copy /B ..\StartMenu\StartMenuHelper\Setup\StartMenuHelper32.pdb Output\PDB32 >
99100
copy /B Output\StartMenuHelper32.dll Output\PDB32 > nul
100101
copy /B ..\Update\Release\Update.pdb Output\PDB32 > nul
101102
copy /B Output\Update.exe Output\PDB32 > nul
103+
copy /B ..\Update\DesktopToasts\Release\DesktopToasts.pdb Output\PDB32 > nul
104+
copy /B Output\DesktopToasts.dll Output\PDB32 > nul
102105

103106
REM Menu 64
104107
copy /B ..\StartMenu\Setup64\StartMenu.pdb Output\PDB64 > nul

Src/Setup/Setup.wxs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,9 @@
105105
</Feature>
106106
<Feature Id="Update" Level="1" Title="!(loc.UpdateTitle)" ConfigurableDirectory="APPLICATIONFOLDER" AllowAdvertise="no" Description="!(loc.UpdateDesc)">
107107
<ComponentRef Id="Update.exe" />
108+
<ComponentRef Id="DesktopToasts.dll" />
108109
<ComponentRef Id="UpdateSettingsLink" />
110+
<ComponentRef Id="ToastActivator" />
109111
</Feature>
110112
</Feature>
111113
<UI>
@@ -476,6 +478,9 @@
476478
<Component Id="Update.exe" Guid="FB6C213F-B670-4888-8B2C-12E807E335A7" Win64="$(var.CS_WIN64)">
477479
<File Id="Update" KeyPath="yes" Source="Output\Update.exe" Checksum="yes" Vital="yes" />
478480
</Component>
481+
<Component Id="DesktopToasts.dll" Guid="B42157AF-3984-4796-8BD6-501FC5450FF1" Win64="$(var.CS_WIN64)">
482+
<File Id="DesktopToasts.dll" KeyPath="yes" Source="Output\DesktopToasts.dll" Checksum="yes" Vital="yes" />
483+
</Component>
479484
<Component Id="PolicyDefinitions.zip" Guid="580A15D0-4023-471d-9D82-9D63FBA42B5D" Win64="$(var.CS_WIN64)">
480485
<File Id="PolicyDefinitions.zip" KeyPath="yes" Source="Output\PolicyDefinitions.zip" Vital="yes" />
481486
</Component>
@@ -551,6 +556,11 @@
551556
<Component Id="TreatAs" Guid="B1E7462A-E1E2-47eb-A42C-7BD272D738AA" Win64="$(var.CS_WIN64)">
552557
<RegistryKey Root="HKCR" Key="CLSID\{ECD4FC4D-521C-11D0-B792-00A0C90312E1}\TreatAs" ForceDeleteOnUninstall="yes" />
553558
</Component>
559+
<Component Id="ToastActivator" Guid="3A0FDC31-D5D3-4C2E-9A0B-292CAB46DA87" Win64="$(var.CS_WIN64)">
560+
<RegistryKey Root="HKCR" Key="CLSID\{E407B70A-1FBD-4D5E-8822-231C69102472}\LocalServer32" ForceDeleteOnUninstall="yes">
561+
<RegistryValue Value="&quot;[APPLICATIONFOLDER]Update.exe&quot; -ToastActivated" Type="string" />
562+
</RegistryKey>
563+
</Component>
554564
</DirectoryRef>
555565
<DirectoryRef Id="StartMenuDir">
556566
<Component Id="HelpLink" Guid="D631C351-7BD4-42CE-813C-5D46347068AF">
@@ -564,7 +574,10 @@
564574
<Condition>START_MENU_FOLDER=1</Condition>
565575
</Component>
566576
<Component Id="UpdateSettingsLink" Guid="10B5A082-6C92-4EA7-AFF8-21AE3D2D7FE0">
567-
<Shortcut Id="UpdateSettingsLink" Name="!(loc.UpdateItem)" Advertise="no" Description="!(loc.UpdateSettingsDesc)" Target="[APPLICATIONFOLDER]Update.exe" WorkingDirectory="APPLICATIONFOLDER" />
577+
<Shortcut Id="UpdateSettingsLink" Name="!(loc.UpdateItem)" Advertise="no" Description="!(loc.UpdateSettingsDesc)" Target="[APPLICATIONFOLDER]Update.exe" WorkingDirectory="APPLICATIONFOLDER">
578+
<ShortcutProperty Key="System.AppUserModel.ID" Value="OpenShell.Update"/>
579+
<ShortcutProperty Key="System.AppUserModel.ToastActivatorCLSID" Value="{E407B70A-1FBD-4D5E-8822-231C69102472}"/>
580+
</Shortcut>
568581
<CreateFolder />
569582
<Condition>START_MENU_FOLDER=1</Condition>
570583
</Component>

Src/Update/Update.cpp

Lines changed: 60 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "ResourceHelper.h"
1717
#include "Translations.h"
1818
#include <shlobj.h>
19+
#include "DesktopToasts/DesktopToasts.h"
1920

2021

2122
void ClosingSettings( HWND hWnd, int flags, int command )
@@ -487,8 +488,6 @@ int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpstrC
487488
CString language=GetSettingString(L"Language");
488489
ParseTranslations(NULL,language);
489490

490-
g_Instance=hInstance;
491-
492491
HINSTANCE resInstance=LoadTranslationDll(language);
493492

494493
LoadTranslationResources(resInstance,g_LoadDialogs);
@@ -500,60 +499,78 @@ int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpstrC
500499

501500
COwnerWindow ownerWindow;
502501
ownerWindow.Create(NULL,0,0,WS_POPUP);
502+
503+
DesktopToasts toasts(L"OpenShell.Update");
504+
503505
if (wcsstr(lpstrCmdLine,L"-popup")!=NULL)
504506
{
505507
g_UpdateDlg.UpdateData();
506508
// wait at least 5 seconds before showing the balloon
507509
int sleep=5000-(timeGetTime()-time0);
508510
if (sleep>0)
509511
Sleep(sleep);
510-
HWND balloon=CreateWindowEx(WS_EX_TOPMOST|WS_EX_TOOLWINDOW|(IsLanguageRTL()?WS_EX_LAYOUTRTL:0),TOOLTIPS_CLASS,NULL,WS_POPUP|TTS_CLOSE|TTS_NOPREFIX,0,0,0,0,NULL,NULL,g_Instance,NULL);
511-
SendMessage(balloon,TTM_SETMAXTIPWIDTH,0,500);
512-
TOOLINFO tool={sizeof(tool),TTF_ABSOLUTE|TTF_TRANSPARENT|TTF_TRACK|(IsLanguageRTL()?TTF_RTLREADING:0U)};
513-
tool.uId=1;
514-
CString message=LoadStringEx(g_UpdateDlg.HasNewLanguage()?IDS_LANG_NEWVERSION:IDS_NEWVERSION);
515-
tool.lpszText=(wchar_t*)(const wchar_t*)message;
516-
SendMessage(balloon,TTM_ADDTOOL,0,(LPARAM)&tool);
517-
SendMessage(balloon,TTM_SETTITLE,(WPARAM)LoadIcon(g_Instance,MAKEINTRESOURCE(IDI_APPICON)),(LPARAM)(const wchar_t*)LoadStringEx(IDS_UPDATE_TITLE));
518-
APPBARDATA appbar={sizeof(appbar)};
519-
SHAppBarMessage(ABM_GETTASKBARPOS,&appbar);
520-
MONITORINFO info={sizeof(info)};
521-
GetMonitorInfo(MonitorFromWindow(appbar.hWnd,MONITOR_DEFAULTTOPRIMARY),&info);
522-
SendMessage(balloon,TTM_TRACKPOSITION,0,0);
523-
SendMessage(balloon,TTM_TRACKACTIVATE,TRUE,(LPARAM)&tool);
524-
RECT rc;
525-
GetWindowRect(balloon,&rc);
526-
LONG pos;
527-
if (appbar.uEdge==ABE_LEFT)
528-
pos=MAKELONG(info.rcWork.left,info.rcWork.bottom-rc.bottom+rc.top);
529-
else if (appbar.uEdge==ABE_RIGHT)
530-
pos=MAKELONG(info.rcWork.right-rc.right+rc.left,info.rcWork.bottom-rc.bottom+rc.top);
531-
else if (appbar.uEdge==ABE_TOP)
532-
pos=MAKELONG(IsLanguageRTL()?info.rcWork.left:info.rcWork.right-rc.right+rc.left,info.rcWork.top);
512+
513+
auto title = LoadStringEx(IDS_UPDATE_TITLE);
514+
auto message = LoadStringEx(g_UpdateDlg.HasNewLanguage() ? IDS_LANG_NEWVERSION : IDS_NEWVERSION);
515+
516+
if (toasts)
517+
{
518+
toasts.DisplaySimpleToast(title, message);
519+
}
533520
else
534-
pos=MAKELONG(IsLanguageRTL()?info.rcWork.left:info.rcWork.right-rc.right+rc.left,info.rcWork.bottom-rc.bottom+rc.top);
535-
SendMessage(balloon,TTM_TRACKPOSITION,0,pos);
536-
SetWindowSubclass(balloon,SubclassBalloonProc,0,'CLSH');
537-
PlaySound(L"SystemNotification",NULL,SND_APPLICATION|SND_ALIAS|SND_ASYNC|SND_NODEFAULT|SND_SYSTEM);
538-
int time0=timeGetTime();
539-
while (IsWindowVisible(balloon))
540521
{
541-
if (time0 && (timeGetTime()-time0)>=15000)
542-
{
543-
time0=0;
544-
TOOLINFO tool={sizeof(tool)};
545-
tool.uId=1;
546-
SendMessage(balloon,TTM_TRACKACTIVATE,FALSE,(LPARAM)&tool);
547-
}
548-
MSG msg;
549-
while (PeekMessage(&msg,0,0,0,PM_REMOVE))
522+
HWND balloon = CreateWindowEx(WS_EX_TOPMOST | WS_EX_TOOLWINDOW | (IsLanguageRTL() ? WS_EX_LAYOUTRTL : 0), TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_CLOSE | TTS_NOPREFIX, 0, 0, 0, 0, NULL, NULL, g_Instance, NULL);
523+
SendMessage(balloon, TTM_SETMAXTIPWIDTH, 0, 500);
524+
TOOLINFO tool = { sizeof(tool),TTF_ABSOLUTE | TTF_TRANSPARENT | TTF_TRACK | (IsLanguageRTL() ? TTF_RTLREADING : 0U) };
525+
tool.uId = 1;
526+
tool.lpszText = (wchar_t*)(const wchar_t*)message;
527+
SendMessage(balloon, TTM_ADDTOOL, 0, (LPARAM)&tool);
528+
SendMessage(balloon, TTM_SETTITLE, (WPARAM)LoadIcon(g_Instance, MAKEINTRESOURCE(IDI_APPICON)), (LPARAM)(const wchar_t*)title);
529+
APPBARDATA appbar = { sizeof(appbar) };
530+
SHAppBarMessage(ABM_GETTASKBARPOS, &appbar);
531+
MONITORINFO info = { sizeof(info) };
532+
GetMonitorInfo(MonitorFromWindow(appbar.hWnd, MONITOR_DEFAULTTOPRIMARY), &info);
533+
SendMessage(balloon, TTM_TRACKPOSITION, 0, 0);
534+
SendMessage(balloon, TTM_TRACKACTIVATE, TRUE, (LPARAM)&tool);
535+
RECT rc;
536+
GetWindowRect(balloon, &rc);
537+
LONG pos;
538+
if (appbar.uEdge == ABE_LEFT)
539+
pos = MAKELONG(info.rcWork.left, info.rcWork.bottom - rc.bottom + rc.top);
540+
else if (appbar.uEdge == ABE_RIGHT)
541+
pos = MAKELONG(info.rcWork.right - rc.right + rc.left, info.rcWork.bottom - rc.bottom + rc.top);
542+
else if (appbar.uEdge == ABE_TOP)
543+
pos = MAKELONG(IsLanguageRTL() ? info.rcWork.left : info.rcWork.right - rc.right + rc.left, info.rcWork.top);
544+
else
545+
pos = MAKELONG(IsLanguageRTL() ? info.rcWork.left : info.rcWork.right - rc.right + rc.left, info.rcWork.bottom - rc.bottom + rc.top);
546+
SendMessage(balloon, TTM_TRACKPOSITION, 0, pos);
547+
SetWindowSubclass(balloon, SubclassBalloonProc, 0, 'CLSH');
548+
PlaySound(L"SystemNotification", NULL, SND_APPLICATION | SND_ALIAS | SND_ASYNC | SND_NODEFAULT | SND_SYSTEM);
549+
int time0 = timeGetTime();
550+
while (IsWindowVisible(balloon))
550551
{
551-
TranslateMessage(&msg);
552-
DispatchMessage(&msg);
552+
if (time0 && (timeGetTime() - time0) >= 15000)
553+
{
554+
time0 = 0;
555+
TOOLINFO tool = { sizeof(tool) };
556+
tool.uId = 1;
557+
SendMessage(balloon, TTM_TRACKACTIVATE, FALSE, (LPARAM)&tool);
558+
}
559+
MSG msg;
560+
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
561+
{
562+
TranslateMessage(&msg);
563+
DispatchMessage(&msg);
564+
}
565+
Sleep(10);
553566
}
554-
Sleep(10);
555567
}
556568
}
569+
else if (wcsstr(lpstrCmdLine, L"-ToastActivated"))
570+
{
571+
g_UpdateDlg.UpdateData();
572+
g_UpdateDlg.Run();
573+
}
557574
else
558575
{
559576
g_UpdateDlg.Run();

0 commit comments

Comments
 (0)