44 Commits

Author SHA1 Message Date
bonzibudd
4b2688245f Don't change Taskbar text color/texture until relaunch
This will accurately represent when these changes are able to take effect. Currently, the settings don't make any immediate changes or are broken when applied, and this should fix that.

Fixes #602.
2021-06-08 19:51:04 +02:00
bonzibudd
082f85a4e2 Scale menu icons up to 250% (240 DPI)
This should allow for icons in the menu to scale better for higher DPI displays. Configurations above 250% will retain the sizes for 240DPI.
2021-05-10 08:11:18 +02:00
bonzibudd
0ce76c9c36 Skin: Tweak programs icon arrows 2021-05-06 08:23:04 +02:00
bonzibudd
6e71d7c414 Skin: Add "Back" arrow to programs button
This can help distinguish when the programs list has been activated.
2021-05-06 08:23:04 +02:00
bonzibudd
84909cf397 Skin: Retain list padding when using icon frames
This will make the padding of list items stay the same regardless of if icon frames are enabled or not. List padding shouldn't change with the icon frame option because lists don't contain icon frames.
2021-05-06 08:23:04 +02:00
bonzibudd
fc290d5a6a Skin: Remove extra "Submenu_opacity" 2021-05-06 08:23:04 +02:00
bonzibudd
ebd530f652 Skin: Better scaling of icon frames
This will make the space around icon frames scale appropriately.
2021-05-06 08:23:04 +02:00
bonzibudd
e50c5f73d7 "About this skin" text should link to Open-Shell 2021-05-06 08:23:04 +02:00
bonzibudd
1db0006c96 Fix right-hand padding with Icon frames enabled
This should improve the right-hand spacing when icon frames are enabled, and right-hand icons are disabled. There shouldn't be any extra icon/text padding for Main2 when icons aren't enabled.
2021-05-04 11:26:29 +02:00
GenesisToxical
7d0a9df1c3 Quick Access to Taskbar Tab - SettingsUI.cpp
Easy access to modify Taskbar options without having to activate all other tabs.
2021-04-03 10:13:01 +02:00
Anis Errais
8e1b4e35a3 Added options for moving the start menu and showing the start menu at the edge of working area instead of against the taskbar 2021-02-09 20:57:48 +01:00
Xenhat
859afc63d3 Label topmost discussion link correctly as Gitter 2020-12-27 10:50:55 -05:00
Xenhat
ee6db35b34 Update README.md
Add link to Discussions section and Discord for questions
2020-12-27 10:49:38 -05:00
ge0rdi
283c0fce03 Fix Shutdown item text
To be consistent with text in Windows.

Fixes #501.
2020-10-23 18:07:39 +02:00
ge0rdi
ac5e69f1a0 Use modern Help icon in Classic/Two column menu style
Fixes #506.
2020-10-23 18:07:38 +02:00
ge0rdi
b2df22104e Setup: Fix installer warning on Windows 7
`Warning 1946. Property 'System.AppUserModel.ToastActivatorCLSID' for shortcut 'Open-Shell Update.lnk' could not be set.`

Windows 7 doesn't recognize `System.AppUserModel.ToastActivatorCLSID`
name so we have to use GUID directly.

https://docs.microsoft.com/en-us/troubleshoot/windows/win32/warning-1946-when-you-install-installer-package

Fixes #507.
2020-10-23 18:07:37 +02:00
ge0rdi
c88f028f3e Show Settings above Control Panel by default
(Modern) Settings are more and more important in Windows 10,
so it makes sense to show them above Control Panel.

This changes only defaults, users will be still able to order start menu
items as they like.

Fixes #23.
2020-10-23 10:13:57 +02:00
ge0rdi
312bfd99d5 Update settings search category names
To make it consistent with the rest of product:

`Settings` category is renamed to `Control Panel`
`Modern Settings` category is renamed to `Settings`
2020-10-23 10:13:57 +02:00
ge0rdi
ca576a0224 Display Modern settings search results above Control Panel ones
(Modern) Settings are just more and more important in Windows 10.
So it makes sense to show their search results first.

Fixes #481.
2020-10-23 10:13:57 +02:00
ge0rdi
a5f35b133f Improve compatibility with WindowBlinds
`Open-Shell` hooks `SHFillRectClr` (ordinal 197) API from `shlwapi.dll`
in order to be able to customize taskbar.

The API is hooked even if taskbar customization is disabled in `Open-Shell` (default).

`WindowBlinds` hooks the same API so this is causing clashes between
both programs.
In fact `Open-Shell` hooks later which makes `WindowBlinds` hook to be
completely ignored.

The solution would be to hook only if taskbar customization is enabled.

This way `Open-Shell` should be more compatible with other customization
tools in default state.

Fixes #433.
2020-10-23 10:13:57 +02:00
ge0rdi
f197c9f43d Don't show jump list for Settings application
It reports just one category with unsupported type, thus jump-list will be
empty.

Fixes #487.
2020-10-23 10:13:57 +02:00
ge0rdi
bce9efcc43 Display monochrome icons using color of corresponding text item
Some icons (modern settings, jump-list tasks) are monochrome, basically
they are defined just by alpha channel.
Thus they can be displayed in any color (white is default).

Since these icons are white by default, they look nice on dark
backgrounds. But they are not very visible on light backgrounds.

Thus the idea is to 'colorize' such icon using color of corresponding
text item. That way they will always have proper color.

Fixes #466.
2020-09-26 15:46:19 +02:00
ge0rdi
80c38d95e9 ModernSettings: Fix crash when invoking with unknown verb 2020-09-26 09:18:42 +02:00
ge0rdi
0b535d1dd8 Update: Properly handle toast activation
Use `OnToastActivate` to display update dialog if user clicked on toast
during `update.exe` life-time.

Process messages for some time after displaying toast.
Otherwise toast may be not displayed at all.
2020-09-26 08:14:56 +02:00
ge0rdi
e2ff745949 Skin: Add support for Immersive* color names 2020-09-25 20:10:39 +02:00
ge0rdi
fbcf85559e Update: Add option to check for nightly updates
Use Appveyor REST API to obtain information about latest build from master.
2020-09-24 18:52:24 +02:00
ge0rdi
ed3da927cc 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.
2020-09-24 18:52:24 +02:00
ge0rdi
225d0ba8f9 Update: Add library for Desktop Toast notifications
Based on sample code in:
https://github.com/WindowsNotifications/desktop-toasts

More info:
https://docs.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/send-local-toast-desktop-cpp-wrl
2020-09-24 18:52:24 +02:00
ge0rdi
afaf16620a Setup: Bring back Update component
This reverts commit ed3675ca7f.
This reverts commit ee59bb76de.
2020-09-24 18:52:24 +02:00
ge0rdi
4883d13950 Update: Support for automatic updates
Use Github REST API to get info about latest release (version,
changelog, installer url).
2020-09-24 18:52:24 +02:00
ge0rdi
b094ddc5f9 Add Json library
https://github.com/nlohmann/json

Will be used to parse REST API responses from Github/Appveyor.
2020-09-24 18:52:24 +02:00
ge0rdi
a422105c61 Proper support for HTTPS in DownloadFile
Use secure connection right from the beginning.
2020-09-24 18:52:24 +02:00
ge0rdi
96423b8918 Log: More precise timing 2020-09-24 18:52:24 +02:00
ge0rdi
ba131ff14b Update build instructions 2020-09-24 18:52:24 +02:00
ge0rdi
7d59f5ebfb Support for modern app jump-list tasks
Task jump-list items for modern apps require special handling.

First of all they don't provide icon directly.
Icon location is stored in `PKEY_AppUserModel_DestListLogoUri` property.
And then has to be resolved for given application package.

Next, context menu of provided `IShellLink` item doesn't seem to be able
to start actual link target.
Thus we need to obtain context menu of target item.

Fixes #375.
2020-09-23 11:50:32 +02:00
ge0rdi
95f3a4b09a Add GetPackageFullName helper 2020-09-23 11:50:32 +02:00
ge0rdi
728f982310 Modernize CItemManager::LoadCustomIcon 2020-09-23 11:50:32 +02:00
ge0rdi
2ca236c291 Don't make metro icons smaller if Invert metro icons is enabled
There should be no need to make icons smaller.
2020-09-23 11:50:32 +02:00
ge0rdi
8a22282191 ItemManager: Better handling of modern application links
Link to modern application will be treat as modern application itself.

This fixes jump-lists and invert metro color option on modern apps pinned
to start menu.
2020-09-23 11:50:32 +02:00
ge0rdi
935600a6d9 Add LogPropertyStore helper 2020-09-23 11:50:32 +02:00
ge0rdi
d3bf4b6207 MenuContainer: Faster recent Metro apps enumeration
It seems that `SHCreateItemInKnownFolder` is quite slow for Metro apps.
Thus we should avoid it and use cached app info.
2020-09-22 19:12:35 +02:00
ge0rdi
aa09a0dcc2 ItemManager: Keep metro name if already obtained 2020-09-22 19:12:35 +02:00
ge0rdi
cd8cc8cbc6 Skin: Add more DPI options
Allow skin customizations for higher DPI displays by adding more DPI options:
- 120_DPI
- 144_DPI
- 168_DPI
- 192_DPI
- 216_DPI
- 240_DPI

Fixes #458 .
2020-09-22 07:08:37 +02:00
Xenhat
1bfbe09c6f Add discord server badge :) (#462)
Squashing because appveyor is stuck, also useless for a readme change
2020-09-21 17:51:15 -04:00
44 changed files with 27252 additions and 604 deletions

View File

@@ -1,4 +1,4 @@
; This file contains all localized text for Open-Shell Menu. There is one section per language.
; This file contains all localized text for Open-Shell Menu. There is one section per language.
; Every section contains text lines in the form of <key> = <string>.
; Which section is used depends on the current OS setting. If a key is missing from the language section
; it will be searched in the [default] section. In some cases more than one language can be used.
@@ -129,7 +129,7 @@ Menu.RemoveHighlight = إزالة التمييز
Menu.Uninstall = إز&الة التثبيت
Menu.UninstallTitle = إزالة التثبيت
Menu.UninstallPrompt = ‏‏هل تريد بالتأكيد إزالة تثبيت %s؟
Search.CategorySettings = الإعدادات
Search.CategorySettings = لوحة التح&كم
Search.CategoryPCSettings = إعدادات الكمبيوتر
Search.CategoryPrograms = البرامج
Search.CategoryDocuments = المستندات
@@ -265,7 +265,7 @@ Menu.RemoveHighlight = Премахни осветяването
Menu.Uninstall = &Деинсталирай
Menu.UninstallTitle = Деинсталиране
Menu.UninstallPrompt = Наистина ли искате да деинсталирате %s?
Search.CategorySettings = Настройки
Search.CategorySettings = Контролен панел
Search.CategoryPCSettings = Настройки на компютъра
Search.CategoryPrograms = Програми
Search.CategoryDocuments = Документи
@@ -403,7 +403,7 @@ Menu.UninstallTitle = Desinstal·la
Menu.UninstallPrompt = Esteu segur que voleu desinstal·lar el %s?
Menu.ClassicSettings = Open-Shell &Menú
Menu.SettingsTip = Ajustaments del Open-Shell Menú
Search.CategorySettings = Configuració
Search.CategorySettings = Panell de control
Search.CategoryPCSettings = Configuració de l'ordinador
Search.CategoryPrograms = Programes
Search.CategoryDocuments = Documents
@@ -539,7 +539,7 @@ Menu.RemoveHighlight = Odebrat nejzajímavější místo
Menu.Uninstall = &Odinstalovat
Menu.UninstallTitle = Odinstalovat
Menu.UninstallPrompt = Opravdu chcete odinstalovat položku %s?
Search.CategorySettings = Nastavení
Search.CategorySettings = Ovládací panely
Search.CategoryPCSettings = Nastavení počítače
Search.CategoryPrograms = Programy
Search.CategoryDocuments = Dokumenty
@@ -675,7 +675,7 @@ Menu.RemoveHighlight = Fjern centralt punkt
Menu.Uninstall = &Fjern
Menu.UninstallTitle = Fjern
Menu.UninstallPrompt = Er du sikker på, at du vil fjerne %s?
Search.CategorySettings = Indstillinger
Search.CategorySettings = Kontrolpanel
Search.CategoryPCSettings = Pc-indstillinger
Search.CategoryPrograms = Programmer
Search.CategoryDocuments = Dokumenter
@@ -811,7 +811,7 @@ Menu.RemoveHighlight = Haupttreffer entfernen
Menu.Uninstall = &Deinstallieren
Menu.UninstallTitle = Deinstallieren
Menu.UninstallPrompt = Möchten Sie %s wirklich deinstallieren?
Search.CategorySettings = Einstellungen
Search.CategorySettings = Systemsteuerung
Search.CategoryPCSettings = PC-Einstellungen
Search.CategoryPrograms = Programme
Search.CategoryDocuments = Dokumente
@@ -947,7 +947,7 @@ Menu.RemoveHighlight = Κατάργηση επισήμανσης
Menu.Uninstall = &Κατάργηση εγκατάστασης
Menu.UninstallTitle = Κατάργηση εγκατάστασης
Menu.UninstallPrompt = Είστε βέβαιοι ότι θέλετε να καταργήσετε την εγκατάσταση του %s;
Search.CategorySettings = Ρυθμίσεις
Search.CategorySettings = Πίνακας Ελέγχου
Search.CategoryPCSettings = Ρυθμίσεις υπολογιστή
Search.CategoryPrograms = Προγράμματα
Search.CategoryDocuments = Έγγραφα
@@ -991,7 +991,7 @@ Menu.LogOffShort = &Log off
Menu.Undock = Undock Comput&er
Menu.Disconnect = D&isconnect
Menu.ShutdownBox = Sh&ut Down...
Menu.Shutdown = Sh&ut Down
Menu.Shutdown = Sh&ut down
Menu.Restart = &Restart
Menu.ShutdownUpdate = Update and shut down
Menu.RestartUpdate = Update and restart
@@ -1083,8 +1083,8 @@ Menu.RemoveHighlight = Remove highlight
Menu.Uninstall = &Uninstall
Menu.UninstallTitle = Uninstall
Menu.UninstallPrompt = Are you sure you want to uninstall %s?
Search.CategorySettings = Settings
Search.CategoryPCSettings = Modern Settings
Search.CategorySettings = Control Panel
Search.CategoryPCSettings = Settings
Search.CategoryPrograms = Programs
Search.CategoryDocuments = Documents
Search.CategoryMusic = Music
@@ -1219,7 +1219,7 @@ Menu.RemoveHighlight = Quitar como elemento destacado
Menu.Uninstall = &Desinstalar
Menu.UninstallTitle = Desinstalar
Menu.UninstallPrompt = ¿Está seguro de que desea desinstalar %s?
Search.CategorySettings = Configuración
Search.CategorySettings = Panel de control
Search.CategoryPCSettings = Configuración de tu PC
Search.CategoryPrograms = Programas
Search.CategoryDocuments = Documentos
@@ -1355,7 +1355,7 @@ Menu.RemoveHighlight = Eemalda esiletõst
Menu.Uninstall = &Desinstalli
Menu.UninstallTitle = Desinstalli
Menu.UninstallPrompt = Kas soovite kindlasti desinstallida %s?
Search.CategorySettings = Sätted
Search.CategorySettings = Juhtpaneel
Search.CategoryPCSettings = Arvutisätted
Search.CategoryPrograms = Programmid
Search.CategoryDocuments = Dokumendid
@@ -1493,7 +1493,7 @@ Menu.UninstallTitle = لغو نصب
Menu.UninstallPrompt = ‏‏آیا مطمئنید می خواهید %s را لغو نصب کنید؟
Menu.ClassicSettings = منوی ش&روع کلاسیک
Menu.SettingsTip = تنظیمات منوی شروع کلاسیک
Search.CategorySettings = تنظیمات
Search.CategorySettings = صفحه کنترل
Search.CategoryPCSettings = تنظیمات رایانه
Search.CategoryPrograms = برنامه‌ها
Search.CategoryDocuments = اسناد
@@ -1629,7 +1629,7 @@ Menu.RemoveHighlight = Poista tärkeä kohde
Menu.Uninstall = &Poista asennus
Menu.UninstallTitle = Poista asennus
Menu.UninstallPrompt = Haluatko varmasti poistaa kohteen %s asennuksen?
Search.CategorySettings = Asetukset
Search.CategorySettings = Ohjauspaneeli
Search.CategoryPCSettings = Tietokoneen asetukset
Search.CategoryPrograms = Ohjelmat
Search.CategoryDocuments = Tiedostot
@@ -1765,7 +1765,7 @@ Menu.RemoveHighlight = Supprimer la recommandation
Menu.Uninstall = &Désinstaller
Menu.UninstallTitle = Désinstaller
Menu.UninstallPrompt = Faut-il vraiment désinstaller %s ?
Search.CategorySettings = Paramètres
Search.CategorySettings = Panneau de configuration
Search.CategoryPCSettings = Paramètres du PC
Search.CategoryPrograms = Programmes
Search.CategoryDocuments = Documents
@@ -1901,7 +1901,7 @@ Menu.RemoveHighlight = Remove highlight
Menu.Uninstall = &Dì-stàlaich
Menu.UninstallTitle = Dì-stàlaich
Menu.UninstallPrompt = A bheil thu cinnteach gu bheil thu airson %s a dhì-stàladh?
Search.CategorySettings = Roghainnean
Search.CategorySettings = A' phanail-smachd
Search.CategoryPCSettings = Roghainnean a' PC
Search.CategoryPrograms = Prògraman
Search.CategoryDocuments = Sgrìobhainnean
@@ -2037,7 +2037,7 @@ Menu.RemoveHighlight = הסר הבלטה
Menu.Uninstall = ה&סר התקנה
Menu.UninstallTitle = הסר התקנה
Menu.UninstallPrompt = ‏‏האם אתה בטוח שברצונך להסיר את התקנת %s?
Search.CategorySettings = הגדרות
Search.CategorySettings = לוח הבקרה
Search.CategoryPCSettings = הגדרות מחשב
Search.CategoryPrograms = תוכניות
Search.CategoryDocuments = מסמכים
@@ -2173,7 +2173,7 @@ Menu.RemoveHighlight = Ukloni isticanje
Menu.Uninstall = &Deinstaliraj
Menu.UninstallTitle = Deinstaliraj
Menu.UninstallPrompt = Jeste li sigurni da želite deinstalirati %s iz računala?
Search.CategorySettings = Postavke
Search.CategorySettings = Upravljačka ploča
Search.CategoryPCSettings = Postavke PC-ja
Search.CategoryPrograms = Programi
Search.CategoryDocuments = Dokumenti
@@ -2309,7 +2309,7 @@ Menu.RemoveHighlight = Kiemelés eltávolítása
Menu.Uninstall = Eltá&volítás
Menu.UninstallTitle = Eltávolítás
Menu.UninstallPrompt = Biztosan el kívánja távolítani a következőt: %s?
Search.CategorySettings = Beállítások
Search.CategorySettings = Vezérlőpult
Search.CategoryPCSettings = Gépház
Search.CategoryPrograms = Programs
Search.CategoryDocuments = Dokumentumok
@@ -2447,8 +2447,8 @@ Menu.RemoveHighlight = Fjarlægja auðkenningu
Menu.Uninstall = Fjarlægja
Menu.UninstallTitle = Fjarlægja
Menu.UninstallPrompt = Ertu viss um að það eigi að fjarlægja %s?
Search.CategorySettings = Stillingar
Search.CategoryPCSettings = Sérstillingar tölvunnar
Search.CategorySettings = Stjórnborð
Search.CategoryPCSettings = PC stillingar
Search.CategoryPrograms = Forrit
Search.CategoryDocuments = Skjöl
Search.CategoryMusic = Tónlist
@@ -2479,7 +2479,7 @@ Menu.Search = Ce&rca
Menu.SearchBox = Cerca
Menu.SearchPrograms = Cerca programmi e file
Menu.SearchInternet = Cerca in Internet
Menu.Searching = Ricerca...
Menu.Searching = Ricerca in corso...
Menu.NoMatch = Nessun elemento corrisponde ai criteri di ricerca.
Menu.MoreResults = Ulteriori risultati
Menu.Help = &Guida e supporto tecnico
@@ -2502,10 +2502,10 @@ Menu.PCSettings = Impostazioni PC
Menu.Security = Protezione di Windows
Menu.Network = Connessioni di &rete
Menu.Printers = &Stampanti
Menu.Taskbar = &Barra applicazioni e menu Start
Menu.Taskbar = &Barra delle applicazioni e menu Start
Menu.SearchFiles = &File o cartelle...
Menu.SearchPrinter = &Per stampante
Menu.SearchComputers = Per &computer
Menu.SearchComputers = Per &Computer
Menu.UserFilesTip = Contiene cartelle per documenti, immagini, musica e altri file dell'utente.
Menu.UserDocumentsTip = Contiene lettere, rapporti e altri documenti e file.
Menu.UserPicturesTip = Contiene foto digitali, immagini e file di grafica.
@@ -2527,8 +2527,8 @@ Menu.HelpTip = Trovare argomenti della Guida, esercitazioni, risoluzione problem
Menu.ProgramsTip = Apre l'elenco dei programmi.
Menu.SearchFilesTip = Cercare documenti, musica, immagini, posta elettronica e altro.
Menu.GamesTip = Consente di giocare e gestire i giochi installati nel computer.
Menu.SecurityTip = Avvia programmi per modifica opzioni di sicurezza di Windows per cambiare la password, cambiare utente o avviare Gestione attività.
Menu.SearchComputersTip = Cerca computer nella rete
Menu.SecurityTip = Avvia le opzioni di Sicurezza di Windows per modificare la password, cambiare utente o avviare Gestione attività.
Menu.SearchComputersTip = Cerca computer sulla rete
Menu.SearchPrintersTip = Cerca stampante
Menu.AdminToolsTip = Configura le impostazioni amministrative del computer.
Menu.ShutdownTip = Chiude tutti i programmi aperti, arresta Windows e spegne il computer.
@@ -2536,7 +2536,7 @@ Menu.RestartTip = Chiude tutti i programmi aperti e riavvia Windows.
Menu.SleepTip = Mantiene la sessione in memoria e imposta la modalità basso consumo che consente di riprendere rapidamente il lavoro.
Menu.HibernateTip = Salva la sessione e spegne il computer. Quando si riaccende il computer, la sessione verrà ripristinata.
Menu.LogOffTip = Chiude i programmi e disconnette l'utente.
Menu.DisconnectTip = Disconnette dalla sessione. È possibile riconnettersi a questa sessione al prossimo accesso.
Menu.DisconnectTip = Disconnette la sessione. È possibile riconnettersi a questa sessione al prossimo accesso.
Menu.LockTip = Blocca il computer.
Menu.UndockTip = Consente di rimuovere il computer portatile o il notebook dall'alloggiamento di espansione.
Menu.SwitchUserTip = Consente di cambiare utente senza chiudere i programmi.
@@ -2553,7 +2553,7 @@ Menu.MenuSettings = Impostazioni
Menu.MenuHelp = Guida
Menu.MenuExit = Esci
Menu.LogoffTitle = Disconnessione da Windows
Menu.LogoffPrompt = Vuoi disconnetterti?
Menu.LogoffPrompt = Disconnettersi?
Menu.LogoffYes = &Disconnetti
Menu.LogoffNo = &No
Menu.RenameTitle = Rinomina
@@ -2570,7 +2570,7 @@ Menu.ActionOpen = Apri
Menu.ActionClose = Chiudi
Menu.ActionExecute = Esegui
Menu.RemoveList = &Rimuovi da questo elenco
Menu.RemoveAll = Azzera elenco ogge&tti recenti
Menu.RemoveAll = Cancella elenco Ogge&tti recenti
Menu.Explorer = Esplora risorse
Menu.Start = Start
Menu.StartScreen = Schermata Start
@@ -2582,8 +2582,8 @@ Menu.MonitorOff = Spegne lo schermo
Menu.RemoveHighlight = Rimuovi elemento di rilievo
Menu.Uninstall = &Disinstalla
Menu.UninstallTitle = Disinstalla
Menu.UninstallPrompt = Vuoi disinstallare %s?
Search.CategorySettings = Impostazioni
Menu.UninstallPrompt = Disinstallare %s?
Search.CategorySettings = Pannello di controllo
Search.CategoryPCSettings = Impostazioni PC
Search.CategoryPrograms = Programmi
Search.CategoryDocuments = Documenti
@@ -2991,7 +2991,7 @@ Menu.RemoveHighlight = Šalinti paryškinimą
Menu.Uninstall = &Pašalinti
Menu.UninstallTitle = Pašalinti
Menu.UninstallPrompt = Ar tikrai norite pašalinti %s?
Search.CategorySettings = Parametrai
Search.CategorySettings = Valdymo skydas
Search.CategoryPCSettings = PC parametrai
Search.CategoryPrograms = Programos
Search.CategoryDocuments = Dokumentai
@@ -3127,7 +3127,7 @@ Menu.RemoveHighlight = Noņemt marķējumu
Menu.Uninstall = &Atinstalēt
Menu.UninstallTitle = Atinstalēt
Menu.UninstallPrompt = Vai esat pārliecināts, ka vēlaties atinstalēt %s?
Search.CategorySettings = Iestatījumi
Search.CategorySettings = Vadības panelis
Search.CategoryPCSettings = Datora iestatījumi
Search.CategoryPrograms = Programmas
Search.CategoryDocuments = Dokumenti
@@ -3263,7 +3263,7 @@ Menu.RemoveHighlight = Remove highlight
Menu.Uninstall = &Деинсталирај
Menu.UninstallTitle = Деинсталирај
Menu.UninstallPrompt = Дали сте сигурни дека сакате да го деинсталирате %s?
Search.CategorySettings = Подесувања
Search.CategorySettings = Контрол панел
Search.CategoryPCSettings = Параметри на компјутерот
Search.CategoryPrograms = Програми
Search.CategoryDocuments = Документи
@@ -3399,7 +3399,7 @@ Menu.RemoveHighlight = Fjern høydepunkt
Menu.Uninstall = &Avinstaller
Menu.UninstallTitle = Avinstaller
Menu.UninstallPrompt = Er du sikker på at du vil avinstallere %s?
Search.CategorySettings = Innstillinger
Search.CategorySettings = Kontrollpanel
Search.CategoryPCSettings = PC-innstillinger
Search.CategoryPrograms = Programmer
Search.CategoryDocuments = Dokumenter
@@ -3535,7 +3535,7 @@ Menu.RemoveHighlight = Aandachtspunt verwijderen
Menu.Uninstall = V&erwijderen
Menu.UninstallTitle = Verwijderen
Menu.UninstallPrompt = Weet u zeker dat u %s wilt verwijderen?
Search.CategorySettings = Instellingen
Search.CategorySettings = Configuratiescherm
Search.CategoryPCSettings = Pc-instellingen
Search.CategoryPrograms = Programma's
Search.CategoryDocuments = Documenten
@@ -3671,7 +3671,7 @@ Menu.RemoveHighlight = Usuń wyróżnienie
Menu.Uninstall = &Odinstaluj
Menu.UninstallTitle = Odinstaluj
Menu.UninstallPrompt = Czy na pewno chcesz odinstalować program %s?
Search.CategorySettings = Ustawienia
Search.CategorySettings = Panel sterowania
Search.CategoryPCSettings = Ustawienia komputera
Search.CategoryPrograms = Programy
Search.CategoryDocuments = Dokumenty
@@ -3807,7 +3807,7 @@ Menu.RemoveHighlight = Remover Destaque
Menu.Uninstall = &Desinstalar
Menu.UninstallTitle = Desinstalar
Menu.UninstallPrompt = Tem certeza de que deseja desinstalar %s?
Search.CategorySettings = Configurações
Search.CategorySettings = Painel de controle
Search.CategoryPCSettings = Configurações do computador
Search.CategoryPrograms = Programas
Search.CategoryDocuments = Documentos
@@ -3943,7 +3943,7 @@ Menu.RemoveHighlight = Remover destaque
Menu.Uninstall = D&esinstalar
Menu.UninstallTitle = Desinstalar
Menu.UninstallPrompt = Tem a certeza de que pretende desinstalar %s?
Search.CategorySettings = Definições
Search.CategorySettings = Painel de controlo
Search.CategoryPCSettings = Definições do PC
Search.CategoryPrograms = Programas
Search.CategoryDocuments = Documentos
@@ -4079,7 +4079,7 @@ Menu.RemoveHighlight = Eliminare evidențiere
Menu.Uninstall = &Dezinstalare
Menu.UninstallTitle = Dezinstalare
Menu.UninstallPrompt = Sigur dezinstalați %s?
Search.CategorySettings = Setări
Search.CategorySettings = Panou de control
Search.CategoryPCSettings = Setări PC
Search.CategoryPrograms = Programe
Search.CategoryDocuments = Documente
@@ -4215,7 +4215,7 @@ Menu.RemoveHighlight = Выключить пометку
Menu.Uninstall = &Удалить
Menu.UninstallTitle = Удалить
Menu.UninstallPrompt = Вы действительно хотите удалить "%s"?
Search.CategorySettings = Параметры
Search.CategorySettings = Панель управления
Search.CategoryPCSettings = Параметры ПК
Search.CategoryPrograms = Программы
Search.CategoryDocuments = Документы
@@ -4351,7 +4351,7 @@ Menu.RemoveHighlight = Odstrániť zvýraznenie
Menu.Uninstall = &Odinštalovať
Menu.UninstallTitle = Odinštalovať
Menu.UninstallPrompt = Naozaj chcete odinštalovať program %s?
Search.CategorySettings = Nastavenia
Search.CategorySettings = Ovládací panel
Search.CategoryPCSettings = Nastavenie PC
Search.CategoryPrograms = Programy
Search.CategoryDocuments = Dokumenty
@@ -4487,7 +4487,7 @@ Menu.RemoveHighlight = Odstrani označitev
Menu.Uninstall = &Odstrani
Menu.UninstallTitle = Odstrani
Menu.UninstallPrompt = Ali ste prepričani, da želite odstraniti %s?
Search.CategorySettings = Nastavitve
Search.CategorySettings = Nadzorna plošča
Search.CategoryPCSettings = Nastavitve računalnika
Search.CategoryPrograms = Programi
Search.CategoryDocuments = Dokumenti
@@ -4623,7 +4623,7 @@ Menu.RemoveHighlight = Ukloni istaknuti sadržaj
Menu.Uninstall = &Deinstaliraj
Menu.UninstallTitle = Deinstaliraj
Menu.UninstallPrompt = Želite li zaista da deinstalirate %s?
Search.CategorySettings = Postavke
Search.CategorySettings = Kontrolna tabla
Search.CategoryPCSettings = Postavke računara
Search.CategoryPrograms = Programs
Search.CategoryDocuments = Dokumenti
@@ -4759,7 +4759,7 @@ Menu.RemoveHighlight = Ta bort fokus
Menu.Uninstall = &Avinstallera
Menu.UninstallTitle = Avinstallera
Menu.UninstallPrompt = Vill du avinstallera %s?
Search.CategorySettings = Inställningar
Search.CategorySettings = Kontrollpanelen
Search.CategoryPCSettings = Datorinställningar
Search.CategoryPrograms = Program
Search.CategoryDocuments = Dokument
@@ -4896,7 +4896,7 @@ Menu.RemoveHighlight = เอาไฮไลท์ออก
Menu.Uninstall = &ถอนการติดตั้ง
Menu.UninstallTitle = ถอนการติดตั้ง
Menu.UninstallPrompt = คุณแน่ใจหรือไม่ว่าคุณต้องการถอนการติดตั้ง %s
Search.CategorySettings = การตั้งค่า
Search.CategorySettings = แผงควบคุม
Search.CategoryPCSettings = การตั้งค่าพีซี
Search.CategoryPrograms = โปรแกรม
Search.CategoryDocuments = เอกสาร
@@ -5032,7 +5032,7 @@ Menu.RemoveHighlight = Önemli Noktayı Kaldır
Menu.Uninstall = &Kaldır
Menu.UninstallTitle = Kaldır
Menu.UninstallPrompt = %s programını kaldırmak istediğinizden emin misiniz?
Search.CategorySettings = Ayarlar
Search.CategorySettings = Denetim Masası
Search.CategoryPCSettings = Bilgisayar ayarları
Search.CategoryPrograms = Programlar
Search.CategoryDocuments = Belgeler
@@ -5168,7 +5168,7 @@ Menu.RemoveHighlight = Видалити виділення
Menu.Uninstall = &Видалити
Menu.UninstallTitle = Видалити
Menu.UninstallPrompt = Дійсно видалити %s?
Search.CategorySettings = Настройки
Search.CategorySettings = Панель керування
Search.CategoryPCSettings = Параметри ПК
Search.CategoryPrograms = Програми
Search.CategoryDocuments = Документи

View File

@@ -2,10 +2,10 @@
*Originally* **[Classic Shell](http://www.classicshell.net)** *by [Ivo Beltchev](https://sourceforge.net/u/ibeltchev/profile/)*
[![GitHub Release](https://img.shields.io/github/release/Open-Shell/Open-Shell-Menu.svg)](https://github.com/Open-Shell/Open-Shell-Menu/releases) [![GitHub Pre-Release](https://img.shields.io/github/release/Open-Shell/Open-Shell-Menu/all.svg)](https://github.com/Open-Shell/Open-Shell-Menu/releases) [![Build status](https://ci.appveyor.com/api/projects/status/2wj5x5qoypfjj0tr/branch/master?svg=true)](https://ci.appveyor.com/project/passionate-coder/open-shell-menu/branch/master) [![GitQ](https://gitq.com/badge.svg)](https://gitq.com/passionate-coder/Classic-Start) [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/open-shell/Lobby)
[![GitHub Release](https://img.shields.io/github/release/Open-Shell/Open-Shell-Menu.svg)](https://github.com/Open-Shell/Open-Shell-Menu/releases) [![GitHub Pre-Release](https://img.shields.io/github/release/Open-Shell/Open-Shell-Menu/all.svg)](https://github.com/Open-Shell/Open-Shell-Menu/releases) [![Build status](https://ci.appveyor.com/api/projects/status/2wj5x5qoypfjj0tr/branch/master?svg=true)](https://ci.appveyor.com/project/passionate-coder/open-shell-menu/branch/master) [![GitQ](https://gitq.com/badge.svg)](https://gitq.com/passionate-coder/Classic-Start) [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/open-shell/Lobby) [![Discord](https://img.shields.io/discord/757701054782636082?color=%4E5D94&label=Discord&logo=discord&logoColor=white)](https://discord.gg/7H6arr5)
[Home Page](https://open-shell.github.io/Open-Shell-Menu)
[Discussion room](https://gitter.im/Open-Shell)
[Gitter Discussion room](https://gitter.im/Open-Shell)
[Latest nightly build](https://ci.appveyor.com/project/passionate-coder/open-shell-menu/branch/master/artifacts)
### Features
@@ -30,4 +30,5 @@ If you just want to use it or looking for setup file, click here to download:
[How To Skin a Start Menu](https://coddec.github.io/Classic-Shell/www.classicshell.net/tutorials/skintutorial.html)
[Classic Shell - Custom Start Buttons](https://coddec.github.io/Classic-Shell/www.classicshell.net/tutorials/buttontutorial.html)
[Questions? Ask on the Discussions section](https://github.com/Open-Shell/Open-Shell-Menu/discussions) or on [Discord](https://discord.gg/7H6arr5)
[Report a bug/issue or submit a feature request](https://github.com/Open-Shell/Open-Shell-Menu/issues)

View File

@@ -5,9 +5,9 @@ for other languages.
The final files (installers, archives) are saved to the Setup\Final folder.
You need the following tools:
Visual Studio 2017 (Community Edition is enough)
Visual Studio 2019 (Community Edition is enough)
- Desktop development with C++ workload
- Windows 10 SDK (10.0.17134.0) for Desktop C++
- Windows 10 SDK (10.0.19041.0) for Desktop C++
- Visual C++ ATL support
HTML Help Workshop
WiX 3.7

View File

@@ -14,6 +14,7 @@
#include "FNVHash.h"
#include "StringUtils.h"
#include "Translations.h"
#include "json.hpp"
#include <wininet.h>
#include <softpub.h>
@@ -141,30 +142,9 @@ LRESULT CProgressDlg::OnCancel( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL&
static bool g_bCheckingVersion;
static DWORD GetTimeStamp( const wchar_t *fname )
{
HANDLE h=CreateFile(fname,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (h==INVALID_HANDLE_VALUE)
return 0;
DWORD res=0;
DWORD q;
IMAGE_DOS_HEADER header;
if (ReadFile(h,&header,sizeof(header),&q,NULL) && q==sizeof(header))
{
if (SetFilePointer(h,header.e_lfanew+8,NULL,FILE_BEGIN)!=INVALID_SET_FILE_POINTER)
{
if (!ReadFile(h,&res,4,&q,NULL) || q!=4)
res=0;
}
}
CloseHandle(h);
return res;
}
enum TDownloadResult
{
DOWNLOAD_OK,
DOWNLOAD_SAMETIME,
DOWNLOAD_CANCEL,
// errors
@@ -176,8 +156,7 @@ enum TDownloadResult
// Downloads a file
// filename - returns the name of the downloaded file
// timestamp - if not zero, it is compared to the timestamp of the file and returns DOWNLOAD_SAMETIME if the same (and buf will be empty)
static TDownloadResult DownloadFile( const wchar_t *url, std::vector<char> &buf, CString *pFilename, DWORD timestamp, bool bAcceptCached, CProgressDlg *pProgress, TSettingsComponent component )
static TDownloadResult DownloadFile( const wchar_t *url, std::vector<char> &buf, CString *pFilename, bool bAcceptCached, CProgressDlg *pProgress, TSettingsComponent component )
{
const wchar_t *compName=L"Open-Shell";
switch (component)
@@ -211,7 +190,7 @@ static TDownloadResult DownloadFile( const wchar_t *url, std::vector<char> &buf,
int time=GetTickCount();
if (pProgress)
pProgress->SetText(LoadStringEx(IDS_PROGRESS_CONNECT));
HINTERNET hConnect=InternetConnect(hInternet,host,INTERNET_DEFAULT_HTTP_PORT,L"",L"",INTERNET_SERVICE_HTTP,0,0);
HINTERNET hConnect=InternetConnect(hInternet,host,components.nPort,L"",L"",INTERNET_SERVICE_HTTP,0,0);
if (hConnect)
{
if (pProgress && pProgress->IsCanceled())
@@ -219,7 +198,7 @@ static TDownloadResult DownloadFile( const wchar_t *url, std::vector<char> &buf,
const wchar_t *accept[]={L"*/*",NULL};
if (res==DOWNLOAD_OK)
{
HINTERNET hRequest=HttpOpenRequest(hConnect,L"GET",file,NULL,NULL,accept,bAcceptCached?0:INTERNET_FLAG_RELOAD,0);
HINTERNET hRequest=HttpOpenRequest(hConnect,L"GET",file,NULL,NULL,accept,((components.nScheme==INTERNET_SCHEME_HTTPS)?INTERNET_FLAG_SECURE:0)|(bAcceptCached?0:INTERNET_FLAG_RELOAD),0);
if (hRequest)
{
if (pProgress && pProgress->IsCanceled())
@@ -264,7 +243,7 @@ static TDownloadResult DownloadFile( const wchar_t *url, std::vector<char> &buf,
if (fileSize==0)
pProgress->SetProgress(-1);
}
int CHUNK_SIZE=timestamp?1024:32768; // start with small chunk to verify the timestamp
int CHUNK_SIZE=32768;
DWORD size=0;
buf.reserve(fileSize+CHUNK_SIZE);
while (1)
@@ -286,25 +265,6 @@ static TDownloadResult DownloadFile( const wchar_t *url, std::vector<char> &buf,
size+=dwSize;
if (pProgress && fileSize)
pProgress->SetProgress(size*100/fileSize);
if (timestamp && (size<sizeof(IMAGE_DOS_HEADER) || buf[0]!='M' || buf[1]!='Z'))
{
res=DOWNLOAD_FAIL;
break;
}
if (timestamp && size>=sizeof(IMAGE_DOS_HEADER))
{
DWORD pos=((IMAGE_DOS_HEADER*)&buf[0])->e_lfanew+8;
if (size>=pos+4)
{
if (timestamp==*(DWORD*)&buf[pos])
{
res=DOWNLOAD_SAMETIME;
break;
}
timestamp=0;
CHUNK_SIZE=32768;
}
}
}
buf.resize(size);
}
@@ -358,6 +318,7 @@ struct VersionCheckParams
TSettingsComponent component;
tNewVersionCallback callback;
CProgressDlg *progress;
bool nightly = false;
};
// 0 - fail, 1 - success, 2 - cancel
@@ -377,80 +338,17 @@ static DWORD WINAPI ThreadVersionCheck( void *param )
return 0;
}
DWORD curVersion=GetVersionEx(g_Instance);
regKey.SetDWORDValue(L"LastUpdateVersion",curVersion);
// download file
wchar_t fname[_MAX_PATH]=L"%ALLUSERSPROFILE%\\OpenShell";
DoEnvironmentSubst(fname,_countof(fname));
SHCreateDirectory(NULL,fname);
PathAppend(fname,L"update.ver");
bool res=false;
CString urlBase=LoadStringEx(IDS_VERSION_URL);
bool res = false;
VersionData data;
data.Clear();
if (data.Load(fname,false)==VersionData::LOAD_OK)
{
if (!data.altUrl.IsEmpty())
urlBase=data.altUrl;
WIN32_FILE_ATTRIBUTE_DATA attr;
if (GetFileAttributesEx(fname,GetFileExInfoStandard,&attr))
{
DWORD writeTime=(DWORD)(((((ULONGLONG)attr.ftLastWriteTime.dwHighDateTime)<<32)|attr.ftLastWriteTime.dwLowDateTime)/TIME_DIVISOR);
if (curTime>writeTime && (curTime-writeTime)<TIME_PRECISION)
{
res=true; // the file is valid and less than an hour old, don't download again
}
}
}
if (!res)
{
data.Clear();
CString url;
url.Format(L"%s%d.%d.%d.ver",urlBase,curVersion>>24,(curVersion>>16)&0xFF,curVersion&0xFFFF);
auto load = params.nightly ? data.LoadNightly() : data.Load();
#ifdef UPDATE_LOG
LogToFile(UPDATE_LOG,L"URL: %s",url);
#endif
std::vector<char> buf;
TDownloadResult download=DownloadFile(url,buf,NULL,GetTimeStamp(fname),false,params.progress,params.component);
#ifdef UPDATE_LOG
LogToFile(UPDATE_LOG,L"Download result: %d",download);
#endif
if (download==DOWNLOAD_CANCEL)
{
g_bCheckingVersion=false;
return 2;
}
if (download<DOWNLOAD_FIRST_ERROR)
{
if (download==DOWNLOAD_SAMETIME || SaveFile(fname,buf)==0)
{
if (download==DOWNLOAD_SAMETIME)
{
HANDLE h=CreateFile(fname,GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (h!=INVALID_HANDLE_VALUE)
{
SetFileTime(h,NULL,NULL,(FILETIME*)&curTimeL);
CloseHandle(h);
}
}
if (params.progress)
{
params.progress->SetText(LoadStringEx(IDS_PROGRESS_VERIFY));
params.progress->SetProgress(-1);
}
VersionData::TLoadResult load=data.Load(fname,false);
#ifdef UPDATE_LOG
LogToFile(UPDATE_LOG,L"Load result: %d",load);
#endif
if (load==VersionData::LOAD_BAD_FILE)
DeleteFile(fname);
res=(load==VersionData::LOAD_OK);
}
}
#ifdef UPDATE_LOG
LogToFile(UPDATE_LOG, L"Load result: %d", load);
#endif
res = (load == VersionData::LOAD_OK);
}
curTime+=(rand()*TIME_PRECISION)/(RAND_MAX+1)-(TIME_PRECISION/2); // add between -30 and 30 minutes to randomize access
@@ -553,6 +451,21 @@ DWORD CheckForNewVersion( HWND owner, TSettingsComponent component, TVersionChec
params->callback=callback;
params->progress=NULL;
// check the Update setting (uses the current value in the registry, not the one from memory
{
CRegKey regSettings, regSettingsUser, regPolicy, regPolicyUser;
bool bUpgrade = OpenSettingsKeys(COMPONENT_SHARED, regSettings, regSettingsUser, regPolicy, regPolicyUser);
CSetting settings[] = {
{L"Nightly",CSetting::TYPE_BOOL,0,0,0},
{NULL}
};
settings[0].LoadValue(regSettings, regSettingsUser, regPolicy, regPolicyUser);
params->nightly = GetSettingBool(settings[0]);
}
if (!owner)
return ThreadVersionCheck(params);
@@ -583,57 +496,38 @@ DWORD CheckForNewVersion( HWND owner, TSettingsComponent component, TVersionChec
}
else
{
DWORD buildTime=0;
{
// skip the update if the update component is not found
wchar_t path[_MAX_PATH];
GetModuleFileName(_AtlBaseModule.GetModuleInstance(),path,_countof(path));
PathRemoveFileSpec(path);
PathAppend(path,L"Update.exe");
WIN32_FILE_ATTRIBUTE_DATA attr;
if (!GetFileAttributesEx(path,GetFileExInfoStandard,&attr))
return 0;
buildTime=(DWORD)(((((ULONGLONG)attr.ftCreationTime.dwHighDateTime)<<32)|attr.ftCreationTime.dwLowDateTime)/TIME_DIVISOR); // in 0.01 hours
}
ULONGLONG curTimeL;
GetSystemTimeAsFileTime((FILETIME*)&curTimeL);
DWORD curTime=(DWORD)(curTimeL/TIME_DIVISOR); // in 0.01 hours
if (curTime-buildTime>24*365*TIME_PRECISION)
return 0; // the build is more than a year old, don't do automatic updates
CRegKey regKey;
if (regKey.Open(HKEY_CURRENT_USER,L"Software\\OpenShell\\OpenShell")!=ERROR_SUCCESS)
regKey.Create(HKEY_CURRENT_USER,L"Software\\OpenShell\\OpenShell");
DWORD lastVersion;
if (regKey.QueryDWORDValue(L"LastUpdateVersion",lastVersion)!=ERROR_SUCCESS)
lastVersion=0;
if (lastVersion==GetVersionEx(g_Instance))
{
DWORD lastTime;
if (regKey.QueryDWORDValue(L"LastUpdateTime",lastTime)!=ERROR_SUCCESS)
lastTime=0;
if ((int)(curTime-lastTime)<168*TIME_PRECISION)
return 0; // check weekly
}
DWORD lastTime;
if (regKey.QueryDWORDValue(L"LastUpdateTime",lastTime)!=ERROR_SUCCESS)
lastTime=0;
if ((int)(curTime-lastTime)<168*TIME_PRECISION)
return 0; // check weekly
// check the Update setting (uses the current value in the registry, not the one from memory
bool nightly = false;
{
CRegKey regSettings, regSettingsUser, regPolicy, regPolicyUser;
bool bUpgrade=OpenSettingsKeys(COMPONENT_SHARED,regSettings,regSettingsUser,regPolicy,regPolicyUser);
CSetting settings[]={
{L"Update",CSetting::TYPE_BOOL,0,0,1},
{L"Nightly",CSetting::TYPE_BOOL,0,0,0},
{NULL}
};
settings[0].LoadValue(regSettings,regSettingsUser,regPolicy,regPolicyUser);
settings[1].LoadValue(regSettings,regSettingsUser,regPolicy,regPolicyUser);
if (!GetSettingBool(settings[0]))
return 0;
return 0;
nightly = GetSettingBool(settings[1]);
}
VersionCheckParams *params=new VersionCheckParams;
@@ -641,6 +535,7 @@ DWORD CheckForNewVersion( HWND owner, TSettingsComponent component, TVersionChec
params->component=component;
params->callback=callback;
params->progress=NULL;
params->nightly=nightly;
g_bCheckingVersion=true;
if (check==CHECK_AUTO_WAIT)
@@ -848,6 +743,204 @@ void VersionData::Swap( VersionData &data )
std::swap(languages,data.languages);
}
std::vector<char> DownloadUrl(const wchar_t* url)
{
#ifdef UPDATE_LOG
LogToFile(UPDATE_LOG, L"URL: %s", url);
#endif
std::vector<char> buffer;
TDownloadResult download = DownloadFile(url, buffer, nullptr, false, nullptr, COMPONENT_UPDATE);
#ifdef UPDATE_LOG
LogToFile(UPDATE_LOG, L"Download result: %d", download);
#endif
if (download != DOWNLOAD_OK)
buffer.clear();
return buffer;
}
using namespace nlohmann;
VersionData::TLoadResult VersionData::Load()
{
Clear();
auto buf = DownloadUrl(L"https://api.github.com/repos/Open-Shell/Open-Shell-Menu/releases/latest");
if (buf.empty())
return LOAD_ERROR;
try
{
auto data = json::parse(buf.begin(), buf.end());
// skip prerelease versions
if (data["prerelease"].get<bool>())
return LOAD_BAD_VERSION;
// get version from tag name
auto tag = data["tag_name"].get<std::string>();
if (tag.empty())
return LOAD_BAD_FILE;
int v1, v2, v3;
if (sscanf_s(tag.c_str(), "v%d.%d.%d", &v1, &v2, &v3) != 3)
return LOAD_BAD_FILE;
newVersion = (v1 << 24) | (v2 << 16) | v3;
// installer url
std::string url;
for (const auto& asset : data["assets"])
{
if (asset["name"].get<std::string>().find("OpenShellSetup") == 0)
{
url = asset["browser_download_url"].get<std::string>();
break;
}
}
if (url.empty())
return LOAD_BAD_FILE;
downloadUrl.Append(CA2T(url.c_str()));
// changelog
auto body = data["body"].get<std::string>();
if (!body.empty())
{
auto name = data["name"].get<std::string>();
if (!name.empty())
{
news.Append(CA2T(name.c_str()));
news.Append(L"\r\n\r\n");
}
news.Append(CA2T(body.c_str()));
news.Replace(L"\\n", L"\n");
news.Replace(L"\\r", L"\r");
}
return LOAD_OK;
}
catch (...)
{
return LOAD_BAD_FILE;
}
}
VersionData::TLoadResult VersionData::LoadNightly()
{
Clear();
auto buf = DownloadUrl(L"https://ci.appveyor.com/api/projects/passionate-coder/open-shell-menu/branch/master");
if (buf.empty())
return LOAD_ERROR;
try
{
auto data = json::parse(buf.begin(), buf.end());
auto build = data["build"];
// get version
auto version = build["version"].get<std::string>();
if (version.empty())
return LOAD_BAD_FILE;
{
int v1, v2, v3;
if (sscanf_s(version.c_str(), "%d.%d.%d", &v1, &v2, &v3) != 3)
return LOAD_BAD_FILE;
newVersion = (v1 << 24) | (v2 << 16) | v3;
if (newVersion <= GetVersionEx(g_Instance))
return LOAD_OK;
}
// artifact url
{
auto jobId = build["jobs"][0]["jobId"].get<std::string>();
if (jobId.empty())
return LOAD_BAD_FILE;
std::wstring jobUrl(L"https://ci.appveyor.com/api/buildjobs/");
jobUrl += std::wstring(jobId.begin(), jobId.end());
jobUrl += L"/artifacts";
buf = DownloadUrl(jobUrl.c_str());
if (buf.empty())
return LOAD_ERROR;
auto artifacts = json::parse(buf.begin(), buf.end());
std::string fileName;
for (const auto& artifact : artifacts)
{
auto name = artifact["fileName"].get<std::string>();
if (name.find("OpenShellSetup") == 0)
{
fileName = name;
break;
}
}
if (fileName.empty())
return LOAD_BAD_FILE;
auto artifactUrl(jobUrl);
artifactUrl += L'/';
artifactUrl += std::wstring(fileName.begin(), fileName.end());
downloadUrl = artifactUrl.c_str();
}
// changelog
news.Append(CA2T(version.c_str()));
news.Append(L"\r\n\r\n");
try
{
// use Github API to compare commit that actual version was built from (APPVEYOR_REPO_COMMIT)
// and commit that AppVeyor version was built from (commitId)
auto commitId = build["commitId"].get<std::string>();
std::wstring compareUrl(L"https://api.github.com/repos/Open-Shell/Open-Shell-Menu/compare/");
compareUrl += _T(APPVEYOR_REPO_COMMIT);
compareUrl += L"...";
compareUrl += std::wstring(commitId.begin(), commitId.end());
buf = DownloadUrl(compareUrl.c_str());
auto compare = json::parse(buf.begin(), buf.end());
// then use first lines (subjects) of commit messages as changelog
auto commits = compare["commits"];
for (const auto& commit : commits)
{
auto message = commit["commit"]["message"].get<std::string>();
auto pos = message.find('\n');
if (pos != message.npos)
message.resize(pos);
news.Append(L"- ");
news.Append(CA2T(message.c_str()));
news.Append(L"\r\n");
}
}
catch (...)
{
}
}
catch (...)
{
return LOAD_BAD_FILE;
}
return LOAD_OK;
}
VersionData::TLoadResult VersionData::Load( const wchar_t *fname, bool bLoadFlags )
{
Clear();
@@ -937,7 +1030,7 @@ static DWORD WINAPI ThreadDownloadFile( void *param )
params.saveRes=0;
std::vector<char> buf;
params.downloadRes=DownloadFile(params.url,buf,params.fname.IsEmpty()?&params.fname:NULL,0,params.bAcceptCached,params.progress,params.component);
params.downloadRes=DownloadFile(params.url,buf,params.fname.IsEmpty()?&params.fname:NULL,params.bAcceptCached,params.progress,params.component);
if (params.downloadRes==DOWNLOAD_CANCEL || params.downloadRes>=DOWNLOAD_FIRST_ERROR)
return 0;
@@ -971,6 +1064,7 @@ static DWORD WINAPI ThreadDownloadFile( void *param )
return 0;
// validate signer
/*
if (params.signer)
{
if (params.progress)
@@ -982,7 +1076,7 @@ static DWORD WINAPI ThreadDownloadFile( void *param )
return 0;
}
}
*/
return 0;
}
@@ -1089,6 +1183,12 @@ DWORD DownloadNewVersion( HWND owner, TSettingsComponent component, const wchar_
params.bAcceptCached=true;
params.component=component;
{
const wchar_t* name = wcsrchr(url, '/');
if (name && name[1])
params.fname.Append(name+1);
}
HANDLE hThread=CreateThread(NULL,0,ThreadDownloadFile,&params,0,NULL);
while (1)

View File

@@ -31,19 +31,19 @@ struct LanguageVersionData
struct VersionData
{
bool bValid;
DWORD newVersion;
DWORD encodedLangVersion;
bool bValid = false;
DWORD newVersion = 0;
DWORD encodedLangVersion = 0;
CString downloadUrl;
CString downloadSigner;
CString news;
CString updateLink;
CString languageLink;
CString altUrl;
bool bNewVersion;
bool bIgnoreVersion;
bool bNewLanguage;
bool bIgnoreLanguage;
bool bNewVersion = false;
bool bIgnoreVersion = false;
bool bNewLanguage = false;
bool bIgnoreLanguage = false;
CString newLanguage;
std::vector<LanguageVersionData> languages;
@@ -59,6 +59,8 @@ struct VersionData
LOAD_BAD_FILE, // the file is corrupted
};
TLoadResult Load();
TLoadResult LoadNightly();
TLoadResult Load( const wchar_t *fname, bool bLoadFlags );
private:
void operator=( const VersionData& );

View File

@@ -83,6 +83,11 @@
<OutDir>$(Configuration)64\</OutDir>
<IntDir>$(Configuration)64\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>APPVEYOR_REPO_COMMIT="$(APPVEYOR_REPO_COMMIT)";%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>

25447
Src/Lib/json.hpp Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -40,6 +40,9 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ClassicIEDLL", "ClassicIE\ClassicIEDLL\ClassicIEDLL.vcxproj", "{BC0E6E7C-08C1-4F12-A754-4608E5A22FA8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Update", "Update\Update.vcxproj", "{171B46B0-6083-4D9E-BD33-946EA3BD76FA}"
ProjectSection(ProjectDependencies) = postProject
{D94BD2A6-1872-4F01-B911-F406603AA2E1} = {D94BD2A6-1872-4F01-B911-F406603AA2E1}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Win7Aero7", "Skins\Win7Aero7\Win7Aero7.vcxproj", "{A2CCDE9F-17CE-461E-8BD9-00261B8855A6}"
EndProject
@@ -63,6 +66,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Metro", "Skins\Metro\Metro.
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Metallic7", "Skins\Metallic7\Metallic7.vcxproj", "{CA5BFC96-428D-42F5-9F7D-CDDE048A357C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DesktopToasts", "Update\DesktopToasts\DesktopToasts.vcxproj", "{D94BD2A6-1872-4F01-B911-F406603AA2E1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -374,6 +379,15 @@ Global
{CA5BFC96-428D-42F5-9F7D-CDDE048A357C}.Setup|Win32.ActiveCfg = Resource|Win32
{CA5BFC96-428D-42F5-9F7D-CDDE048A357C}.Setup|Win32.Build.0 = Resource|Win32
{CA5BFC96-428D-42F5-9F7D-CDDE048A357C}.Setup|x64.ActiveCfg = Resource|Win32
{D94BD2A6-1872-4F01-B911-F406603AA2E1}.Debug|Win32.ActiveCfg = Debug|Win32
{D94BD2A6-1872-4F01-B911-F406603AA2E1}.Debug|Win32.Build.0 = Debug|Win32
{D94BD2A6-1872-4F01-B911-F406603AA2E1}.Debug|x64.ActiveCfg = Debug|Win32
{D94BD2A6-1872-4F01-B911-F406603AA2E1}.Release|Win32.ActiveCfg = Release|Win32
{D94BD2A6-1872-4F01-B911-F406603AA2E1}.Release|Win32.Build.0 = Release|Win32
{D94BD2A6-1872-4F01-B911-F406603AA2E1}.Release|x64.ActiveCfg = Release|Win32
{D94BD2A6-1872-4F01-B911-F406603AA2E1}.Setup|Win32.ActiveCfg = Release|Win32
{D94BD2A6-1872-4F01-B911-F406603AA2E1}.Setup|Win32.Build.0 = Release|Win32
{D94BD2A6-1872-4F01-B911-F406603AA2E1}.Setup|x64.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -37,6 +37,8 @@ copy /B ..\ClassicIE\Setup\ClassicIEDLL_32.dll Output > nul
copy /B ..\ClassicIE\Setup\ClassicIE_32.exe Output > nul
copy /B ..\StartMenu\Setup\StartMenu.exe Output > nul
copy /B ..\StartMenu\Setup\StartMenuDLL.dll Output > nul
copy /B ..\Update\Release\Update.exe Output > nul
copy /B ..\Update\DesktopToasts\Release\DesktopToasts.dll Output > nul
copy /B ..\StartMenu\StartMenuHelper\Setup\StartMenuHelper32.dll Output > nul
copy /B ..\Setup\SetupHelper\Release\SetupHelper.exe Output > nul
@@ -96,6 +98,10 @@ copy /B ..\StartMenu\Setup\StartMenuDLL.pdb Output\PDB32 > nul
copy /B Output\StartMenuDLL.dll Output\PDB32 > nul
copy /B ..\StartMenu\StartMenuHelper\Setup\StartMenuHelper32.pdb Output\PDB32 > nul
copy /B Output\StartMenuHelper32.dll Output\PDB32 > nul
copy /B ..\Update\Release\Update.pdb Output\PDB32 > nul
copy /B Output\Update.exe Output\PDB32 > nul
copy /B ..\Update\DesktopToasts\Release\DesktopToasts.pdb Output\PDB32 > nul
copy /B Output\DesktopToasts.dll Output\PDB32 > nul
REM Menu 64
copy /B ..\StartMenu\Setup64\StartMenu.pdb Output\PDB64 > nul

View File

@@ -103,6 +103,12 @@
<ComponentRef Id="IESettingsLink" />
<Condition Level="1">IE_BUILD&gt;=90000</Condition>
</Feature>
<Feature Id="Update" Level="1" Title="!(loc.UpdateTitle)" ConfigurableDirectory="APPLICATIONFOLDER" AllowAdvertise="no" Description="!(loc.UpdateDesc)">
<ComponentRef Id="Update.exe" />
<ComponentRef Id="DesktopToasts.dll" />
<ComponentRef Id="UpdateSettingsLink" />
<ComponentRef Id="ToastActivator" />
</Feature>
</Feature>
<UI>
<TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
@@ -469,6 +475,12 @@
<Component Id="StartMenuHelperL10N.ini" Guid="144CE4DC-0C77-4793-B79A-A32E48A90E64" Win64="$(var.CS_WIN64)">
<File Id="StartMenuHelperL10N.ini" KeyPath="yes" Source="..\StartMenu\StartMenuHelper\StartMenuHelperL10N.ini" Vital="yes" />
</Component>
<Component Id="Update.exe" Guid="FB6C213F-B670-4888-8B2C-12E807E335A7" Win64="$(var.CS_WIN64)">
<File Id="Update" KeyPath="yes" Source="Output\Update.exe" Checksum="yes" Vital="yes" />
</Component>
<Component Id="DesktopToasts.dll" Guid="B42157AF-3984-4796-8BD6-501FC5450FF1" Win64="$(var.CS_WIN64)">
<File Id="DesktopToasts.dll" KeyPath="yes" Source="Output\DesktopToasts.dll" Checksum="yes" Vital="yes" />
</Component>
<Component Id="PolicyDefinitions.zip" Guid="580A15D0-4023-471d-9D82-9D63FBA42B5D" Win64="$(var.CS_WIN64)">
<File Id="PolicyDefinitions.zip" KeyPath="yes" Source="Output\PolicyDefinitions.zip" Vital="yes" />
</Component>
@@ -544,6 +556,11 @@
<Component Id="TreatAs" Guid="B1E7462A-E1E2-47eb-A42C-7BD272D738AA" Win64="$(var.CS_WIN64)">
<RegistryKey Root="HKCR" Key="CLSID\{ECD4FC4D-521C-11D0-B792-00A0C90312E1}\TreatAs" ForceDeleteOnUninstall="yes" />
</Component>
<Component Id="ToastActivator" Guid="3A0FDC31-D5D3-4C2E-9A0B-292CAB46DA87" Win64="$(var.CS_WIN64)">
<RegistryKey Root="HKCR" Key="CLSID\{E407B70A-1FBD-4D5E-8822-231C69102472}\LocalServer32" ForceDeleteOnUninstall="yes">
<RegistryValue Value="&quot;[APPLICATIONFOLDER]Update.exe&quot; -ToastActivated" Type="string" />
</RegistryKey>
</Component>
</DirectoryRef>
<DirectoryRef Id="StartMenuDir">
<Component Id="HelpLink" Guid="D631C351-7BD4-42CE-813C-5D46347068AF">
@@ -556,6 +573,15 @@
<CreateFolder />
<Condition>START_MENU_FOLDER=1</Condition>
</Component>
<Component Id="UpdateSettingsLink" Guid="10B5A082-6C92-4EA7-AFF8-21AE3D2D7FE0">
<Shortcut Id="UpdateSettingsLink" Name="!(loc.UpdateItem)" Advertise="no" Description="!(loc.UpdateSettingsDesc)" Target="[APPLICATIONFOLDER]Update.exe" WorkingDirectory="APPLICATIONFOLDER">
<ShortcutProperty Key="System.AppUserModel.ID" Value="OpenShell.Update"/>
<!-- Windows 7 doesn't recognize `System.AppUserModel.ToastActivatorCLSID` name so we have to use GUID directly -->
<ShortcutProperty Key="{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}, 26" Value="{E407B70A-1FBD-4D5E-8822-231C69102472}"/>
</Shortcut>
<CreateFolder />
<Condition>START_MENU_FOLDER=1</Condition>
</Component>
<Component Id="ExplorerSettingsLink" Guid="6EC027F2-115D-4110-8189-DDAFC78169EC">
<Shortcut Id="ExplorerSettingsLink" Name="!(loc.ExplorerItem)" Advertise="no" Description="!(loc.ExplorerSettingsDesc)" Target="[APPLICATIONFOLDER]ClassicExplorerSettings.exe" WorkingDirectory="APPLICATIONFOLDER">
<ShortcutProperty Key="System.AppUserModel.ID" Value="OpenShell.ClassicExplorer.Settings" />

View File

@@ -405,7 +405,7 @@ void ShowMetroColorViewer( void )
if (fout) fprintf(fout,"%02X%02X%02X%02X %S\n",(color>>24)&0xFF,color&0xFF,(color>>8)&0xFF,(color>>16)&0xFF,name);
#endif
MetroColor mc;
mc.name=name;
mc.name=text;
mc.NAME=mc.name;
mc.NAME.MakeUpper();
mc.type=type;

View File

@@ -105,7 +105,6 @@ Submenu_padding=2,2,2,2
; These have the same meaning as the Main_... properties
Submenu_opacity=region
Submenu_opacity=region
Submenu_bitmap=$SystemAccentDark1|$StartBackground
Submenu_bitmap_tint1=$StartHighlight
Submenu_bitmap_mask=2
@@ -179,9 +178,11 @@ Main_icon_frame_tint1=$SystemAccentDark2|$StartSelectionBackground
Main_icon_frame_mask=10
Main_icon_frame_slices_X=4,4,4
Main_icon_frame_slices_Y=4,4,4
Main_icon_frame_offset=3,3
Main_icon_frame_offset=3,3,100%
Main_icon_padding=6,6,6,6,100%
Main_text_padding=5,2,8,2,100%
[ICON_FRAMES AND NOT SMALL_ICONS AND NOT NO_ICONS]
Main2_icon_padding=6,6,6,6,100%
Main2_text_padding=5,2,8,2,100%

View File

@@ -143,6 +143,7 @@ Scrollbar_arrows_mask=17
; LIST SECTION
List_icon_padding=3,3,3,3,100%
List_text_padding=0,0,4,0,100%
List_separator_font="Segoe UI",bold,-9
List_separator_text_padding=3,0,0,0,100%
@@ -249,7 +250,7 @@ Main_icon_frame_tint1=$SystemAccentDark2|$StartSelectionBackground
Main_icon_frame_mask=10
Main_icon_frame_slices_X=4,4,4
Main_icon_frame_slices_Y=4,4,4
Main_icon_frame_offset=3,3
Main_icon_frame_offset=3,3,100%
List_icon_frame=0
Main_icon_padding=6,6,6,6,100%
Main_text_padding=5,2,8,2,100%

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@@ -55,8 +55,8 @@ GUID IID_IApplicationResolver8={0xde25675a,0x72de,0x44b4,{0x93,0x73,0x05,0x17,0x
interface IResourceContext;
const GUID IID_IResourceMap={0x6e21e72b, 0xb9b0, 0x42ae, {0xa6, 0x86, 0x98, 0x3c, 0xf7, 0x84, 0xed, 0xcd}};
interface IResourceMap : public IUnknown
MIDL_INTERFACE("6e21e72b-b9b0-42ae-a686-983cf784edcd")
IResourceMap : public IUnknown
{
virtual HRESULT STDMETHODCALLTYPE GetUri(const wchar_t **pUri ) = 0;
virtual HRESULT STDMETHODCALLTYPE GetSubtree(const wchar_t *propName, IResourceMap **pSubTree ) = 0;
@@ -76,8 +76,8 @@ enum RESOURCE_SCALE
RES_SCALE_80 =3,
};
const GUID IID_ResourceContext={0xe3c22b30, 0x8502, 0x4b2f, {0x91, 0x33, 0x55, 0x96, 0x74, 0x58, 0x7e, 0x51}};
interface IResourceContext : public IUnknown
MIDL_INTERFACE("e3c22b30-8502-4b2f-9133-559674587e51")
IResourceContext : public IUnknown
{
virtual HRESULT STDMETHODCALLTYPE GetLanguage( void ) = 0;
virtual HRESULT STDMETHODCALLTYPE GetHomeRegion( wchar_t *pRegion ) = 0;
@@ -176,6 +176,27 @@ static void CreateMonochromeImage( unsigned int *bits, int stride, int width, in
}
}
HBITMAP ColorizeMonochromeImage(HBITMAP bitmap, DWORD color)
{
{
BITMAP info{};
GetObject(bitmap, sizeof(info), &info);
if (!DetectGrayscaleImage((const unsigned int*)info.bmBits, info.bmWidth, info.bmWidth, info.bmHeight))
return nullptr;
}
HBITMAP bmp = (HBITMAP)CopyImage(bitmap, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
if (bmp)
{
BITMAP info{};
GetObject(bmp, sizeof(info), &info);
CreateMonochromeImage((unsigned int*)info.bmBits, info.bmWidth, info.bmWidth, info.bmHeight, color);
}
return bmp;
}
static HBITMAP BitmapFromMetroIcon( HICON hIcon, int bitmapSize, int iconSize, DWORD metroColor, bool bDestroyIcon=true )
{
ICONINFO info;
@@ -259,7 +280,6 @@ static HBITMAP BitmapFromMetroBitmap( HBITMAP hBitmap, int bitmapSize, DWORD met
HGDIOBJ bmp0=SelectObject(hdc,bmp);
HGDIOBJ bmp02=SelectObject(hsrc,hBitmap);
int offset=(bitmapSize-info.bmWidth)/2;
bool bInvert=g_bInvertMetroIcons;
if (g_bInvertMetroIcons && bGrayscale)
{
FillRect(hdc,&rc,(HBRUSH)GetStockObject(BLACK_BRUSH));
@@ -300,10 +320,9 @@ static HBITMAP BitmapFromMetroBitmap( HBITMAP hBitmap, int bitmapSize, DWORD met
///////////////////////////////////////////////////////////////////////////////
static HBITMAP LoadMetroBitmap0( const wchar_t *path, int bitmapSize, DWORD metroColor )
static HBITMAP LoadMetroBitmap0(const wchar_t *path, int bitmapSize, DWORD metroColor = 0xFFFFFFFF)
{
int iconSize=g_bInvertMetroIcons?bitmapSize:(bitmapSize-2);
SIZE size={-iconSize,iconSize};
SIZE size={-bitmapSize,bitmapSize};
HBITMAP hBitmap=LoadImageFile(path,&size,true,true,NULL);
if (hBitmap)
{
@@ -440,16 +459,8 @@ static HBITMAP LoadMetroBitmap2( const wchar_t *location, int bitmapSize, DWORD
}
if (iconSize)
{
if (g_bInvertMetroIcons)
{
if (iconSize>bitmapSize)
iconSize=bitmapSize;
}
else
{
if (iconSize>bitmapSize-2)
iconSize=bitmapSize-2;
}
if (iconSize>bitmapSize)
iconSize=bitmapSize;
SIZE size={iconSize,iconSize};
HBITMAP hBitmap=LoadImageFile(path,&size,true,true,NULL);
if (hBitmap)
@@ -1114,6 +1125,49 @@ const CItemManager::ItemInfo *CItemManager::GetCustomIcon( const wchar_t *path,
return GetCustomIcon(text,index,iconSizeType,false);
}
const CItemManager::ItemInfo* CItemManager::GetLinkIcon(IShellLink* link, TIconSizeType iconSizeType)
{
wchar_t location[_MAX_PATH];
int index;
if (link->GetIconLocation(location, _countof(location), &index) == S_OK && location[0])
return GetCustomIcon(location, index, iconSizeType, (index == 0)); // assuming that if index!=0 the icon comes from a permanent location like a dll or exe
CComQIPtr<IPropertyStore> store(link);
if (store)
{
// Name: System.AppUserModel.DestListLogoUri -- PKEY_AppUserModel_DestListLogoUri
// Type: String -- VT_LPWSTR
// FormatID: {9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}, 29
static const PROPERTYKEY PKEY_AppUserModel_DestListLogoUri = { {0x9F4C2855, 0x9F79, 0x4B39, {0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3}}, 29 };
auto logoUri = GetPropertyStoreString(store, PKEY_AppUserModel_DestListLogoUri);
if (!logoUri.IsEmpty())
{
auto appId = GetPropertyStoreString(store, PKEY_AppUserModel_ID);
if (!appId.IsEmpty())
{
CComPtr<IResourceManager> resManager;
if (SUCCEEDED(resManager.CoCreateInstance(CLSID_ResourceManager)))
{
if (SUCCEEDED(resManager->InitializeForPackage(GetPackageFullName(appId))))
{
CComPtr<IResourceMap> resMap;
if (SUCCEEDED(resManager->GetMainResourceMap(IID_PPV_ARGS(&resMap))))
{
CComString location;
if (SUCCEEDED(resMap->GetFilePath(logoUri, &location)))
return GetCustomIcon(location, -65536, iconSizeType, true);
}
}
}
}
}
}
return nullptr;
}
const CItemManager::ItemInfo *CItemManager::GetMetroAppInfo10( const wchar_t *appid )
{
wchar_t APPID[256];
@@ -1824,7 +1878,11 @@ void CItemManager::RefreshItemInfo( ItemInfo *pInfo, int refreshFlags, IShellIte
{
newInfo.bLink=true;
pStore=pLink;
#ifdef _DEBUG
LOG_MENU(LOG_OPEN, L"Link: %s", newInfo.path);
LOG_MENU(LOG_OPEN, L"Link property store:");
LogPropertyStore(LOG_OPEN, pStore);
#endif
if (SUCCEEDED(pLink->GetIDList(&newInfo.targetPidl)))
{
wchar_t path[_MAX_PATH];
@@ -1833,6 +1891,28 @@ void CItemManager::RefreshItemInfo( ItemInfo *pInfo, int refreshFlags, IShellIte
CharUpper(path);
newInfo.targetPATH=path;
}
CComPtr<IShellItem> target;
if (SUCCEEDED(SHCreateItemFromIDList(newInfo.targetPidl, IID_PPV_ARGS(&target))))
{
CComPtr<IPropertyStore> store;
if (SUCCEEDED(target->BindToHandler(nullptr, BHID_PropertyStore, IID_PPV_ARGS(&store))))
{
#ifdef _DEBUG
LOG_MENU(LOG_OPEN, L"Target property store:");
LogPropertyStore(LOG_OPEN, store);
#endif
PROPVARIANT val;
PropVariantInit(&val);
if (SUCCEEDED(store->GetValue(PKEY_MetroAppLauncher, &val)) && (val.vt == VT_I4 || val.vt == VT_UI4) && val.intVal)
{
newInfo.bLink = false;
pItem = target;
pStore = store;
}
PropVariantClear(&val);
}
}
}
}
}
@@ -1924,7 +2004,6 @@ void CItemManager::RefreshItemInfo( ItemInfo *pInfo, int refreshFlags, IShellIte
{
newInfo.targetPidl.Clear();
newInfo.targetPATH.Empty();
newInfo.metroName.Empty();
newInfo.iconPath.Empty();
newInfo.bNoPin=newInfo.bNoNew=false;
if (!newInfo.bMetroApp)
@@ -2297,12 +2376,6 @@ void CItemManager::LoadShellIcon( IShellItem *pItem, int refreshFlags, const Ico
int smallIconSize=SMALL_ICON_SIZE;
int largeIconSize=LARGE_ICON_SIZE;
int extraLargeIconSize=EXTRA_LARGE_ICON_SIZE;
if (pMetroColor)
{
smallIconSize-=2;
largeIconSize-=2;
extraLargeIconSize-=2;
}
HICON hSmallIcon=NULL, hLargeIcon=NULL, hExtraLargeIcon=NULL;
if (bNotFileName)
{
@@ -2415,14 +2488,13 @@ void CItemManager::LoadMetroIcon( IShellItem *pItem, int &refreshFlags, const Ic
if (FAILED(pResManager->InitializeForPackage(packageName)))
return;
CComPtr<IResourceMap> pResMap;
if (FAILED(pResManager->GetMainResourceMap(IID_IResourceMap,(void**)&pResMap)))
if (FAILED(pResManager->GetMainResourceMap(IID_PPV_ARGS(&pResMap))))
return;
CComPtr<IResourceContext> pResContext;
if (FAILED(pResManager->GetDefaultContext(IID_ResourceContext,(void**)&pResContext)))
if (FAILED(pResManager->GetDefaultContext(IID_PPV_ARGS(&pResContext))))
return;
int iconFlags=0;
int delta=g_bInvertMetroIcons?0:2;
if ((refreshFlags&INFO_SMALL_ICON) && SetResContextTargetSize(pResContext,SMALL_ICON_SIZE-delta))
if ((refreshFlags&INFO_SMALL_ICON) && SetResContextTargetSize(pResContext,SMALL_ICON_SIZE))
{
CComString pLocation;
if (SUCCEEDED(pResMap->GetFilePath(iconName,&pLocation)))
@@ -2432,7 +2504,7 @@ void CItemManager::LoadMetroIcon( IShellItem *pItem, int &refreshFlags, const Ic
StoreInCache(hash,L"",hSmallBitmap,NULL,NULL,INFO_SMALL_ICON,smallIcon,largeIcon,extraLargeIcon,false,true);
}
}
if ((refreshFlags&INFO_LARGE_ICON) && SetResContextTargetSize(pResContext,LARGE_ICON_SIZE-delta))
if ((refreshFlags&INFO_LARGE_ICON) && SetResContextTargetSize(pResContext,LARGE_ICON_SIZE))
{
CComString pLocation;
if (SUCCEEDED(pResMap->GetFilePath(iconName,&pLocation)))
@@ -2442,7 +2514,7 @@ void CItemManager::LoadMetroIcon( IShellItem *pItem, int &refreshFlags, const Ic
StoreInCache(hash,L"",NULL,hLargeBitmap,NULL,INFO_LARGE_ICON,smallIcon,largeIcon,extraLargeIcon,false,true);
}
}
if ((refreshFlags&INFO_EXTRA_LARGE_ICON) && SetResContextTargetSize(pResContext,EXTRA_LARGE_ICON_SIZE-delta))
if ((refreshFlags&INFO_EXTRA_LARGE_ICON) && SetResContextTargetSize(pResContext,EXTRA_LARGE_ICON_SIZE))
{
CComString pLocation;
if (SUCCEEDED(pResMap->GetFilePath(iconName,&pLocation)))
@@ -2587,49 +2659,45 @@ void CItemManager::IconInfo::SetPath( const wchar_t *path )
timestamp.dwHighDateTime=timestamp.dwLowDateTime=0;
}
void CItemManager::LoadCustomIcon( const wchar_t *iconPath, int iconIndex, int refreshFlags, const IconInfo *&smallIcon, const IconInfo *&largeIcon, const IconInfo *&extraLargeIcon, bool bTemp )
void CItemManager::LoadCustomIcon(const wchar_t *iconPath, int iconIndex, int refreshFlags, const IconInfo *&smallIcon, const IconInfo *&largeIcon, const IconInfo *&extraLargeIcon, bool bTemp)
{
unsigned int hash=CalcFNVHash(iconPath,CalcFNVHash(&iconIndex,4));
unsigned int hash = CalcFNVHash(iconPath, CalcFNVHash(&iconIndex, 4));
FindInCache(hash,refreshFlags,smallIcon,largeIcon,extraLargeIcon);
if (!refreshFlags) return;
FindInCache(hash, refreshFlags, smallIcon, largeIcon, extraLargeIcon);
if (!refreshFlags)
return;
auto ExtractIconAsBitmap = [&](int iconSize) -> HBITMAP {
if (iconIndex == -65536)
return LoadMetroBitmap0(iconPath, iconSize);
HICON hIcon;
if (!*iconPath)
hIcon = (HICON)LoadImage(g_Instance, MAKEINTRESOURCE(-iconIndex), IMAGE_ICON, iconSize, iconSize, LR_DEFAULTCOLOR);
else
hIcon = ShExtractIcon(iconPath, iconIndex == -1 ? 0 : iconIndex, iconSize);
if (hIcon)
return BitmapFromIcon(hIcon, iconSize);
return nullptr;
};
// extract icon
HBITMAP hSmallBitmap=NULL, hLargeBitmap=NULL, hExtraLargeBitmap=NULL;
if (refreshFlags&INFO_SMALL_ICON)
{
HICON hIcon;
if (!*iconPath)
hIcon=(HICON)LoadImage(g_Instance,MAKEINTRESOURCE(-iconIndex),IMAGE_ICON,SMALL_ICON_SIZE,SMALL_ICON_SIZE,LR_DEFAULTCOLOR);
else
hIcon=ShExtractIcon(iconPath,iconIndex==-1?0:iconIndex,SMALL_ICON_SIZE);
if (hIcon)
hSmallBitmap=BitmapFromIcon(hIcon,SMALL_ICON_SIZE);
}
HBITMAP hSmallBitmap = nullptr, hLargeBitmap = nullptr, hExtraLargeBitmap = nullptr;
if (refreshFlags&INFO_LARGE_ICON)
{
HICON hIcon;
if (!*iconPath)
hIcon=(HICON)LoadImage(g_Instance,MAKEINTRESOURCE(-iconIndex),IMAGE_ICON,LARGE_ICON_SIZE,LARGE_ICON_SIZE,LR_DEFAULTCOLOR);
else
hIcon=ShExtractIcon(iconPath,iconIndex==-1?0:iconIndex,LARGE_ICON_SIZE);
if (hIcon)
hLargeBitmap=BitmapFromIcon(hIcon,LARGE_ICON_SIZE);
}
if (refreshFlags & INFO_SMALL_ICON)
hSmallBitmap = ExtractIconAsBitmap(SMALL_ICON_SIZE);
if (refreshFlags&INFO_EXTRA_LARGE_ICON)
{
HICON hIcon;
if (!*iconPath)
hIcon=(HICON)LoadImage(g_Instance,MAKEINTRESOURCE(-iconIndex),IMAGE_ICON,EXTRA_LARGE_ICON_SIZE,EXTRA_LARGE_ICON_SIZE,LR_DEFAULTCOLOR);
else
hIcon=ShExtractIcon(iconPath,iconIndex==-1?0:iconIndex,EXTRA_LARGE_ICON_SIZE);
if (hIcon)
hExtraLargeBitmap=BitmapFromIcon(hIcon,EXTRA_LARGE_ICON_SIZE);
}
if (refreshFlags & INFO_LARGE_ICON)
hLargeBitmap = ExtractIconAsBitmap(LARGE_ICON_SIZE);
StoreInCache(hash,bTemp?NULL:iconPath,hSmallBitmap,hLargeBitmap,hExtraLargeBitmap,refreshFlags,smallIcon,largeIcon,extraLargeIcon,bTemp,false);
if (refreshFlags & INFO_EXTRA_LARGE_ICON)
hExtraLargeBitmap = ExtractIconAsBitmap(EXTRA_LARGE_ICON_SIZE);
StoreInCache(hash, bTemp ? nullptr : iconPath, hSmallBitmap, hLargeBitmap, hExtraLargeBitmap, refreshFlags, smallIcon, largeIcon, extraLargeIcon, bTemp, false);
}
// Recursive function to preload the items for a folder

View File

@@ -173,6 +173,7 @@ public:
const ItemInfo *GetItemInfo( CString path, int refreshFlags, TLocation location=LOCATION_UNKNOWN );
const ItemInfo *GetCustomIcon( const wchar_t *location, int index, TIconSizeType iconSizeType, bool bTemp );
const ItemInfo *GetCustomIcon( const wchar_t *path, TIconSizeType iconSizeType );
const ItemInfo* GetLinkIcon(IShellLink* link, TIconSizeType iconSizeType);
const ItemInfo *GetMetroAppInfo10( const wchar_t *appid );
void UpdateItemInfo( const ItemInfo *pInfo, int refreshFlags, bool bHasWriteLock=false );
void WaitForShortcuts( const POINT &balloonPos );
@@ -466,6 +467,7 @@ bool MenuGetFileTimestamp( const wchar_t *path, FILETIME *pWriteTime, FILETIME *
STDAPI ShGetKnownFolderPath( REFKNOWNFOLDERID rfid, PWSTR *pPath );
STDAPI ShGetKnownFolderIDList(REFKNOWNFOLDERID rfid, PIDLIST_ABSOLUTE *pPidl );
STDAPI ShGetKnownFolderItem(REFKNOWNFOLDERID rfid, IShellItem **ppItem );
HBITMAP ColorizeMonochromeImage(HBITMAP bitmap, DWORD color);
#define TASKBAR_PINNED_ROOT L"%APPDATA%\\Microsoft\\Internet Explorer\\Quick Launch\\User Pinned\\TaskBar"
#define START_MENU_PINNED_ROOT L"%APPDATA%\\OpenShell\\Pinned"

View File

@@ -198,7 +198,13 @@ bool HasJumplist( const wchar_t *appid )
{
UINT count;
if (SUCCEEDED(pCustomList->GetCategoryCount(&count)) && count>0)
{
// skip Settings app (it reports one category with unsupported type, thus jump-list will be empty)
if (wcscmp(appid, L"windows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel") == 0)
return false;
return true;
}
}
if (CAutomaticList(appid).HasList())
@@ -322,6 +328,9 @@ static void AddJumpItem( CJumpGroup &group, IUnknown *pUnknown, std::vector<CCom
}
}
LOG_MENU(LOG_OPEN,L"Jumplist Link Name: %s",item.name);
#ifdef _DEBUG
LogPropertyStore(LOG_OPEN, pStore);
#endif
if (!item.name.IsEmpty())
group.items.push_back(item);
return;
@@ -519,91 +528,15 @@ bool GetJumplist( const wchar_t *appid, CJumpList &list, int maxCount, int maxHe
bool ExecuteJumpItem( const CItemManager::ItemInfo *pAppInfo, const CJumpItem &item, HWND hwnd )
{
Assert(GetWinVersion()>=WIN_VER_WIN7);
if (!item.pItem) return false;
if (!item.pItem)
return false;
if (item.type==CJumpItem::TYPE_ITEM)
{
/* CString appid;
{
CItemManager::RWLock lock(&g_ItemManager,false,CItemManager::RWLOCK_ITEMS);
appid=pAppInfo->GetAppid();
}
LOG_MENU(LOG_OPEN,L"Execute Item: name=%s, appid=%s",item.name,appid);*/
CComQIPtr<IShellItem> pItem(item.pItem);
if (!pItem)
return false;
/* CComString pName;
if (FAILED(pItem->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING,&pName)))
return false;
wchar_t ext[_MAX_EXT];
Strcpy(ext,_countof(ext),PathFindExtension(pName));
// find the correct association handler by appid and invoke it on the item
CComPtr<IEnumAssocHandlers> pEnumHandlers;
if (ext[0] && SUCCEEDED(SHAssocEnumHandlers(ext,ASSOC_FILTER_RECOMMENDED,&pEnumHandlers)))
{
CComPtr<IAssocHandler> pHandler;
ULONG count;
while (SUCCEEDED(pEnumHandlers->Next(1,&pHandler,&count)) && count==1)
{
CComQIPtr<IObjectWithAppUserModelID> pObject=pHandler;
if (pObject)
{
CComString pID;
if (SUCCEEDED(pObject->GetAppID(&pID)))
{
// found explicit appid
if (_wcsicmp(appid,pID)==0)
{
LOG_MENU(LOG_OPEN,L"Found handler appid");
CComPtr<IDataObject> pDataObject;
if (SUCCEEDED(pItem->BindToHandler(NULL,BHID_DataObject,IID_IDataObject,(void**)&pDataObject)) && SUCCEEDED(pHandler->Invoke(pDataObject)))
return true;
break;
}
}
}
pHandler=NULL;
}
pEnumHandlers=NULL;
// find the correct association handler by exe name and invoke it on the item
wchar_t targetPath[_MAX_PATH];
targetPath[0]=0;
{
CComPtr<IShellItem> pItem;
SHCreateItemFromIDList(pAppInfo->GetPidl(),IID_IShellItem,(void**)&pItem);
CComPtr<IShellLink> pLink;
if (pItem)
pItem->BindToHandler(NULL,BHID_SFUIObject,IID_IShellLink,(void**)&pLink);
CAbsolutePidl target;
if (pLink && SUCCEEDED(pLink->Resolve(NULL,SLR_INVOKE_MSI|SLR_NO_UI|SLR_NOUPDATE)) && SUCCEEDED(pLink->GetIDList(&target)))
{
if (FAILED(SHGetPathFromIDList(target,targetPath)))
targetPath[0]=0;
}
}
if (targetPath[0] && SUCCEEDED(SHAssocEnumHandlers(ext,ASSOC_FILTER_RECOMMENDED,&pEnumHandlers)))
{
while (SUCCEEDED(pEnumHandlers->Next(1,&pHandler,&count)) && count==1)
{
CComString pExe;
if (SUCCEEDED(pHandler->GetName(&pExe)))
{
if (_wcsicmp(targetPath,pExe)==0)
{
LOG_MENU(LOG_OPEN,L"Found handler appexe %s",targetPath);
CComPtr<IDataObject> pDataObject;
if (SUCCEEDED(pItem->BindToHandler(NULL,BHID_DataObject,IID_IDataObject,(void**)&pDataObject)) && SUCCEEDED(pHandler->Invoke(pDataObject)))
return true;
break;
}
}
pHandler=NULL;
}
}
}
*/
// couldn't find a handler, execute the old way
SHELLEXECUTEINFO execute={sizeof(execute),SEE_MASK_IDLIST|SEE_MASK_FLAG_LOG_USAGE};
execute.nShow=SW_SHOWNORMAL;
CAbsolutePidl pidl;
@@ -617,9 +550,50 @@ bool ExecuteJumpItem( const CItemManager::ItemInfo *pAppInfo, const CJumpItem &i
if (item.type==CJumpItem::TYPE_LINK)
{
// invoke the link through its context menu
// Name: System.AppUserModel.HostEnvironment -- PKEY_AppUserModel_HostEnvironment
// Type: UInt32 -- VT_UI4
// FormatID: {9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}, 14
static const PROPERTYKEY PKEY_AppUserModel_HostEnvironment = { {0x9F4C2855, 0x9F79, 0x4B39, {0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3}}, 14 };
// Name: System.AppUserModel.ActivationContext -- PKEY_AppUserModel_ActivationContext
// Type: String -- VT_LPWSTR
// FormatID: {9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}, 20
static const PROPERTYKEY PKEY_AppUserModel_ActivationContext = { {0x9F4C2855, 0x9F79, 0x4B39, {0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3}}, 20 };
CComQIPtr<IContextMenu> pMenu(item.pItem);
if (!pMenu) return false;
CStringA params;
CComQIPtr<IShellLink> pLink(item.pItem);
if (pLink)
{
CComQIPtr<IPropertyStore> store(pLink);
if (store)
{
auto appId = GetPropertyStoreString(store, PKEY_AppUserModel_ID);
if (!appId.IsEmpty())
{
CComPtr<IShellItem2> target;
if (SUCCEEDED(SHCreateItemInKnownFolder(FOLDERID_AppsFolder, 0, appId, IID_PPV_ARGS(&target))))
{
ULONG modern = 0;
if (SUCCEEDED(target->GetUInt32(PKEY_AppUserModel_HostEnvironment, &modern)) && modern)
{
CComQIPtr<IContextMenu> targetMenu;
if (SUCCEEDED(target->BindToHandler(nullptr, BHID_SFUIObject, IID_PPV_ARGS(&targetMenu))))
{
pMenu = targetMenu;
params = CT2CA(GetPropertyStoreString(store, PKEY_AppUserModel_ActivationContext));
}
}
}
}
}
}
// invoke the link through its context menu
if (!pMenu)
return false;
HRESULT hr;
HMENU menu=CreatePopupMenu();
hr=pMenu->QueryContextMenu(menu,0,1,1000,CMF_DEFAULTONLY);
@@ -633,6 +607,8 @@ bool ExecuteJumpItem( const CItemManager::ItemInfo *pAppInfo, const CJumpItem &i
{
CMINVOKECOMMANDINFO command={sizeof(command),CMIC_MASK_FLAG_LOG_USAGE};
command.lpVerb=MAKEINTRESOURCEA(id-1);
if (!params.IsEmpty())
command.lpParameters = params;
wchar_t path[_MAX_PATH];
GetModuleFileName(NULL,path,_countof(path));
if (_wcsicmp(PathFindFileName(path),L"explorer.exe")==0)

View File

@@ -7,10 +7,13 @@
#include "stdafx.h"
#include "LogManager.h"
#include "ResourceHelper.h"
#include "ComHelper.h"
#include <propvarutil.h>
#include <chrono>
int g_LogCategories;
static FILE *g_LogFile;
static int g_LogTime;
static std::chrono::time_point<std::chrono::steady_clock> g_LogTime;
void InitLog( int categories, const wchar_t *fname )
{
@@ -21,7 +24,7 @@ void InitLog( int categories, const wchar_t *fname )
wchar_t bom=0xFEFF;
fwrite(&bom,2,1,g_LogFile);
g_LogCategories=categories;
g_LogTime=GetTickCount();
g_LogTime=std::chrono::steady_clock::now();
LogMessage(L"version=%x, PID=%d, TID=%d, Categories=%08x\r\n",GetWinVersion(),GetCurrentProcessId(),GetCurrentThreadId(),categories);
}
}
@@ -38,7 +41,7 @@ void LogMessage( const wchar_t *text, ... )
if (!g_LogFile) return;
wchar_t buf[2048];
int len=Sprintf(buf,_countof(buf),L"%8d: ",GetTickCount()-g_LogTime);
int len=Sprintf(buf,_countof(buf),L"%8d: ",std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now()-g_LogTime).count());
fwrite(buf,2,len,g_LogFile);
va_list args;
@@ -51,3 +54,31 @@ void LogMessage( const wchar_t *text, ... )
fflush(g_LogFile);
}
void LogPropertyStore(TLogCategory category, IPropertyStore* store)
{
if (!store)
return;
DWORD count = 0;
store->GetCount(&count);
for (DWORD i = 0; i < count; i++)
{
PROPERTYKEY key{};
store->GetAt(i, &key);
PROPVARIANT val;
PropVariantInit(&val);
store->GetValue(key, &val);
CComString valueStr;
PropVariantToStringAlloc(val, &valueStr);
PropVariantClear(&val);
wchar_t guidStr[100]{};
StringFromGUID2(key.fmtid, guidStr, _countof(guidStr));
LOG_MENU(category, L"Property: {%s, %u} = %s", guidStr, key.pid, valueStr ? valueStr : L"???");
}
}

View File

@@ -4,6 +4,8 @@
#pragma once
#include <propsys.h>
// LogManager.h - logging functionality (for debugging)
// Logs different events in the start menu
// Turn it on by setting the LogLevel setting in the registry
@@ -33,3 +35,5 @@ void CloseLog( void );
void LogMessage( const wchar_t *text, ... );
#define STARTUP_LOG L"Software\\OpenShell\\StartMenu\\Settings|LogStartup|%LOCALAPPDATA%\\OpenShell\\StartupLog.txt"
void LogPropertyStore(TLogCategory category, IPropertyStore* store);

View File

@@ -1937,15 +1937,6 @@ void CMenuContainer::GetRecentPrograms( std::vector<MenuItem> &items, int maxCou
continue;
}
{
CComPtr<IShellItem> pAppItem;
if (FAILED(SHCreateItemInKnownFolder(FOLDERID_AppsFolder2,0,uaItem.name,IID_IShellItem,(void**)&pAppItem)))
continue;
CComString pName;
if (FAILED(pAppItem->GetDisplayName(SIGDN_NORMALDISPLAY,&pName)) || wcsncmp(pName,L"@{",2)==0)
continue;
}
uaItem.pLinkInfo=g_ItemManager.GetMetroAppInfo10(uaItem.name);
if (!uaItem.pLinkInfo)
{
@@ -1956,6 +1947,11 @@ void CMenuContainer::GetRecentPrograms( std::vector<MenuItem> &items, int maxCou
LOG_MENU(LOG_MFU,L"UserAssist: '%s', %d, %.3f",uaItem.name,data.count,uaItem.rank);
{
CItemManager::RWLock lock(&g_ItemManager,false,CItemManager::RWLOCK_ITEMS);
if (uaItem.pLinkInfo->GetMetroName().IsEmpty() || wcsncmp(uaItem.pLinkInfo->GetMetroName(), L"@{",2)==0)
{
LOG_MENU(LOG_MFU, L"UserAssist: Dropping: No metro name");
continue;
}
if (uaItem.pLinkInfo->IsNoPin())
{
LOG_MENU(LOG_MFU,L"UserAssist: Dropping: No pin");
@@ -2207,10 +2203,7 @@ void CMenuContainer::AddJumpListItems( std::vector<MenuItem> &items )
if (pLink)
{
pLink->GetIDList(&item.pItem1);
wchar_t location[_MAX_PATH];
int index;
if (pLink->GetIconLocation(location,_countof(location),&index)==S_OK && location[0])
item.pItemInfo=g_ItemManager.GetCustomIcon(location,index,CItemManager::ICON_SIZE_TYPE_SMALL,(index==0)); // assuming that if index!=0 the icon comes from a permanent location like a dll or exe
item.pItemInfo = g_ItemManager.GetLinkIcon(pLink, CItemManager::ICON_SIZE_TYPE_SMALL);
}
}
else if (jumpItem.type==CJumpItem::TYPE_ITEM)
@@ -2775,18 +2768,18 @@ bool CMenuContainer::InitSearchItems( void )
if (m_SearchCategoryHash==CSearchManager::CATEGORY_PROGRAM)
selectedCount=(int)s_SearchResults.programs.size();
}
if (!s_SearchResults.settings.empty())
{
counts.push_back((int)s_SearchResults.settings.size());
if (m_SearchCategoryHash==CSearchManager::CATEGORY_SETTING)
selectedCount=(int)s_SearchResults.settings.size();
}
if (!s_SearchResults.metrosettings.empty())
{
counts.push_back((int)s_SearchResults.metrosettings.size());
if (m_SearchCategoryHash==CSearchManager::CATEGORY_METROSETTING)
selectedCount=(int)s_SearchResults.metrosettings.size();
}
if (!s_SearchResults.settings.empty())
{
counts.push_back((int)s_SearchResults.settings.size());
if (m_SearchCategoryHash==CSearchManager::CATEGORY_SETTING)
selectedCount=(int)s_SearchResults.settings.size();
}
for (std::list<CSearchManager::SearchCategory>::const_iterator it=s_SearchResults.indexed.begin();it!=s_SearchResults.indexed.end();++it)
{
if (!it->items.empty())
@@ -2836,9 +2829,9 @@ bool CMenuContainer::InitSearchItems( void )
if (idx==0)
categoryHash=CSearchManager::CATEGORY_PROGRAM;
else if (idx==1)
categoryHash=CSearchManager::CATEGORY_SETTING;
else if (idx==2)
categoryHash=CSearchManager::CATEGORY_METROSETTING;
else if (idx==2)
categoryHash=CSearchManager::CATEGORY_SETTING;
else
categoryHash=it->categoryHash;
@@ -2873,16 +2866,6 @@ bool CMenuContainer::InitSearchItems( void )
name=FindTranslation(L"Search.CategoryPrograms",L"Programs");
}
else if (idx==1)
{
originalCount=(int)s_SearchResults.settings.size();
if (count>originalCount)
count=originalCount;
items.reserve(count);
for (std::vector<const CItemManager::ItemInfo*>::const_iterator it=s_SearchResults.settings.begin();it!=s_SearchResults.settings.end() && (int)items.size()<count;++it)
items.push_back(SearchItem(*it));
name=FindTranslation(L"Search.CategorySettings",L"Settings");
}
else if (idx==2)
{
originalCount=(int)s_SearchResults.metrosettings.size();
if (count>originalCount)
@@ -2890,7 +2873,17 @@ bool CMenuContainer::InitSearchItems( void )
items.reserve(count);
for (std::vector<const CItemManager::ItemInfo*>::const_iterator it=s_SearchResults.metrosettings.begin();it!=s_SearchResults.metrosettings.end() && (int)items.size()<count;++it)
items.push_back(SearchItem(*it));
name=FindTranslation(L"Search.CategoryPCSettings", L"Modern Settings");
name=FindTranslation(L"Search.CategoryPCSettings", L"Settings");
}
else if (idx==2)
{
originalCount=(int)s_SearchResults.settings.size();
if (count>originalCount)
count=originalCount;
items.reserve(count);
for (std::vector<const CItemManager::ItemInfo*>::const_iterator it=s_SearchResults.settings.begin();it!=s_SearchResults.settings.end() && (int)items.size()<count;++it)
items.push_back(SearchItem(*it));
name=FindTranslation(L"Search.CategorySettings",L"Control Panel");
}
else
{
@@ -6672,8 +6665,7 @@ bool CMenuContainer::GetDescription( int index, wchar_t *text, int size )
{
if (SUCCEEDED(pLink->GetDescription(text,size)) && text[0])
return true;
wchar_t args[256];
if (SUCCEEDED(pLink->GetArguments(args,_countof(args))) && args[0])
if (jumpItem.bHasArguments)
{
// don't use default tip for items with arguments
Strcpy(text,size,item.name);
@@ -7331,8 +7323,9 @@ static void NewVersionCallback( VersionData &data )
wchar_t cmdLine[1024];
Sprintf(cmdLine,_countof(cmdLine),L"\"%s\" -popup",path);
STARTUPINFO startupInfo={sizeof(startupInfo)};
PROCESS_INFORMATION processInfo;
memset(&processInfo,0,sizeof(processInfo));
// don't display busy cursor as we are doing this on background
startupInfo.dwFlags=STARTF_FORCEOFFFEEDBACK;
PROCESS_INFORMATION processInfo{};
if (CreateProcess(path,cmdLine,NULL,NULL,TRUE,0,NULL,NULL,&startupInfo,&processInfo))
{
CloseHandle(processInfo.hThread);
@@ -7408,35 +7401,46 @@ bool CMenuContainer::HasMoreResults( void )
RECT CMenuContainer::CalculateWorkArea( const RECT &taskbarRect )
{
RECT rc=s_MenuLimits;
if ((s_TaskBarEdge==ABE_LEFT || s_TaskBarEdge==ABE_RIGHT) && GetSettingBool(L"ShowNextToTaskbar"))
RECT rc;
if (!GetSettingBool(L"AlignToWorkArea"))
{
// when the taskbar is on the side and the menu is not on top of it
// the start button is assumed at the top
if (s_TaskBarEdge==ABE_LEFT)
rc.left=taskbarRect.right;
rc = s_MenuLimits;
if ((s_TaskBarEdge == ABE_LEFT || s_TaskBarEdge == ABE_RIGHT) && GetSettingBool(L"ShowNextToTaskbar"))
{
// when the taskbar is on the side and the menu is not on top of it
// the start button is assumed at the top
if (s_TaskBarEdge == ABE_LEFT)
rc.left = taskbarRect.right;
else
rc.right = taskbarRect.left;
}
else
rc.right=taskbarRect.left;
{
if (s_TaskBarEdge == ABE_BOTTOM)
{
// taskbar is at the bottom
rc.bottom = taskbarRect.top;
}
else if (s_TaskBarEdge == ABE_TOP)
{
// taskbar is at the top
rc.top = taskbarRect.bottom;
}
else
{
// taskbar is on the side, start button must be at the top
rc.top = s_StartRect.bottom;
}
}
}
else
{
if (s_TaskBarEdge==ABE_BOTTOM)
{
// taskbar is at the bottom
rc.bottom=taskbarRect.top;
}
else if (s_TaskBarEdge==ABE_TOP)
{
// taskbar is at the top
rc.top=taskbarRect.bottom;
}
else
{
// taskbar is on the side, start button must be at the top
rc.top=s_StartRect.bottom;
}
// Get working area of the monitor the specified taskbar is on
MONITORINFO info{ sizeof(MONITORINFO) };
HMONITOR mon = MonitorFromRect(&taskbarRect, 0);
GetMonitorInfo(mon, &info);
rc = info.rcWork;
}
if (!s_bLockWorkArea)
{
// exclude floating keyboard
@@ -7462,6 +7466,32 @@ RECT CMenuContainer::CalculateWorkArea( const RECT &taskbarRect )
}
}
}
//calculate offsets
int xOff = GetSettingInt(L"HorizontalMenuOffset");
int yOff = GetSettingInt(L"VerticalMenuOffset");
if (s_TaskBarEdge == ABE_BOTTOM)
{
if (xOff != 0)
rc.left += xOff;
if (yOff != 0)
rc.bottom += yOff;
}
else if (s_TaskBarEdge == ABE_TOP || s_TaskBarEdge == ABE_LEFT)
{
if (xOff != 0)
rc.left += xOff;
if (yOff != 0)
rc.top += yOff;
}
else
{
if (xOff != 0)
rc.right += xOff;
if (yOff != 0)
rc.top += yOff;
}
return rc;
}

View File

@@ -2200,6 +2200,21 @@ void CMenuContainer::DrawBackground( HDC hdc, const RECT &drawRect )
else
iconSize.cx=iconSize.cy=0;
COLORREF color, shadowColor;
{
bool bHotColor = (bHot && !bSplit) || stateLeft > 0;
if (item.id == MENU_EMPTY || item.id == MENU_EMPTY_TOP)
{
color = settings.textColors[bHotColor ? 3 : 2];
shadowColor = settings.textShadowColors[bHotColor ? 3 : 2];
}
else
{
color = settings.textColors[bHotColor ? 1 : 0];
shadowColor = settings.textShadowColors[bHotColor ? 1 : 0];
}
}
// draw icon
if (drawType==MenuSkin::PROGRAMS_BUTTON || drawType==MenuSkin::PROGRAMS_BUTTON_NEW)
{
@@ -2256,15 +2271,21 @@ void CMenuContainer::DrawBackground( HDC hdc, const RECT &drawRect )
const CItemManager::IconInfo *pIcon=(settings.iconSize==MenuSkin::ICON_SIZE_LARGE)?item.pItemInfo->largeIcon:item.pItemInfo->smallIcon;
if (pIcon && pIcon->bitmap)
{
HBITMAP temp = ColorizeMonochromeImage(pIcon->bitmap, color);
HBITMAP bitmap = temp ? temp : pIcon->bitmap;
BITMAP info;
GetObject(pIcon->bitmap,sizeof(info),&info);
HGDIOBJ bmp0=SelectObject(hdc2,pIcon->bitmap);
GetObject(bitmap,sizeof(info),&info);
HGDIOBJ bmp0=SelectObject(hdc2,bitmap);
if (bmp0)
{
BLENDFUNCTION func={AC_SRC_OVER,0,255,AC_SRC_ALPHA};
AlphaBlend(hdc,iconX,iconY,iconSize.cx,iconSize.cy,hdc2,0,0,info.bmWidth,info.bmHeight,func);
SelectObject(hdc2,bmp0);
}
if (temp)
DeleteObject(temp);
}
}
else if (item.id==MENU_SHUTDOWN_BUTTON && s_bHasUpdates && s_Skin.Shutdown_bitmap.GetBitmap())
@@ -2287,18 +2308,6 @@ void CMenuContainer::DrawBackground( HDC hdc, const RECT &drawRect )
// draw text
SelectObject(hdc,settings.font);
COLORREF color, shadowColor;
bool bHotColor=(bHot && !bSplit) || stateLeft>0;
if (item.id==MENU_EMPTY || item.id==MENU_EMPTY_TOP)
{
color=settings.textColors[bHotColor?3:2];
shadowColor=settings.textShadowColors[bHotColor?3:2];
}
else
{
color=settings.textColors[bHotColor?1:0];
shadowColor=settings.textShadowColors[bHotColor?1:0];
}
RECT rc={itemRect.left+settings.iconPadding.left+settings.iconPadding.right+settings.textPadding.left,itemRect.top+settings.textPadding.top,
itemRect.right-settings.arrPadding.cx-settings.arrPadding.cy-settings.textPadding.right,itemRect.bottom-settings.textPadding.bottom};
if (item.id==MENU_SHUTDOWN_BUTTON)

View File

@@ -301,21 +301,12 @@ bool CanUninstallMetroApp( const wchar_t *appid )
// Uninstalls the app with the given id
void UninstallMetroApp( const wchar_t *appid )
{
CComPtr<IShellItem> pAppItem;
if (SUCCEEDED(SHCreateItemInKnownFolder(FOLDERID_AppsFolder2,0,appid,IID_IShellItem,(void**)&pAppItem)))
auto packageName = GetPackageFullName(appid);
if (!packageName.IsEmpty())
{
CComPtr<IPropertyStore> pStore;
pAppItem->BindToHandler(NULL,BHID_PropertyStore,IID_IPropertyStore,(void**)&pStore);
if (pStore)
{
CString packageName=GetPropertyStoreString(pStore,PKEY_MetroPackageName);
if (!packageName.IsEmpty())
{
wchar_t command[1024];
Sprintf(command,_countof(command),L"Remove-AppxPackage %s",packageName);
ShellExecute(NULL,L"open",L"powershell.exe",command,NULL,SW_HIDE);
}
}
wchar_t command[1024];
Sprintf(command, _countof(command), L"Remove-AppxPackage %s", packageName);
ShellExecute(NULL, L"open", L"powershell.exe", command, NULL, SW_HIDE);
}
}
@@ -381,3 +372,16 @@ bool IsEdgeDefaultBrowser( void )
}
return false;
}
CString GetPackageFullName(const wchar_t* appId)
{
CComPtr<IShellItem> item;
if (SUCCEEDED(SHCreateItemInKnownFolder(FOLDERID_AppsFolder, 0, appId, IID_PPV_ARGS(&item))))
{
CComPtr<IPropertyStore> store;
if (SUCCEEDED(item->BindToHandler(nullptr, BHID_PropertyStore, IID_PPV_ARGS(&store))))
return GetPropertyStoreString(store, PKEY_MetroPackageName);
}
return {};
}

View File

@@ -53,3 +53,6 @@ CComPtr<IContextMenu> GetMetroPinMenu( const wchar_t *appid );
// Determines if Edge is the default browser
bool IsEdgeDefaultBrowser( void );
// Returns full package name for given App ID
CString GetPackageFullName(const wchar_t* appId);

View File

@@ -805,7 +805,7 @@ void CSearchManager::SearchThread( void )
scopeList.push_back(SearchScope());
SearchScope &scope=*scopeList.rbegin();
scope.bFiles=true;
scope.name=FindTranslation(L"Search.CategoryPCSettings",L"Modern Settings");
scope.name=FindTranslation(L"Search.CategoryPCSettings",L"Settings");
scope.categoryHash=CATEGORY_METROSETTING;
scope.roots.push_back(L"FILE:");
}

View File

@@ -1001,7 +1001,7 @@ static const CStdCommand g_StdCommands[]={
{L"settings",IDS_SETTINGS_ITEM,IDS_SETTINGS_MENU_TIP,L"SettingsMenu",L"$Menu.Settings",L"",L"shell32.dll,330"},
{L"search",IDS_SEARCH_MENU_ITEM,IDS_SEARCH_TIP,L"SearchMenu",L"$Menu.Search",L"",L"shell32.dll,323"},
{L"search_box",IDS_SEARCH_BOX_ITEM,IDS_SEARCH_BOX_TIP,L"SearchBoxItem",L"$Menu.SearchBox",NULL,L"none",NULL,StdMenuItem::MENU_TRACK|StdMenuItem::MENU_OPENUP},
{L"help",IDS_HELP_ITEM,IDS_HELP_TIP,L"HelpItem",L"$Menu.Help",L"$Menu.HelpTip",L"shell32.dll,324"},
{L"help",IDS_HELP_ITEM,IDS_HELP_TIP,L"HelpItem",L"$Menu.Help",L"$Menu.HelpTip",L"imageres.dll,99"},
{L"run",IDS_RUN_ITEM,IDS_RUN_TIP,L"RunItem",L"$Menu.Run",L"$Menu.RunTip",L"shell32.dll,328"},
{L"logoff",IDS_SHUTDOWN_LOGOFF,IDS_LOGOFF_TIP,L"LogOffItem",L"$Menu.Logoff",L"$Menu.LogOffTip",L"shell32.dll,325",NULL,StdMenuItem::MENU_STYLE_CLASSIC1},
{L"logoff",IDS_SHUTDOWN_LOGOFF,IDS_LOGOFF_TIP,L"LogOffItem",L"$Menu.Logoff",L"$Menu.LogOffTip",L"none",NULL,StdMenuItem::MENU_STYLE_CLASSIC2},
@@ -1057,7 +1057,7 @@ L"RecentDocumentsItem.Label=$Menu.Documents\n"
L"RecentDocumentsItem.Icon=shell32.dll,327\n"
L"RecentDocumentsItem.Settings=ITEMS_FIRST\n"
L"SettingsMenu.Command=settings\n"
L"SettingsMenu.Items=ControlPanelItem, PCSettingsItem, SEPARATOR, SecurityItem, NetworkItem, PrintersItem, TaskbarSettingsItem, ProgramsFeaturesItem, SEPARATOR, MenuSettingsItem\n"
L"SettingsMenu.Items=PCSettingsItem, ControlPanelItem, SEPARATOR, SecurityItem, NetworkItem, PrintersItem, TaskbarSettingsItem, ProgramsFeaturesItem, SEPARATOR, MenuSettingsItem\n"
L"SettingsMenu.Label=$Menu.Settings\n"
L"SettingsMenu.Icon=shell32.dll,330\n"
L"SearchMenu.Command=search\n"
@@ -1068,7 +1068,7 @@ L"ComputerItem.Command=computer\n"
L"HelpItem.Command=help\n"
L"HelpItem.Label=$Menu.Help\n"
L"HelpItem.Tip=$Menu.HelpTip\n"
L"HelpItem.Icon=shell32.dll,324\n"
L"HelpItem.Icon=imageres.dll,99\n"
L"RunItem.Command=run\n"
L"RunItem.Label=$Menu.Run\n"
L"RunItem.Tip=$Menu.RunTip\n"
@@ -1183,7 +1183,7 @@ L"ShutdownItem.Icon=none\n"
;
const wchar_t *g_DefaultStartMenu2=
L"Items=COLUMN_PADDING, ProgramsMenu, AppsMenu, SearchBoxItem, COLUMN_BREAK, FavoritesItem, UserFilesItem, UserDocumentsItem, UserPicturesItem, ComputerItem, RecentDocumentsItem, SEPARATOR, ControlPanelItem, PCSettingsItem, SecurityItem, NetworkItem, PrintersItem, SEPARATOR, SearchMenu, HelpItem, RunItem, COLUMN_PADDING, SEPARATOR, ShutdownBoxItem\n"
L"Items=COLUMN_PADDING, ProgramsMenu, AppsMenu, SearchBoxItem, COLUMN_BREAK, FavoritesItem, UserFilesItem, UserDocumentsItem, UserPicturesItem, ComputerItem, RecentDocumentsItem, SEPARATOR, PCSettingsItem, ControlPanelItem, SecurityItem, NetworkItem, PrintersItem, SEPARATOR, SearchMenu, HelpItem, RunItem, COLUMN_PADDING, SEPARATOR, ShutdownBoxItem\n"
L"ProgramsMenu.Command=programs\n"
L"ProgramsMenu.Label=$Menu.Programs\n"
L"ProgramsMenu.Icon=shell32.dll,326\n"
@@ -1203,7 +1203,7 @@ L"SearchMenu.Icon=shell32.dll,323\n"
L"HelpItem.Command=help\n"
L"HelpItem.Label=$Menu.Help\n"
L"HelpItem.Tip=$Menu.HelpTip\n"
L"HelpItem.Icon=shell32.dll,324\n"
L"HelpItem.Icon=imageres.dll,99\n"
L"RunItem.Command=run\n"
L"RunItem.Label=$Menu.Run\n"
L"RunItem.Tip=$Menu.RunTip\n"
@@ -1379,9 +1379,9 @@ L"Item13.Settings=ITEM_DISABLED\n"
L"Item14.Command=network_connections\n"
L"Item14.Settings=ITEM_DISABLED\n"
L"Item15.Command=separator\n"
L"Item16.Command=control_panel\n"
L"Item16.Command=pc_settings\n"
L"Item16.Settings=TRACK_RECENT\n"
L"Item17.Command=pc_settings\n"
L"Item17.Command=control_panel\n"
L"Item17.Settings=TRACK_RECENT\n"
L"Item18.Command=admin\n"
L"Item18.Settings=TRACK_RECENT|ITEM_DISABLED\n"
@@ -4348,6 +4348,9 @@ CSetting g_Settings[]={
{L"InvertMetroIcons",CSetting::TYPE_BOOL,IDS_INVERT_ICONS,IDS_INVERT_ICONS_TIP,0},
{L"MaxMainMenuWidth",CSetting::TYPE_INT,IDS_MENU_WIDTH,IDS_MENU_WIDTH_TIP,60,CSetting::FLAG_MENU_CLASSIC_BOTH},
{L"MaxMenuWidth",CSetting::TYPE_INT,IDS_SUBMENU_WIDTH,IDS_SUBMENU_WIDTH_TIP,60},
{L"AlignToWorkArea",CSetting::TYPE_BOOL,IDS_ALIGN_WORK_AREA,IDS_ALIGN_WORK_AREA_TIP,0},
{L"HorizontalMenuOffset",CSetting::TYPE_INT,IDS_HOR_OFFSET,IDS_HOR_OFFSET_TIP,0},
{L"VerticalMenuOffset",CSetting::TYPE_INT,IDS_VERT_OFFSET,IDS_VERT_OFFSET_TIP,0 },
{L"OverrideDPI",CSetting::TYPE_INT,IDS_DPI_OVERRIDE,IDS_DPI_OVERRIDE_TIP,0,CSetting::FLAG_COLD},
{L"MainMenuAnimate",CSetting::TYPE_BOOL,IDS_ANIMATION7,IDS_ANIMATION7_TIP,1,CSetting::FLAG_MENU_WIN7},
{L"MainMenuAnimation",CSetting::TYPE_INT,IDS_ANIMATION,IDS_ANIMATION_TIP,-1}, // system animation type
@@ -4413,7 +4416,7 @@ CSetting g_Settings[]={
{L"StartButtonIconSize",CSetting::TYPE_INT,IDS_BUTTON_ICON_SIZE,IDS_BUTTON_ICON_SIZE_TIP,0,0,L"#StartButtonType=1",L"ClasicButton"},
{L"StartButtonText",CSetting::TYPE_STRING,IDS_BUTTON_TEXT,IDS_BUTTON_TEXT_TIP,L"$Menu.Start",0,L"#StartButtonType=1",L"ClasicButton"},
{L"Taskbar",CSetting::TYPE_GROUP,IDS_TASKBAR_SETTINGS},
{L"Taskbar",CSetting::TYPE_GROUP,IDS_TASKBAR_SETTINGS,0,0,CSetting::FLAG_BASIC},
{L"CustomTaskbar",CSetting::TYPE_BOOL,IDS_TASK_CUSTOM,IDS_TASK_CUSTOM_TIP,0,CSetting::FLAG_CALLBACK},
{L"TaskbarLook",CSetting::TYPE_INT,IDS_TASK_LOOK,IDS_TASK_LOOK_TIP,1,CSetting::FLAG_CALLBACK,L"CustomTaskbar",L"CustomTaskbar"},
{L"Opaque",CSetting::TYPE_RADIO,IDS_TASK_OPAQUE,IDS_TASK_OPAQUE_TIP},
@@ -4422,8 +4425,8 @@ CSetting g_Settings[]={
{L"AeroGlass",CSetting::TYPE_RADIO,IDS_TASK_AEROGLASS,IDS_TASK_AEROGLASS_TIP,0,CSetting::FLAG_HIDDEN},
{L"TaskbarOpacity",CSetting::TYPE_INT,IDS_TASK_OPACITY,IDS_TASK_OPACITY_TIP,DEFAULT_TASK_OPACITY10,CSetting::FLAG_CALLBACK,L"TaskbarLook",L"CustomTaskbar"},
{L"TaskbarColor",CSetting::TYPE_COLOR,IDS_TASK_COLOR,IDS_TASK_COLOR_TIP,0,CSetting::FLAG_CALLBACK,L"CustomTaskbar",L"CustomTaskbar"},
{L"TaskbarTextColor",CSetting::TYPE_COLOR,IDS_TASK_TEXTCOLOR,IDS_TASK_TEXTCOLOR_TIP,0xFFFFFF,CSetting::FLAG_CALLBACK|(1<<24),L"CustomTaskbar",L"CustomTaskbar"},
{L"TaskbarTexture",CSetting::TYPE_BITMAP_JPG,IDS_TASK_TEXTURE,IDS_TASK_TEXTURE_TIP,L"",CSetting::FLAG_CALLBACK,L"CustomTaskbar",L"CustomTaskbar"},
{L"TaskbarTextColor",CSetting::TYPE_COLOR,IDS_TASK_TEXTCOLOR,IDS_TASK_TEXTCOLOR_TIP,0xFFFFFF,CSetting::FLAG_COLD|(1<<24),L"CustomTaskbar",L"CustomTaskbar"},
{L"TaskbarTexture",CSetting::TYPE_BITMAP_JPG,IDS_TASK_TEXTURE,IDS_TASK_TEXTURE_TIP,L"",CSetting::FLAG_COLD,L"CustomTaskbar",L"CustomTaskbar"},
{L"TaskbarTileH",CSetting::TYPE_INT,IDS_TASK_STRETCHH,IDS_TASK_STRETCHH_TIP,1,CSetting::FLAG_CALLBACK,L"#TaskbarTexture",L"TaskbarTexture"},
{L"Tile",CSetting::TYPE_RADIO,IDS_TASK_TILE,IDS_TASK_TILE_TIP},
{L"Stretch",CSetting::TYPE_RADIO,IDS_TASK_STRETCH,IDS_TASK_STRETCH_TIP},
@@ -4656,11 +4659,19 @@ void UpdateSettings( void )
else if (dpi<96) dpi=96;
else if (dpi>480) dpi=480;
int iconSize=24;
if (dpi<=96)
iconSize=16;
else if (dpi<=120)
iconSize=20;
int iconSize=16;
if (dpi>=240)
iconSize=40; // for 250% scaling
else if (dpi>=216)
iconSize=36; // for 225% scaling
else if (dpi>=192)
iconSize=32; // for 200% scaling
else if (dpi>=168)
iconSize=28; // for 175% scaling
else if (dpi>=144)
iconSize=24; // for 150% scaling
else if (dpi>=120)
iconSize=20; // for 125% scaling
UpdateSetting(L"SmallIconSize",CComVariant(iconSize),false);
UpdateSetting(L"LargeIconSize",CComVariant(iconSize*2),false);

View File

@@ -375,7 +375,10 @@ COLORREF MenuSkin::GetMetroColor( const wchar_t *names ) const
if (GetImmersiveUserColorSetPreference!=NULL)
{
wchar_t text[256];
Sprintf(text,_countof(text),L"Immersive%s",name);
if (wcsncmp(name,L"Immersive",9)==0)
wcscpy_s(text,name);
else
Sprintf(text,_countof(text),L"Immersive%s",name);
int type=GetImmersiveColorTypeFromName(text);
data.colorType=type<0?-1:type;
if (type>=0)
@@ -1495,8 +1498,21 @@ bool MenuSkin::ComputeOptionStates( const std::map<CString,CString> &options, st
values.push_back(L"ALL_PROGRAMS");
if (SkinType==SKIN_TYPE_CLASSIC2)
values.push_back(L"TWO_COLUMNS");
// for compatibility with existing skins
if (Dpi>=144)
values.push_back(L"HIGH_DPI");
if (Dpi>=240)
values.push_back(L"240_DPI"); // 250% scaling
else if (Dpi>=216)
values.push_back(L"216_DPI"); // 225% scaling
else if (Dpi>=192)
values.push_back(L"192_DPI"); // 200% scaling
else if (Dpi>=168)
values.push_back(L"168_DPI"); // 175% scaling
else if (Dpi>=144)
values.push_back(L"144_DPI"); // 150% scaling
else if (Dpi>=120)
values.push_back(L"120_DPI"); // 125% scaling
if (ForceTouch || (GetWinVersion()>=WIN_VER_WIN8 && GetSettingBool(L"EnableTouch") && (GetSystemMetrics(SM_DIGITIZER)&NID_INTEGRATED_TOUCH)!=0))
values.push_back(L"TOUCH_ENABLED");
if (GetSettingInt(L"SearchBox")!=SEARCHBOX_HIDDEN)

View File

@@ -2790,6 +2790,9 @@ static void OpenCortana( void )
static void InitStartMenuDLL( void )
{
LogToFile(STARTUP_LOG, L"StartMenu DLL: InitStartMenuDLL");
WaitDllInitThread();
InitializeIatHooks();
if (IsWin81Update1())
{
@@ -2817,39 +2820,40 @@ static void InitStartMenuDLL( void )
}
}
if (GetWinVersion()>=WIN_VER_WIN10)
if (GetSettingBool(L"CustomTaskbar"))
{
HMODULE shlwapi=GetModuleHandle(L"shlwapi.dll");
if (shlwapi)
if (GetWinVersion()>=WIN_VER_WIN10)
{
g_SHFillRectClr=(tSHFillRectClr)GetProcAddress(shlwapi,MAKEINTRESOURCEA(197));
if (g_SHFillRectClr)
HMODULE shlwapi=GetModuleHandle(L"shlwapi.dll");
if (shlwapi)
{
g_SHFillRectClrHook=SetIatHook(GetModuleHandle(NULL),"shlwapi.dll",MAKEINTRESOURCEA(197),SHFillRectClr2);
if (!g_SHFillRectClrHook)
g_SHFillRectClrHook=SetIatHook(GetModuleHandle(NULL),"api-ms-win-shlwapi-winrt-storage-l1-1-1.dll",MAKEINTRESOURCEA(197),SHFillRectClr2);
g_SHFillRectClr=(tSHFillRectClr)GetProcAddress(shlwapi,MAKEINTRESOURCEA(197));
if (g_SHFillRectClr)
{
g_SHFillRectClrHook=SetIatHook(GetModuleHandle(NULL),"shlwapi.dll",MAKEINTRESOURCEA(197),SHFillRectClr2);
if (!g_SHFillRectClrHook)
g_SHFillRectClrHook=SetIatHook(GetModuleHandle(NULL),"api-ms-win-shlwapi-winrt-storage-l1-1-1.dll",MAKEINTRESOURCEA(197),SHFillRectClr2);
}
}
g_StretchDIBitsHook=SetIatHook(GetModuleHandle(NULL),"gdi32.dll","StretchDIBits",StretchDIBits2);
}
g_StretchDIBitsHook=SetIatHook(GetModuleHandle(NULL),"gdi32.dll","StretchDIBits",StretchDIBits2);
}
{
HWND dlg=CreateWindow(L"#32770",L"",WS_POPUP,0,0,0,0,NULL,0,0,0);
HWND toolbar=CreateWindow(TOOLBARCLASSNAME,L"",WS_CHILD|TBS_TOOLTIPS,0,0,0,0,dlg,0,0,0);
DestroyWindow(dlg);
}
{
HWND dlg=CreateWindow(L"#32770",L"",WS_POPUP,0,0,0,0,NULL,0,0,0);
HWND toolbar=CreateWindow(TOOLBARCLASSNAME,L"",WS_CHILD|TBS_TOOLTIPS,0,0,0,0,dlg,0,0,0);
DestroyWindow(dlg);
}
if (GetWinVersion()<=WIN_VER_WIN81)
g_DrawThemeBackgroundHook=SetIatHook(GetModuleHandle(NULL),"uxtheme.dll","DrawThemeBackground",DrawThemeBackground2);
g_DrawThemeTextHook=SetIatHook(GetModuleHandle(NULL),"uxtheme.dll","DrawThemeText",DrawThemeText2);
g_DrawThemeTextExHook=SetIatHook(GetModuleHandle(NULL),"uxtheme.dll","DrawThemeTextEx",DrawThemeTextEx2);
g_DrawThemeTextCtlHook=SetIatHook(GetModuleHandle(L"comctl32.dll"),"uxtheme.dll","DrawThemeText",DrawThemeText2);
if (GetWinVersion()>=WIN_VER_WIN10)
g_SetWindowCompositionAttributeHook=SetIatHook(GetModuleHandle(NULL),"user32.dll","SetWindowCompositionAttribute",SetWindowCompositionAttribute2);
if (GetWinVersion()<=WIN_VER_WIN81)
g_DrawThemeBackgroundHook=SetIatHook(GetModuleHandle(NULL),"uxtheme.dll","DrawThemeBackground",DrawThemeBackground2);
g_DrawThemeTextHook=SetIatHook(GetModuleHandle(NULL),"uxtheme.dll","DrawThemeText",DrawThemeText2);
g_DrawThemeTextExHook=SetIatHook(GetModuleHandle(NULL),"uxtheme.dll","DrawThemeTextEx",DrawThemeTextEx2);
g_DrawThemeTextCtlHook=SetIatHook(GetModuleHandle(L"comctl32.dll"),"uxtheme.dll","DrawThemeText",DrawThemeText2);
if (GetWinVersion()>=WIN_VER_WIN10)
g_SetWindowCompositionAttributeHook=SetIatHook(GetModuleHandle(NULL),"user32.dll","SetWindowCompositionAttribute",SetWindowCompositionAttribute2);
}
g_TaskbarThreadId=GetCurrentThreadId();
LogToFile(STARTUP_LOG,L"StartMenu DLL: InitStartMenuDLL");
WaitDllInitThread();
g_bTrimHooks=GetWinVersion()==WIN_VER_WIN7 && (GetSettingInt(L"CompatibilityFixes")&COMPATIBILITY_TRIM_HOOKS);
InitManagers(false);
int level=GetSettingInt(L"CrashDump");

View File

@@ -644,6 +644,12 @@ BEGIN
IDS_PIC_COMMAND_TIP "Enter the command you want to run when you click on the user picture"
IDS_NAME_COMMAND "User name command"
IDS_NAME_COMMAND_TIP "Enter the command you want to run when you click on the user name"
IDS_ALIGN_WORK_AREA "Align start menu to working area"
IDS_ALIGN_WORK_AREA_TIP "Align the start menu to the working area instead of to the taskbar. Use with custom taskbars"
IDS_HOR_OFFSET "Horizontal position offset"
IDS_HOR_OFFSET_TIP "Offset the start menu horizontally by the amount of pixels specified"
IDS_VERT_OFFSET "Vertical position offset"
IDS_VERT_OFFSET_TIP "Offset the start menu vertically by the amount of pixels specified"
IDS_SMALL_SIZE_SM "Small icon size"
IDS_SMALL_SIZE_SM_TIP "Set the small icon size. The default is 16 for DPI<=96, 20 for 96<DPI<=120 and 24 for DPI>120"
IDS_LARGE_SIZE_SM "Large icon size"
@@ -1154,21 +1160,21 @@ END
STRINGTABLE
BEGIN
IDS_STRING7100 "This is the default skin when no other skin is selected or if the selected skin fails to load.\n\nPart of <A HREF=""http://www.classicshell.net/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7101 "Windows Aero skin\n\nDefault skin to use for the Windows Aero theme.\n\nPart of <A HREF=""http://www.classicshell.net/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7102 "Windows Basic skin\n\nDefault skin to use for the Windows Basic theme.\n\nPart of <A HREF=""http://www.classicshell.net/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7103 "Classic skin\n\nClassic look with large or small icons.\n\nPart of <A HREF=""http://www.classicshell.net/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7100 "This is the default skin when no other skin is selected or if the selected skin fails to load.\n\nPart of <A HREF=""https://github.com/Open-Shell/Open-Shell-Menu/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7101 "Windows Aero skin\n\nDefault skin to use for the Windows Aero theme.\n\nPart of <A HREF=""https://github.com/Open-Shell/Open-Shell-Menu/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7102 "Windows Basic skin\n\nDefault skin to use for the Windows Basic theme.\n\nPart of <A HREF=""https://github.com/Open-Shell/Open-Shell-Menu/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7103 "Classic skin\n\nClassic look with large or small icons.\n\nPart of <A HREF=""https://github.com/Open-Shell/Open-Shell-Menu/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
END
STRINGTABLE
BEGIN
IDS_STRING7104 "Full Glass skin\n\nTransparent menu with large or small icons.\n\nPart of <A HREF=""http://www.classicshell.net/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7105 "Smoked Glass skin\n\nSimple transparent menu with dark background.\n\nPart of <A HREF=""http://www.classicshell.net/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7106 "Windows XP Luna skin\n\nA start menu similar to the one in Windows XP.\n\nPart of <A HREF=""http://www.classicshell.net/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7107 "Windows 8 skin\n\nDefault skin to use for Windows 8.\n\nPart of <A HREF=""http://www.classicshell.net/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7108 "Midnight skin\n\nSkin with dark background.\n\nPart of <A HREF=""http://www.classicshell.net/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7109 "Metro skin\n\nSkin that uses the start screen colors.\n\nPart of <A HREF=""http://www.classicshell.net/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7110 "Metallic skin\n\nA start menu skin with metallic look.\n\nPart of <A HREF=""http://www.classicshell.net/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7104 "Full Glass skin\n\nTransparent menu with large or small icons.\n\nPart of <A HREF=""https://github.com/Open-Shell/Open-Shell-Menu/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7105 "Smoked Glass skin\n\nSimple transparent menu with dark background.\n\nPart of <A HREF=""https://github.com/Open-Shell/Open-Shell-Menu/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7106 "Windows XP Luna skin\n\nA start menu similar to the one in Windows XP.\n\nPart of <A HREF=""https://github.com/Open-Shell/Open-Shell-Menu/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7107 "Windows 8 skin\n\nDefault skin to use for Windows 8.\n\nPart of <A HREF=""https://github.com/Open-Shell/Open-Shell-Menu/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7108 "Midnight skin\n\nSkin with dark background.\n\nPart of <A HREF=""https://github.com/Open-Shell/Open-Shell-Menu/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7109 "Metro skin\n\nSkin that uses the start screen colors.\n\nPart of <A HREF=""https://github.com/Open-Shell/Open-Shell-Menu/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7110 "Metallic skin\n\nA start menu skin with metallic look.\n\nPart of <A HREF=""https://github.com/Open-Shell/Open-Shell-Menu/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
END
STRINGTABLE

View File

@@ -754,6 +754,12 @@
#define IDS_SELECT_LAST 3657
#define IDS_SELECT_LAST_TIP 3658
#define IDS_CLEAR_CACHE 3659
#define IDS_ALIGN_WORK_AREA 3660
#define IDS_ALIGN_WORK_AREA_TIP 3661
#define IDS_HOR_OFFSET 3662
#define IDS_HOR_OFFSET_TIP 3663
#define IDS_VERT_OFFSET 3664
#define IDS_VERT_OFFSET_TIP 3665
#define IDS_STRING7001 7001
#define IDS_STRING7002 7002
#define IDS_STRING7003 7003

View File

@@ -19,7 +19,6 @@ struct ICIVERBTOIDMAP
static const ICIVERBTOIDMAP g_ContextMenuIDMap[] =
{
{ L"open", "open", MENUVERB_OPEN },
{ NULL, NULL, (UINT)-1 }
};
HRESULT _MapICIVerbToCmdID(LPCMINVOKECOMMANDINFO pici, UINT* pid)

View File

@@ -129,7 +129,7 @@ Menu.RemoveHighlight = إزالة التمييز
Menu.Uninstall = إز&الة التثبيت
Menu.UninstallTitle = إزالة التثبيت
Menu.UninstallPrompt = ‏‏هل تريد بالتأكيد إزالة تثبيت %s؟
Search.CategorySettings = الإعدادات
Search.CategorySettings = لوحة التح&كم
Search.CategoryPCSettings = إعدادات الكمبيوتر
Search.CategoryPrograms = البرامج
Search.CategoryDocuments = المستندات
@@ -265,7 +265,7 @@ Menu.RemoveHighlight = Премахни осветяването
Menu.Uninstall = &Деинсталирай
Menu.UninstallTitle = Деинсталиране
Menu.UninstallPrompt = Наистина ли искате да деинсталирате %s?
Search.CategorySettings = Настройки
Search.CategorySettings = Контролен панел
Search.CategoryPCSettings = Настройки на компютъра
Search.CategoryPrograms = Програми
Search.CategoryDocuments = Документи
@@ -403,7 +403,7 @@ Menu.UninstallTitle = Desinstal·la
Menu.UninstallPrompt = Esteu segur que voleu desinstal·lar el %s?
Menu.ClassicSettings = Open-Shell &Menú
Menu.SettingsTip = Ajustaments del Open-Shell Menú
Search.CategorySettings = Configuració
Search.CategorySettings = Panell de control
Search.CategoryPCSettings = Configuració de l'ordinador
Search.CategoryPrograms = Programes
Search.CategoryDocuments = Documents
@@ -539,7 +539,7 @@ Menu.RemoveHighlight = Odebrat nejzajímavější místo
Menu.Uninstall = &Odinstalovat
Menu.UninstallTitle = Odinstalovat
Menu.UninstallPrompt = Opravdu chcete odinstalovat položku %s?
Search.CategorySettings = Nastavení
Search.CategorySettings = Ovládací panely
Search.CategoryPCSettings = Nastavení počítače
Search.CategoryPrograms = Programy
Search.CategoryDocuments = Dokumenty
@@ -675,7 +675,7 @@ Menu.RemoveHighlight = Fjern centralt punkt
Menu.Uninstall = &Fjern
Menu.UninstallTitle = Fjern
Menu.UninstallPrompt = Er du sikker på, at du vil fjerne %s?
Search.CategorySettings = Indstillinger
Search.CategorySettings = Kontrolpanel
Search.CategoryPCSettings = Pc-indstillinger
Search.CategoryPrograms = Programmer
Search.CategoryDocuments = Dokumenter
@@ -811,7 +811,7 @@ Menu.RemoveHighlight = Haupttreffer entfernen
Menu.Uninstall = &Deinstallieren
Menu.UninstallTitle = Deinstallieren
Menu.UninstallPrompt = Möchten Sie %s wirklich deinstallieren?
Search.CategorySettings = Einstellungen
Search.CategorySettings = Systemsteuerung
Search.CategoryPCSettings = PC-Einstellungen
Search.CategoryPrograms = Programme
Search.CategoryDocuments = Dokumente
@@ -947,7 +947,7 @@ Menu.RemoveHighlight = Κατάργηση επισήμανσης
Menu.Uninstall = &Κατάργηση εγκατάστασης
Menu.UninstallTitle = Κατάργηση εγκατάστασης
Menu.UninstallPrompt = Είστε βέβαιοι ότι θέλετε να καταργήσετε την εγκατάσταση του %s;
Search.CategorySettings = Ρυθμίσεις
Search.CategorySettings = Πίνακας Ελέγχου
Search.CategoryPCSettings = Ρυθμίσεις υπολογιστή
Search.CategoryPrograms = Προγράμματα
Search.CategoryDocuments = Έγγραφα
@@ -991,7 +991,7 @@ Menu.LogOffShort = &Log off
Menu.Undock = Undock Comput&er
Menu.Disconnect = D&isconnect
Menu.ShutdownBox = Sh&ut Down...
Menu.Shutdown = Sh&ut Down
Menu.Shutdown = Sh&ut down
Menu.Restart = &Restart
Menu.ShutdownUpdate = Update and shut down
Menu.RestartUpdate = Update and restart
@@ -1083,8 +1083,8 @@ Menu.RemoveHighlight = Remove highlight
Menu.Uninstall = &Uninstall
Menu.UninstallTitle = Uninstall
Menu.UninstallPrompt = Are you sure you want to uninstall %s?
Search.CategorySettings = Settings
Search.CategoryPCSettings = Modern Settings
Search.CategorySettings = Control Panel
Search.CategoryPCSettings = Settings
Search.CategoryPrograms = Programs
Search.CategoryDocuments = Documents
Search.CategoryMusic = Music
@@ -1219,7 +1219,7 @@ Menu.RemoveHighlight = Quitar como elemento destacado
Menu.Uninstall = &Desinstalar
Menu.UninstallTitle = Desinstalar
Menu.UninstallPrompt = ¿Está seguro de que desea desinstalar %s?
Search.CategorySettings = Configuración
Search.CategorySettings = Panel de control
Search.CategoryPCSettings = Configuración de tu PC
Search.CategoryPrograms = Programas
Search.CategoryDocuments = Documentos
@@ -1355,7 +1355,7 @@ Menu.RemoveHighlight = Eemalda esiletõst
Menu.Uninstall = &Desinstalli
Menu.UninstallTitle = Desinstalli
Menu.UninstallPrompt = Kas soovite kindlasti desinstallida %s?
Search.CategorySettings = Sätted
Search.CategorySettings = Juhtpaneel
Search.CategoryPCSettings = Arvutisätted
Search.CategoryPrograms = Programmid
Search.CategoryDocuments = Dokumendid
@@ -1493,7 +1493,7 @@ Menu.UninstallTitle = لغو نصب
Menu.UninstallPrompt = ‏‏آیا مطمئنید می خواهید %s را لغو نصب کنید؟
Menu.ClassicSettings = منوی ش&روع کلاسیک
Menu.SettingsTip = تنظیمات منوی شروع کلاسیک
Search.CategorySettings = تنظیمات
Search.CategorySettings = صفحه کنترل
Search.CategoryPCSettings = تنظیمات رایانه
Search.CategoryPrograms = برنامه‌ها
Search.CategoryDocuments = اسناد
@@ -1629,7 +1629,7 @@ Menu.RemoveHighlight = Poista tärkeä kohde
Menu.Uninstall = &Poista asennus
Menu.UninstallTitle = Poista asennus
Menu.UninstallPrompt = Haluatko varmasti poistaa kohteen %s asennuksen?
Search.CategorySettings = Asetukset
Search.CategorySettings = Ohjauspaneeli
Search.CategoryPCSettings = Tietokoneen asetukset
Search.CategoryPrograms = Ohjelmat
Search.CategoryDocuments = Tiedostot
@@ -1765,7 +1765,7 @@ Menu.RemoveHighlight = Supprimer la recommandation
Menu.Uninstall = &Désinstaller
Menu.UninstallTitle = Désinstaller
Menu.UninstallPrompt = Faut-il vraiment désinstaller %s ?
Search.CategorySettings = Paramètres
Search.CategorySettings = Panneau de configuration
Search.CategoryPCSettings = Paramètres du PC
Search.CategoryPrograms = Programmes
Search.CategoryDocuments = Documents
@@ -1901,7 +1901,7 @@ Menu.RemoveHighlight = Remove highlight
Menu.Uninstall = &Dì-stàlaich
Menu.UninstallTitle = Dì-stàlaich
Menu.UninstallPrompt = A bheil thu cinnteach gu bheil thu airson %s a dhì-stàladh?
Search.CategorySettings = Roghainnean
Search.CategorySettings = A' phanail-smachd
Search.CategoryPCSettings = Roghainnean a' PC
Search.CategoryPrograms = Prògraman
Search.CategoryDocuments = Sgrìobhainnean
@@ -2037,7 +2037,7 @@ Menu.RemoveHighlight = הסר הבלטה
Menu.Uninstall = ה&סר התקנה
Menu.UninstallTitle = הסר התקנה
Menu.UninstallPrompt = ‏‏האם אתה בטוח שברצונך להסיר את התקנת %s?
Search.CategorySettings = הגדרות
Search.CategorySettings = לוח הבקרה
Search.CategoryPCSettings = הגדרות מחשב
Search.CategoryPrograms = תוכניות
Search.CategoryDocuments = מסמכים
@@ -2173,7 +2173,7 @@ Menu.RemoveHighlight = Ukloni isticanje
Menu.Uninstall = &Deinstaliraj
Menu.UninstallTitle = Deinstaliraj
Menu.UninstallPrompt = Jeste li sigurni da želite deinstalirati %s iz računala?
Search.CategorySettings = Postavke
Search.CategorySettings = Upravljačka ploča
Search.CategoryPCSettings = Postavke PC-ja
Search.CategoryPrograms = Programi
Search.CategoryDocuments = Dokumenti
@@ -2309,7 +2309,7 @@ Menu.RemoveHighlight = Kiemelés eltávolítása
Menu.Uninstall = Eltá&volítás
Menu.UninstallTitle = Eltávolítás
Menu.UninstallPrompt = Biztosan el kívánja távolítani a következőt: %s?
Search.CategorySettings = Beállítások
Search.CategorySettings = Vezérlőpult
Search.CategoryPCSettings = Gépház
Search.CategoryPrograms = Programs
Search.CategoryDocuments = Dokumentumok
@@ -2447,8 +2447,8 @@ Menu.RemoveHighlight = Fjarlægja auðkenningu
Menu.Uninstall = Fjarlægja
Menu.UninstallTitle = Fjarlægja
Menu.UninstallPrompt = Ertu viss um að það eigi að fjarlægja %s?
Search.CategorySettings = Stillingar
Search.CategoryPCSettings = Sérstillingar tölvunnar
Search.CategorySettings = Stjórnborð
Search.CategoryPCSettings = PC stillingar
Search.CategoryPrograms = Forrit
Search.CategoryDocuments = Skjöl
Search.CategoryMusic = Tónlist
@@ -2583,7 +2583,7 @@ Menu.RemoveHighlight = Rimuovi elemento di rilievo
Menu.Uninstall = &Disinstalla
Menu.UninstallTitle = Disinstalla
Menu.UninstallPrompt = Disinstallare %s?
Search.CategorySettings = Impostazioni
Search.CategorySettings = Pannello di controllo
Search.CategoryPCSettings = Impostazioni PC
Search.CategoryPrograms = Programmi
Search.CategoryDocuments = Documenti
@@ -2991,7 +2991,7 @@ Menu.RemoveHighlight = Šalinti paryškinimą
Menu.Uninstall = &Pašalinti
Menu.UninstallTitle = Pašalinti
Menu.UninstallPrompt = Ar tikrai norite pašalinti %s?
Search.CategorySettings = Parametrai
Search.CategorySettings = Valdymo skydas
Search.CategoryPCSettings = PC parametrai
Search.CategoryPrograms = Programos
Search.CategoryDocuments = Dokumentai
@@ -3127,7 +3127,7 @@ Menu.RemoveHighlight = Noņemt marķējumu
Menu.Uninstall = &Atinstalēt
Menu.UninstallTitle = Atinstalēt
Menu.UninstallPrompt = Vai esat pārliecināts, ka vēlaties atinstalēt %s?
Search.CategorySettings = Iestatījumi
Search.CategorySettings = Vadības panelis
Search.CategoryPCSettings = Datora iestatījumi
Search.CategoryPrograms = Programmas
Search.CategoryDocuments = Dokumenti
@@ -3263,7 +3263,7 @@ Menu.RemoveHighlight = Remove highlight
Menu.Uninstall = &Деинсталирај
Menu.UninstallTitle = Деинсталирај
Menu.UninstallPrompt = Дали сте сигурни дека сакате да го деинсталирате %s?
Search.CategorySettings = Подесувања
Search.CategorySettings = Контрол панел
Search.CategoryPCSettings = Параметри на компјутерот
Search.CategoryPrograms = Програми
Search.CategoryDocuments = Документи
@@ -3399,7 +3399,7 @@ Menu.RemoveHighlight = Fjern høydepunkt
Menu.Uninstall = &Avinstaller
Menu.UninstallTitle = Avinstaller
Menu.UninstallPrompt = Er du sikker på at du vil avinstallere %s?
Search.CategorySettings = Innstillinger
Search.CategorySettings = Kontrollpanel
Search.CategoryPCSettings = PC-innstillinger
Search.CategoryPrograms = Programmer
Search.CategoryDocuments = Dokumenter
@@ -3535,7 +3535,7 @@ Menu.RemoveHighlight = Aandachtspunt verwijderen
Menu.Uninstall = V&erwijderen
Menu.UninstallTitle = Verwijderen
Menu.UninstallPrompt = Weet u zeker dat u %s wilt verwijderen?
Search.CategorySettings = Instellingen
Search.CategorySettings = Configuratiescherm
Search.CategoryPCSettings = Pc-instellingen
Search.CategoryPrograms = Programma's
Search.CategoryDocuments = Documenten
@@ -3671,7 +3671,7 @@ Menu.RemoveHighlight = Usuń wyróżnienie
Menu.Uninstall = &Odinstaluj
Menu.UninstallTitle = Odinstaluj
Menu.UninstallPrompt = Czy na pewno chcesz odinstalować program %s?
Search.CategorySettings = Ustawienia
Search.CategorySettings = Panel sterowania
Search.CategoryPCSettings = Ustawienia komputera
Search.CategoryPrograms = Programy
Search.CategoryDocuments = Dokumenty
@@ -3807,7 +3807,7 @@ Menu.RemoveHighlight = Remover Destaque
Menu.Uninstall = &Desinstalar
Menu.UninstallTitle = Desinstalar
Menu.UninstallPrompt = Tem certeza de que deseja desinstalar %s?
Search.CategorySettings = Configurações
Search.CategorySettings = Painel de controle
Search.CategoryPCSettings = Configurações do computador
Search.CategoryPrograms = Programas
Search.CategoryDocuments = Documentos
@@ -3943,7 +3943,7 @@ Menu.RemoveHighlight = Remover destaque
Menu.Uninstall = D&esinstalar
Menu.UninstallTitle = Desinstalar
Menu.UninstallPrompt = Tem a certeza de que pretende desinstalar %s?
Search.CategorySettings = Definições
Search.CategorySettings = Painel de controlo
Search.CategoryPCSettings = Definições do PC
Search.CategoryPrograms = Programas
Search.CategoryDocuments = Documentos
@@ -4079,7 +4079,7 @@ Menu.RemoveHighlight = Eliminare evidențiere
Menu.Uninstall = &Dezinstalare
Menu.UninstallTitle = Dezinstalare
Menu.UninstallPrompt = Sigur dezinstalați %s?
Search.CategorySettings = Setări
Search.CategorySettings = Panou de control
Search.CategoryPCSettings = Setări PC
Search.CategoryPrograms = Programe
Search.CategoryDocuments = Documente
@@ -4215,7 +4215,7 @@ Menu.RemoveHighlight = Выключить пометку
Menu.Uninstall = &Удалить
Menu.UninstallTitle = Удалить
Menu.UninstallPrompt = Вы действительно хотите удалить "%s"?
Search.CategorySettings = Параметры
Search.CategorySettings = Панель управления
Search.CategoryPCSettings = Параметры ПК
Search.CategoryPrograms = Программы
Search.CategoryDocuments = Документы
@@ -4351,7 +4351,7 @@ Menu.RemoveHighlight = Odstrániť zvýraznenie
Menu.Uninstall = &Odinštalovať
Menu.UninstallTitle = Odinštalovať
Menu.UninstallPrompt = Naozaj chcete odinštalovať program %s?
Search.CategorySettings = Nastavenia
Search.CategorySettings = Ovládací panel
Search.CategoryPCSettings = Nastavenie PC
Search.CategoryPrograms = Programy
Search.CategoryDocuments = Dokumenty
@@ -4487,7 +4487,7 @@ Menu.RemoveHighlight = Odstrani označitev
Menu.Uninstall = &Odstrani
Menu.UninstallTitle = Odstrani
Menu.UninstallPrompt = Ali ste prepričani, da želite odstraniti %s?
Search.CategorySettings = Nastavitve
Search.CategorySettings = Nadzorna plošča
Search.CategoryPCSettings = Nastavitve računalnika
Search.CategoryPrograms = Programi
Search.CategoryDocuments = Dokumenti
@@ -4623,7 +4623,7 @@ Menu.RemoveHighlight = Ukloni istaknuti sadržaj
Menu.Uninstall = &Deinstaliraj
Menu.UninstallTitle = Deinstaliraj
Menu.UninstallPrompt = Želite li zaista da deinstalirate %s?
Search.CategorySettings = Postavke
Search.CategorySettings = Kontrolna tabla
Search.CategoryPCSettings = Postavke računara
Search.CategoryPrograms = Programs
Search.CategoryDocuments = Dokumenti
@@ -4759,7 +4759,7 @@ Menu.RemoveHighlight = Ta bort fokus
Menu.Uninstall = &Avinstallera
Menu.UninstallTitle = Avinstallera
Menu.UninstallPrompt = Vill du avinstallera %s?
Search.CategorySettings = Inställningar
Search.CategorySettings = Kontrollpanelen
Search.CategoryPCSettings = Datorinställningar
Search.CategoryPrograms = Program
Search.CategoryDocuments = Dokument
@@ -4896,7 +4896,7 @@ Menu.RemoveHighlight = เอาไฮไลท์ออก
Menu.Uninstall = &ถอนการติดตั้ง
Menu.UninstallTitle = ถอนการติดตั้ง
Menu.UninstallPrompt = คุณแน่ใจหรือไม่ว่าคุณต้องการถอนการติดตั้ง %s
Search.CategorySettings = การตั้งค่า
Search.CategorySettings = แผงควบคุม
Search.CategoryPCSettings = การตั้งค่าพีซี
Search.CategoryPrograms = โปรแกรม
Search.CategoryDocuments = เอกสาร
@@ -5032,7 +5032,7 @@ Menu.RemoveHighlight = Önemli Noktayı Kaldır
Menu.Uninstall = &Kaldır
Menu.UninstallTitle = Kaldır
Menu.UninstallPrompt = %s programını kaldırmak istediğinizden emin misiniz?
Search.CategorySettings = Ayarlar
Search.CategorySettings = Denetim Masası
Search.CategoryPCSettings = Bilgisayar ayarları
Search.CategoryPrograms = Programlar
Search.CategoryDocuments = Belgeler
@@ -5168,7 +5168,7 @@ Menu.RemoveHighlight = Видалити виділення
Menu.Uninstall = &Видалити
Menu.UninstallTitle = Видалити
Menu.UninstallPrompt = Дійсно видалити %s?
Search.CategorySettings = Настройки
Search.CategorySettings = Панель керування
Search.CategoryPCSettings = Параметри ПК
Search.CategoryPrograms = Програми
Search.CategoryDocuments = Документи

View File

@@ -0,0 +1,291 @@
// ******************************************************************
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE.
// ******************************************************************
#include "DesktopNotificationManagerCompat.h"
#include <appmodel.h>
#include <wrl\wrappers\corewrappers.h>
#define RETURN_IF_FAILED(hr) do { HRESULT _hrTemp = hr; if (FAILED(_hrTemp)) { return _hrTemp; } } while (false)
using namespace ABI::Windows::Data::Xml::Dom;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
namespace DesktopNotificationManagerCompat
{
HRESULT RegisterComServer(GUID clsid, const wchar_t exePath[]);
HRESULT EnsureRegistered();
bool IsRunningAsUwp();
bool s_registeredAumidAndComServer = false;
std::wstring s_aumid;
bool s_registeredActivator = false;
bool s_hasCheckedIsRunningAsUwp = false;
bool s_isRunningAsUwp = false;
HRESULT RegisterAumidAndComServer(const wchar_t *aumid, GUID clsid)
{
/*
// If running as Desktop Bridge
if (IsRunningAsUwp())
{
// Clear the AUMID since Desktop Bridge doesn't use it, and then we're done.
// Desktop Bridge apps are registered with platform through their manifest.
// Their LocalServer32 key is also registered through their manifest.
s_aumid = L"";
s_registeredAumidAndComServer = true;
return S_OK;
}
*/
// Copy the aumid
s_aumid = std::wstring(aumid);
/*
// Get the EXE path
wchar_t exePath[MAX_PATH];
DWORD charWritten = ::GetModuleFileName(nullptr, exePath, ARRAYSIZE(exePath));
RETURN_IF_FAILED(charWritten > 0 ? S_OK : HRESULT_FROM_WIN32(::GetLastError()));
// Register the COM server
RETURN_IF_FAILED(RegisterComServer(clsid, exePath));
*/
s_registeredAumidAndComServer = true;
return S_OK;
}
HRESULT RegisterActivator()
{
// Module<OutOfProc> needs a callback registered before it can be used.
// Since we don't care about when it shuts down, we'll pass an empty lambda here.
Module<OutOfProc>::Create([] {});
// If a local server process only hosts the COM object then COM expects
// the COM server host to shutdown when the references drop to zero.
// Since the user might still be using the program after activating the notification,
// we don't want to shutdown immediately. Incrementing the object count tells COM that
// we aren't done yet.
Module<OutOfProc>::GetModule().IncrementObjectCount();
RETURN_IF_FAILED(Module<OutOfProc>::GetModule().RegisterObjects());
s_registeredActivator = true;
return S_OK;
}
HRESULT RegisterComServer(GUID clsid, const wchar_t exePath[])
{
// Turn the GUID into a string
OLECHAR* clsidOlechar;
StringFromCLSID(clsid, &clsidOlechar);
std::wstring clsidStr(clsidOlechar);
::CoTaskMemFree(clsidOlechar);
// Create the subkey
// Something like SOFTWARE\Classes\CLSID\{23A5B06E-20BB-4E7E-A0AC-6982ED6A6041}\LocalServer32
std::wstring subKey = LR"(SOFTWARE\Classes\CLSID\)" + clsidStr + LR"(\LocalServer32)";
// Include -ToastActivated launch args on the exe
std::wstring exePathStr(exePath);
exePathStr = L"\"" + exePathStr + L"\" " + TOAST_ACTIVATED_LAUNCH_ARG;
// We don't need to worry about overflow here as ::GetModuleFileName won't
// return anything bigger than the max file system path (much fewer than max of DWORD).
DWORD dataSize = static_cast<DWORD>((exePathStr.length() + 1) * sizeof(WCHAR));
// Register the EXE for the COM server
return HRESULT_FROM_WIN32(::RegSetKeyValue(
HKEY_CURRENT_USER,
subKey.c_str(),
nullptr,
REG_SZ,
reinterpret_cast<const BYTE*>(exePathStr.c_str()),
dataSize));
}
HRESULT CreateToastNotifier(IToastNotifier **notifier)
{
RETURN_IF_FAILED(EnsureRegistered());
ComPtr<IToastNotificationManagerStatics> toastStatics;
RETURN_IF_FAILED(Windows::Foundation::GetActivationFactory(
HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager).Get(),
&toastStatics));
if (s_aumid.empty())
{
return toastStatics->CreateToastNotifier(notifier);
}
else
{
return toastStatics->CreateToastNotifierWithId(HStringReference(s_aumid.c_str()).Get(), notifier);
}
}
HRESULT CreateXmlDocumentFromString(const wchar_t *xmlString, IXmlDocument **doc)
{
ComPtr<IXmlDocument> answer;
RETURN_IF_FAILED(Windows::Foundation::ActivateInstance(HStringReference(RuntimeClass_Windows_Data_Xml_Dom_XmlDocument).Get(), &answer));
ComPtr<IXmlDocumentIO> docIO;
RETURN_IF_FAILED(answer.As(&docIO));
// Load the XML string
RETURN_IF_FAILED(docIO->LoadXml(HStringReference(xmlString).Get()));
return answer.CopyTo(doc);
}
HRESULT CreateToastNotification(IXmlDocument *content, IToastNotification **notification)
{
ComPtr<IToastNotificationFactory> factory;
RETURN_IF_FAILED(Windows::Foundation::GetActivationFactory(
HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotification).Get(),
&factory));
return factory->CreateToastNotification(content, notification);
}
HRESULT get_History(std::unique_ptr<DesktopNotificationHistoryCompat>* history)
{
RETURN_IF_FAILED(EnsureRegistered());
ComPtr<IToastNotificationManagerStatics> toastStatics;
RETURN_IF_FAILED(Windows::Foundation::GetActivationFactory(
HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager).Get(),
&toastStatics));
ComPtr<IToastNotificationManagerStatics2> toastStatics2;
RETURN_IF_FAILED(toastStatics.As(&toastStatics2));
ComPtr<IToastNotificationHistory> nativeHistory;
RETURN_IF_FAILED(toastStatics2->get_History(&nativeHistory));
*history = std::unique_ptr<DesktopNotificationHistoryCompat>(new DesktopNotificationHistoryCompat(s_aumid.c_str(), nativeHistory));
return S_OK;
}
bool CanUseHttpImages()
{
return IsRunningAsUwp();
}
HRESULT EnsureRegistered()
{
// If not registered AUMID yet
if (!s_registeredAumidAndComServer)
{
// Check if Desktop Bridge
if (IsRunningAsUwp())
{
// Implicitly registered, all good!
s_registeredAumidAndComServer = true;
}
else
{
// Otherwise, incorrect usage, must call RegisterAumidAndComServer first
return E_ILLEGAL_METHOD_CALL;
}
}
// If not registered activator yet
if (!s_registeredActivator)
{
// Incorrect usage, must call RegisterActivator first
return E_ILLEGAL_METHOD_CALL;
}
return S_OK;
}
bool IsRunningAsUwp()
{
if (!s_hasCheckedIsRunningAsUwp)
{
// https://stackoverflow.com/questions/39609643/determine-if-c-application-is-running-as-a-uwp-app-in-desktop-bridge-project
UINT32 length;
wchar_t packageFamilyName[PACKAGE_FAMILY_NAME_MAX_LENGTH + 1];
LONG result = GetPackageFamilyName(GetCurrentProcess(), &length, packageFamilyName);
s_isRunningAsUwp = result == ERROR_SUCCESS;
s_hasCheckedIsRunningAsUwp = true;
}
return s_isRunningAsUwp;
}
}
DesktopNotificationHistoryCompat::DesktopNotificationHistoryCompat(const wchar_t *aumid, ComPtr<IToastNotificationHistory> history)
{
m_aumid = std::wstring(aumid);
m_history = history;
}
HRESULT DesktopNotificationHistoryCompat::Clear()
{
if (m_aumid.empty())
{
return m_history->Clear();
}
else
{
return m_history->ClearWithId(HStringReference(m_aumid.c_str()).Get());
}
}
HRESULT DesktopNotificationHistoryCompat::GetHistory(ABI::Windows::Foundation::Collections::IVectorView<ToastNotification*> **toasts)
{
ComPtr<IToastNotificationHistory2> history2;
RETURN_IF_FAILED(m_history.As(&history2));
if (m_aumid.empty())
{
return history2->GetHistory(toasts);
}
else
{
return history2->GetHistoryWithId(HStringReference(m_aumid.c_str()).Get(), toasts);
}
}
HRESULT DesktopNotificationHistoryCompat::Remove(const wchar_t *tag)
{
if (m_aumid.empty())
{
return m_history->Remove(HStringReference(tag).Get());
}
else
{
return m_history->RemoveGroupedTagWithId(HStringReference(tag).Get(), HStringReference(L"").Get(), HStringReference(m_aumid.c_str()).Get());
}
}
HRESULT DesktopNotificationHistoryCompat::RemoveGroupedTag(const wchar_t *tag, const wchar_t *group)
{
if (m_aumid.empty())
{
return m_history->RemoveGroupedTag(HStringReference(tag).Get(), HStringReference(group).Get());
}
else
{
return m_history->RemoveGroupedTagWithId(HStringReference(tag).Get(), HStringReference(group).Get(), HStringReference(m_aumid.c_str()).Get());
}
}
HRESULT DesktopNotificationHistoryCompat::RemoveGroup(const wchar_t *group)
{
if (m_aumid.empty())
{
return m_history->RemoveGroup(HStringReference(group).Get());
}
else
{
return m_history->RemoveGroupWithId(HStringReference(group).Get(), HStringReference(m_aumid.c_str()).Get());
}
}

View File

@@ -0,0 +1,108 @@
// ******************************************************************
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE.
// ******************************************************************
#pragma once
#include <string>
#include <memory>
#include <Windows.h>
#include <windows.ui.notifications.h>
#include <wrl.h>
#define TOAST_ACTIVATED_LAUNCH_ARG L"-ToastActivated"
using namespace ABI::Windows::UI::Notifications;
class DesktopNotificationHistoryCompat;
namespace DesktopNotificationManagerCompat
{
/// <summary>
/// If not running under the Desktop Bridge, you must call this method to register your AUMID with the Compat library and to
/// register your COM CLSID and EXE in LocalServer32 registry. Feel free to call this regardless, and we will no-op if running
/// under Desktop Bridge. Call this upon application startup, before calling any other APIs.
/// </summary>
/// <param name="aumid">An AUMID that uniquely identifies your application.</param>
/// <param name="clsid">The CLSID of your NotificationActivator class.</param>
HRESULT RegisterAumidAndComServer(const wchar_t *aumid, GUID clsid);
/// <summary>
/// Registers your module to handle COM activations. Call this upon application startup.
/// </summary>
HRESULT RegisterActivator();
/// <summary>
/// Creates a toast notifier. You must have called RegisterActivator first (and also RegisterAumidAndComServer if you're a classic Win32 app), or this will throw an exception.
/// </summary>
HRESULT CreateToastNotifier(IToastNotifier** notifier);
/// <summary>
/// Creates an XmlDocument initialized with the specified string. This is simply a convenience helper method.
/// </summary>
HRESULT CreateXmlDocumentFromString(const wchar_t *xmlString, ABI::Windows::Data::Xml::Dom::IXmlDocument** doc);
/// <summary>
/// Creates a toast notification. This is simply a convenience helper method.
/// </summary>
HRESULT CreateToastNotification(ABI::Windows::Data::Xml::Dom::IXmlDocument* content, IToastNotification** notification);
/// <summary>
/// Gets the DesktopNotificationHistoryCompat object. You must have called RegisterActivator first (and also RegisterAumidAndComServer if you're a classic Win32 app), or this will throw an exception.
/// </summary>
HRESULT get_History(std::unique_ptr<DesktopNotificationHistoryCompat>* history);
/// <summary>
/// Gets a boolean representing whether http images can be used within toasts. This is true if running under Desktop Bridge.
/// </summary>
bool CanUseHttpImages();
}
class DesktopNotificationHistoryCompat
{
public:
/// <summary>
/// Removes all notifications sent by this app from action center.
/// </summary>
HRESULT Clear();
/// <summary>
/// Gets all notifications sent by this app that are currently still in Action Center.
/// </summary>
HRESULT GetHistory(ABI::Windows::Foundation::Collections::IVectorView<ToastNotification*>** history);
/// <summary>
/// Removes an individual toast, with the specified tag label, from action center.
/// </summary>
/// <param name="tag">The tag label of the toast notification to be removed.</param>
HRESULT Remove(const wchar_t *tag);
/// <summary>
/// Removes a toast notification from the action using the notification's tag and group labels.
/// </summary>
/// <param name="tag">The tag label of the toast notification to be removed.</param>
/// <param name="group">The group label of the toast notification to be removed.</param>
HRESULT RemoveGroupedTag(const wchar_t *tag, const wchar_t *group);
/// <summary>
/// Removes a group of toast notifications, identified by the specified group label, from action center.
/// </summary>
/// <param name="group">The group label of the toast notifications to be removed.</param>
HRESULT RemoveGroup(const wchar_t *group);
/// <summary>
/// Do not call this. Instead, call DesktopNotificationManagerCompat.get_History() to obtain an instance.
/// </summary>
DesktopNotificationHistoryCompat(const wchar_t *aumid, Microsoft::WRL::ComPtr<IToastNotificationHistory> history);
private:
std::wstring m_aumid;
Microsoft::WRL::ComPtr<IToastNotificationHistory> m_history = nullptr;
};

View File

@@ -0,0 +1,5 @@
LIBRARY "DesktopToasts.dll"
EXPORTS
Initialize
DisplaySimpleToast

View File

@@ -0,0 +1,59 @@
#include <VersionHelpers.h>
using DesktopToastActivateHandler = void(__cdecl*)(void* context, LPCWSTR invokedArgs);
HRESULT Initialize(LPCWSTR appUserModelId, DesktopToastActivateHandler handler, void* handlerContext);
HRESULT DisplaySimpleToast(LPCWSTR title, LPCWSTR text);
class DesktopToasts
{
public:
explicit DesktopToasts(LPCWSTR appUserModelId)
{
if (::IsWindows10OrGreater())
{
auto m_lib = ::LoadLibrary(L"DesktopToasts.dll");
if (m_lib)
{
m_pInitialize = (decltype(m_pInitialize))::GetProcAddress(m_lib, "Initialize");
m_pDisplayToast = (decltype(m_pDisplayToast))::GetProcAddress(m_lib, "DisplaySimpleToast");
if (m_pInitialize && m_pDisplayToast)
{
if (m_pInitialize(appUserModelId, ToastActivate, this) == S_OK)
m_initialized = true;
}
}
}
}
~DesktopToasts()
{
if (m_lib)
::FreeLibrary(m_lib);
}
explicit operator bool() const
{
return m_initialized;
}
HRESULT DisplaySimpleToast(LPCWSTR title, LPCWSTR text)
{
return m_pDisplayToast(title, text);
}
private:
virtual void OnToastActivate(LPCWSTR invokedArgs) {}
static void __cdecl ToastActivate(void* context, LPCWSTR invokedArgs)
{
static_cast<DesktopToasts*>(context)->OnToastActivate(invokedArgs);
}
bool m_initialized = false;
HMODULE m_lib = nullptr;
decltype(&::Initialize) m_pInitialize = nullptr;
decltype(&::DisplaySimpleToast) m_pDisplayToast = nullptr;
};

View File

@@ -0,0 +1,61 @@
// Microsoft Visual C++ generated resource script.
//
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION _PRODUCT_VERSION
PRODUCTVERSION _PRODUCT_VERSION
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904e4"
BEGIN
VALUE "CompanyName", "Open-Shell"
VALUE "FileDescription", "Desktop toast notifications support"
VALUE "FileVersion", _PRODUCT_VERSION_STR
VALUE "InternalName", "DesktopToasts.dll"
VALUE "LegalCopyright", "Copyright (C) 2020, The Open-Shell Team"
VALUE "OriginalFilename", "DesktopToasts.dll"
VALUE "ProductName", "Open-Shell"
VALUE "ProductVersion", _PRODUCT_VERSION_STR
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,110 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" 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>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{d94bd2a6-1872-4f01-b911-f406603aa2e1}</ProjectGuid>
<RootNamespace>DesktopToasts</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</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" />
<Import Project="..\..\Version.props" />
</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" />
<Import Project="..\..\Version.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>..\$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;DESKTOPTOASTS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<AdditionalDependencies>runtimeobject.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>DesktopToasts.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;DESKTOPTOASTS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<AdditionalDependencies>runtimeobject.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>DesktopToasts.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="DesktopNotificationManagerCompat.h" />
<ClInclude Include="DesktopToasts.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="DesktopNotificationManagerCompat.cpp" />
<ClCompile Include="dllmain.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="DesktopToasts.def" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="DesktopToasts.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="DesktopNotificationManagerCompat.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DesktopToasts.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DesktopNotificationManagerCompat.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="DesktopToasts.def">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="DesktopToasts.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,131 @@
// dllmain.cpp : Defines the entry point for the DLL application.
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#include <NotificationActivationCallback.h>
#include <windows.ui.notifications.h>
#include <wrl/wrappers/corewrappers.h>
#include "DesktopToasts.h"
#include "DesktopNotificationManagerCompat.h"
#define RETURN_IF_FAILED(hr) do { HRESULT _hrTemp = hr; if (FAILED(_hrTemp)) { return _hrTemp; } } while (false)
using namespace ABI::Windows::Data::Xml::Dom;
using namespace ABI::Windows::UI::Notifications;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
DesktopToastActivateHandler g_handler = nullptr;
void* g_handlerContext = nullptr;
class DECLSPEC_UUID("E407B70A-1FBD-4D5E-8822-231C69102472") NotificationActivator WrlSealed WrlFinal
: public RuntimeClass<RuntimeClassFlags<ClassicCom>, INotificationActivationCallback>
{
public:
virtual HRESULT STDMETHODCALLTYPE Activate(
_In_ LPCWSTR appUserModelId,
_In_ LPCWSTR invokedArgs,
_In_reads_(dataCount) const NOTIFICATION_USER_INPUT_DATA * data,
ULONG dataCount) override
{
if (g_handler)
g_handler(g_handlerContext, invokedArgs);
return S_OK;
}
};
// Flag class as COM creatable
CoCreatableClass(NotificationActivator);
HRESULT Initialize(LPCWSTR appUserModelId, DesktopToastActivateHandler handler, void* handlerContext)
{
RETURN_IF_FAILED(DesktopNotificationManagerCompat::RegisterAumidAndComServer(appUserModelId, __uuidof(NotificationActivator)));
RETURN_IF_FAILED(DesktopNotificationManagerCompat::RegisterActivator());
g_handler = handler;
g_handlerContext = handlerContext;
return S_OK;
}
HRESULT SetNodeValueString(HSTRING inputString, IXmlNode* node, IXmlDocument* xml)
{
ComPtr<IXmlText> inputText;
RETURN_IF_FAILED(xml->CreateTextNode(inputString, &inputText));
ComPtr<IXmlNode> inputTextNode;
RETURN_IF_FAILED(inputText.As(&inputTextNode));
ComPtr<IXmlNode> appendedChild;
return node->AppendChild(inputTextNode.Get(), &appendedChild);
}
_Use_decl_annotations_
HRESULT SetTextValues(const PCWSTR* textValues, UINT32 textValuesCount, IXmlDocument* toastXml)
{
ComPtr<IXmlNodeList> nodeList;
RETURN_IF_FAILED(toastXml->GetElementsByTagName(HStringReference(L"text").Get(), &nodeList));
UINT32 nodeListLength;
RETURN_IF_FAILED(nodeList->get_Length(&nodeListLength));
// If a template was chosen with fewer text elements, also change the amount of strings
// passed to this method.
RETURN_IF_FAILED(textValuesCount <= nodeListLength ? S_OK : E_INVALIDARG);
for (UINT32 i = 0; i < textValuesCount; i++)
{
ComPtr<IXmlNode> textNode;
RETURN_IF_FAILED(nodeList->Item(i, &textNode));
RETURN_IF_FAILED(SetNodeValueString(HStringReference(textValues[i]).Get(), textNode.Get(), toastXml));
}
return S_OK;
}
HRESULT DisplaySimpleToast(LPCWSTR title, LPCWSTR text)
{
// Construct XML
ComPtr<IXmlDocument> doc;
HRESULT hr = DesktopNotificationManagerCompat::CreateXmlDocumentFromString(L"<toast><visual><binding template='ToastGeneric'><text></text><text></text></binding></visual></toast>", &doc);
if (SUCCEEDED(hr))
{
PCWSTR textValues[] = { title, text };
SetTextValues(textValues, ARRAYSIZE(textValues), doc.Get());
// Create the notifier
// Classic Win32 apps MUST use the compat method to create the notifier
ComPtr<IToastNotifier> notifier;
hr = DesktopNotificationManagerCompat::CreateToastNotifier(&notifier);
if (SUCCEEDED(hr))
{
// Create the notification itself (using helper method from compat library)
ComPtr<IToastNotification> toast;
hr = DesktopNotificationManagerCompat::CreateToastNotification(doc.Get(), &toast);
if (SUCCEEDED(hr))
{
// And show it!
hr = notifier->Show(toast.Get());
}
}
}
return hr;
}
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;
}

View File

@@ -16,6 +16,7 @@
#include "ResourceHelper.h"
#include "Translations.h"
#include <shlobj.h>
#include "DesktopToasts/DesktopToasts.h"
void ClosingSettings( HWND hWnd, int flags, int command )
@@ -59,11 +60,13 @@ static CSetting g_Settings[]={
{L"Update",CSetting::TYPE_GROUP},
{L"Language",CSetting::TYPE_STRING,0,0,L"",CSetting::FLAG_SHARED},
{L"Update",CSetting::TYPE_BOOL,0,0,1,CSetting::FLAG_SHARED},
{L"Nightly",CSetting::TYPE_BOOL,0,0,0,CSetting::FLAG_SHARED},
{NULL}
};
const int SETTING_UPDATE=2;
const int SETTING_NIGHTLY=3;
///////////////////////////////////////////////////////////////////////////////
@@ -78,6 +81,7 @@ public:
MESSAGE_HANDLER( WM_GETMINMAXINFO, OnGetMinMaxInfo )
MESSAGE_HANDLER( WM_CTLCOLORSTATIC, OnColorStatic )
COMMAND_HANDLER( IDC_CHECKAUTOCHECK, BN_CLICKED, OnCheckAuto )
COMMAND_HANDLER( IDC_CHECKNIGHTLY, BN_CLICKED, OnCheckNightly )
COMMAND_HANDLER( IDC_BUTTONCHECKNOW, BN_CLICKED, OnCheckNow )
COMMAND_HANDLER( IDC_BUTTONDOWNLOAD, BN_CLICKED, OnDownload )
COMMAND_HANDLER( IDC_CHECKDONT, BN_CLICKED, OnDontRemind )
@@ -113,6 +117,7 @@ protected:
LRESULT OnCancel( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled );
LRESULT OnColorStatic( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnCheckAuto( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled );
LRESULT OnCheckNightly( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled );
LRESULT OnCheckNow( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled );
LRESULT OnDownload( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled );
LRESULT OnDontRemind( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled );
@@ -160,6 +165,13 @@ LRESULT CUpdateDlg::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&
CheckDlgButton(IDC_CHECKAUTOCHECK,check?BST_CHECKED:BST_UNCHECKED);
GetDlgItem(IDC_CHECKAUTOCHECK).EnableWindow(!(g_Settings[SETTING_UPDATE].flags&CSetting::FLAG_LOCKED_MASK));
GetDlgItem(IDC_BUTTONCHECKNOW).EnableWindow(!(g_Settings[SETTING_UPDATE].flags&CSetting::FLAG_LOCKED_MASK) || check);
bool nightly = false;
if (g_Settings[SETTING_NIGHTLY].value.vt == VT_I4)
nightly = g_Settings[SETTING_NIGHTLY].value.intVal != 0;
CheckDlgButton(IDC_CHECKNIGHTLY, nightly ? BST_CHECKED : BST_UNCHECKED);
GetDlgItem(IDC_CHECKNIGHTLY).EnableWindow(!(g_Settings[SETTING_NIGHTLY].flags & CSetting::FLAG_LOCKED_MASK) && check);
UpdateUI();
return TRUE;
@@ -209,6 +221,17 @@ LRESULT CUpdateDlg::OnCheckAuto( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL&
bool check=IsDlgButtonChecked(IDC_CHECKAUTOCHECK)==BST_CHECKED;
g_Settings[SETTING_UPDATE].value=CComVariant(check?1:0);
g_Settings[SETTING_UPDATE].flags&=~CSetting::FLAG_DEFAULT;
GetDlgItem(IDC_CHECKNIGHTLY).EnableWindow(check);
UpdateUI();
return 0;
}
LRESULT CUpdateDlg::OnCheckNightly(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
CSettingsLockWrite lock;
bool check = IsDlgButtonChecked(IDC_CHECKNIGHTLY) == BST_CHECKED;
g_Settings[SETTING_NIGHTLY].value = CComVariant(check ? 1 : 0);
g_Settings[SETTING_NIGHTLY].flags &= ~CSetting::FLAG_DEFAULT;
UpdateUI();
return 0;
}
@@ -319,7 +342,7 @@ LRESULT CUpdateDlg::OnDontRemind( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL
LRESULT CUpdateDlg::OnWeb( int idCtrl, LPNMHDR pnmh, BOOL& bHandled )
{
ShellExecute(m_hWnd,NULL,L"https://github.com/Open-Shell/Open-Shell-Menu",NULL,NULL,SW_SHOWNORMAL);
ShellExecute(m_hWnd,NULL,L"https://open-shell.github.io/Open-Shell-Menu/",NULL,NULL,SW_SHOWNORMAL);
return 0;
}
@@ -399,6 +422,9 @@ void CUpdateDlg::UpdateUI( void )
void CUpdateDlg::Run( void )
{
if (m_hWnd)
return;
DLGTEMPLATE *pTemplate=LoadDialogEx(IDD_UPDATE);
Create(NULL,pTemplate);
MSG msg;
@@ -457,15 +483,25 @@ protected:
///////////////////////////////////////////////////////////////////////////////
class UpdateToasts : public DesktopToasts
{
public:
UpdateToasts() : DesktopToasts(L"OpenShell.Update") {}
private:
void OnToastActivate(LPCWSTR invokedArgs) override
{
g_UpdateDlg.Run();
}
};
///////////////////////////////////////////////////////////////////////////////
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpstrCmdLine, int nCmdShow )
{
INITCOMMONCONTROLSEX init={sizeof(init),ICC_STANDARD_CLASSES};
InitCommonControlsEx(&init);
/*
VersionData data;
data.Load(L"D:\\Work\\OpenShell\\Setup\\Final\\update_4.0.4.ver",false);
return 0;
*/
// prevent multiple instances from running on the same desktop
// the assumption is that multiple desktops for the same user will have different name (but may repeat across users)
wchar_t userName[256];
@@ -491,8 +527,6 @@ int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpstrC
CString language=GetSettingString(L"Language");
ParseTranslations(NULL,language);
g_Instance=hInstance;
HINSTANCE resInstance=LoadTranslationDll(language);
LoadTranslationResources(resInstance,g_LoadDialogs);
@@ -504,6 +538,9 @@ int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpstrC
COwnerWindow ownerWindow;
ownerWindow.Create(NULL,0,0,WS_POPUP);
UpdateToasts toasts;
if (wcsstr(lpstrCmdLine,L"-popup")!=NULL)
{
g_UpdateDlg.UpdateData();
@@ -511,57 +548,85 @@ int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpstrC
int sleep=5000-(timeGetTime()-time0);
if (sleep>0)
Sleep(sleep);
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);
SendMessage(balloon,TTM_SETMAXTIPWIDTH,0,500);
TOOLINFO tool={sizeof(tool),TTF_ABSOLUTE|TTF_TRANSPARENT|TTF_TRACK|(IsLanguageRTL()?TTF_RTLREADING:0U)};
tool.uId=1;
CString message=LoadStringEx(g_UpdateDlg.HasNewLanguage()?IDS_LANG_NEWVERSION:IDS_NEWVERSION);
tool.lpszText=(wchar_t*)(const wchar_t*)message;
SendMessage(balloon,TTM_ADDTOOL,0,(LPARAM)&tool);
SendMessage(balloon,TTM_SETTITLE,(WPARAM)LoadIcon(g_Instance,MAKEINTRESOURCE(IDI_APPICON)),(LPARAM)(const wchar_t*)LoadStringEx(IDS_UPDATE_TITLE));
APPBARDATA appbar={sizeof(appbar)};
SHAppBarMessage(ABM_GETTASKBARPOS,&appbar);
MONITORINFO info={sizeof(info)};
GetMonitorInfo(MonitorFromWindow(appbar.hWnd,MONITOR_DEFAULTTOPRIMARY),&info);
SendMessage(balloon,TTM_TRACKPOSITION,0,0);
SendMessage(balloon,TTM_TRACKACTIVATE,TRUE,(LPARAM)&tool);
RECT rc;
GetWindowRect(balloon,&rc);
LONG pos;
if (appbar.uEdge==ABE_LEFT)
pos=MAKELONG(info.rcWork.left,info.rcWork.bottom-rc.bottom+rc.top);
else if (appbar.uEdge==ABE_RIGHT)
pos=MAKELONG(info.rcWork.right-rc.right+rc.left,info.rcWork.bottom-rc.bottom+rc.top);
else if (appbar.uEdge==ABE_TOP)
pos=MAKELONG(IsLanguageRTL()?info.rcWork.left:info.rcWork.right-rc.right+rc.left,info.rcWork.top);
else
pos=MAKELONG(IsLanguageRTL()?info.rcWork.left:info.rcWork.right-rc.right+rc.left,info.rcWork.bottom-rc.bottom+rc.top);
SendMessage(balloon,TTM_TRACKPOSITION,0,pos);
SetWindowSubclass(balloon,SubclassBalloonProc,0,'CLSH');
PlaySound(L"SystemNotification",NULL,SND_APPLICATION|SND_ALIAS|SND_ASYNC|SND_NODEFAULT|SND_SYSTEM);
int time0=timeGetTime();
while (IsWindowVisible(balloon))
auto title = LoadStringEx(IDS_UPDATE_TITLE);
auto message = LoadStringEx(g_UpdateDlg.HasNewLanguage() ? IDS_LANG_NEWVERSION : IDS_NEWVERSION);
if (toasts)
{
if (time0 && (timeGetTime()-time0)>=15000)
{
time0=0;
TOOLINFO tool={sizeof(tool)};
tool.uId=1;
SendMessage(balloon,TTM_TRACKACTIVATE,FALSE,(LPARAM)&tool);
}
MSG msg;
while (PeekMessage(&msg,0,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Sleep(10);
toasts.DisplaySimpleToast(title, message);
}
else
{
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);
SendMessage(balloon, TTM_SETMAXTIPWIDTH, 0, 500);
TOOLINFO tool = { sizeof(tool),TTF_ABSOLUTE | TTF_TRANSPARENT | TTF_TRACK | (IsLanguageRTL() ? TTF_RTLREADING : 0U) };
tool.uId = 1;
tool.lpszText = (wchar_t*)(const wchar_t*)message;
SendMessage(balloon, TTM_ADDTOOL, 0, (LPARAM)&tool);
SendMessage(balloon, TTM_SETTITLE, (WPARAM)LoadIcon(g_Instance, MAKEINTRESOURCE(IDI_APPICON)), (LPARAM)(const wchar_t*)title);
APPBARDATA appbar = { sizeof(appbar) };
SHAppBarMessage(ABM_GETTASKBARPOS, &appbar);
MONITORINFO info = { sizeof(info) };
GetMonitorInfo(MonitorFromWindow(appbar.hWnd, MONITOR_DEFAULTTOPRIMARY), &info);
SendMessage(balloon, TTM_TRACKPOSITION, 0, 0);
SendMessage(balloon, TTM_TRACKACTIVATE, TRUE, (LPARAM)&tool);
RECT rc;
GetWindowRect(balloon, &rc);
LONG pos;
if (appbar.uEdge == ABE_LEFT)
pos = MAKELONG(info.rcWork.left, info.rcWork.bottom - rc.bottom + rc.top);
else if (appbar.uEdge == ABE_RIGHT)
pos = MAKELONG(info.rcWork.right - rc.right + rc.left, info.rcWork.bottom - rc.bottom + rc.top);
else if (appbar.uEdge == ABE_TOP)
pos = MAKELONG(IsLanguageRTL() ? info.rcWork.left : info.rcWork.right - rc.right + rc.left, info.rcWork.top);
else
pos = MAKELONG(IsLanguageRTL() ? info.rcWork.left : info.rcWork.right - rc.right + rc.left, info.rcWork.bottom - rc.bottom + rc.top);
SendMessage(balloon, TTM_TRACKPOSITION, 0, pos);
SetWindowSubclass(balloon, SubclassBalloonProc, 0, 'CLSH');
PlaySound(L"SystemNotification", NULL, SND_APPLICATION | SND_ALIAS | SND_ASYNC | SND_NODEFAULT | SND_SYSTEM);
int time0 = timeGetTime();
while (IsWindowVisible(balloon))
{
if (time0 && (timeGetTime() - time0) >= 15000)
{
time0 = 0;
TOOLINFO tool = { sizeof(tool) };
tool.uId = 1;
SendMessage(balloon, TTM_TRACKACTIVATE, FALSE, (LPARAM)&tool);
}
MSG msg;
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Sleep(10);
}
}
}
else if (wcsstr(lpstrCmdLine, L"-ToastActivated"))
{
g_UpdateDlg.UpdateData();
// dialog will be shown once toast is activated (UpdateToasts::OnToastActivate)
}
else
{
g_UpdateDlg.Run();
}
// process messages for a while
for (int i = 0; i < 100; i++)
{
MSG msg;
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Sleep(10);
}
ownerWindow.DestroyWindow();
CoUninitialize();
return 0;

View File

@@ -123,22 +123,24 @@ END
// Dialog
//
IDD_UPDATE DIALOGEX 0, 0, 316, 181
IDD_UPDATE DIALOGEX 0, 0, 316, 200
STYLE DS_SETFONT | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "Open-Shell Update"
FONT 9, "Segoe UI", 400, 0, 0x0
BEGIN
CONTROL "Automatically check for new versions",IDC_CHECKAUTOCHECK,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,129,10
PUSHBUTTON "Check now",IDC_BUTTONCHECKNOW,7,17,50,14
LTEXT "message",IDC_STATICLATEST,7,33,302,10,SS_CENTERIMAGE
EDITTEXT IDC_EDITTEXT,7,45,302,97,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY | NOT WS_VISIBLE | WS_VSCROLL
PUSHBUTTON "Download",IDC_BUTTONDOWNLOAD,7,144,50,14,NOT WS_VISIBLE
CONTROL "Check for nightly builds",IDC_CHECKNIGHTLY,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,19,151,10
PUSHBUTTON "Check now",IDC_BUTTONCHECKNOW,7,34,50,14
LTEXT "message",IDC_STATICLATEST,7,48,302,10,SS_CENTERIMAGE
EDITTEXT IDC_EDITTEXT,7,60,302,97,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY | NOT WS_VISIBLE | WS_VSCROLL
PUSHBUTTON "Download",IDC_BUTTONDOWNLOAD,7,161,50,14,NOT WS_VISIBLE
CONTROL "Don't remind me again about this version",IDC_CHECKDONT,
"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,61,144,141,14
CONTROL "<a>https://github.com/Open-Shell/Open-Shell-Menu</a>",IDC_LINKWEB,"SysLink",WS_TABSTOP,7,164,66,10,WS_EX_TRANSPARENT
DEFPUSHBUTTON "OK",IDOK,202,160,50,14
PUSHBUTTON "Cancel",IDCANCEL,259,160,50,14
"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,61,161,141,14
CONTROL "<a>Open-Shell-Menu</a>",IDC_LINKWEB,"SysLink",WS_TABSTOP,7,181,66,10,WS_EX_TRANSPARENT
DEFPUSHBUTTON "OK",IDOK,202,177,50,14
PUSHBUTTON "Cancel",IDCANCEL,259,177,50,14
END
@@ -155,7 +157,7 @@ BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 309
TOPMARGIN, 7
BOTTOMMARGIN, 174
BOTTOMMARGIN, 191
END
END
#endif // APSTUDIO_INVOKED

View File

@@ -9,6 +9,7 @@
#define IDC_CHECKDONT 1004
#define IDC_BUTTONCHECKNOW 1005
#define IDC_CHECKAUTOCHECK 1006
#define IDC_CHECKNIGHTLY 1007
#define IDD_UPDATE 6001
#define IDS_UPDATED 6001
#define IDS_OUTOFDATE 6002
@@ -21,7 +22,7 @@
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 227
#define _APS_NEXT_RESOURCE_VALUE 228
#define _APS_NEXT_COMMAND_VALUE 32769
#define _APS_NEXT_CONTROL_VALUE 262
#define _APS_NEXT_SYMED_VALUE 106