Compare commits
91 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93245dc4d6 | ||
|
|
86447299b1 | ||
|
|
64259f73e8 | ||
|
|
8031739110 | ||
|
|
27e5c2bc74 | ||
|
|
bb26cec0ec | ||
|
|
ef663d2051 | ||
|
|
be8568ce00 | ||
|
|
5399e3ad8c | ||
|
|
68379f4098 | ||
|
|
daa1d96f12 | ||
|
|
998d83c15c | ||
|
|
0cb43dd17c | ||
|
|
b89aaed785 | ||
|
|
47cc2b2304 | ||
|
|
a20215d9da | ||
|
|
4f362760b6 | ||
|
|
2e43d4c7a1 | ||
|
|
4b2688245f | ||
|
|
082f85a4e2 | ||
|
|
0ce76c9c36 | ||
|
|
6e71d7c414 | ||
|
|
84909cf397 | ||
|
|
fc290d5a6a | ||
|
|
ebd530f652 | ||
|
|
e50c5f73d7 | ||
|
|
1db0006c96 | ||
|
|
7d0a9df1c3 | ||
|
|
8e1b4e35a3 | ||
|
|
859afc63d3 | ||
|
|
ee6db35b34 | ||
|
|
283c0fce03 | ||
|
|
ac5e69f1a0 | ||
|
|
b2df22104e | ||
|
|
c88f028f3e | ||
|
|
312bfd99d5 | ||
|
|
ca576a0224 | ||
|
|
a5f35b133f | ||
|
|
f197c9f43d | ||
|
|
bce9efcc43 | ||
|
|
80c38d95e9 | ||
|
|
0b535d1dd8 | ||
|
|
e2ff745949 | ||
|
|
fbcf85559e | ||
|
|
ed3da927cc | ||
|
|
225d0ba8f9 | ||
|
|
afaf16620a | ||
|
|
4883d13950 | ||
|
|
b094ddc5f9 | ||
|
|
a422105c61 | ||
|
|
96423b8918 | ||
|
|
ba131ff14b | ||
|
|
7d59f5ebfb | ||
|
|
95f3a4b09a | ||
|
|
728f982310 | ||
|
|
2ca236c291 | ||
|
|
8a22282191 | ||
|
|
935600a6d9 | ||
|
|
d3bf4b6207 | ||
|
|
aa09a0dcc2 | ||
|
|
cd8cc8cbc6 | ||
|
|
1bfbe09c6f | ||
|
|
61d05b49c5 | ||
|
|
9752afbebc | ||
|
|
e210b4a65a | ||
|
|
6581868336 | ||
|
|
7ee668e474 | ||
|
|
62b949679b | ||
|
|
6242e8d9b9 | ||
|
|
ee59bb76de | ||
|
|
3eb134a280 | ||
|
|
257023209b | ||
|
|
0da20180ac | ||
|
|
1f57c782e5 | ||
|
|
1f6e06fc85 | ||
|
|
ed3675ca7f | ||
|
|
695e419722 | ||
|
|
3bceac1515 | ||
|
|
473f7e1445 | ||
|
|
fcf95a3ea6 | ||
|
|
cc02e38aef | ||
|
|
9c119c6e29 | ||
|
|
9e297866ed | ||
|
|
261929f4c3 | ||
|
|
9976e134ca | ||
|
|
1b410e5a80 | ||
|
|
9ebe53fdbf | ||
|
|
5f59aab40a | ||
|
|
4f46134f10 | ||
|
|
519f4afe17 | ||
|
|
30ffce6939 |
4
.gitignore
vendored
@@ -4,6 +4,10 @@
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# ignore vscode stuff
|
||||
.vscode/
|
||||
.ionide/
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
|
||||
@@ -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 = Документи
|
||||
|
||||
26
README.md
@@ -2,16 +2,13 @@
|
||||
|
||||
*Originally* **[Classic Shell](http://www.classicshell.net)** *by [Ivo Beltchev](https://sourceforge.net/u/ibeltchev/profile/)*
|
||||
|
||||
[](https://github.com/Open-Shell/Open-Shell-Menu/releases) [](https://github.com/Open-Shell/Open-Shell-Menu/releases) [](https://ci.appveyor.com/project/passionate-coder/open-shell-menu/branch/master) [](https://gitq.com/passionate-coder/Classic-Start) [](https://gitter.im/open-shell/Lobby)
|
||||
[](https://github.com/Open-Shell/Open-Shell-Menu/releases) [](https://github.com/Open-Shell/Open-Shell-Menu/releases) [](https://ci.appveyor.com/project/passionate-coder/open-shell-menu/branch/master) [](https://gitq.com/passionate-coder/Classic-Start) [](https://gitter.im/open-shell/Lobby) [](https://discord.gg/7H6arr5)
|
||||
|
||||
[Home Page](https://open-shell.github.io/Open-Shell-Menu)
|
||||
|
||||
[Discussion room](https://gitter.im/Open-Shell)
|
||||
|
||||
[Latest nightly build](https://ci.appveyor.com/project/passionate-coder/open-shell-menu/branch/master/artifacts)
|
||||
[Home Page](https://open-shell.github.io/Open-Shell-Menu)
|
||||
[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
|
||||
|
||||
- Classic style Start Menu for Windows 7, 8, 8.1, 10
|
||||
- Toolbar for Windows Explorer
|
||||
- Classic copy UI (Windows 7 only)
|
||||
@@ -19,16 +16,19 @@
|
||||
- Title bar and status bar for Internet Explorer
|
||||
|
||||
### Download
|
||||
If you just want to use it or looking for setup file, click here to download!!!
|
||||
If you just want to use it or looking for setup file, click here to download:
|
||||
|
||||
[](https://github.com/Open-Shell/Open-Shell-Menu/releases)
|
||||
|
||||
---
|
||||
### Temporary Translation/Language Solution
|
||||
1. Download [language DLL](https://coddec.github.io/Classic-Shell/www.classicshell.net/translations/index.html)
|
||||
2. Place it either in the Open-Shell's __install folder__ or in the `%ALLUSERSPROFILE%\OpenShell\Languages` folder
|
||||
|
||||
----
|
||||
|
||||
*For archival reasons, we have a mirror of `www.classicshell.net` [here](https://coddec.github.io/Classic-Shell/www.classicshell.net/).*
|
||||
|
||||
[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)
|
||||
|
||||
[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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -158,7 +158,6 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
@@ -178,6 +177,7 @@
|
||||
<ModuleDefinitionFile>.\$(TargetName).def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<PerUserRedirection>true</PerUserRedirection>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
@@ -194,7 +194,6 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
@@ -214,6 +213,7 @@
|
||||
<ModuleDefinitionFile>.\$(TargetName).def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<PerUserRedirection>true</PerUserRedirection>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
@@ -251,6 +251,7 @@
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<PerUserRedirection>true</PerUserRedirection>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
@@ -287,6 +288,7 @@
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<PerUserRedirection>true</PerUserRedirection>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Setup|Win32'">
|
||||
|
||||
@@ -77,7 +77,6 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
|
||||
@@ -380,7 +380,7 @@ LRESULT CEditToolbarDlg::OnBrowseLink( WORD wNotifyCode, WORD wID, HWND hWndCtl,
|
||||
{
|
||||
wchar_t text[_MAX_PATH];
|
||||
GetDlgItemText(IDC_COMBOLINK,text,_countof(text));
|
||||
if (BrowseLinkHelper(m_hWnd,text))
|
||||
if (BrowseLinkHelper(m_hWnd,text,false))
|
||||
{
|
||||
SetDlgItemText(IDC_COMBOLINK,text);
|
||||
SendMessage(WM_COMMAND,MAKEWPARAM(IDC_COMBOLINK,CBN_KILLFOCUS));
|
||||
|
||||
@@ -142,7 +142,6 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
@@ -163,7 +162,6 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
|
||||
@@ -152,7 +152,6 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_USRDLL;CLASSICIEDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
@@ -171,6 +170,7 @@
|
||||
<ModuleDefinitionFile>.\$(TargetName).def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<PerUserRedirection>true</PerUserRedirection>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
@@ -187,7 +187,6 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_USRDLL;CLASSICIEDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
@@ -206,6 +205,7 @@
|
||||
<ModuleDefinitionFile>.\$(TargetName).def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<PerUserRedirection>true</PerUserRedirection>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
@@ -242,6 +242,7 @@
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<PerUserRedirection>true</PerUserRedirection>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
@@ -277,6 +278,7 @@
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<PerUserRedirection>true</PerUserRedirection>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Setup|Win32'">
|
||||
|
||||
@@ -14,6 +14,7 @@ public:
|
||||
CAbsolutePidl( const CAbsolutePidl &pidl ) { m_Pidl=pidl?ILCloneFull(pidl):NULL; }
|
||||
~CAbsolutePidl( void ) { Clear(); }
|
||||
void operator=( const CAbsolutePidl &pidl ) { Clone(pidl); }
|
||||
void operator=( PCIDLIST_ABSOLUTE pidl ) { Clone(pidl); }
|
||||
|
||||
void Clear( void ) { if (m_Pidl) ILFree(m_Pidl); m_Pidl=NULL; }
|
||||
operator PIDLIST_ABSOLUTE( void ) const { return m_Pidl; }
|
||||
@@ -21,7 +22,7 @@ public:
|
||||
void Swap( CAbsolutePidl &pidl ) { PIDLIST_ABSOLUTE q=pidl.m_Pidl; pidl.m_Pidl=m_Pidl; m_Pidl=q; }
|
||||
void Attach( PIDLIST_ABSOLUTE pidl ) { Clear(); m_Pidl=pidl; }
|
||||
PIDLIST_ABSOLUTE Detach( void ) { PIDLIST_ABSOLUTE pidl=m_Pidl; m_Pidl=NULL; return pidl; }
|
||||
void Clone( PIDLIST_ABSOLUTE pidl ) { Clear(); m_Pidl=pidl?ILCloneFull(pidl):NULL; }
|
||||
void Clone( PCIDLIST_ABSOLUTE pidl ) { Clear(); m_Pidl=pidl?ILCloneFull(pidl):NULL; }
|
||||
|
||||
private:
|
||||
PIDLIST_ABSOLUTE m_Pidl;
|
||||
|
||||
@@ -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,15 +190,16 @@ 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())
|
||||
res=DOWNLOAD_CANCEL;
|
||||
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);
|
||||
const wchar_t* accept[] = { L"*/*",NULL };
|
||||
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 +244,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 +266,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 +319,7 @@ struct VersionCheckParams
|
||||
TSettingsComponent component;
|
||||
tNewVersionCallback callback;
|
||||
CProgressDlg *progress;
|
||||
bool nightly = false;
|
||||
};
|
||||
|
||||
// 0 - fail, 1 - success, 2 - cancel
|
||||
@@ -377,80 +339,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 +452,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 +497,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 +536,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 +744,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 +1031,7 @@ static DWORD WINAPI ThreadDownloadFile( void *param )
|
||||
params.saveRes=0;
|
||||
|
||||
std::vector<char> buf;
|
||||
params.downloadRes=DownloadFile(params.url,buf,params.fname.IsEmpty()?¶ms.fname:NULL,0,params.bAcceptCached,params.progress,params.component);
|
||||
params.downloadRes=DownloadFile(params.url,buf,params.fname.IsEmpty()?¶ms.fname:NULL,params.bAcceptCached,params.progress,params.component);
|
||||
if (params.downloadRes==DOWNLOAD_CANCEL || params.downloadRes>=DOWNLOAD_FIRST_ERROR)
|
||||
return 0;
|
||||
|
||||
@@ -971,6 +1065,7 @@ static DWORD WINAPI ThreadDownloadFile( void *param )
|
||||
return 0;
|
||||
|
||||
// validate signer
|
||||
/*
|
||||
if (params.signer)
|
||||
{
|
||||
if (params.progress)
|
||||
@@ -982,7 +1077,7 @@ static DWORD WINAPI ThreadDownloadFile( void *param )
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1089,6 +1184,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,¶ms,0,NULL);
|
||||
|
||||
while (1)
|
||||
|
||||
@@ -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& );
|
||||
|
||||
@@ -60,3 +60,17 @@ bool IsFakeFolder( const wchar_t *fname )
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GetFakeFolder( wchar_t *dst, int len, const wchar_t *src )
|
||||
{
|
||||
Sprintf(dst,len,L"%s\\target.lnk",src);
|
||||
if (GetFileAttributes(dst)!=INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
wchar_t path[_MAX_PATH];
|
||||
Sprintf(path,_countof(path),L"%s\\desktop.ini",src);
|
||||
DWORD attrib=GetFileAttributes(path);
|
||||
if (attrib!=INVALID_FILE_ATTRIBUTES && (attrib&FILE_ATTRIBUTE_SYSTEM))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -7,3 +7,4 @@
|
||||
bool CreateFakeFolder( const wchar_t *source, const wchar_t *fname );
|
||||
void DeleteFakeFolder( const wchar_t *fname );
|
||||
bool IsFakeFolder( const wchar_t *fname );
|
||||
bool GetFakeFolder( wchar_t *dst, int len, const wchar_t *src );
|
||||
|
||||
@@ -127,7 +127,6 @@ VersionData CLanguageSettingsDlg::s_VersionData;
|
||||
|
||||
void CLanguageSettingsDlg::AddFlag( const wchar_t *langName, int langId, HBITMAP bmp )
|
||||
{
|
||||
std::vector<LangInfo>::iterator it=m_LanguageIDs.begin()+1;
|
||||
int idx=1;
|
||||
for (;idx<(int)m_LanguageIDs.size();idx++)
|
||||
{
|
||||
@@ -205,8 +204,6 @@ void CLanguageSettingsDlg::UpdateFlags( void )
|
||||
DoEnvironmentSubst(path,_countof(path));
|
||||
}
|
||||
|
||||
CWindow list=GetDlgItem(IDC_LISTLANGUAGE);
|
||||
|
||||
wchar_t find[_MAX_PATH];
|
||||
Sprintf(find,_countof(find),L"%s\\*.dll",path);
|
||||
WIN32_FIND_DATA data;
|
||||
@@ -408,7 +405,7 @@ LRESULT CLanguageSettingsDlg::OnSelChange( int idCtrl, LPNMHDR pnmh, BOOL& bHand
|
||||
CComVariant val(name);
|
||||
if (m_pSetting->value!=val)
|
||||
SetSettingsDirty();
|
||||
m_pSetting->value=val;
|
||||
m_pSetting->value=std::move(val);
|
||||
|
||||
if (_wcsicmp(m_pSetting->value.bstrVal,m_pSetting->defValue.bstrVal)==0)
|
||||
m_pSetting->flags|=CSetting::FLAG_DEFAULT;
|
||||
|
||||
@@ -71,7 +71,7 @@ BEGIN
|
||||
CONTROL "Show all settings",IDC_CHECKALL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,154,7,79,12
|
||||
CONTROL "<a>Help...</a>",IDC_LINKHELP,"SysLink",WS_TABSTOP,348,9,26,10,WS_EX_TRANSPARENT
|
||||
CONTROL "",IDC_TABSETTINGS,"SysTabControl32",TCS_MULTILINE | TCS_FOCUSNEVER,7,20,367,169
|
||||
CONTROL "<a>www.classicshell.net</a>",IDC_LINKWEB,"SysLink",WS_TABSTOP,7,195,66,10,WS_EX_TRANSPARENT
|
||||
CONTROL "<a>Open-Shell Homepage</a>",IDC_LINKWEB,"SysLink",WS_TABSTOP,7,195,75,10,WS_EX_TRANSPARENT
|
||||
CONTROL "Name of translator goes <a href=""http://www.yoursite.com"">here</a>",IDC_SYSLINKLOC,
|
||||
"SysLink",NOT WS_VISIBLE | WS_TABSTOP,80,195,111,10
|
||||
PUSHBUTTON "&Backup",IDC_BUTTONBACKUP,200,192,60,14,WS_GROUP
|
||||
@@ -277,7 +277,7 @@ BEGIN
|
||||
IDS_BMP_TITLE "Select Image File"
|
||||
IDS_SEARCH_PROMPT "Search Settings"
|
||||
IDS_SETTING_SEARCH "Search Results"
|
||||
IDS_WEBSITE_TIP "Visit Open-Shell on the web - http://www.classicshell.net"
|
||||
IDS_WEBSITE_TIP "Visit Open-Shell on the web - https://open-shell.github.io/Open-Shell-Menu"
|
||||
IDS_LOCATE_SETTING "Locate setting"
|
||||
IDS_LANGUAGE_UPDATED "The language %s is up to date."
|
||||
IDS_LANGUAGE_MISSING "Update for language %s is not available."
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -332,6 +332,7 @@ HBITMAP BitmapFromIcon( HICON hIcon, int iconSize, unsigned int **pBits, bool bD
|
||||
// Premultiplies a DIB section by the alpha channel and a given color
|
||||
void PremultiplyBitmap( HBITMAP hBitmap, COLORREF rgb )
|
||||
{
|
||||
if (hBitmap == NULL) return;
|
||||
BITMAP info;
|
||||
GetObject(hBitmap,sizeof(info),&info);
|
||||
int n=info.bmWidth*info.bmHeight;
|
||||
|
||||
@@ -125,7 +125,7 @@ bool CSetting::IsEnabled( void ) const
|
||||
if (operation=='>' && pSetting->GetValue().intVal<=val)
|
||||
return false;
|
||||
}
|
||||
if ((pSetting->type==CSetting::TYPE_STRING || pSetting->type==CSetting::TYPE_BITMAP || pSetting->type==CSetting::TYPE_BITMAP_JPG) && pSetting->GetValue().vt==VT_BSTR)
|
||||
if ((pSetting->type==CSetting::TYPE_STRING || pSetting->type==CSetting::TYPE_BITMAP || pSetting->type==CSetting::TYPE_BITMAP_JPG || pSetting->type==CSetting::TYPE_DIRECTORY) && pSetting->GetValue().vt==VT_BSTR)
|
||||
{
|
||||
if (operation=='~' && *pSetting->GetValue().bstrVal==0)
|
||||
return false;
|
||||
@@ -202,7 +202,7 @@ bool CSetting::ReadValue( CRegKey ®Key, const wchar_t *valName )
|
||||
}
|
||||
|
||||
// string
|
||||
if (type>=CSetting::TYPE_STRING && type<CSetting::TYPE_MULTISTRING)
|
||||
if (type>=CSetting::TYPE_STRING && type!=CSetting::TYPE_MULTISTRING)
|
||||
{
|
||||
ULONG len;
|
||||
if (regKey.QueryStringValue(valName,NULL,&len)==ERROR_SUCCESS)
|
||||
@@ -789,11 +789,14 @@ CString CSettingsManager::LoadSettingsXml( const wchar_t *fname )
|
||||
}
|
||||
CComPtr<IXMLDOMNode> next;
|
||||
child2->get_nextSibling(&next);
|
||||
child2=next;
|
||||
child2=std::move(next);
|
||||
}
|
||||
string.push_back(0);
|
||||
pSetting->value=CComVariant(&string[0]);
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (pSetting->value==pSetting->defValue)
|
||||
pSetting->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -806,7 +809,10 @@ CString CSettingsManager::LoadSettingsXml( const wchar_t *fname )
|
||||
if (pSetting->type>=CSetting::TYPE_STRING)
|
||||
{
|
||||
pSetting->value=value;
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (pSetting->value==pSetting->defValue)
|
||||
pSetting->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
}
|
||||
else if (pSetting->type==CSetting::TYPE_BOOL || (pSetting->type==CSetting::TYPE_INT && pSetting[1].type!=CSetting::TYPE_RADIO) || pSetting->type==CSetting::TYPE_HOTKEY || pSetting->type==CSetting::TYPE_HOTKEY_ANY || pSetting->type==CSetting::TYPE_COLOR)
|
||||
{
|
||||
@@ -815,7 +821,10 @@ CString CSettingsManager::LoadSettingsXml( const wchar_t *fname )
|
||||
pSetting->value=CComVariant(val?1:0);
|
||||
else
|
||||
pSetting->value=CComVariant(val);
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (pSetting->value==pSetting->defValue)
|
||||
pSetting->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
}
|
||||
else if (pSetting->type==CSetting::TYPE_INT && pSetting[1].type==CSetting::TYPE_RADIO)
|
||||
{
|
||||
@@ -825,7 +834,10 @@ CString CSettingsManager::LoadSettingsXml( const wchar_t *fname )
|
||||
if (_wcsicmp(pRadio->name,value.bstrVal)==0)
|
||||
{
|
||||
pSetting->value=CComVariant(val);
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (pSetting->value==pSetting->defValue)
|
||||
pSetting->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -839,7 +851,7 @@ CString CSettingsManager::LoadSettingsXml( const wchar_t *fname )
|
||||
CComPtr<IXMLDOMNode> next;
|
||||
if (child->get_nextSibling(&next)!=S_OK)
|
||||
break;
|
||||
child=next;
|
||||
child=std::move(next);
|
||||
}
|
||||
if (ver<0x03090000)
|
||||
UpgradeSettings(false);
|
||||
@@ -1701,6 +1713,7 @@ LRESULT CSettingsDlg::OnBackup( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL&
|
||||
ofn.Flags=OFN_DONTADDTORECENT|OFN_ENABLESIZING|OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_NOCHANGEDIR;
|
||||
if (GetOpenFileName(&ofn))
|
||||
{
|
||||
SetCurTab(m_Index,true); // reload tab once to force-close any active edit boxes
|
||||
CString error=g_SettingsManager.LoadSettingsXml(path);
|
||||
if (!error.IsEmpty())
|
||||
{
|
||||
@@ -1710,7 +1723,7 @@ LRESULT CSettingsDlg::OnBackup( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL&
|
||||
::MessageBox(m_hWnd,text,LoadStringEx(IDS_ERROR_TITLE),MB_OK|MB_ICONERROR);
|
||||
}
|
||||
SetSettingsDirty();
|
||||
SetCurTab(m_Index,true);
|
||||
SetCurTab(m_Index,true); // reload tab again to show the new settings
|
||||
}
|
||||
}
|
||||
if (res==3)
|
||||
@@ -1810,7 +1823,7 @@ LRESULT CSettingsDlg::OnHelp( int idCtrl, LPNMHDR pnmh, BOOL& bHandled )
|
||||
|
||||
LRESULT CSettingsDlg::OnWeb( int idCtrl, LPNMHDR pnmh, BOOL& bHandled )
|
||||
{
|
||||
ShellExecute(m_hWnd,NULL,L"http://www.classicshell.net",NULL,NULL,SW_SHOWNORMAL);
|
||||
ShellExecute(m_hWnd,NULL,L"https://open-shell.github.io/Open-Shell-Menu",NULL,NULL,SW_SHOWNORMAL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2208,7 +2221,7 @@ bool GetSettingBool( const CSetting &setting )
|
||||
|
||||
CString GetSettingString( const CSetting &setting )
|
||||
{
|
||||
Assert(setting.type==CSetting::TYPE_STRING);
|
||||
Assert(setting.type==CSetting::TYPE_STRING || setting.type==CSetting::TYPE_DIRECTORY);
|
||||
if (setting.value.vt!=VT_BSTR)
|
||||
return CString();
|
||||
return setting.value.bstrVal;
|
||||
@@ -2709,7 +2722,7 @@ bool SaveAdmx( TSettingsComponent component, const char *admxFile, const char *a
|
||||
{
|
||||
fprintf_s(fAdmx,"\t\t\t\t<decimal id=\"Value\" valueName=\"%S\"/>\r\n",pSetting->name);
|
||||
}
|
||||
else if (pSetting->type==CSetting::TYPE_STRING || pSetting->type==CSetting::TYPE_ICON || pSetting->type==CSetting::TYPE_BITMAP || pSetting->type==CSetting::TYPE_BITMAP_JPG || pSetting->type==CSetting::TYPE_SOUND || pSetting->type==CSetting::TYPE_FONT)
|
||||
else if (pSetting->type==CSetting::TYPE_STRING || pSetting->type==CSetting::TYPE_ICON || pSetting->type==CSetting::TYPE_BITMAP || pSetting->type==CSetting::TYPE_BITMAP_JPG || pSetting->type==CSetting::TYPE_SOUND || pSetting->type==CSetting::TYPE_FONT || pSetting->type==CSetting::TYPE_DIRECTORY)
|
||||
{
|
||||
fprintf_s(fAdmx,"\t\t\t\t<text id=\"Value\" valueName=\"%S\"/>\r\n",pSetting->name);
|
||||
}
|
||||
@@ -2769,7 +2782,7 @@ bool SaveAdmx( TSettingsComponent component, const char *admxFile, const char *a
|
||||
{
|
||||
fprintf_s(fAdml,"\t\t\t\t<decimalTextBox refId=\"Value\" spin=\"false\">%s</decimalTextBox>\r\n",(const char*)name);
|
||||
}
|
||||
else if (pSetting->type==CSetting::TYPE_STRING || pSetting->type==CSetting::TYPE_ICON || pSetting->type==CSetting::TYPE_BITMAP || pSetting->type==CSetting::TYPE_BITMAP_JPG || pSetting->type==CSetting::TYPE_SOUND || pSetting->type==CSetting::TYPE_FONT)
|
||||
else if (pSetting->type==CSetting::TYPE_STRING || pSetting->type==CSetting::TYPE_ICON || pSetting->type==CSetting::TYPE_BITMAP || pSetting->type==CSetting::TYPE_BITMAP_JPG || pSetting->type==CSetting::TYPE_SOUND || pSetting->type==CSetting::TYPE_FONT || pSetting->type==CSetting::TYPE_DIRECTORY)
|
||||
{
|
||||
fprintf_s(fAdml,"\t\t\t\t<textBox refId=\"Value\"><label>%s</label></textBox>\r\n",(const char*)name);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ struct CSetting
|
||||
TYPE_SOUND,
|
||||
TYPE_FONT,
|
||||
TYPE_MULTISTRING,
|
||||
TYPE_DIRECTORY,
|
||||
};
|
||||
|
||||
enum
|
||||
|
||||
@@ -1156,7 +1156,7 @@ HRESULT STDMETHODCALLTYPE CBrowseLinkEvents::OnButtonClicked( IFileDialogCustomi
|
||||
{
|
||||
pfd->GetFolder(&pItem);
|
||||
}
|
||||
m_pResult=pItem;
|
||||
m_pResult=std::move(pItem);
|
||||
pfd->Close(S_FALSE);
|
||||
return S_OK;
|
||||
}
|
||||
@@ -1216,7 +1216,7 @@ bool BrowseCommandHelper( HWND parent, wchar_t *text )
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BrowseLinkHelper( HWND parent, wchar_t *text )
|
||||
bool BrowseLinkHelper( HWND parent, wchar_t *text, bool bFoldersOnly )
|
||||
{
|
||||
DoEnvironmentSubst(text,_MAX_PATH);
|
||||
|
||||
@@ -1227,16 +1227,22 @@ bool BrowseLinkHelper( HWND parent, wchar_t *text )
|
||||
if (!pCustomize)
|
||||
return false;
|
||||
|
||||
pDialog->SetTitle(LoadStringEx(IDS_PICK_LINK_TITLE));
|
||||
pDialog->SetOkButtonLabel(LoadStringEx(IDS_PICK_LINK_FILE));
|
||||
wchar_t button[256];
|
||||
Sprintf(button,_countof(button),L" %s ",LoadStringEx(IDS_PICK_LINK_FOLDER));
|
||||
pCustomize->AddPushButton(101,button);
|
||||
pDialog->SetTitle(LoadStringEx(bFoldersOnly?IDS_PICK_LINK_FOLDER:IDS_PICK_LINK_TITLE));
|
||||
if (!bFoldersOnly) // add separate buttons for selecting files/folders to the dialog
|
||||
{
|
||||
pDialog->SetOkButtonLabel(LoadStringEx(IDS_PICK_LINK_FILE));
|
||||
wchar_t button[256];
|
||||
Sprintf(button,_countof(button),L" %s ",LoadStringEx(IDS_PICK_LINK_FOLDER));
|
||||
pCustomize->AddPushButton(101,button);
|
||||
}
|
||||
|
||||
CBrowseLinkEvents events;
|
||||
DWORD cookie;
|
||||
pDialog->Advise(&events,&cookie);
|
||||
pDialog->SetOptions(FOS_ALLNONSTORAGEITEMS|FOS_FILEMUSTEXIST|FOS_DONTADDTORECENT|FOS_DEFAULTNOMINIMODE|FOS_NODEREFERENCELINKS);
|
||||
if (bFoldersOnly) // set FOS_PICKFOLDERS option to use dialog in folder-only mode
|
||||
pDialog->SetOptions(FOS_PICKFOLDERS|FOS_ALLNONSTORAGEITEMS|FOS_DONTADDTORECENT|FOS_DEFAULTNOMINIMODE);
|
||||
else
|
||||
pDialog->SetOptions(FOS_ALLNONSTORAGEITEMS|FOS_FILEMUSTEXIST|FOS_DONTADDTORECENT|FOS_DEFAULTNOMINIMODE|FOS_NODEREFERENCELINKS);
|
||||
{
|
||||
const wchar_t *c=wcschr(text,'|');
|
||||
if (c)
|
||||
@@ -1822,7 +1828,10 @@ void CCustomTreeDlg::SerializeData( void )
|
||||
if ((m_pSetting->flags&CSetting::FLAG_DEFAULT) || wcscmp(strNew,strOld)!=0)
|
||||
SetSettingsDirty();
|
||||
m_pSetting->value=CComVariant(strNew);
|
||||
m_pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (m_pSetting->value==m_pSetting->defValue)
|
||||
m_pSetting->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
m_pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
ItemsChanged();
|
||||
}
|
||||
|
||||
@@ -2271,6 +2280,7 @@ public:
|
||||
EDIT_HOTKEY_ANY,
|
||||
EDIT_COLOR,
|
||||
EDIT_FONT,
|
||||
EDIT_DIRECTORY,
|
||||
};
|
||||
|
||||
BEGIN_MSG_MAP( CTreeSettingsDlg )
|
||||
@@ -2714,6 +2724,29 @@ LRESULT CTreeSettingsDlg::OnBrowse( WORD wNotifyCode, WORD wID, HWND hWndCtl, BO
|
||||
m_EditBox.SetFocus();
|
||||
m_bIgnoreFocus=false;
|
||||
}
|
||||
else if (m_EditMode==EDIT_DIRECTORY)
|
||||
{
|
||||
m_bIgnoreFocus=true;
|
||||
CString str;
|
||||
m_EditBox.GetWindowText(str);
|
||||
str.TrimLeft(); str.TrimRight();
|
||||
wchar_t text[1024];
|
||||
DWORD dwAttrs=GetFileAttributes(str); // ensure directory exists before passing it to dialog
|
||||
if (dwAttrs!=INVALID_FILE_ATTRIBUTES && dwAttrs&FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
Strcpy(text,_countof(text),str);
|
||||
DoEnvironmentSubst(text,_countof(text));
|
||||
}
|
||||
else
|
||||
text[0]=0;
|
||||
Strcpy(text,_countof(text),str);
|
||||
DoEnvironmentSubst(text,_countof(text));
|
||||
if (BrowseLinkHelper(m_hWnd,text,true))
|
||||
m_EditBox.SetWindowText(text);
|
||||
SendMessage(WM_NEXTDLGCTL,(LPARAM)m_EditBox.m_hWnd,TRUE);
|
||||
m_EditBox.SetFocus();
|
||||
m_bIgnoreFocus=false;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2778,7 +2811,10 @@ void CTreeSettingsDlg::ToggleItem( HTREEITEM hItem, bool bDefault )
|
||||
{
|
||||
CSettingsLockWrite lock;
|
||||
pSetting->value=CComVariant(state?0:1);
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (pSetting->value==pSetting->defValue)
|
||||
pSetting->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
SetSettingsDirty();
|
||||
}
|
||||
if (pSetting->flags&CSetting::FLAG_CALLBACK)
|
||||
@@ -2802,7 +2838,10 @@ void CTreeSettingsDlg::ToggleItem( HTREEITEM hItem, bool bDefault )
|
||||
{
|
||||
CSettingsLockWrite lock;
|
||||
pTarget->value=CComVariant(val);
|
||||
pTarget->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (pTarget->value==pTarget->defValue)
|
||||
pTarget->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pTarget->flags&=~CSetting::FLAG_DEFAULT;
|
||||
SetSettingsDirty();
|
||||
}
|
||||
if (pParent->flags&CSetting::FLAG_CALLBACK)
|
||||
@@ -3013,7 +3052,10 @@ void CTreeSettingsDlg::ApplyEditBox( void )
|
||||
if (pSetting->value.vt!=VT_I4 || pSetting->value.intVal!=val)
|
||||
{
|
||||
pSetting->value=CComVariant(val);
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (pSetting->value==pSetting->defValue)
|
||||
pSetting->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
}
|
||||
}
|
||||
else if (pSetting->type==CSetting::TYPE_COLOR)
|
||||
@@ -3023,7 +3065,10 @@ void CTreeSettingsDlg::ApplyEditBox( void )
|
||||
if (pSetting->value.vt!=VT_I4 || pSetting->value.intVal!=val)
|
||||
{
|
||||
pSetting->value=CComVariant(val);
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (pSetting->value==pSetting->defValue)
|
||||
pSetting->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
}
|
||||
}
|
||||
else if (pSetting->type==CSetting::TYPE_HOTKEY || pSetting->type==CSetting::TYPE_HOTKEY_ANY)
|
||||
@@ -3031,7 +3076,24 @@ void CTreeSettingsDlg::ApplyEditBox( void )
|
||||
if (pSetting->value.vt!=VT_I4 || pSetting->value.intVal!=g_HotKey)
|
||||
{
|
||||
pSetting->value=CComVariant(g_HotKey);
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (pSetting->value==pSetting->defValue)
|
||||
pSetting->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
}
|
||||
}
|
||||
else if (pSetting->type==CSetting::TYPE_DIRECTORY)
|
||||
{
|
||||
if (pSetting->value.vt!=VT_BSTR || str!=pSetting->value.bstrVal)
|
||||
{
|
||||
if (str.IsEmpty()) // empty directory strings cause unexpected behavior, so we reset to avoid this
|
||||
pSetting->value=pSetting->defValue;
|
||||
else // otherwise we are very lenient about what users can input as a path
|
||||
pSetting->value=CComVariant(str);
|
||||
if (pSetting->value==pSetting->defValue)
|
||||
pSetting->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -3039,7 +3101,10 @@ void CTreeSettingsDlg::ApplyEditBox( void )
|
||||
if (pSetting->value.vt!=VT_BSTR || str!=pSetting->value.bstrVal)
|
||||
{
|
||||
pSetting->value=CComVariant(str);
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (pSetting->value==pSetting->defValue)
|
||||
pSetting->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
}
|
||||
}
|
||||
SetSettingsDirty();
|
||||
@@ -3074,7 +3139,7 @@ void CTreeSettingsDlg::ItemSelected( HTREEITEM hItem, CSetting *pSetting, bool b
|
||||
val=valVar.intVal;
|
||||
Sprintf(text,_countof(text),L"%d",val);
|
||||
}
|
||||
else if (pSetting->type==CSetting::TYPE_STRING || pSetting->type==CSetting::TYPE_ICON || pSetting->type==CSetting::TYPE_BITMAP || pSetting->type==CSetting::TYPE_BITMAP_JPG || pSetting->type==CSetting::TYPE_SOUND || pSetting->type==CSetting::TYPE_FONT)
|
||||
else if (pSetting->type==CSetting::TYPE_STRING || pSetting->type==CSetting::TYPE_ICON || pSetting->type==CSetting::TYPE_BITMAP || pSetting->type==CSetting::TYPE_BITMAP_JPG || pSetting->type==CSetting::TYPE_SOUND || pSetting->type==CSetting::TYPE_FONT || pSetting->type==CSetting::TYPE_DIRECTORY)
|
||||
{
|
||||
if (valVar.vt==VT_BSTR)
|
||||
Strcpy(text,_countof(text),valVar.bstrVal);
|
||||
@@ -3090,8 +3155,10 @@ void CTreeSettingsDlg::ItemSelected( HTREEITEM hItem, CSetting *pSetting, bool b
|
||||
mode=EDIT_BITMAP_JPG;
|
||||
else if (pSetting->type==CSetting::TYPE_SOUND)
|
||||
mode=EDIT_SOUND;
|
||||
else
|
||||
else if (pSetting->type==CSetting::TYPE_FONT)
|
||||
mode=EDIT_FONT;
|
||||
else
|
||||
mode=EDIT_DIRECTORY;
|
||||
}
|
||||
else if (pSetting->type==CSetting::TYPE_HOTKEY || pSetting->type==CSetting::TYPE_HOTKEY_ANY)
|
||||
{
|
||||
@@ -3131,7 +3198,7 @@ void CTreeSettingsDlg::ItemSelected( HTREEITEM hItem, CSetting *pSetting, bool b
|
||||
m_pEditSetting=pSetting;
|
||||
}
|
||||
|
||||
if (mode==EDIT_ICON || mode==EDIT_BITMAP || mode==EDIT_BITMAP_JPG || mode==EDIT_SOUND || mode==EDIT_FONT || mode==EDIT_COLOR)
|
||||
if (mode==EDIT_ICON || mode==EDIT_BITMAP || mode==EDIT_BITMAP_JPG || mode==EDIT_SOUND || mode==EDIT_FONT || mode==EDIT_COLOR || mode==EDIT_DIRECTORY)
|
||||
{
|
||||
RECT rc2=rc;
|
||||
int width=(rc2.bottom-rc2.top)*3/2;
|
||||
@@ -3189,14 +3256,15 @@ void CTreeSettingsDlg::UpdateEditPosition( void )
|
||||
DeleteDC(hdc);
|
||||
DWORD margins=(DWORD)m_EditBox.SendMessage(EM_GETMARGINS);
|
||||
size.cx+=HIWORD(margins)+LOWORD(margins)+12;
|
||||
if (m_EditMode==EDIT_ICON || m_EditMode==EDIT_BITMAP || m_EditMode==EDIT_BITMAP_JPG || m_EditMode==EDIT_FONT || m_EditMode==EDIT_COLOR)
|
||||
// adjust size and position of edit boxes for settings that use browse/play buttons
|
||||
if (m_EditMode==EDIT_ICON || m_EditMode==EDIT_BITMAP || m_EditMode==EDIT_BITMAP_JPG || m_EditMode==EDIT_FONT || m_EditMode==EDIT_COLOR || m_EditMode==EDIT_DIRECTORY)
|
||||
size.cx+=width;
|
||||
if (m_EditMode==EDIT_SOUND)
|
||||
size.cx+=width*2;
|
||||
if (size.cx<w)
|
||||
rc.right=rc.left+size.cx;
|
||||
|
||||
if (m_EditMode==EDIT_ICON || m_EditMode==EDIT_BITMAP || m_EditMode==EDIT_BITMAP_JPG || m_EditMode==EDIT_SOUND || m_EditMode==EDIT_FONT || m_EditMode==EDIT_COLOR)
|
||||
if (m_EditMode==EDIT_ICON || m_EditMode==EDIT_BITMAP || m_EditMode==EDIT_BITMAP_JPG || m_EditMode==EDIT_SOUND || m_EditMode==EDIT_FONT || m_EditMode==EDIT_COLOR || m_EditMode==EDIT_DIRECTORY)
|
||||
{
|
||||
RECT rc2=rc;
|
||||
rc2.left=rc2.right-width;
|
||||
@@ -3376,6 +3444,9 @@ void CTreeSettingsDlg::UpdateGroup( const CSetting *pModified )
|
||||
bool bDefault=pSetting->IsDefault();
|
||||
const CComVariant &valVar=pSetting->GetValue();
|
||||
|
||||
// check if modified items should be bold
|
||||
bool bBoldSettings=GetSettingBool(L"BoldSettings");
|
||||
|
||||
// calculate text
|
||||
if (pSetting!=m_pEditSetting)
|
||||
{
|
||||
@@ -3458,7 +3529,7 @@ void CTreeSettingsDlg::UpdateGroup( const CSetting *pModified )
|
||||
DeleteDC(hdc);
|
||||
DeleteDC(hdcMask);
|
||||
}
|
||||
int state=bDefault?0:TVIS_BOLD;
|
||||
int state=bDefault||!bBoldSettings?0:TVIS_BOLD; // check if item should be highlighted in bold
|
||||
if (!bEnabled)
|
||||
{
|
||||
if (pSetting->type!=CSetting::TYPE_COLOR) image|=SETTING_STATE_DISABLED;
|
||||
|
||||
@@ -385,5 +385,5 @@ const wchar_t *GetSettingsRegPath( void );
|
||||
extern const GUID FOLDERID_DesktopRoot;
|
||||
|
||||
bool BrowseCommandHelper( HWND parent, wchar_t *text );
|
||||
bool BrowseLinkHelper( HWND parent, wchar_t *text );
|
||||
bool BrowseLinkHelper( HWND parent, wchar_t *text, bool bFoldersOnly );
|
||||
bool BrowseIconHelper( HWND parent, wchar_t *text );
|
||||
|
||||
25447
Src/Lib/json.hpp
Normal 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
|
||||
|
||||
@@ -3,9 +3,7 @@ REM ***** Collect PDBs
|
||||
echo -- Creating symbols package
|
||||
set CS_SYMBOLS_NAME=OpenShellPDB_%CS_VERSION_STR%.7z
|
||||
|
||||
cd Output
|
||||
7z a -mx9 ..\Final\%CS_SYMBOLS_NAME% PDB32 PDB64 > nul
|
||||
cd ..
|
||||
7z a -mx9 .\Final\%CS_SYMBOLS_NAME% .\Output\symbols\* > nul
|
||||
|
||||
if defined APPVEYOR (
|
||||
appveyor PushArtifact Final\%CS_SYMBOLS_NAME%
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
if exist Output rd /Q /S Output
|
||||
md Output
|
||||
md Output\x64
|
||||
md Output\PDB32
|
||||
md Output\PDB64
|
||||
|
||||
echo -- Compiling
|
||||
|
||||
@@ -40,6 +38,7 @@ 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
|
||||
|
||||
@@ -67,6 +66,8 @@ copy /B "..\StartMenu\Skins\Metallic.skin7" Output > nul
|
||||
|
||||
|
||||
REM ********* Collect debug info
|
||||
md Output\PDB32
|
||||
md Output\PDB64
|
||||
|
||||
REM Explorer 32
|
||||
copy /B ..\ClassicExplorer\Setup\ClassicExplorer32.pdb Output\PDB32 > nul
|
||||
@@ -99,6 +100,8 @@ copy /B ..\StartMenu\StartMenuHelper\Setup\StartMenuHelper32.pdb Output\PDB32 >
|
||||
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
|
||||
@@ -126,6 +129,18 @@ if exist %PDBSTR_PATH% (
|
||||
)
|
||||
)
|
||||
|
||||
REM ********* Prepare symbols
|
||||
|
||||
set SYMSTORE_PATH="C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\symstore.exe"
|
||||
|
||||
%SYMSTORE_PATH% add /r /f Output\PDB32 /s Output\symbols /t OpenShell -:NOREFS > nul
|
||||
%SYMSTORE_PATH% add /r /f Output\PDB64 /s Output\symbols /t OpenShell -:NOREFS > nul
|
||||
rd /Q /S Output\symbols\000Admin > nul
|
||||
del Output\symbols\pingme.txt > nul
|
||||
|
||||
rd /Q /S Output\PDB32
|
||||
rd /Q /S Output\PDB64
|
||||
|
||||
REM ********* Build ADMX
|
||||
echo --- ADMX
|
||||
if exist Output\PolicyDefinitions.zip (
|
||||
|
||||
@@ -55,7 +55,6 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
|
||||
@@ -105,7 +105,9 @@
|
||||
</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>
|
||||
@@ -388,8 +390,8 @@
|
||||
<Control Type="Icon" Id="Icon1" Width="12" Height="12" X="7" Y="203" Hidden="yes" Text="web.ico">
|
||||
<Condition Action="show">NOT Installed</Condition>
|
||||
</Control>
|
||||
<Control Type="Hyperlink" Id="Link1" Width="131" Height="10" X="22" Y="204" Hidden="yes" ToolTip="https://github.com/Open-Shell/Open-Shell-Menu">
|
||||
<Text><![CDATA[<a href="https://github.com/Open-Shell/Open-Shell-Menu">!(loc.WebLink)</a>]]></Text>
|
||||
<Control Type="Hyperlink" Id="Link1" Width="131" Height="10" X="22" Y="204" Hidden="yes" ToolTip="https://open-shell.github.io/Open-Shell-Menu">
|
||||
<Text><![CDATA[<a href="https://open-shell.github.io/Open-Shell-Menu">!(loc.WebLink)</a>]]></Text>
|
||||
<Condition Action="show">NOT Installed</Condition>
|
||||
</Control>
|
||||
</Dialog>
|
||||
@@ -476,6 +478,9 @@
|
||||
<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>
|
||||
@@ -551,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=""[APPLICATIONFOLDER]Update.exe" -ToastActivated" Type="string" />
|
||||
</RegistryKey>
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
<DirectoryRef Id="StartMenuDir">
|
||||
<Component Id="HelpLink" Guid="D631C351-7BD4-42CE-813C-5D46347068AF">
|
||||
@@ -564,7 +574,11 @@
|
||||
<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" />
|
||||
<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>
|
||||
@@ -607,9 +621,9 @@
|
||||
<Property Id="ApplicationFolderName" Value="Open-Shell" />
|
||||
<Property Id="WixAppFolder" Value="WixPerMachineFolder" />
|
||||
<Property Id="ALLUSERS" Value="1" />
|
||||
<Property Id="ARPHELPLINK" Value="http://www.classicshell.net/forum/" />
|
||||
<Property Id="ARPHELPLINK" Value="https://github.com/Open-Shell/Open-Shell-Menu/issues" />
|
||||
<Property Id="ARPSIZE" Value="9000" />
|
||||
<Property Id="ARPURLINFOABOUT" Value="http://www.classicshell.net/" />
|
||||
<Property Id="ARPURLINFOABOUT" Value="https://open-shell.github.io/Open-Shell-Menu" />
|
||||
<Property Id="ARPNOMODIFY" Value="1" />
|
||||
<Property Id="ARPNOREPAIR" Value="1" />
|
||||
<Property Id="START_MENU_FOLDER" Value="1" />
|
||||
|
||||
@@ -53,7 +53,6 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
|
||||
@@ -453,6 +453,32 @@ static void SaveReportFile( void )
|
||||
}
|
||||
}
|
||||
|
||||
static void RemoveShellExtKey(const wchar_t* progID)
|
||||
{
|
||||
static const auto ShellExtName = L"StartMenuExt";
|
||||
auto contextMenuHandlers = std::wstring(progID) + L"\\ShellEx\\ContextMenuHandlers";
|
||||
auto startMenuExt = contextMenuHandlers + L"\\" + ShellExtName;
|
||||
|
||||
HKEY hkey = NULL;
|
||||
if (RegOpenKeyEx(HKEY_CLASSES_ROOT, startMenuExt.c_str(), 0, KEY_READ | KEY_WOW64_64KEY, &hkey) == ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey(hkey);
|
||||
LogMessage(-1, L"Deleting registry key HKEY_CLASSES_ROOT\\%s", startMenuExt.c_str());
|
||||
auto error = RegCreateKeyEx(HKEY_CLASSES_ROOT, contextMenuHandlers.c_str(), NULL, NULL, REG_OPTION_BACKUP_RESTORE, KEY_WRITE | DELETE | KEY_WOW64_64KEY, NULL, &hkey, NULL);
|
||||
if (error == ERROR_SUCCESS)
|
||||
{
|
||||
error = RegDeleteTree2(hkey, ShellExtName);
|
||||
if (error != ERROR_SUCCESS && error != ERROR_FILE_NOT_FOUND)
|
||||
LogMessage(error, L"Failed to delete registry key HKEY_CLASSES_ROOT\\%s.", startMenuExt.c_str());
|
||||
RegCloseKey(hkey);
|
||||
}
|
||||
else if (error != ERROR_FILE_NOT_FOUND)
|
||||
{
|
||||
LogMessage(error, L"Failed to open registry key HKEY_CLASSES_ROOT\\%s for writing.", contextMenuHandlers.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool RemoveRegistryKeys( bool bPin )
|
||||
{
|
||||
HKEY hkey=NULL;
|
||||
@@ -489,40 +515,11 @@ static bool RemoveRegistryKeys( bool bPin )
|
||||
}
|
||||
}
|
||||
|
||||
hkey=NULL;
|
||||
if (bPin)
|
||||
{
|
||||
if (RegOpenKeyEx(HKEY_CLASSES_ROOT,L"Launcher.ImmersiveApplication\\ShellEx\\ContextMenuHandlers\\StartMenuExt",0,KEY_READ|KEY_WOW64_64KEY,&hkey)==ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey(hkey);
|
||||
LogMessage(-1,L"Deleting registry key HKEY_CLASSES_ROOT\\Launcher.ImmersiveApplication\\ShellEx\\ContextMenuHandlers\\StartMenuExt");
|
||||
error=RegCreateKeyEx(HKEY_CLASSES_ROOT,L"Launcher.ImmersiveApplication\\ShellEx\\ContextMenuHandlers",NULL,NULL,REG_OPTION_BACKUP_RESTORE,KEY_WRITE|DELETE|KEY_WOW64_64KEY,NULL,&hkey,NULL);
|
||||
if (error==ERROR_SUCCESS)
|
||||
{
|
||||
error=RegDeleteTree2(hkey,L"StartMenuExt");
|
||||
if (error!=ERROR_SUCCESS && error!=ERROR_FILE_NOT_FOUND)
|
||||
LogMessage(error,L"Failed to delete registry key HKEY_CLASSES_ROOT\\Launcher.ImmersiveApplication\\ShellEx\\ContextMenuHandlers\\StartMenuExt.");
|
||||
RegCloseKey(hkey);
|
||||
}
|
||||
else if (error!=ERROR_FILE_NOT_FOUND)
|
||||
LogMessage(error,L"Failed to open registry key HKEY_CLASSES_ROOT\\Launcher.ImmersiveApplication\\ShellEx\\ContextMenuHandlers for writing.");
|
||||
}
|
||||
|
||||
if (RegOpenKeyEx(HKEY_CLASSES_ROOT,L"Launcher.SystemSettings\\ShellEx\\ContextMenuHandlers\\StartMenuExt",0,KEY_READ|KEY_WOW64_64KEY,&hkey)==ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey(hkey);
|
||||
LogMessage(-1,L"Deleting registry key HKEY_CLASSES_ROOT\\Launcher.SystemSettings\\ShellEx\\ContextMenuHandlers\\StartMenuExt");
|
||||
error=RegCreateKeyEx(HKEY_CLASSES_ROOT,L"Launcher.SystemSettings\\ShellEx\\ContextMenuHandlers",NULL,NULL,REG_OPTION_BACKUP_RESTORE,KEY_WRITE|DELETE|KEY_WOW64_64KEY,NULL,&hkey,NULL);
|
||||
if (error==ERROR_SUCCESS)
|
||||
{
|
||||
error=RegDeleteTree2(hkey,L"StartMenuExt");
|
||||
if (error!=ERROR_SUCCESS && error!=ERROR_FILE_NOT_FOUND)
|
||||
LogMessage(error,L"Failed to delete registry key HKEY_CLASSES_ROOT\\Launcher.SystemSettings\\ShellEx\\ContextMenuHandlers\\StartMenuExt.");
|
||||
RegCloseKey(hkey);
|
||||
}
|
||||
else if (error!=ERROR_FILE_NOT_FOUND)
|
||||
LogMessage(error,L"Failed to open registry key HKEY_CLASSES_ROOT\\Launcher.SystemSettings\\ShellEx\\ContextMenuHandlers for writing.");
|
||||
}
|
||||
RemoveShellExtKey(L"Launcher.ImmersiveApplication");
|
||||
RemoveShellExtKey(L"Launcher.DesktopPackagedApplication");
|
||||
RemoveShellExtKey(L"Launcher.SystemSettings");
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -943,7 +943,7 @@ static BOOL CALLBACK EnumResLangProc( HMODULE hModule, LPCTSTR lpszType, LPCTSTR
|
||||
if (IS_INTRESOURCE(lpszName))
|
||||
{
|
||||
std::vector<std::pair<int,WORD>> &oldStrings=*(std::vector<std::pair<int,WORD>>*)lParam;
|
||||
oldStrings.push_back(std::pair<int,WORD>(PtrToInt(lpszName),wIDLanguage));
|
||||
oldStrings.emplace_back(PtrToInt(lpszName),wIDLanguage);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -92,7 +92,6 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
@@ -112,7 +111,6 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
|
||||
@@ -7,7 +7,7 @@ rem Clean repository and build fresh. Will erase current changes so disabled by
|
||||
rem git clean -dfx
|
||||
|
||||
rem Default version
|
||||
set CS_VERSION=4.4.110
|
||||
set CS_VERSION=4.4.1000
|
||||
|
||||
if defined APPVEYOR_BUILD_VERSION (
|
||||
set CS_VERSION=%APPVEYOR_BUILD_VERSION%
|
||||
|
||||
@@ -9,7 +9,7 @@ rem Clean repository and build fresh. Will erase current changes so disabled by
|
||||
rem git clean -dfx
|
||||
|
||||
rem Default version
|
||||
set CS_VERSION=4.3.2
|
||||
set CS_VERSION=4.4.1000
|
||||
|
||||
if defined APPVEYOR_BUILD_VERSION (
|
||||
set CS_VERSION=%APPVEYOR_BUILD_VERSION%
|
||||
|
||||
@@ -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%
|
||||
|
||||
|
||||
@@ -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%
|
||||
|
||||
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
@@ -136,7 +136,6 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
@@ -159,7 +158,6 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
|
||||
@@ -16,9 +16,7 @@ CMenuAccessible::CMenuAccessible( CMenuContainer *pOwner )
|
||||
CreateStdAccessibleObject(pOwner->m_hWnd,OBJID_CLIENT,IID_IAccessible,(void**)&m_pStdAccessible);
|
||||
}
|
||||
|
||||
CMenuAccessible::~CMenuAccessible( void )
|
||||
{
|
||||
}
|
||||
CMenuAccessible::~CMenuAccessible( void ) = default;
|
||||
|
||||
void CMenuAccessible::Reset( void )
|
||||
{
|
||||
@@ -182,7 +180,7 @@ HRESULT STDMETHODCALLTYPE CMenuAccessible::accSelect( long flagsSelect, VARIANT
|
||||
int index=varChild.lVal-1;
|
||||
if (index<0 || index>=(int)m_pOwner->m_Items.size())
|
||||
return S_FALSE;
|
||||
m_pOwner->ActivateItem(index,CMenuContainer::ACTIVATE_SELECT,NULL,false);
|
||||
m_pOwner->ActivateItem(index,CMenuContainer::ACTIVATE_SELECT,NULL);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -95,13 +95,13 @@ CStdCommand7 g_StdCommands7[]={
|
||||
{L"user_videos",0,NULL,L"$Menu.UserVideosTip",NULL,&FOLDERID_Videos},
|
||||
{L"control_panel",0,L"$Menu.ControlPanel",L"$Menu.ControlPanelTip",NULL,&FOLDERID_ControlPanelFolder,NULL,StdMenuItem::MENU_TRACK},
|
||||
{L"pc_settings",IDS_PCSETTINGS,L"$Menu.PCSettings",L"",L"%windir%\\ImmersiveControlPanel\\SystemSettings.exe,10",NULL,NULL,StdMenuItem::MENU_TRACK,CStdCommand7::ITEM_SINGLE},
|
||||
{L"network_connections",0,NULL,L"$Menu.NetworkTip",NULL,&FOLDERID_ConnectionsFolder},
|
||||
{L"network_connections",0,NULL,L"$Menu.NetworkTip",NULL,&FOLDERID_ConnectionsFolder,NULL,0,CStdCommand7::ITEM_NODRIVES},
|
||||
{L"network",0,NULL,NULL,NULL,&FOLDERID_NetworkFolder,NULL,0,CStdCommand7::ITEM_SINGLE},
|
||||
{L"printers",0,NULL,L"$Menu.PrintersTip",NULL,&FOLDERID_PrintersFolder},
|
||||
{L"printers",0,NULL,L"$Menu.PrintersTip",NULL,&FOLDERID_PrintersFolder,NULL,0,CStdCommand7::ITEM_NODRIVES},
|
||||
{L"fonts",0,NULL,NULL,NULL,&FOLDERID_Fonts},
|
||||
{L"desktop",0,NULL,NULL,NULL,&FOLDERID_Desktop},
|
||||
{L"admin",0,NULL,L"$Menu.AdminToolsTip",L"imageres.dll,114",&FOLDERID_CommonAdminTools,NULL,StdMenuItem::MENU_TRACK},
|
||||
{L"startup",0,NULL,NULL,NULL,&FOLDERID_Startup,NULL,StdMenuItem::MENU_TRACK},
|
||||
{L"admin",0,NULL,L"$Menu.AdminToolsTip",L"imageres.dll,114",&FOLDERID_CommonAdminTools,NULL,StdMenuItem::MENU_TRACK,CStdCommand7::ITEM_NODRIVES},
|
||||
{L"startup",0,NULL,NULL,NULL,&FOLDERID_Startup,NULL,StdMenuItem::MENU_TRACK,CStdCommand7::ITEM_NODRIVES},
|
||||
{L"downloads",0,NULL,L"$Menu.DownloadTip",NULL,&FOLDERID_Downloads},
|
||||
{L"games",0,NULL,L"$Menu.GamesTip",NULL,&FOLDERID_Games,NULL,StdMenuItem::MENU_TRACK},
|
||||
{L"links",0,NULL,NULL,NULL,&FOLDERID_Links},
|
||||
@@ -112,7 +112,7 @@ CStdCommand7 g_StdCommands7[]={
|
||||
{L"lib_videos",IDS_LIB_VIDEOS_ITEM,NULL,L"$Menu.VideosLibTip",NULL,&FOLDERID_VideosLibrary},
|
||||
{L"lib_tv",IDS_LIB_TV_ITEM,NULL,L"$Menu.RecordingsLibTip",NULL,&FOLDERID_RecordedTVLibrary},
|
||||
{L"homegroup",0,NULL,L"$Menu.HomegroupTip",NULL,&FOLDERID_HomeGroup,NULL,0,CStdCommand7::ITEM_SINGLE},
|
||||
{L"devices",0,NULL,NULL,NULL,NULL,L"::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{A8A91A66-3A7D-4424-8D24-04E180695C7A}"},
|
||||
{L"devices",0,NULL,NULL,NULL,NULL,L"::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{A8A91A66-3A7D-4424-8D24-04E180695C7A}",0,CStdCommand7::ITEM_NODRIVES},
|
||||
{L"defaults",0,NULL,NULL,NULL,NULL,L"::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{17CD9488-1228-4B2F-88CE-4298E93E0966}",0,CStdCommand7::ITEM_SINGLE},
|
||||
{L"apps",IDS_METRO_APPS,L"$Menu.Apps",NULL,L",2",NULL,NULL,StdMenuItem::MENU_TRACK,CStdCommand7::ITEM_FOLDER},
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ struct CStdCommand7
|
||||
ITEM_SINGLE=1, // this item never has sub-menu
|
||||
ITEM_FOLDER=2, // this item always has sub-menu
|
||||
ITEM_COMPUTER=4, // this item can be expanded only one level
|
||||
ITEM_NODRIVES=8, // this item can never be expanded only one level
|
||||
};
|
||||
const wchar_t *command;
|
||||
int nameID;
|
||||
|
||||
@@ -852,9 +852,14 @@ HRESULT STDMETHODCALLTYPE CMenuContainer::Drop( IDataObject *pDataObj, DWORD grf
|
||||
CComQIPtr<IDataObjectAsyncCapability> pAsync=pDataObj;
|
||||
if (pAsync)
|
||||
pAsync->SetAsyncMode(FALSE);
|
||||
for (std::vector<CMenuContainer*>::iterator it=s_Menus.begin();it!=s_Menus.end();++it)
|
||||
if (!(*it)->m_bDestroyed)
|
||||
(*it)->EnableWindow(FALSE); // disable all menus
|
||||
for (auto& it : s_Menus)
|
||||
{
|
||||
if (!it->m_bDestroyed)
|
||||
{
|
||||
it->EnableWindow(FALSE); // disable all menus
|
||||
it->SetWindowPos(HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
}
|
||||
}
|
||||
bool bAllPrograms=s_bAllPrograms;
|
||||
if (bAllPrograms) ::EnableWindow(g_TopWin7Menu,FALSE);
|
||||
bool bOld=s_bPreventClosing;
|
||||
@@ -862,9 +867,14 @@ HRESULT STDMETHODCALLTYPE CMenuContainer::Drop( IDataObject *pDataObj, DWORD grf
|
||||
AddRef();
|
||||
pTarget->Drop(pDataObj,grfKeyState,pt,pdwEffect);
|
||||
s_bPreventClosing=bOld;
|
||||
for (std::vector<CMenuContainer*>::iterator it=s_Menus.begin();it!=s_Menus.end();++it)
|
||||
if (!(*it)->m_bDestroyed)
|
||||
(*it)->EnableWindow(TRUE); // enable all menus
|
||||
for (auto& it : s_Menus)
|
||||
{
|
||||
if (!it->m_bDestroyed)
|
||||
{
|
||||
it->EnableWindow(TRUE); // enable all menus
|
||||
it->SetWindowPos(HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
}
|
||||
}
|
||||
if (bAllPrograms) ::EnableWindow(g_TopWin7Menu,TRUE);
|
||||
}
|
||||
else
|
||||
@@ -893,7 +903,7 @@ HRESULT STDMETHODCALLTYPE CMenuContainer::Drop( IDataObject *pDataObj, DWORD grf
|
||||
else if (i<before)
|
||||
skip++;
|
||||
}
|
||||
SortMenuItem ins(L"",FNV_HASH0,false,false,folderIndex*2,0);
|
||||
SortMenuItem ins(L"",FNV_HASH0,false,false,false,folderIndex*2,0);
|
||||
items.insert(items.begin()+(before-skip),ins);
|
||||
SaveItemOrder(items);
|
||||
}
|
||||
|
||||
@@ -15,9 +15,7 @@ public:
|
||||
m_RefCount=0;
|
||||
}
|
||||
|
||||
~CDropTargetProxy( void )
|
||||
{
|
||||
}
|
||||
~CDropTargetProxy( void ) = default;
|
||||
|
||||
void Reset( void )
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
@@ -142,10 +142,11 @@ static bool DetectGrayscaleImage( const unsigned int *bits, int stride, int widt
|
||||
for (int x=0;x<width;x++)
|
||||
{
|
||||
unsigned int pixel=bits[x];
|
||||
int a=(pixel>>24)&255;
|
||||
int r=(pixel>>16)&255;
|
||||
int g=(pixel>>8)&255;
|
||||
int b=(pixel)&255;
|
||||
if (abs(r-g)>2 || abs(r-b)>2 || abs(g-b)>2)
|
||||
if (abs(a-r)>2 || abs(r-g)>2 || abs(r-b)>2 || abs(g-b)>2)
|
||||
return false; // found colored pixel
|
||||
if (!(pixel&0xFF000000))
|
||||
transparent++;
|
||||
@@ -175,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;
|
||||
@@ -258,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));
|
||||
@@ -299,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)
|
||||
{
|
||||
@@ -439,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)
|
||||
@@ -577,7 +589,7 @@ void CItemManager::Init( void )
|
||||
|
||||
m_RootGames=L"::{ED228FDF-9EA8-4870-83B1-96B02CFE0D52}\\";
|
||||
wchar_t text[_MAX_PATH];
|
||||
Strcpy(text,_countof(text),START_MENU_PINNED_ROOT L"\\");
|
||||
Sprintf(text,_countof(text),L"%s\\",GetSettingString(L"PinnedItemsPath"));
|
||||
DoEnvironmentSubst(text,_countof(text));
|
||||
m_RootStartMenu3=text;
|
||||
StringUpper(m_RootStartMenu3);
|
||||
@@ -597,7 +609,7 @@ void CItemManager::Init( void )
|
||||
{
|
||||
int width, height;
|
||||
pList->GetIconSize(&width,&height);
|
||||
m_ListSizes.push_back(std::pair<int,int>(width,i));
|
||||
m_ListSizes.emplace_back(width,i);
|
||||
}
|
||||
}
|
||||
std::sort(m_ListSizes.begin(),m_ListSizes.end());
|
||||
@@ -605,7 +617,7 @@ void CItemManager::Init( void )
|
||||
CreateDefaultIcons();
|
||||
LoadCacheFile();
|
||||
|
||||
ItemInfo &item=m_ItemInfos.insert(std::pair<unsigned int,ItemInfo>(0,ItemInfo()))->second;
|
||||
ItemInfo &item=m_ItemInfos.emplace(0,ItemInfo())->second;
|
||||
item.bIconOnly=true;
|
||||
item.smallIcon=m_DefaultSmallIcon;
|
||||
item.largeIcon=m_DefaultLargeIcon;
|
||||
@@ -692,21 +704,21 @@ void CItemManager::CreateDefaultIcons( void )
|
||||
icon.bitmap=BitmapFromIcon(LoadShellIcon(index,SMALL_ICON_SIZE),SMALL_ICON_SIZE);
|
||||
else
|
||||
icon.bitmap=NULL;
|
||||
m_DefaultSmallIcon=&m_IconInfos.insert(std::pair<unsigned int,IconInfo>(0,icon))->second;
|
||||
m_DefaultSmallIcon=&m_IconInfos.emplace(0,icon)->second;
|
||||
|
||||
icon.sizeType=ICON_SIZE_TYPE_LARGE;
|
||||
if (index>=0)
|
||||
icon.bitmap=BitmapFromIcon(LoadShellIcon(index,LARGE_ICON_SIZE),LARGE_ICON_SIZE);
|
||||
else
|
||||
icon.bitmap=NULL;
|
||||
m_DefaultLargeIcon=&m_IconInfos.insert(std::pair<unsigned int,IconInfo>(0,icon))->second;
|
||||
m_DefaultLargeIcon=&m_IconInfos.emplace(0,icon)->second;
|
||||
|
||||
icon.sizeType=ICON_SIZE_TYPE_EXTRA_LARGE;
|
||||
if (index>=0)
|
||||
icon.bitmap=BitmapFromIcon(LoadShellIcon(index,EXTRA_LARGE_ICON_SIZE),EXTRA_LARGE_ICON_SIZE);
|
||||
else
|
||||
icon.bitmap=NULL;
|
||||
m_DefaultExtraLargeIcon=&m_IconInfos.insert(std::pair<unsigned int,IconInfo>(0,icon))->second;
|
||||
m_DefaultExtraLargeIcon=&m_IconInfos.emplace(0,icon)->second;
|
||||
}
|
||||
|
||||
CItemManager::LoadIconData &CItemManager::GetLoadIconData( void )
|
||||
@@ -884,7 +896,7 @@ const CItemManager::ItemInfo *CItemManager::GetItemInfo( IShellItem *pItem, PIDL
|
||||
}
|
||||
if (!pInfo)
|
||||
{
|
||||
pInfo=&m_ItemInfos.insert(std::pair<unsigned int,ItemInfo>(hash,ItemInfo()))->second;
|
||||
pInfo=&m_ItemInfos.emplace(hash,ItemInfo())->second;
|
||||
pInfo->pidl.Clone(pidl);
|
||||
pInfo->path=path;
|
||||
pInfo->PATH=PATH;
|
||||
@@ -966,7 +978,7 @@ const CItemManager::ItemInfo *CItemManager::GetItemInfo( CString path, int refre
|
||||
}
|
||||
if (!pInfo)
|
||||
{
|
||||
pInfo=&m_ItemInfos.insert(std::pair<unsigned int,ItemInfo>(hash,ItemInfo()))->second;
|
||||
pInfo=&m_ItemInfos.emplace(hash,ItemInfo())->second;
|
||||
if (!PATH.IsEmpty())
|
||||
MenuParseDisplayName(path,&pInfo->pidl,NULL,NULL);
|
||||
if (pInfo->pidl)
|
||||
@@ -1064,7 +1076,7 @@ const CItemManager::ItemInfo *CItemManager::GetCustomIcon( const wchar_t *locati
|
||||
}
|
||||
if (!pInfo)
|
||||
{
|
||||
pInfo=&m_ItemInfos.insert(std::pair<unsigned int,ItemInfo>(hash,ItemInfo()))->second;
|
||||
pInfo=&m_ItemInfos.emplace(hash,ItemInfo())->second;
|
||||
pInfo->bIconOnly=true;
|
||||
pInfo->bTemp=bTemp;
|
||||
pInfo->iconPath=location;
|
||||
@@ -1113,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];
|
||||
@@ -1823,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];
|
||||
@@ -1832,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 = std::move(target);
|
||||
pStore = store;
|
||||
}
|
||||
PropVariantClear(&val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1923,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)
|
||||
@@ -2296,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)
|
||||
{
|
||||
@@ -2414,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)))
|
||||
@@ -2431,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)))
|
||||
@@ -2441,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_SMALL_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)))
|
||||
@@ -2524,7 +2597,7 @@ void CItemManager::StoreInCache( unsigned int hash, const wchar_t *path, HBITMAP
|
||||
|
||||
if ((refreshFlags&INFO_SMALL_ICON) && hSmallBitmap)
|
||||
{
|
||||
IconInfo *pInfo=&m_IconInfos.insert(std::pair<unsigned int,IconInfo>(hash,IconInfo()))->second;
|
||||
IconInfo *pInfo=&m_IconInfos.emplace(hash,IconInfo())->second;
|
||||
pInfo->sizeType=ICON_SIZE_TYPE_SMALL;
|
||||
pInfo->bTemp=bTemp;
|
||||
pInfo->bMetro=bMetro;
|
||||
@@ -2534,7 +2607,7 @@ void CItemManager::StoreInCache( unsigned int hash, const wchar_t *path, HBITMAP
|
||||
}
|
||||
if ((refreshFlags&INFO_LARGE_ICON) && hLargeBitmap)
|
||||
{
|
||||
IconInfo *pInfo=&m_IconInfos.insert(std::pair<unsigned int,IconInfo>(hash,IconInfo()))->second;
|
||||
IconInfo *pInfo=&m_IconInfos.emplace(hash,IconInfo())->second;
|
||||
pInfo->sizeType=ICON_SIZE_TYPE_LARGE;
|
||||
pInfo->bTemp=bTemp;
|
||||
pInfo->bMetro=bMetro;
|
||||
@@ -2544,7 +2617,7 @@ void CItemManager::StoreInCache( unsigned int hash, const wchar_t *path, HBITMAP
|
||||
}
|
||||
if ((refreshFlags&INFO_EXTRA_LARGE_ICON) && hExtraLargeBitmap)
|
||||
{
|
||||
IconInfo *pInfo=&m_IconInfos.insert(std::pair<unsigned int,IconInfo>(hash,IconInfo()))->second;
|
||||
IconInfo *pInfo=&m_IconInfos.emplace(hash,IconInfo())->second;
|
||||
pInfo->sizeType=ICON_SIZE_TYPE_EXTRA_LARGE;
|
||||
pInfo->bTemp=bTemp;
|
||||
pInfo->bMetro=bMetro;
|
||||
@@ -2586,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
|
||||
@@ -2798,7 +2867,8 @@ void CItemManager::PreloadItemsThread( void )
|
||||
else if (g_CacheFolders[i].folder==FOLDERID_ClassicPinned)
|
||||
{
|
||||
if (GetSettingInt(L"PinnedPrograms")!=PINNED_PROGRAMS_PINNED) continue;
|
||||
wchar_t path[_MAX_PATH]=START_MENU_PINNED_ROOT;
|
||||
wchar_t path[_MAX_PATH];
|
||||
Strcpy(path,_countof(path),GetSettingString(L"PinnedItemsPath"));
|
||||
DoEnvironmentSubst(path,_countof(path));
|
||||
if (FAILED(SHParseDisplayName(path,NULL,&pidl,0,NULL)) || !pidl) continue;
|
||||
if (FAILED(SHCreateItemFromIDList(pidl,IID_IShellItem,(void**)&pFolder)) || !pFolder) continue;
|
||||
@@ -3204,7 +3274,7 @@ void CItemManager::LoadCacheFile( void )
|
||||
bError=true;
|
||||
break;
|
||||
}
|
||||
remapIcons.push_back(&m_IconInfos.insert(std::pair<unsigned int,IconInfo>(data.key,info))->second);
|
||||
remapIcons.push_back(&m_IconInfos.emplace(data.key,info)->second);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3235,7 +3305,7 @@ void CItemManager::LoadCacheFile( void )
|
||||
bError=true;
|
||||
break;
|
||||
}
|
||||
ItemInfo &info=m_ItemInfos.insert(std::pair<unsigned int,ItemInfo>(data.key,ItemInfo()))->second;
|
||||
ItemInfo &info=m_ItemInfos.emplace(data.key,ItemInfo())->second;
|
||||
|
||||
info.writestamp=data.writestamp;
|
||||
info.createstamp=data.createstamp;
|
||||
@@ -3499,7 +3569,7 @@ void CItemManager::ClearCache( void )
|
||||
m_IconInfos.clear();
|
||||
m_MetroItemInfos10.clear();
|
||||
CreateDefaultIcons();
|
||||
ItemInfo &item=m_ItemInfos.insert(std::pair<unsigned int,ItemInfo>(0,ItemInfo()))->second;
|
||||
ItemInfo &item=m_ItemInfos.emplace(0,ItemInfo())->second;
|
||||
item.bIconOnly=true;
|
||||
item.smallIcon=m_DefaultSmallIcon;
|
||||
item.largeIcon=m_DefaultLargeIcon;
|
||||
|
||||
@@ -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,9 +467,9 @@ 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"
|
||||
#define STARTSCREEN_COMMAND L"startscreen.lnk"
|
||||
#define USERASSIST_LINKS_KEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\UserAssist\\{F4E57C4B-2036-45F0-A9AB-443BCFE33D9F}\\Count"
|
||||
#define USERASSIST_APPIDS_KEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\UserAssist\\{CEBFF5CD-ACE2-4F4F-9178-9926F41749EA}\\Count"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"???");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "Settings.h"
|
||||
#include "SettingsUI.h"
|
||||
#include "SettingsUIHelper.h"
|
||||
#include "FileHelper.h"
|
||||
#include "Translations.h"
|
||||
#include "LogManager.h"
|
||||
#include "FNVHash.h"
|
||||
@@ -402,7 +403,7 @@ void CMenuContainer::OpenSubMenu( int index, TActivateType type, bool bShift )
|
||||
if (m_Options&CONTAINER_NOEXTENSIONS)
|
||||
options|=CONTAINER_NOEXTENSIONS;
|
||||
|
||||
if (item.id==MENU_PROGRAMS || item.id==MENU_APPS || (m_Options&CONTAINER_MULTICOL_REC))
|
||||
if (item.id==MENU_PROGRAMS || item.id==MENU_APPS || item.bFolder || (m_Options&CONTAINER_MULTICOL_REC))
|
||||
options|=CONTAINER_MULTICOL_REC;
|
||||
if ((options&CONTAINER_MULTICOL_REC) && !bShift)
|
||||
options|=CONTAINER_MULTICOLUMN;
|
||||
@@ -2192,11 +2193,15 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p
|
||||
|
||||
if (res==CMD_PINSETTING)
|
||||
{
|
||||
CSearchManager::TItemCategory cat=(CSearchManager::TItemCategory)(item.categoryHash&CSearchManager::CATEGORY_MASK);
|
||||
if (cat==CSearchManager::CATEGORY_SETTING)
|
||||
CreatePinLink(pItemPidl1,item.name,NULL,0);
|
||||
else if (cat==CSearchManager::CATEGORY_METROSETTING)
|
||||
CreatePinLink(pItemPidl1,item.name,L"%windir%\\ImmersiveControlPanel\\systemsettings.exe",0);
|
||||
CString iconPath;
|
||||
if (item.pItemInfo)
|
||||
{
|
||||
CItemManager::RWLock lock(&g_ItemManager, false, CItemManager::RWLOCK_ITEMS);
|
||||
if (_wcsicmp(PathFindExtension(item.pItemInfo->GetPath()), L".settingcontent-ms") == 0)
|
||||
iconPath = L"%windir%\\ImmersiveControlPanel\\systemsettings.exe";
|
||||
}
|
||||
|
||||
CreatePinLink(pItemPidl1, item.name, iconPath.IsEmpty() ? nullptr : iconPath.GetString(), 0);
|
||||
m_bRefreshItems=true;
|
||||
}
|
||||
|
||||
@@ -2778,12 +2783,19 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p
|
||||
info.lpVerb=MAKEINTRESOURCEA(res-verbOffset);
|
||||
info.lpVerbW=MAKEINTRESOURCEW(res-verbOffset);
|
||||
info.nShow=SW_SHOWNORMAL;
|
||||
bool bOpenTruePath=false;
|
||||
wchar_t targetlnkPath[_MAX_PATH]; // path to target.lnk in a fake folder
|
||||
wchar_t dir[_MAX_PATH];
|
||||
if (SHGetPathFromIDList(pItemPidl1,dir))
|
||||
{
|
||||
PathRemoveFileSpec(dir);
|
||||
if (GetFileAttributes(dir)!=INVALID_FILE_ATTRIBUTES)
|
||||
info.lpDirectoryW=dir;
|
||||
if (_stricmp(command,"open")==0 && GetSettingBool(L"OpenTruePath") && GetFakeFolder(targetlnkPath,_countof(targetlnkPath),dir))
|
||||
bOpenTruePath=true;
|
||||
else
|
||||
{
|
||||
PathRemoveFileSpec(dir);
|
||||
if (GetFileAttributes(dir)!=INVALID_FILE_ATTRIBUTES)
|
||||
info.lpDirectoryW=dir;
|
||||
}
|
||||
}
|
||||
if (pPt)
|
||||
{
|
||||
@@ -2800,8 +2812,11 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p
|
||||
info.fMask|=CMIC_MASK_NOASYNC; // wait for delete/link commands to finish so we can refresh the menu
|
||||
|
||||
s_bPreventClosing=true;
|
||||
for (std::vector<CMenuContainer*>::iterator it=s_Menus.begin();it!=s_Menus.end();++it)
|
||||
(*it)->EnableWindow(FALSE); // disable all menus
|
||||
for (auto& it : s_Menus)
|
||||
{
|
||||
it->EnableWindow(FALSE); // disable all menus
|
||||
it->SetWindowPos(HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
}
|
||||
bool bAllPrograms=s_bAllPrograms;
|
||||
if (bAllPrograms) ::EnableWindow(g_TopWin7Menu,FALSE);
|
||||
info.hwnd=g_OwnerWindow;
|
||||
@@ -2811,9 +2826,20 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p
|
||||
::SetForegroundWindow(g_OwnerWindow);
|
||||
::SetWindowPos(g_OwnerWindow,HWND_TOPMOST,rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top,0);
|
||||
LOG_MENU(LOG_EXECUTE,L"Invoke command, ptr=%p, command='%S'",this,command);
|
||||
HRESULT hr=pInvokeMenu->InvokeCommand((LPCMINVOKECOMMANDINFO)&info);
|
||||
LOG_MENU(LOG_EXECUTE,L"Invoke command, ptr=%p, res=%d",this,hr);
|
||||
if (type==ACTIVATE_EXECUTE && SUCCEEDED(hr))
|
||||
bool executeSuccess;
|
||||
if (bOpenTruePath) // we are trying to open a fake folder, directly open target.lnk instead
|
||||
{
|
||||
HINSTANCE hinst=ShellExecute(NULL,NULL,targetlnkPath,NULL,NULL,SW_SHOWNORMAL);
|
||||
LOG_MENU(LOG_EXECUTE,L"Invoke command, ptr=%p, res=%d",this,hinst);
|
||||
executeSuccess=static_cast<int>(reinterpret_cast<uintptr_t>(hinst))>=32;
|
||||
}
|
||||
else
|
||||
{
|
||||
HRESULT hr=pInvokeMenu->InvokeCommand((LPCMINVOKECOMMANDINFO)&info);
|
||||
LOG_MENU(LOG_EXECUTE,L"Invoke command, ptr=%p, res=%d",this,hr);
|
||||
executeSuccess=SUCCEEDED(hr);
|
||||
}
|
||||
if (type==ACTIVATE_EXECUTE && executeSuccess)
|
||||
{
|
||||
if (bTrackRecent)
|
||||
{
|
||||
@@ -2846,9 +2872,14 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p
|
||||
}
|
||||
}
|
||||
}
|
||||
for (std::vector<CMenuContainer*>::iterator it=s_Menus.begin();it!=s_Menus.end();++it)
|
||||
if (!(*it)->m_bDestroyed)
|
||||
(*it)->EnableWindow(TRUE); // enable all menus
|
||||
for (auto& it : s_Menus)
|
||||
{
|
||||
if (!it->m_bDestroyed)
|
||||
{
|
||||
it->EnableWindow(TRUE); // enable all menus
|
||||
it->SetWindowPos(HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
}
|
||||
}
|
||||
if (bAllPrograms) ::EnableWindow(g_TopWin7Menu,TRUE);
|
||||
if (bRefreshMain && m_bSubMenu)
|
||||
{
|
||||
|
||||
@@ -315,6 +315,7 @@ bool CMenuContainer::s_bShowTopEmpty=false;
|
||||
bool CMenuContainer::s_bNoDragDrop=false;
|
||||
bool CMenuContainer::s_bNoContextMenu=false;
|
||||
bool CMenuContainer::s_bExpandLinks=false;
|
||||
bool CMenuContainer::s_bSingleClickFolders=false;
|
||||
bool CMenuContainer::s_bLogicalSort=false;
|
||||
bool CMenuContainer::s_bExtensionSort=false;
|
||||
bool CMenuContainer::s_bAllPrograms=false;
|
||||
@@ -334,6 +335,7 @@ bool CMenuContainer::s_bDragMovable;
|
||||
bool CMenuContainer::s_bRightDrag;
|
||||
bool CMenuContainer::s_bLockWorkArea;
|
||||
bool CMenuContainer::s_bPendingSearchEnter;
|
||||
bool CMenuContainer::s_bMoreResults;
|
||||
std::vector<CMenuContainer*> CMenuContainer::s_Menus;
|
||||
volatile HWND CMenuContainer::s_FirstMenu, CMenuContainer::s_SearchMenu;
|
||||
CSearchManager::SearchResults CMenuContainer::s_SearchResults;
|
||||
@@ -443,7 +445,10 @@ LRESULT CALLBACK CMenuContainer::SubclassSearchBox( HWND hWnd, UINT uMsg, WPARAM
|
||||
SetBkColor(hdc,GetSysColor(COLOR_WINDOW));
|
||||
SetBkMode(hdc,TRANSPARENT);
|
||||
SetTextColor(hdc,s_Skin.Search_text_colors[1]);
|
||||
DrawText(hdc,pParent->m_Items[pParent->m_SearchIndex].name,-1,&rc,DT_SINGLELINE|DT_EDITCONTROL|(s_bRTL?DT_RIGHT:DT_LEFT));
|
||||
if (GetSettingBool(L"SearchHint"))
|
||||
DrawText(hdc,GetSettingString(L"SearchHintText"),-1,&rc,DT_SINGLELINE|DT_EDITCONTROL|(s_bRTL?DT_RIGHT:DT_LEFT));
|
||||
else
|
||||
DrawText(hdc,pParent->m_Items[pParent->m_SearchIndex].name,-1,&rc,DT_SINGLELINE|DT_EDITCONTROL|(s_bRTL?DT_RIGHT:DT_LEFT));
|
||||
SelectObject(hdc,font0);
|
||||
}
|
||||
return res;
|
||||
@@ -856,7 +861,8 @@ void CMenuContainer::AddFirstFolder( IShellItem *pFolder, std::vector<MenuItem>
|
||||
|
||||
if (bLibrary) flags&=~SFGAO_STREAM;
|
||||
item.bLink=(flags&SFGAO_LINK)!=0;
|
||||
item.bFolder=(!(options&CONTAINER_CONTROLPANEL) && !(options&CONTAINER_NOSUBFOLDERS) && (flags&SFGAO_FOLDER) && (!(flags&(SFGAO_STREAM|SFGAO_LINK)) || (s_bExpandLinks && item.bLink)));
|
||||
item.bFolderLink=(flags&SFGAO_FOLDER && (!(flags&(SFGAO_STREAM|SFGAO_LINK)) || (s_bExpandLinks && item.bLink)));
|
||||
item.bFolder=(!(options&CONTAINER_CONTROLPANEL) && !(options&CONTAINER_NOSUBFOLDERS) && item.bFolderLink);
|
||||
{
|
||||
CItemManager::RWLock lock(&g_ItemManager,false,CItemManager::RWLOCK_ITEMS);
|
||||
if (item.pItemInfo->IsMetroLink())
|
||||
@@ -1084,7 +1090,8 @@ void CMenuContainer::AddStandardItems( void )
|
||||
if (m_bSubMenu && pStdItem->id==s_ShutdownCommand)
|
||||
continue;
|
||||
|
||||
if (pStdItem->id==MENU_COLUMN_BREAK && m_bTwoColumns)
|
||||
const bool bTwoColumns = (!m_bSubMenu && s_Skin.TwoColumns);
|
||||
if (pStdItem->id==MENU_COLUMN_BREAK && bTwoColumns)
|
||||
mainIconSize=s_Skin.Main2_icon_size;
|
||||
|
||||
int stdOptions=GetStdOptions(pStdItem->id);
|
||||
@@ -1937,15 +1944,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 +1954,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 +2210,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)
|
||||
@@ -2244,7 +2244,7 @@ void CMenuContainer::AddJumpListItems( std::vector<MenuItem> &items )
|
||||
{
|
||||
ILFree(item.pItem1);
|
||||
item.pItem1=pidl2.Detach();
|
||||
pItem=pItem2;
|
||||
pItem=std::move(pItem2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2506,9 +2506,9 @@ void CMenuContainer::InitItems( void )
|
||||
m_Items.resize(MAX_MENU_ITEMS);
|
||||
}
|
||||
|
||||
if (m_Options&CONTAINER_CONTROLPANEL)
|
||||
if (m_Options&CONTAINER_CONTROLPANEL && !(m_Options&CONTAINER_NOSUBFOLDERS))
|
||||
{
|
||||
// expand Administrative Tools. must be done after the sorting because we don't want the folder to jump to the top
|
||||
// expand Administrative Tools when displaying as a menu. must be done after the sorting because we don't want the folder to jump to the top
|
||||
unsigned int AdminToolsHash=CalcFNVHash(L"::{D20EA4E1-3957-11D2-A40B-0C5020524153}");
|
||||
for (std::vector<MenuItem>::iterator it=m_Items.begin();it!=m_Items.end();++it)
|
||||
if (it->nameHash==AdminToolsHash)
|
||||
@@ -2656,17 +2656,11 @@ int CMenuContainer::AddSearchItems( const std::vector<SearchItem> &items, const
|
||||
if (!categoryName.IsEmpty())
|
||||
{
|
||||
MenuItem item(MENU_SEARCH_CATEGORY);
|
||||
if (categoryHash==CSearchManager::CATEGORY_PROGRAM || categoryHash==CSearchManager::CATEGORY_SETTING)
|
||||
{
|
||||
item.name.Format(L"%s (%d)",categoryName,originalCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.name=categoryName;
|
||||
item.bSplit=(s_Skin.More_bitmap_Size.cx>0);
|
||||
}
|
||||
item.name.Format(L"%s (%d)",categoryName,originalCount);
|
||||
item.nameHash=CalcFNVHash(categoryName);
|
||||
item.categoryHash=categoryHash;
|
||||
if (categoryHash!=CSearchManager::CATEGORY_PROGRAM || categoryHash!=CSearchManager::CATEGORY_SETTING)
|
||||
item.bSplit=(s_Skin.More_bitmap_Size.cx>0);
|
||||
m_Items.push_back(item);
|
||||
}
|
||||
}
|
||||
@@ -2724,7 +2718,7 @@ bool CMenuContainer::InitSearchItems( void )
|
||||
unsigned int runCategoryHash=0;
|
||||
CString runCommand;
|
||||
CComString runExe;
|
||||
if (!bAutoComlpete && !s_bNoRun && s_SearchResults.programs.empty() && s_SearchResults.settings.empty())
|
||||
if (!bAutoComlpete && !s_bNoRun && s_SearchResults.programs.empty() && s_SearchResults.settings.empty() && s_SearchResults.metrosettings.empty())
|
||||
{
|
||||
if (s_bWin7Style)
|
||||
m_SearchBox.GetWindowText(runCommand);
|
||||
@@ -2753,9 +2747,9 @@ bool CMenuContainer::InitSearchItems( void )
|
||||
{
|
||||
sepHeight=s_Skin.ItemSettings[s_Skin.More_bitmap_Size.cx?MenuSkin::LIST_SEPARATOR_SPLIT:MenuSkin::LIST_SEPARATOR].itemHeight;
|
||||
itemHeight=s_Skin.ItemSettings[MenuSkin::LIST_ITEM].itemHeight;
|
||||
// total height minus the search box and the "more results"/"search internet"
|
||||
// total height minus the search box and the "more results"/"search internet", if present
|
||||
maxHeight=m_Items[m_SearchIndex].itemRect.top-s_Skin.Main_search_padding.top-s_Skin.Search_padding.top;
|
||||
maxHeight-=itemHeight*(m_SearchItemCount-1);
|
||||
maxHeight-=itemHeight*(m_SearchItemCount-(s_bMoreResults?1:2));
|
||||
if (!s_SearchResults.bSearching && !HasMoreResults())
|
||||
maxHeight+=itemHeight;
|
||||
}
|
||||
@@ -2781,6 +2775,12 @@ bool CMenuContainer::InitSearchItems( void )
|
||||
if (m_SearchCategoryHash==CSearchManager::CATEGORY_PROGRAM)
|
||||
selectedCount=(int)s_SearchResults.programs.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());
|
||||
@@ -2829,13 +2829,15 @@ bool CMenuContainer::InitSearchItems( void )
|
||||
|
||||
// add categories
|
||||
std::list<CSearchManager::SearchCategory>::const_iterator it=s_SearchResults.indexed.begin();
|
||||
for (size_t idx=0;idx<s_SearchResults.indexed.size()+2;idx++)
|
||||
for (size_t idx=0;idx<s_SearchResults.indexed.size()+3;idx++)
|
||||
{
|
||||
items.clear();
|
||||
unsigned int categoryHash;
|
||||
if (idx==0)
|
||||
categoryHash=CSearchManager::CATEGORY_PROGRAM;
|
||||
else if (idx==1)
|
||||
categoryHash=CSearchManager::CATEGORY_METROSETTING;
|
||||
else if (idx==2)
|
||||
categoryHash=CSearchManager::CATEGORY_SETTING;
|
||||
else
|
||||
categoryHash=it->categoryHash;
|
||||
@@ -2854,7 +2856,7 @@ bool CMenuContainer::InitSearchItems( void )
|
||||
}
|
||||
if (count<=0)
|
||||
{
|
||||
if (idx>=2) ++it;
|
||||
if (idx>=3) ++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2871,6 +2873,16 @@ bool CMenuContainer::InitSearchItems( void )
|
||||
name=FindTranslation(L"Search.CategoryPrograms",L"Programs");
|
||||
}
|
||||
else if (idx==1)
|
||||
{
|
||||
originalCount=(int)s_SearchResults.metrosettings.size();
|
||||
if (count>originalCount)
|
||||
count=originalCount;
|
||||
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"Settings");
|
||||
}
|
||||
else if (idx==2)
|
||||
{
|
||||
originalCount=(int)s_SearchResults.settings.size();
|
||||
if (count>originalCount)
|
||||
@@ -2878,7 +2890,7 @@ bool CMenuContainer::InitSearchItems( void )
|
||||
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");
|
||||
name=FindTranslation(L"Search.CategorySettings",L"Control Panel");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2931,25 +2943,28 @@ bool CMenuContainer::InitSearchItems( void )
|
||||
if (s_bWin7Style)
|
||||
{
|
||||
UpdateAccelerators(m_OriginalCount,(int)m_Items.size());
|
||||
MenuItem &item=m_Items[m_SearchIndex-m_SearchItemCount+1];
|
||||
if (s_SearchResults.bSearching)
|
||||
if (s_bMoreResults)
|
||||
{
|
||||
item.id=MENU_SEARCH_EMPTY;
|
||||
item.name=FindTranslation(L"Menu.Searching",L"Searching...");
|
||||
item.pItemInfo=g_ItemManager.GetCustomIcon(L"imageres.dll,8",CItemManager::ICON_SIZE_TYPE_SMALL);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.id=MENU_MORE_RESULTS;
|
||||
item.name=FindTranslation(L"Menu.MoreResults",L"See more results");
|
||||
item.pItemInfo=g_ItemManager.GetCustomIcon(L"imageres.dll,177",CItemManager::ICON_SIZE_TYPE_SMALL);
|
||||
MenuItem &item=m_Items[m_SearchIndex-m_SearchItemCount+1];
|
||||
if (s_SearchResults.bSearching)
|
||||
{
|
||||
item.id=MENU_SEARCH_EMPTY;
|
||||
item.name=FindTranslation(L"Menu.Searching",L"Searching...");
|
||||
item.pItemInfo=g_ItemManager.GetCustomIcon(L"imageres.dll,8",CItemManager::ICON_SIZE_TYPE_SMALL);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.id=MENU_MORE_RESULTS;
|
||||
item.name=FindTranslation(L"Menu.MoreResults",L"See more results");
|
||||
item.pItemInfo=g_ItemManager.GetCustomIcon(L"imageres.dll,177",CItemManager::ICON_SIZE_TYPE_SMALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ScrollCount=(int)m_Items.size();
|
||||
bool bInternet=GetSettingBool(L"SearchInternet");
|
||||
if (s_SearchResults.bSearching)
|
||||
bool bInternet=GetSettingBool(L"SearchInternet");
|
||||
if (s_bMoreResults && s_SearchResults.bSearching)
|
||||
{
|
||||
MenuItem item(MENU_SEARCH_EMPTY);
|
||||
item.name=FindTranslation(L"Menu.Searching",L"Searching...");
|
||||
@@ -2964,7 +2979,7 @@ bool CMenuContainer::InitSearchItems( void )
|
||||
item.name=FindTranslation(L"Menu.NoMatch",L"No items match your search.");
|
||||
m_Items.push_back(item);
|
||||
}
|
||||
if (HasMoreResults())
|
||||
if (s_bMoreResults && HasMoreResults())
|
||||
{
|
||||
{
|
||||
MenuItem item(MENU_SEPARATOR);
|
||||
@@ -5052,7 +5067,7 @@ void CMenuContainer::UpdateSearchResults( bool bForceShowAll )
|
||||
g_SearchManager.BeginSearch(s_SearchResults.currentString);
|
||||
s_SearchResults.bSearching=true;
|
||||
s_bPendingSearchEnter=false;
|
||||
if (s_bWin7Style)
|
||||
if (s_bWin7Style && s_bMoreResults)
|
||||
{
|
||||
MenuItem &item=m_Items[m_SearchIndex-m_SearchItemCount+1];
|
||||
item.id=MENU_SEARCH_EMPTY;
|
||||
@@ -6660,8 +6675,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);
|
||||
@@ -6794,7 +6808,7 @@ LRESULT CMenuContainer::OnLButtonDblClick( UINT uMsg, WPARAM wParam, LPARAM lPar
|
||||
ClientToScreen(&pt);
|
||||
if (s_bWin7Style && item.id==MENU_PROGRAMS) // only single clicks for All Programs
|
||||
OnLButtonDown(WM_LBUTTONDOWN,wParam,lParam,bHandled);
|
||||
else if (!bArrow) // ignore double-click on the split arrow
|
||||
else if (!bArrow && item.id!=MENU_APPS) // ignore double-click on the split arrow and Apps folder
|
||||
ActivateItem(index,ACTIVATE_EXECUTE,&pt);
|
||||
return 0;
|
||||
}
|
||||
@@ -6818,7 +6832,7 @@ LRESULT CMenuContainer::OnLButtonUp( UINT uMsg, WPARAM wParam, LPARAM lParam, BO
|
||||
const MenuItem &item=m_Items[index];
|
||||
POINT pt2=pt;
|
||||
ClientToScreen(&pt2);
|
||||
if (!item.bFolder)
|
||||
if (!item.bFolder || (s_bSingleClickFolders && item.id!=MENU_PROGRAMS && item.id!=MENU_APPS && !bArrow)) // never open All Programs, Apps folder, or jumplists with single click
|
||||
{
|
||||
if (item.jumpIndex>=0 && m_bHotArrow)
|
||||
{
|
||||
@@ -7319,8 +7333,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);
|
||||
@@ -7396,35 +7411,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
|
||||
@@ -7450,6 +7476,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;
|
||||
}
|
||||
|
||||
@@ -7629,6 +7681,7 @@ HWND CMenuContainer::ToggleStartMenu( int taskbarId, bool bKeyboard, bool bAllPr
|
||||
g_ItemManager.ResetTempIcons();
|
||||
s_ScrollMenus=GetSettingInt(L"ScrollType");
|
||||
s_bExpandLinks=GetSettingBool(L"ExpandFolderLinks");
|
||||
s_bSingleClickFolders=GetSettingBool(L"SingleClickFolders");
|
||||
s_bLogicalSort=GetSettingBool(L"NumericSort");
|
||||
s_MaxRecentDocuments=GetSettingInt(L"MaxRecentDocuments");
|
||||
s_ShellFormat=RegisterClipboardFormat(CFSTR_SHELLIDLIST);
|
||||
@@ -7646,6 +7699,7 @@ HWND CMenuContainer::ToggleStartMenu( int taskbarId, bool bKeyboard, bool bAllPr
|
||||
s_bDisableHover=false;
|
||||
s_bDragClosed=false;
|
||||
s_bPendingSearchEnter=false;
|
||||
s_bMoreResults=GetSettingBool(L"MoreResults");
|
||||
InitTouchHelper();
|
||||
|
||||
bool bRemote=GetSystemMetrics(SM_REMOTESESSION)!=0;
|
||||
@@ -8014,7 +8068,8 @@ HWND CMenuContainer::ToggleStartMenu( int taskbarId, bool bKeyboard, bool bAllPr
|
||||
}
|
||||
else
|
||||
{
|
||||
wchar_t path[_MAX_PATH]=START_MENU_PINNED_ROOT;
|
||||
wchar_t path[_MAX_PATH];
|
||||
Strcpy(path,_countof(path),GetSettingString(L"PinnedItemsPath"));
|
||||
DoEnvironmentSubst(path,_countof(path));
|
||||
SHCreateDirectory(NULL,path);
|
||||
s_PinFolder=path;
|
||||
@@ -8026,7 +8081,8 @@ HWND CMenuContainer::ToggleStartMenu( int taskbarId, bool bKeyboard, bool bAllPr
|
||||
{
|
||||
bool bPinned=GetSettingInt(L"PinnedPrograms")==PINNED_PROGRAMS_PINNED;
|
||||
bool bShortcut=GetSettingBool(L"StartScreenShortcut");
|
||||
wchar_t path[_MAX_PATH]=START_MENU_PINNED_ROOT L"\\" STARTSCREEN_COMMAND;
|
||||
wchar_t path[_MAX_PATH];
|
||||
Sprintf(path,_countof(path),L"%s\\%s",GetSettingString(L"PinnedItemsPath"),STARTSCREEN_COMMAND);
|
||||
DoEnvironmentSubst(path,_countof(path));
|
||||
if (bPinned)
|
||||
{
|
||||
|
||||
@@ -453,7 +453,7 @@ private:
|
||||
drawType=MenuSkin::COLUMN1_ITEM;
|
||||
column=row=0;
|
||||
memset(&itemRect,0,sizeof(itemRect));
|
||||
bFolder=bLink=bPrograms=bAlignBottom=bBreak=bInline=bInlineFirst=bInlineLast=bSplit=bHasJumpList=bMetroLink=bMetroApp=bBlankSeparator=bNew=bStartScreen=bCustomAccelerator=false;
|
||||
bFolder=bLink=bFolderLink=bPrograms=bAlignBottom=bBreak=bInline=bInlineFirst=bInlineLast=bSplit=bHasJumpList=bMetroLink=bMetroApp=bBlankSeparator=bNew=bStartScreen=bCustomAccelerator=false;
|
||||
priority=0;
|
||||
pItem1=pItem2=NULL;
|
||||
mfuHash=0;
|
||||
@@ -477,6 +477,7 @@ private:
|
||||
RECT itemRect;
|
||||
bool bFolder:1; // this is a folder - draw arrow
|
||||
bool bLink:1; // this is a link (if a link to a folder is expanded it is always single-column)
|
||||
bool bFolderLink:1; // this is a folder that is not explicitly expandable - used for sorting the list-of-links style
|
||||
bool bPrograms:1; // this item is part of the Start Menu folder hierarchy
|
||||
bool bAlignBottom:1; // two-column menu: this item is aligned to the bottom
|
||||
bool bBreak:1; // two-column menu: this item starts the second column
|
||||
@@ -512,8 +513,8 @@ private:
|
||||
if (priority>item.priority) return false;
|
||||
if (row<item.row) return true;
|
||||
if (row>item.row) return false;
|
||||
if ((bFolder && !bHasJumpList) && !(item.bFolder && !item.bHasJumpList)) return true;
|
||||
if (!(bFolder && !bHasJumpList) && (item.bFolder && !item.bHasJumpList)) return false;
|
||||
if (((bFolder || bFolderLink) && !bHasJumpList) && !((item.bFolder || item.bFolderLink) && !item.bHasJumpList)) return true;
|
||||
if (!((bFolder || bFolderLink) && !bHasJumpList) && ((item.bFolder || item.bFolderLink) && !item.bHasJumpList)) return false;
|
||||
if (drive && !item.drive) return true;
|
||||
if (!drive && item.drive) return false;
|
||||
if (drive && item.drive) return drive<item.drive;
|
||||
@@ -578,18 +579,19 @@ private:
|
||||
CString name;
|
||||
unsigned int nameHash;
|
||||
bool bFolder;
|
||||
bool bFolderLink;
|
||||
bool bHasJumpList;
|
||||
char priority;
|
||||
char drive;
|
||||
|
||||
SortMenuItem( const CString &_name, unsigned _nameHash, bool _bFolder, bool _bHasJumpList, char _priority ,char _drive) { name=_name; nameHash=_nameHash; bFolder=_bFolder; bHasJumpList=_bHasJumpList; priority=_priority; drive=_drive; }
|
||||
SortMenuItem( const MenuItem &item ) { name=item.name; nameHash=item.nameHash; bFolder=item.bFolder; bHasJumpList=item.bHasJumpList; priority=item.priority; drive=item.drive; }
|
||||
SortMenuItem( const CString &_name, unsigned _nameHash, bool _bFolder, bool _bFolderLink, bool _bHasJumpList, char _priority ,char _drive) { name=_name; nameHash=_nameHash; bFolder=_bFolder; bFolderLink=_bFolderLink; bHasJumpList=_bHasJumpList; priority=_priority; drive=_drive; }
|
||||
SortMenuItem( const MenuItem &item ) { name=item.name; nameHash=item.nameHash; bFolder=item.bFolder; bFolderLink=item.bFolderLink; bHasJumpList=item.bHasJumpList; priority=item.priority; drive=item.drive; }
|
||||
bool operator<( const SortMenuItem &x ) const
|
||||
{
|
||||
if (priority<x.priority) return true;
|
||||
if (priority>x.priority) return false;
|
||||
if ((bFolder && !bHasJumpList) && !(x.bFolder && !x.bHasJumpList)) return true;
|
||||
if (!(bFolder && !bHasJumpList) && (x.bFolder && !x.bHasJumpList)) return false;
|
||||
if (((bFolder || bFolderLink) && !bHasJumpList) && !((x.bFolder || x.bFolderLink) && !x.bHasJumpList)) return true;
|
||||
if (!((bFolder || bFolderLink) && !bHasJumpList) && ((x.bFolder || x.bFolderLink) && !x.bHasJumpList)) return false;
|
||||
if (drive && !x.drive) return true;
|
||||
if (!drive && x.drive) return false;
|
||||
if (drive && x.drive) return drive<x.drive;
|
||||
@@ -876,6 +878,7 @@ private:
|
||||
static bool s_bNoDragDrop; // disables drag/drop
|
||||
static bool s_bNoContextMenu; // disables the context menu
|
||||
static bool s_bExpandLinks; // expand links to folders
|
||||
static bool s_bSingleClickFolders; // open links to folders with one click instead of two
|
||||
static bool s_bLogicalSort; // use StrCmpLogical instead of CompareString
|
||||
static bool s_bExtensionSort; // sort file names by extension
|
||||
static bool s_bAllPrograms; // this is the All Programs menu of the Windows start menu
|
||||
@@ -895,6 +898,7 @@ private:
|
||||
static bool s_bRightDrag; // dragging with the right mouse button
|
||||
static bool s_bLockWorkArea; // changes to the work area are ignored
|
||||
static bool s_bPendingSearchEnter; // Enter was pressed before the search results were ready
|
||||
static bool s_bMoreResults; // shows the "Show More Results" item at the bottom of searches
|
||||
static RECT s_MenuLimits; // area of the main monitor accessible to all menus
|
||||
static RECT s_MainMenuLimits; // area of the main monitor accessible by the main menu
|
||||
static DWORD s_TaskbarState; // the state of the taskbar (ABS_AUTOHIDE and ABS_ALWAYSONTOP)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {};
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -60,9 +60,9 @@ void CProgramsTree::Create( CMenuContainer *pOwner )
|
||||
HWND hWnd=CreateWindowEx(0,WC_TREEVIEW,NULL,WS_CHILD|TVS_EDITLABELS|TVS_FULLROWSELECT|(CMenuContainer::s_TipHideTime?TVS_INFOTIP:0)|TVS_NOHSCROLL|TVS_SHOWSELALWAYS|TVS_NONEVENHEIGHT,0,0,0,0,pOwner->m_hWnd,NULL,g_Instance,NULL);
|
||||
TreeView_SetExtendedStyle(hWnd,TVS_EX_AUTOHSCROLL,TVS_EX_AUTOHSCROLL);
|
||||
const MenuSkin &skin=CMenuContainer::s_Skin;
|
||||
m_TreeTheme=OpenThemeData(m_hWnd,L"treeview");
|
||||
m_TreeTheme=OpenThemeData(hWnd,L"treeview");
|
||||
if (skin.BHasScrollbar)
|
||||
m_ScrollTheme=OpenThemeData(m_hWnd,L"scrollbar");
|
||||
m_ScrollTheme=OpenThemeData(hWnd,L"scrollbar");
|
||||
|
||||
const MenuSkin::ItemDrawSettings &settings=skin.ItemSettings[MenuSkin::PROGRAMS_TREE_ITEM];
|
||||
|
||||
|
||||
@@ -139,18 +139,25 @@ void CSearchManager::CloseMenu( void )
|
||||
Lock lock(this,LOCK_DATA);
|
||||
m_LastRequestId++;
|
||||
m_LastProgramsRequestId=m_LastRequestId;
|
||||
if (g_LogCategories&LOG_SEARCH)
|
||||
if (g_LogCategories & LOG_SEARCH)
|
||||
{
|
||||
for (std::vector<SearchItem>::const_iterator it=m_ProgramItems.begin();it!=m_ProgramItems.end();++it)
|
||||
for (const auto& item : m_ProgramItems)
|
||||
{
|
||||
if (it->category==CATEGORY_PROGRAM)
|
||||
LOG_MENU(LOG_SEARCH,L"Program: '%s', %d",it->name,it->rank);
|
||||
if (item.category == CATEGORY_PROGRAM)
|
||||
LOG_MENU(LOG_SEARCH, L"Program: '%s', %d", item.name, item.rank);
|
||||
}
|
||||
std::sort(m_SettingsItems.begin(),m_SettingsItems.end());
|
||||
for (std::vector<SearchItem>::const_iterator it=m_SettingsItems.begin();it!=m_SettingsItems.end();++it)
|
||||
|
||||
std::sort(m_SettingsItems.begin(), m_SettingsItems.end());
|
||||
|
||||
for (const auto& item : m_SettingsItems)
|
||||
{
|
||||
if (it->category==CATEGORY_SETTING)
|
||||
LOG_MENU(LOG_SEARCH,L"Setting: '%s', %d",it->name,it->rank);
|
||||
if (item.category == CATEGORY_SETTING)
|
||||
LOG_MENU(LOG_SEARCH, L"Setting: '%s', %d", item.name, item.rank);
|
||||
}
|
||||
for (const auto& item : m_SettingsItems)
|
||||
{
|
||||
if (item.category == CATEGORY_METROSETTING)
|
||||
LOG_MENU(LOG_SEARCH, L"MetroSetting: '%s', %d", item.name, item.rank);
|
||||
}
|
||||
}
|
||||
if (m_bProgramsFound)
|
||||
@@ -170,6 +177,7 @@ void CSearchManager::CloseMenu( void )
|
||||
m_SettingsItems.clear();
|
||||
m_SettingsHash=FNV_HASH0;
|
||||
m_bSettingsFound=false;
|
||||
m_bMetroSettingsFound = false;
|
||||
|
||||
m_IndexedItems.clear();
|
||||
m_AutoCompleteItems.clear();
|
||||
@@ -310,7 +318,9 @@ bool CSearchManager::AddSearchItem( IShellItem *pItem, const wchar_t *name, int
|
||||
PROPVARIANT val;
|
||||
PropVariantInit(&val);
|
||||
pItem2->GetProperty(PKEY_Keywords,&val);
|
||||
wchar_t keywords[1024];
|
||||
if (val.vt==VT_EMPTY)
|
||||
pItem2->GetProperty(PKEY_HighKeywords,&val);
|
||||
wchar_t keywords[2048];
|
||||
int len=0;
|
||||
if (val.vt==VT_BSTR || val.vt==VT_LPWSTR)
|
||||
{
|
||||
@@ -334,7 +344,7 @@ bool CSearchManager::AddSearchItem( IShellItem *pItem, const wchar_t *name, int
|
||||
}
|
||||
|
||||
Lock lock(this,LOCK_DATA);
|
||||
if (category==CATEGORY_PROGRAM || category==CATEGORY_SETTING)
|
||||
if (category==CATEGORY_PROGRAM || category==CATEGORY_SETTING || category==CATEGORY_METROSETTING)
|
||||
{
|
||||
if (searchRequest.requestId<m_LastProgramsRequestId)
|
||||
return false;
|
||||
@@ -345,10 +355,10 @@ bool CSearchManager::AddSearchItem( IShellItem *pItem, const wchar_t *name, int
|
||||
return false;
|
||||
}
|
||||
bool res=true;
|
||||
if (category==CATEGORY_PROGRAM || category==CATEGORY_SETTING)
|
||||
if (category==CATEGORY_PROGRAM || category==CATEGORY_SETTING || category==CATEGORY_METROSETTING)
|
||||
{
|
||||
std::vector<SearchItem> &items=(category==CATEGORY_PROGRAM)?m_ProgramItems:m_SettingsItems;
|
||||
if (category==CATEGORY_SETTING)
|
||||
if (category==CATEGORY_SETTING || category==CATEGORY_METROSETTING)
|
||||
{
|
||||
// remove duplicate settings
|
||||
for (std::vector<SearchItem>::const_iterator it=items.begin();it!=items.end();++it)
|
||||
@@ -381,6 +391,8 @@ bool CSearchManager::AddSearchItem( IShellItem *pItem, const wchar_t *name, int
|
||||
}
|
||||
|
||||
items.push_back(item);
|
||||
if (item.category==CATEGORY_METROSETTING)
|
||||
m_bMetroSettingsFound=true;
|
||||
}
|
||||
else if (category==CATEGORY_AUTOCOMPLETE)
|
||||
{
|
||||
@@ -409,7 +421,7 @@ void CSearchManager::CollectSearchItems( IShellItem *pFolder, int flags, TItemCa
|
||||
CComPtr<IShellItem> pChild;
|
||||
while (pChild=NULL,pEnum->Next(1,&pChild,NULL)==S_OK)
|
||||
{
|
||||
if (category==CATEGORY_PROGRAM || category==CATEGORY_SETTING)
|
||||
if (category==CATEGORY_PROGRAM || category==CATEGORY_SETTING || category==CATEGORY_METROSETTING)
|
||||
{
|
||||
if (searchRequest.requestId<m_LastProgramsRequestId)
|
||||
break;
|
||||
@@ -428,7 +440,7 @@ void CSearchManager::CollectSearchItems( IShellItem *pFolder, int flags, TItemCa
|
||||
{
|
||||
// go into subfolders but not archives or links to folders
|
||||
CollectSearchItems(pChild,flags,category,searchRequest);
|
||||
if (category==CATEGORY_PROGRAM || category==CATEGORY_SETTING)
|
||||
if (category==CATEGORY_PROGRAM || category==CATEGORY_SETTING || category==CATEGORY_METROSETTING)
|
||||
{
|
||||
if (searchRequest.requestId<m_LastProgramsRequestId)
|
||||
break;
|
||||
@@ -514,7 +526,7 @@ bool CSearchManager::SearchScope::ParseSearchConnector( const wchar_t *fname )
|
||||
CComPtr<IXMLDOMNode> pNext;
|
||||
if (pScopeItem->get_nextSibling(&pNext)!=S_OK)
|
||||
break;
|
||||
pScopeItem=pNext;
|
||||
pScopeItem=std::move(pNext);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -627,7 +639,8 @@ void CSearchManager::SearchThread( void )
|
||||
// pinned folder
|
||||
if (searchRequest.bPinnedFolder)
|
||||
{
|
||||
wchar_t path[_MAX_PATH]=START_MENU_PINNED_ROOT;
|
||||
wchar_t path[_MAX_PATH];
|
||||
Strcpy(path,_countof(path),GetSettingString(L"PinnedItemsPath"));
|
||||
DoEnvironmentSubst(path,_MAX_PATH);
|
||||
CComPtr<IShellItem> pFolder;
|
||||
if (SUCCEEDED(SHCreateItemFromParsingName(path,NULL,IID_IShellItem,(void**)&pFolder)))
|
||||
@@ -670,7 +683,7 @@ void CSearchManager::SearchThread( void )
|
||||
if (GetWinVersion()>=WIN_VER_WIN8 && searchRequest.bSearchMetroApps)
|
||||
{
|
||||
std::vector<MetroLink> links;
|
||||
GetMetroLinks(links,false);
|
||||
GetMetroLinks(links,true);
|
||||
for (std::vector<MetroLink>::const_iterator it=links.begin();it!=links.end();++it)
|
||||
{
|
||||
if (GetWinVersion()<WIN_VER_WIN10)
|
||||
@@ -733,6 +746,14 @@ void CSearchManager::SearchThread( void )
|
||||
if (searchRequest.requestId<m_LastProgramsRequestId)
|
||||
continue;
|
||||
}
|
||||
if (searchRequest.bSearchMetroSettings)
|
||||
{
|
||||
CComPtr<IShellItem> pFolder;
|
||||
if (SUCCEEDED(SHCreateItemFromParsingName(L"shell:::{82E749ED-B971-4550-BAF7-06AA2BF7E836}",NULL,IID_IShellItem,(void**)&pFolder)))
|
||||
CollectSearchItems(pFolder,(searchRequest.bSearchKeywords?COLLECT_KEYWORDS:0)|COLLECT_NOREFRESH,CATEGORY_METROSETTING,searchRequest);
|
||||
if (searchRequest.requestId<m_LastProgramsRequestId)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
bool bRefresh=false;
|
||||
{
|
||||
@@ -778,9 +799,9 @@ void CSearchManager::SearchThread( void )
|
||||
CSession session;
|
||||
if (SUCCEEDED(dataSource.OpenFromInitializationString(L"provider=Search.CollatorDSO.1;EXTENDED PROPERTIES=\"Application=Windows\"")) && SUCCEEDED(session.Open(dataSource)))
|
||||
{
|
||||
std::list<SearchScope> scopeList;
|
||||
std::vector<SearchScope> scopeList;
|
||||
|
||||
if (searchRequest.bSearchMetroSettings)
|
||||
if (searchRequest.bSearchMetroSettings && !m_bMetroSettingsFound)
|
||||
{
|
||||
scopeList.push_back(SearchScope());
|
||||
SearchScope &scope=*scopeList.rbegin();
|
||||
@@ -1084,7 +1105,7 @@ void CSearchManager::SearchThread( void )
|
||||
command0.Close();
|
||||
continue;
|
||||
}
|
||||
for (std::list<SearchScope>::iterator it=scopeList.begin();it!=scopeList.end();++it)
|
||||
for (auto it=scopeList.begin();it!=scopeList.end();++it)
|
||||
{
|
||||
if (it->roots.empty())
|
||||
continue;
|
||||
@@ -1102,7 +1123,7 @@ void CSearchManager::SearchThread( void )
|
||||
else
|
||||
{
|
||||
len+=Strcpy(query+len,_countof(query)-len,L" AND System.Search.Store='FILE' AND System.ItemType!='.settingcontent-ms'");
|
||||
for (std::list<SearchScope>::iterator it2=scopeList.begin();it2!=it;++it2)
|
||||
for (auto it2=scopeList.begin();it2!=it;++it2)
|
||||
{
|
||||
if (it2->categoryHash==CATEGORY_METROSETTING)
|
||||
continue;
|
||||
@@ -1240,7 +1261,7 @@ void CSearchManager::SearchThread( void )
|
||||
Lock lock(this,LOCK_DATA);
|
||||
m_IndexedItems.push_back(SearchCategory());
|
||||
pCategory=&*m_IndexedItems.rbegin();
|
||||
pCategory->name.Format(L"%s (%d)",it->name,it->resultCount);
|
||||
pCategory->name=it->name;
|
||||
pCategory->categoryHash=it->categoryHash;
|
||||
pCategory->search.Clone(it->search);
|
||||
}
|
||||
@@ -1348,6 +1369,7 @@ void CSearchManager::GetSearchResults( SearchResults &results )
|
||||
{
|
||||
results.programs.clear();
|
||||
results.settings.clear();
|
||||
results.metrosettings.clear();
|
||||
results.indexed.clear();
|
||||
results.autocomplete.clear();
|
||||
results.autoCompletePath.Empty();
|
||||
@@ -1397,14 +1419,19 @@ void CSearchManager::GetSearchResults( SearchResults &results )
|
||||
std::vector<SearchItem> &settings=m_bSettingsFound?m_SettingsItems:m_SettingsItemsOld;
|
||||
for (std::vector<SearchItem>::iterator it=settings.begin();it!=settings.end();++it)
|
||||
{
|
||||
int match=(it->category==CATEGORY_SETTING)?it->MatchText(m_SearchText,bSearchSubWord):0;
|
||||
int match=(it->category==CATEGORY_SETTING || it->category==CATEGORY_METROSETTING)?it->MatchText(m_SearchText,bSearchSubWord):0;
|
||||
it->rank=(it->rank&0xFFFFFFFE)|(match>>1);
|
||||
}
|
||||
std::sort(settings.begin(),settings.end());
|
||||
for (std::vector<SearchItem>::const_iterator it=settings.begin();it!=settings.end();++it)
|
||||
{
|
||||
if (it->category==CATEGORY_SETTING && it->MatchText(m_SearchText,bSearchSubWord))
|
||||
results.settings.push_back(it->pInfo);
|
||||
if (it->MatchText(m_SearchText, bSearchSubWord))
|
||||
{
|
||||
if (it->category==CATEGORY_SETTING)
|
||||
results.settings.push_back(it->pInfo);
|
||||
if (it->category==CATEGORY_METROSETTING)
|
||||
results.metrosettings.push_back(it->pInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1423,7 +1450,7 @@ void CSearchManager::GetSearchResults( SearchResults &results )
|
||||
results.autocomplete.push_back(it->pInfo);
|
||||
}
|
||||
}
|
||||
results.bResults=(!results.programs.empty() || !results.settings.empty() || !results.indexed.empty() || !results.autocomplete.empty());
|
||||
results.bResults=(!results.programs.empty() || !results.settings.empty() || !results.metrosettings.empty() || !results.indexed.empty() || !results.autocomplete.empty());
|
||||
results.bSearching=(m_LastCompletedId!=m_LastRequestId);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
|
||||
struct SearchCategory
|
||||
{
|
||||
SearchCategory( void ) {}
|
||||
SearchCategory( void ) = default;
|
||||
SearchCategory( const SearchCategory &cat )
|
||||
{
|
||||
search.Clone(cat.search);
|
||||
@@ -63,6 +63,7 @@ public:
|
||||
CString autoCompletePath;
|
||||
std::vector<const CItemManager::ItemInfo*> programs;
|
||||
std::vector<const CItemManager::ItemInfo*> settings;
|
||||
std::vector<const CItemManager::ItemInfo*> metrosettings;
|
||||
std::vector<const CItemManager::ItemInfo*> autocomplete;
|
||||
std::list<SearchCategory> indexed;
|
||||
};
|
||||
@@ -149,6 +150,7 @@ private:
|
||||
unsigned int m_SettingsHashOld;
|
||||
bool m_bProgramsFound;
|
||||
bool m_bSettingsFound;
|
||||
bool m_bMetroSettingsFound = false;
|
||||
std::vector<SearchItem> m_AutoCompleteItems;
|
||||
std::list<SearchCategory> m_IndexedItems;
|
||||
std::vector<ItemRank> m_ItemRanks;
|
||||
|
||||
@@ -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"
|
||||
@@ -1742,7 +1742,7 @@ LRESULT CEditMenuDlg::OnBrowseLink( WORD wNotifyCode, WORD wID, HWND hWndCtl, BO
|
||||
{
|
||||
wchar_t text[_MAX_PATH];
|
||||
GetDlgItemText(IDC_COMBOLINK,text,_countof(text));
|
||||
if (BrowseLinkHelper(m_hWnd,text))
|
||||
if (BrowseLinkHelper(m_hWnd,text,false))
|
||||
{
|
||||
SetDlgItemText(IDC_COMBOLINK,text);
|
||||
SendMessage(WM_COMMAND,MAKEWPARAM(IDC_COMBOLINK,CBN_KILLFOCUS));
|
||||
@@ -2437,7 +2437,7 @@ LRESULT CEditMenuDlg7::OnBrowseLink( WORD wNotifyCode, WORD wID, HWND hWndCtl, B
|
||||
{
|
||||
wchar_t text[_MAX_PATH];
|
||||
GetDlgItemText(IDC_EDITLINK2,text,_countof(text));
|
||||
if (BrowseLinkHelper(m_hWnd,text))
|
||||
if (BrowseLinkHelper(m_hWnd,text,false))
|
||||
{
|
||||
SetDlgItemText(IDC_EDITLINK2,text);
|
||||
SendMessage(WM_COMMAND,MAKEWPARAM(IDC_EDITLINK2,EN_KILLFOCUS));
|
||||
@@ -2725,8 +2725,11 @@ void CCustomMenuDlg7::CItemList::UpdateItem( int index )
|
||||
str=LoadStringEx(IDS_ITEM_SHOW2);
|
||||
else if ((menuItem.settings&StdMenuItem::MENU_NOEXPAND) && !(g_StdCommands7[menuItem.stdItemIndex].flags&CStdCommand7::ITEM_FOLDER))
|
||||
str=LoadStringEx(IDS_ITEM_SHOW);
|
||||
else if ((menuItem.settings&StdMenuItem::MENU_SINGLE_EXPAND) && (g_StdCommands7[menuItem.stdItemIndex].flags&CStdCommand7::ITEM_COMPUTER))
|
||||
str=LoadStringEx(IDS_ITEM_DRIVES);
|
||||
else if ((menuItem.settings&StdMenuItem::MENU_SINGLE_EXPAND) && !(g_StdCommands7[menuItem.stdItemIndex].flags&CStdCommand7::ITEM_NODRIVES))
|
||||
if (g_StdCommands7[menuItem.stdItemIndex].flags&CStdCommand7::ITEM_COMPUTER)
|
||||
str=LoadStringEx(IDS_ITEM_DRIVES);
|
||||
else
|
||||
str=LoadStringEx(IDS_ITEM_LINKS);
|
||||
else
|
||||
str=LoadStringEx(IDS_ITEM_MENU);
|
||||
ListView_SetItemText(m_hWnd,index,2,(wchar_t*)(const wchar_t*)str);
|
||||
@@ -3155,13 +3158,12 @@ LRESULT CCustomMenuDlg7::CItemList::OnSelEndOk( WORD wNotifyCode, WORD wID, HWND
|
||||
if (m_Column==2)
|
||||
{
|
||||
// state
|
||||
CString str;
|
||||
menuItem.settings&=~CEditMenuDlg7::SETTINGS_MASK;
|
||||
if (sel==0)
|
||||
menuItem.settings|=StdMenuItem::MENU_ITEM_DISABLED;
|
||||
else if (sel==1 && !(g_StdCommands7[menuItem.stdItemIndex].flags&(CStdCommand7::ITEM_SINGLE|CStdCommand7::ITEM_FOLDER)))
|
||||
menuItem.settings|=StdMenuItem::MENU_NOEXPAND;
|
||||
else if (sel==3 && (g_StdCommands7[menuItem.stdItemIndex].flags&CStdCommand7::ITEM_COMPUTER))
|
||||
else if (sel==3 && !(g_StdCommands7[menuItem.stdItemIndex].flags&CStdCommand7::ITEM_NODRIVES))
|
||||
menuItem.settings|=StdMenuItem::MENU_SINGLE_EXPAND;
|
||||
}
|
||||
UpdateItem(m_Line);
|
||||
@@ -3308,12 +3310,17 @@ void CCustomMenuDlg7::CItemList::CreateCombo( int line, int column )
|
||||
str=LoadStringEx(IDS_ITEM_DRIVES);
|
||||
m_Combo.SendMessage(CB_ADDSTRING,0,(LPARAM)(const wchar_t*)str);
|
||||
}
|
||||
else if (!(g_StdCommands7[menuItem.stdItemIndex].flags&CStdCommand7::ITEM_NODRIVES))
|
||||
{
|
||||
str=LoadStringEx(IDS_ITEM_LINKS);
|
||||
m_Combo.SendMessage(CB_ADDSTRING,0,(LPARAM)(const wchar_t*)str);
|
||||
}
|
||||
}
|
||||
if (menuItem.settings&StdMenuItem::MENU_ITEM_DISABLED)
|
||||
m_Combo.SendMessage(CB_SETCURSEL,0);
|
||||
else if ((g_StdCommands7[menuItem.stdItemIndex].flags&(CStdCommand7::ITEM_SINGLE|CStdCommand7::ITEM_FOLDER)) || (menuItem.settings&StdMenuItem::MENU_NOEXPAND))
|
||||
m_Combo.SendMessage(CB_SETCURSEL,1);
|
||||
else if ((g_StdCommands7[menuItem.stdItemIndex].flags&CStdCommand7::ITEM_COMPUTER) && (menuItem.settings&StdMenuItem::MENU_SINGLE_EXPAND))
|
||||
else if (!(g_StdCommands7[menuItem.stdItemIndex].flags&CStdCommand7::ITEM_NODRIVES) && (menuItem.settings&StdMenuItem::MENU_SINGLE_EXPAND))
|
||||
m_Combo.SendMessage(CB_SETCURSEL,3);
|
||||
else
|
||||
m_Combo.SendMessage(CB_SETCURSEL,2);
|
||||
@@ -3617,7 +3624,10 @@ void CCustomMenuDlg7::SerializeData( void )
|
||||
stringBuilder.push_back(0);
|
||||
CSettingsLockWrite lock;
|
||||
m_pSetting->value=CComVariant(&stringBuilder[0]);
|
||||
m_pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (m_pSetting->value==m_pSetting->defValue)
|
||||
m_pSetting->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
m_pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
SetSettingsDirty();
|
||||
}
|
||||
|
||||
@@ -3718,7 +3728,6 @@ protected:
|
||||
CWindow m_ImageClassic1, m_ImageClassic2, m_ImageWin7;
|
||||
CWindow m_Tooltip;
|
||||
CWindow m_ButtonAero, m_ButtonClassic, m_ButtonCustom;
|
||||
bool m_bLargeBitmaps;
|
||||
HICON m_hIcon;
|
||||
CString m_IconPath;
|
||||
|
||||
@@ -3737,14 +3746,13 @@ LRESULT CMenuStyleDlg::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BO
|
||||
HDC hdc=::GetDC(NULL);
|
||||
int dpi=GetDeviceCaps(hdc,LOGPIXELSY);
|
||||
::ReleaseDC(NULL,hdc);
|
||||
m_bLargeBitmaps=dpi>=144;
|
||||
if (m_bLargeBitmaps)
|
||||
bool bLargeBitmaps=dpi>=144;
|
||||
{
|
||||
HBITMAP bmp=(HBITMAP)LoadImage(g_Instance,MAKEINTRESOURCE(IDB_STYLE_CLASSIC1150),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);
|
||||
HBITMAP bmp=LoadImageResource(g_Instance,MAKEINTRESOURCE(bLargeBitmaps?IDB_STYLE_CLASSIC1150:IDB_STYLE_CLASSIC1),true,true);
|
||||
m_ImageClassic1.SendMessage(STM_SETIMAGE,IMAGE_BITMAP,(LPARAM)bmp);
|
||||
bmp=(HBITMAP)LoadImage(g_Instance,MAKEINTRESOURCE(IDB_STYLE_CLASSIC2150),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);
|
||||
bmp=LoadImageResource(g_Instance,MAKEINTRESOURCE(bLargeBitmaps?IDB_STYLE_CLASSIC2150:IDB_STYLE_CLASSIC2),true,true);
|
||||
m_ImageClassic2.SendMessage(STM_SETIMAGE,IMAGE_BITMAP,(LPARAM)bmp);
|
||||
bmp=(HBITMAP)LoadImage(g_Instance,MAKEINTRESOURCE(IDB_STYLE_WIN7150),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);
|
||||
bmp=LoadImageResource(g_Instance,MAKEINTRESOURCE(bLargeBitmaps?IDB_STYLE_WIN7150:IDB_STYLE_WIN7),true,true);
|
||||
m_ImageWin7.SendMessage(STM_SETIMAGE,IMAGE_BITMAP,(LPARAM)bmp);
|
||||
}
|
||||
|
||||
@@ -3779,7 +3787,6 @@ LRESULT CMenuStyleDlg::OnDestroy( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&
|
||||
{
|
||||
if (m_hIcon) DestroyIcon(m_hIcon);
|
||||
m_hIcon=NULL;
|
||||
if (m_bLargeBitmaps)
|
||||
{
|
||||
HBITMAP bmp=(HBITMAP)m_ImageClassic1.SendMessage(STM_GETIMAGE,IMAGE_BITMAP);
|
||||
if (bmp) DeleteObject(bmp);
|
||||
@@ -3847,7 +3854,10 @@ LRESULT CMenuStyleDlg::OnClick( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL&
|
||||
CheckDlgButton(IDC_RADIO_CLASSIC,pSetting->value.intVal==MENU_CLASSIC1?BST_CHECKED:BST_UNCHECKED);
|
||||
CheckDlgButton(IDC_RADIO_TWO_COLUMNS,pSetting->value.intVal==MENU_CLASSIC2?BST_CHECKED:BST_UNCHECKED);
|
||||
CheckDlgButton(IDC_RADIO_WIN7,pSetting->value.intVal==MENU_WIN7?BST_CHECKED:BST_UNCHECKED);
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (pSetting->value==pSetting->defValue)
|
||||
pSetting->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
SetSettingsDirty();
|
||||
|
||||
SetSettingsStyle(styleFlag,CSetting::FLAG_MENU_MASK);
|
||||
@@ -3865,7 +3875,10 @@ LRESULT CMenuStyleDlg::OnEnabled( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL
|
||||
CSettingsLockWrite lock;
|
||||
CSetting *pSetting=FindSetting(L"EnableStartButton");
|
||||
pSetting->value=CComVariant(bEnabled);
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (pSetting->value==pSetting->defValue)
|
||||
pSetting->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
SetSettingsDirty();
|
||||
}
|
||||
Update(false);
|
||||
@@ -3904,7 +3917,10 @@ LRESULT CMenuStyleDlg::OnButtonStyle( WORD wNotifyCode, WORD wID, HWND hWndCtl,
|
||||
CSettingsLockWrite lock;
|
||||
CSetting *pSetting=FindSetting(L"StartButtonType");
|
||||
pSetting->value=CComVariant(style);
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (pSetting->value==pSetting->defValue)
|
||||
pSetting->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
SetSettingsDirty();
|
||||
}
|
||||
Update(false);
|
||||
@@ -3928,7 +3944,10 @@ LRESULT CMenuStyleDlg::OnPick( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& b
|
||||
CSettingsLockWrite lock;
|
||||
CSetting *pSetting=FindSetting(L"StartButtonPath");
|
||||
pSetting->value=CComVariant(path);
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (pSetting->value==pSetting->defValue)
|
||||
pSetting->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pSetting->flags&=~CSetting::FLAG_DEFAULT;
|
||||
SetSettingsDirty();
|
||||
}
|
||||
Update(true);
|
||||
@@ -4143,38 +4162,50 @@ CSetting g_Settings[]={
|
||||
{L"Nothing",CSetting::TYPE_RADIO,IDS_OPEN_NOTHING,IDS_OPEN_NOTHING_TIP},
|
||||
{L"ClassicMenu",CSetting::TYPE_RADIO,IDS_OPEN_CSM,IDS_OPEN_CSM_TIP},
|
||||
{L"WindowsMenu",CSetting::TYPE_RADIO,IDS_OPEN_WSM,IDS_OPEN_WSM_TIP},
|
||||
{L"Command",CSetting::TYPE_RADIO,IDS_OPEN_CMD,IDS_OPEN_CMD_TIP},
|
||||
{L"Both",CSetting::TYPE_RADIO,IDS_OPEN_BOTH,IDS_OPEN_BOTH_TIP,0,CSetting::FLAG_HIDDEN},
|
||||
{L"MouseClickCommand",CSetting::TYPE_STRING,IDS_OPEN_CMD_TEXT,IDS_OPEN_CMD_TEXT_TIP,"%userprofile%",0,L"MouseClick=3",L"Command"},
|
||||
{L"ShiftClick",CSetting::TYPE_INT,IDS_SHIFT_LCLICK,IDS_SHIFT_LCLICK_TIP,2,CSetting::FLAG_BASIC},
|
||||
{L"Nothing",CSetting::TYPE_RADIO,IDS_OPEN_NOTHING,IDS_OPEN_NOTHING_TIP},
|
||||
{L"ClassicMenu",CSetting::TYPE_RADIO,IDS_OPEN_CSM,IDS_OPEN_CSM_TIP},
|
||||
{L"WindowsMenu",CSetting::TYPE_RADIO,IDS_OPEN_WSM,IDS_OPEN_WSM_TIP},
|
||||
{L"Command",CSetting::TYPE_RADIO,IDS_OPEN_CMD,IDS_OPEN_CMD_TIP},
|
||||
{L"Both",CSetting::TYPE_RADIO,IDS_OPEN_BOTH,IDS_OPEN_BOTH_TIP,0,CSetting::FLAG_HIDDEN},
|
||||
/* {L"Desktop",CSetting::TYPE_RADIO,IDS_OPEN_DESKTOP,IDS_OPEN_DESKTOP_TIP,0,CSetting::FLAG_HIDDEN},
|
||||
{L"Cortana",CSetting::TYPE_RADIO,IDS_OPEN_CORTANA,IDS_OPEN_CORTANA_TIP},*/
|
||||
{L"ShiftClickCommand",CSetting::TYPE_STRING,IDS_OPEN_CMD_TEXT,IDS_OPEN_CMD_TEXT_TIP,"%systemdrive%",0,L"ShiftClick=3",L"Command"},
|
||||
{L"WinKey",CSetting::TYPE_INT,IDS_WIN_KEY,IDS_WIN_KEY_TIP,1,CSetting::FLAG_BASIC},
|
||||
{L"Nothing",CSetting::TYPE_RADIO,IDS_OPEN_NOTHING,IDS_OPEN_NOTHING_TIP},
|
||||
{L"ClassicMenu",CSetting::TYPE_RADIO,IDS_OPEN_CSM,IDS_OPEN_CSM_TIP},
|
||||
{L"WindowsMenu",CSetting::TYPE_RADIO,IDS_OPEN_WSM,IDS_OPEN_WSM_TIP},
|
||||
{L"Command",CSetting::TYPE_RADIO,IDS_OPEN_CMD,IDS_OPEN_CMD_TIP},
|
||||
{L"Both",CSetting::TYPE_RADIO,IDS_OPEN_BOTH,IDS_OPEN_BOTH_TIP},
|
||||
{L"Desktop",CSetting::TYPE_RADIO,IDS_OPEN_DESKTOP,IDS_OPEN_DESKTOP_TIP},
|
||||
{L"WinKeyCommand",CSetting::TYPE_STRING,IDS_OPEN_CMD_TEXT,IDS_OPEN_CMD_TEXT_TIP,"cmd",0,L"WinKey=3",L"Command"},
|
||||
{L"ShiftWin",CSetting::TYPE_INT,IDS_SHIFT_WIN,IDS_SHIFT_WIN_TIP,2,CSetting::FLAG_BASIC},
|
||||
{L"Nothing",CSetting::TYPE_RADIO,IDS_OPEN_NOTHING,IDS_OPEN_NOTHING_TIP},
|
||||
{L"ClassicMenu",CSetting::TYPE_RADIO,IDS_OPEN_CSM,IDS_OPEN_CSM_TIP},
|
||||
{L"WindowsMenu",CSetting::TYPE_RADIO,IDS_OPEN_WSM,IDS_OPEN_WSM_TIP},
|
||||
{L"Command",CSetting::TYPE_RADIO,IDS_OPEN_CMD,IDS_OPEN_CMD_TIP},
|
||||
{L"Both",CSetting::TYPE_RADIO,IDS_OPEN_BOTH,IDS_OPEN_BOTH_TIP},
|
||||
/* {L"Desktop",CSetting::TYPE_RADIO,IDS_OPEN_DESKTOP,IDS_OPEN_DESKTOP_TIP,0,CSetting::FLAG_HIDDEN},
|
||||
{L"Cortana",CSetting::TYPE_RADIO,IDS_OPEN_CORTANA,IDS_OPEN_CORTANA_TIP},*/
|
||||
{L"ShiftWinCommand",CSetting::TYPE_STRING,IDS_OPEN_CMD_TEXT,IDS_OPEN_CMD_TEXT_TIP,"powershell",0,L"ShiftWin=3",L"Command"},
|
||||
{L"MiddleClick",CSetting::TYPE_INT,IDS_MCLICK,IDS_MCLICK_TIP,0},
|
||||
{L"Nothing",CSetting::TYPE_RADIO,IDS_OPEN_NOTHING,IDS_OPEN_NOTHING_TIP},
|
||||
{L"ClassicMenu",CSetting::TYPE_RADIO,IDS_OPEN_CSM,IDS_OPEN_CSM_TIP},
|
||||
{L"WindowsMenu",CSetting::TYPE_RADIO,IDS_OPEN_WSM,IDS_OPEN_WSM_TIP},
|
||||
{L"Command",CSetting::TYPE_RADIO,IDS_OPEN_CMD,IDS_OPEN_CMD_TIP},
|
||||
/* {L"Both",CSetting::TYPE_RADIO,IDS_OPEN_BOTH,IDS_OPEN_BOTH_TIP,0,CSetting::FLAG_HIDDEN},
|
||||
{L"Desktop",CSetting::TYPE_RADIO,IDS_OPEN_DESKTOP,IDS_OPEN_DESKTOP_TIP,0,CSetting::FLAG_HIDDEN},
|
||||
{L"Cortana",CSetting::TYPE_RADIO,IDS_OPEN_CORTANA,IDS_OPEN_CORTANA_TIP},*/
|
||||
{L"MiddleClickCommand",CSetting::TYPE_STRING,IDS_OPEN_CMD_TEXT,IDS_OPEN_CMD_TEXT_TIP,"taskmgr",0,L"MiddleClick=3",L"Command"},
|
||||
{L"Hover",CSetting::TYPE_INT,IDS_HOVER,IDS_HOVER_TIP,0},
|
||||
{L"Nothing",CSetting::TYPE_RADIO,IDS_OPEN_NOTHING,IDS_OPEN_NOTHING_TIP},
|
||||
{L"ClassicMenu",CSetting::TYPE_RADIO,IDS_OPEN_CSM,IDS_OPEN_CSM_TIP},
|
||||
{L"WindowsMenu",CSetting::TYPE_RADIO,IDS_OPEN_WSM,IDS_OPEN_WSM_TIP},
|
||||
{L"Command",CSetting::TYPE_RADIO,IDS_OPEN_CMD,IDS_OPEN_CMD_TIP},
|
||||
{L"HoverCommand",CSetting::TYPE_STRING,IDS_OPEN_CMD_TEXT,IDS_OPEN_CMD_TEXT_TIP,"",0,L"Hover=3",L"Command"},
|
||||
{L"StartHoverDelay",CSetting::TYPE_INT,IDS_HOVER_DELAY,IDS_HOVER_DELAY_TIP,1000,0,L"Hover",L"Hover"},
|
||||
{L"ShiftRight",CSetting::TYPE_BOOL,IDS_RIGHT_SHIFT,IDS_RIGHT_SHIFT_TIP,0},
|
||||
{L"CSMHotkey",CSetting::TYPE_HOTKEY,IDS_CSM_HOTKEY,IDS_CSM_HOTKEY_TIP,0},
|
||||
@@ -4249,6 +4280,7 @@ CSetting g_Settings[]={
|
||||
{L"PinnedPrograms",CSetting::TYPE_INT,IDS_PINNED_PROGRAMS,IDS_PINNED_PROGRAMS_TIP,PINNED_PROGRAMS_PINNED},
|
||||
{L"FastItems",CSetting::TYPE_RADIO,IDS_FAST_ITEMS,IDS_FAST_ITEMS_TIP},
|
||||
{L"PinnedItems",CSetting::TYPE_RADIO,IDS_PINNED_ITEMS,IDS_PINNED_ITEMS_TIP},
|
||||
{L"PinnedItemsPath",CSetting::TYPE_DIRECTORY,IDS_PINNED_PATH,IDS_PINNED_PATH_TIP,L"%APPDATA%\\OpenShell\\Pinned",0,L"PinnedPrograms=1",L"PinnedItems"},
|
||||
{L"RecentPrograms",CSetting::TYPE_INT,IDS_RECENT_PROGRAMS,IDS_RECENT_PROGRAMS_TIP,RECENT_PROGRAMS_RECENT,CSetting::FLAG_BASIC},
|
||||
{L"None",CSetting::TYPE_RADIO,IDS_NO_RECENT,IDS_NO_RECENT_TIP},
|
||||
{L"Recent",CSetting::TYPE_RADIO,IDS_SHOW_RECENT,IDS_SHOW_RECENT_TIP},
|
||||
@@ -4317,11 +4349,14 @@ CSetting g_Settings[]={
|
||||
{L"UserNameCommand",CSetting::TYPE_STRING,IDS_NAME_COMMAND,IDS_NAME_COMMAND_TIP,L"control nusrmgr.cpl"},
|
||||
{L"SearchFilesCommand",CSetting::TYPE_STRING,IDS_SEARCH_COMMAND,IDS_SEARCH_COMMAND_TIP,L"search-ms:",CSetting::FLAG_MENU_CLASSIC_BOTH},
|
||||
{L"ExpandFolderLinks",CSetting::TYPE_BOOL,IDS_EXPAND_LINKS,IDS_EXPAND_LINKS_TIP,1},
|
||||
{L"SingleClickFolders",CSetting::TYPE_BOOL,IDS_NO_DBLCLICK,IDS_NO_DBLCLICK_TIP,0},
|
||||
{L"OpenTruePath",CSetting::TYPE_BOOL,IDS_OPEN_TRUE_PATH,IDS_OPEN_TRUE_PATH_TIP,1},
|
||||
{L"EnableTouch",CSetting::TYPE_BOOL,IDS_ENABLE_TOUCH,IDS_ENABLE_TOUCH_TIP,1},
|
||||
{L"EnableAccessibility",CSetting::TYPE_BOOL,IDS_ACCESSIBILITY,IDS_ACCESSIBILITY_TIP,1},
|
||||
{L"ShowNextToTaskbar",CSetting::TYPE_BOOL,IDS_NEXTTASKBAR,IDS_NEXTTASKBAR_TIP,0},
|
||||
{L"PreCacheIcons",CSetting::TYPE_BOOL,IDS_CACHE_ICONS,IDS_CACHE_ICONS_TIP,1,CSetting::FLAG_COLD},
|
||||
{L"DelayIcons",CSetting::TYPE_BOOL,IDS_DELAY_ICONS,IDS_DELAY_ICONS_TIP,1,CSetting::FLAG_COLD},
|
||||
{L"BoldSettings",CSetting::TYPE_BOOL,IDS_BOLD_SETTINGS,IDS_BOLD_SETTINGS_TIP,1},
|
||||
{L"ReportSkinErrors",CSetting::TYPE_BOOL,IDS_SKIN_ERRORS,IDS_SKIN_ERRORS_TIP,0},
|
||||
|
||||
{L"SearchBoxSettings",CSetting::TYPE_GROUP,IDS_SEARCH_BOX},
|
||||
@@ -4330,6 +4365,8 @@ CSetting g_Settings[]={
|
||||
{L"Normal",CSetting::TYPE_RADIO,IDS_SEARCH_BOX_SHOW,IDS_SEARCH_BOX_SHOW_TIP},
|
||||
{L"Tab",CSetting::TYPE_RADIO,IDS_SEARCH_BOX_TAB,IDS_SEARCH_BOX_TAB_TIP},
|
||||
{L"SearchSelect",CSetting::TYPE_BOOL,IDS_SEARCH_BOX_SEL,IDS_SEARCH_BOX_SEL_TIP,1,0,L"SearchBox=1",L"Normal"},
|
||||
{L"SearchHint",CSetting::TYPE_BOOL,IDS_SEARCH_HINT,IDS_SEARCH_HINT_TIP,0,0,L"SearchBox"},
|
||||
{L"SearchHintText",CSetting::TYPE_STRING,IDS_NEW_SEARCH_HINT,IDS_NEW_SEARCH_HINT_TIP,L"",0,L"#SearchHint",L"SearchHint"},
|
||||
{L"SearchTrack",CSetting::TYPE_BOOL,IDS_SEARCH_TRACK,IDS_SEARCH_TRACK_TIP,1,0,L"SearchBox"},
|
||||
{L"SearchResults",CSetting::TYPE_INT,IDS_SEARCH_MAX2,IDS_SEARCH_MAX_TIP2,5,CSetting::FLAG_MENU_CLASSIC_BOTH,L"SearchBox"},
|
||||
{L"SearchResultsMax",CSetting::TYPE_INT,IDS_SEARCH_MAX3,IDS_SEARCH_MAX_TIP3,20,CSetting::FLAG_MENU_CLASSIC_BOTH,L"SearchBox"},
|
||||
@@ -4344,6 +4381,7 @@ CSetting g_Settings[]={
|
||||
{L"SearchContents",CSetting::TYPE_BOOL,IDS_SEARCH_CONTENTS,IDS_SEARCH_CONTENTS_TIP,1,0,L"#SearchFiles",L"SearchFiles"},
|
||||
{L"SearchCategories",CSetting::TYPE_BOOL,IDS_SEARCH_CATEGORIES,IDS_SEARCH_CATEGORIES_TIP,1,0,L"#SearchFiles",L"SearchFiles"},
|
||||
{L"SearchInternet",CSetting::TYPE_BOOL,IDS_SEARCH_INTERNET,IDS_SEARCH_INTERNET_TIP,1,0,L"SearchBox"},
|
||||
{L"MoreResults",CSetting::TYPE_BOOL,IDS_MORE_RESULTS,IDS_MORE_RESULTS_TIP,1,0,L"SearchBox"},
|
||||
|
||||
{L"Look",CSetting::TYPE_GROUP,IDS_LOOK_SETTINGS},
|
||||
{L"SmallIconSize",CSetting::TYPE_INT,IDS_SMALL_SIZE_SM,IDS_SMALL_SIZE_SM_TIP,-1,CSetting::FLAG_COLD}, // 16 for DPI<=96, 20 for DPI<=120, 24 otherwise
|
||||
@@ -4351,6 +4389,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
|
||||
@@ -4416,7 +4457,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},
|
||||
@@ -4425,8 +4466,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},
|
||||
@@ -4545,7 +4586,10 @@ void UpgradeSettings( bool bShared )
|
||||
items.Replace(L"Command=recent_items\n",L"Command=recent_programs\n");
|
||||
items.Replace(L"Command=control_panel_categories\n",L"Command=control_panel\n");
|
||||
pSettingItems->value=items;
|
||||
pSettingItems->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (pSettingItems->value==pSettingItems->defValue)
|
||||
pSettingItems->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pSettingItems->flags&=~CSetting::FLAG_DEFAULT;
|
||||
}
|
||||
|
||||
// set initial menu style
|
||||
@@ -4553,7 +4597,10 @@ void UpgradeSettings( bool bShared )
|
||||
if (!pSettingStyle->IsLocked())
|
||||
{
|
||||
pSettingStyle->value=(bTwoColumns?1:0);
|
||||
pSettingStyle->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (pSettingStyle->value==pSettingStyle->defValue)
|
||||
pSettingStyle->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pSettingStyle->flags&=~CSetting::FLAG_DEFAULT;
|
||||
SetSettingsStyle(bTwoColumns?CSetting::FLAG_MENU_CLASSIC2:CSetting::FLAG_MENU_CLASSIC1,CSetting::FLAG_MENU_MASK);
|
||||
}
|
||||
|
||||
@@ -4565,7 +4612,10 @@ void UpgradeSettings( bool bShared )
|
||||
if (!pSetting->IsDefault())
|
||||
{
|
||||
pSettingSkin->value=pSetting->value;
|
||||
pSettingSkin->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (pSettingSkin->value==pSettingSkin->defValue)
|
||||
pSettingSkin->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pSettingSkin->flags&=~CSetting::FLAG_DEFAULT;
|
||||
}
|
||||
}
|
||||
CSetting *pSettingOpt=FindSetting(bTwoColumns?L"SkinOptionsC2":L"SkinOptionsC1");
|
||||
@@ -4575,7 +4625,10 @@ void UpgradeSettings( bool bShared )
|
||||
if (!pSetting->IsDefault())
|
||||
{
|
||||
pSettingOpt->value=pSetting->value;
|
||||
pSettingOpt->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (pSettingOpt->value==pSettingOpt->defValue)
|
||||
pSettingOpt->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pSettingOpt->flags&=~CSetting::FLAG_DEFAULT;
|
||||
}
|
||||
}
|
||||
CSetting *pSettingVar=FindSetting(bTwoColumns?L"SkinVariationC2":L"SkinVariationC1");
|
||||
@@ -4585,7 +4638,10 @@ void UpgradeSettings( bool bShared )
|
||||
if (!pSetting->IsDefault())
|
||||
{
|
||||
pSettingVar->value=pSetting->value;
|
||||
pSettingVar->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (pSettingVar->value==pSettingVar->defValue)
|
||||
pSettingVar->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pSettingVar->flags&=~CSetting::FLAG_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4597,7 +4653,10 @@ void UpgradeSettings( bool bShared )
|
||||
if (!pSetting->IsDefault())
|
||||
{
|
||||
pSettingSkin->value=pSetting->value;
|
||||
pSettingSkin->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (pSettingSkin->value==pSettingSkin->defValue)
|
||||
pSettingSkin->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pSettingSkin->flags&=~CSetting::FLAG_DEFAULT;
|
||||
}
|
||||
}
|
||||
pSettingOpt=FindSetting(L"SkinOptionsA");
|
||||
@@ -4607,7 +4666,10 @@ void UpgradeSettings( bool bShared )
|
||||
if (!pSetting->IsDefault())
|
||||
{
|
||||
pSettingOpt->value=pSetting->value;
|
||||
pSettingOpt->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (pSettingOpt->value==pSettingOpt->defValue)
|
||||
pSettingOpt->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pSettingOpt->flags&=~CSetting::FLAG_DEFAULT;
|
||||
}
|
||||
}
|
||||
pSettingVar=FindSetting(L"SkinVariationA");
|
||||
@@ -4617,7 +4679,10 @@ void UpgradeSettings( bool bShared )
|
||||
if (!pSetting->IsDefault())
|
||||
{
|
||||
pSettingVar->value=pSetting->value;
|
||||
pSettingVar->flags&=~CSetting::FLAG_DEFAULT;
|
||||
if (pSettingVar->value==pSettingVar->defValue)
|
||||
pSettingVar->flags|=CSetting::FLAG_DEFAULT;
|
||||
else
|
||||
pSettingVar->flags&=~CSetting::FLAG_DEFAULT;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4659,11 +4724,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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -1762,7 +1778,7 @@ bool MenuSkin::LoadSkin( HMODULE hMod, const wchar_t *variation, const wchar_t *
|
||||
var.label=token;
|
||||
if (var.labelEn.IsEmpty())
|
||||
var.labelEn=var.label;
|
||||
Variations.push_back(std::pair<int,Variation>(res,var));
|
||||
Variations.emplace_back(res,var);
|
||||
LOG_MENU(LOG_OPEN,L"Variation found: name=%s, id=%d",token,res);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -79,6 +79,7 @@ enum
|
||||
OPEN_NOTHING,
|
||||
OPEN_CLASSIC,
|
||||
OPEN_WINDOWS,
|
||||
OPEN_CUSTOM,
|
||||
OPEN_BOTH,
|
||||
OPEN_DESKTOP,
|
||||
OPEN_CORTANA,
|
||||
@@ -2790,6 +2791,9 @@ static void OpenCortana( void )
|
||||
|
||||
static void InitStartMenuDLL( void )
|
||||
{
|
||||
LogToFile(STARTUP_LOG, L"StartMenu DLL: InitStartMenuDLL");
|
||||
WaitDllInitThread();
|
||||
|
||||
InitializeIatHooks();
|
||||
if (IsWin81Update1())
|
||||
{
|
||||
@@ -2817,39 +2821,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");
|
||||
@@ -3344,6 +3349,16 @@ static LRESULT CALLBACK HookProgManThread( int code, WPARAM wParam, LPARAM lPara
|
||||
msg->message=WM_NULL;
|
||||
if (control==OPEN_CLASSIC)
|
||||
PostMessage(g_TaskBar,g_StartMenuMsg,MSG_TOGGLE,0);
|
||||
else if (control==OPEN_CUSTOM)
|
||||
{
|
||||
CString commandText=GetSettingString(L"WinKeyCommand");
|
||||
if (!commandText.IsEmpty())
|
||||
{
|
||||
wchar_t expandedCommand[_MAX_PATH]{};
|
||||
::ExpandEnvironmentStrings(commandText, expandedCommand, _countof(expandedCommand));
|
||||
ShellExecute(NULL,NULL,expandedCommand,NULL,NULL,SW_SHOWNORMAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3427,6 +3442,16 @@ if (!g_bTrimHooks)
|
||||
PostMessage(g_ProgWin,WM_SYSCOMMAND,SC_TASKLIST,'WSMK');
|
||||
else if (control==OPEN_CORTANA)
|
||||
OpenCortana();
|
||||
else if (control==OPEN_CUSTOM)
|
||||
{
|
||||
CString commandText=GetSettingString(L"ShiftWinCommand");
|
||||
if (!commandText.IsEmpty())
|
||||
{
|
||||
wchar_t expandedCommand[_MAX_PATH]{};
|
||||
::ExpandEnvironmentStrings(commandText, expandedCommand, _countof(expandedCommand));
|
||||
ShellExecute(NULL,NULL,expandedCommand,NULL,NULL,SW_SHOWNORMAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (msg->wParam==MSG_DRAG || msg->wParam==MSG_SHIFTDRAG)
|
||||
{
|
||||
@@ -3586,12 +3611,22 @@ if (!g_bTrimHooks)
|
||||
// left or middle click on start button
|
||||
FindWindowsMenu();
|
||||
const wchar_t *name;
|
||||
const wchar_t *command;
|
||||
if (bMiddle)
|
||||
{
|
||||
name=L"MiddleClick";
|
||||
command=L"MiddleClickCommand";
|
||||
}
|
||||
else if (GetKeyState(VK_SHIFT)<0)
|
||||
{
|
||||
name=L"ShiftClick";
|
||||
command=L"ShiftClickCommand";
|
||||
}
|
||||
else
|
||||
{
|
||||
name=L"MouseClick";
|
||||
command=L"MouseClickCommand";
|
||||
}
|
||||
|
||||
int control=GetSettingInt(name);
|
||||
if (control==OPEN_BOTH && GetWinVersion()>=WIN_VER_WIN10)
|
||||
@@ -3607,6 +3642,16 @@ if (!g_bTrimHooks)
|
||||
PostMessage(g_ProgWin,WM_SYSCOMMAND,SC_TASKLIST,'WSMM');
|
||||
else if (control==OPEN_CORTANA)
|
||||
OpenCortana();
|
||||
else if (control==OPEN_CUSTOM)
|
||||
{
|
||||
CString commandText=GetSettingString(command);
|
||||
if (!commandText.IsEmpty())
|
||||
{
|
||||
wchar_t expandedCommand[_MAX_PATH]{};
|
||||
::ExpandEnvironmentStrings(commandText, expandedCommand, _countof(expandedCommand));
|
||||
ShellExecute(NULL,NULL,expandedCommand,NULL,NULL,SW_SHOWNORMAL);
|
||||
}
|
||||
}
|
||||
msg->message=WM_NULL;
|
||||
}
|
||||
}
|
||||
@@ -3747,6 +3792,16 @@ if (!g_bTrimHooks)
|
||||
FindWindowsMenu();
|
||||
PostMessage(g_ProgWin,WM_SYSCOMMAND,SC_TASKLIST,'WSMM');
|
||||
}
|
||||
else if (control==OPEN_CUSTOM)
|
||||
{
|
||||
CString commandText=GetSettingString(L"HoverCommand");
|
||||
if (!commandText.IsEmpty())
|
||||
{
|
||||
wchar_t expandedCommand[_MAX_PATH]{};
|
||||
::ExpandEnvironmentStrings(commandText, expandedCommand, _countof(expandedCommand));
|
||||
ShellExecute(NULL,NULL,expandedCommand,NULL,NULL,SW_SHOWNORMAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
taskBar->bTimer=false;
|
||||
@@ -3756,7 +3811,6 @@ if (!g_bTrimHooks)
|
||||
// context menu
|
||||
if (msg->message==WM_NCRBUTTONUP || msg->message==WM_RBUTTONUP)
|
||||
{
|
||||
CPoint pt0(GetMessagePos());
|
||||
TaskbarInfo *taskBar=FindTaskBarInfoButton(msg->hwnd);
|
||||
DWORD winVer=GetWinVersion();
|
||||
if (!taskBar && winVer>=WIN_VER_WIN8)
|
||||
@@ -3767,6 +3821,7 @@ if (!g_bTrimHooks)
|
||||
}
|
||||
if (taskBar)
|
||||
{
|
||||
CPoint pt0(GetMessagePos());
|
||||
if (msg->message==WM_RBUTTONUP && msg->hwnd==taskBar->startButton && msg->lParam==MAKELPARAM(-1,-1))
|
||||
{
|
||||
RECT rc;
|
||||
@@ -3801,6 +3856,7 @@ if (!g_bTrimHooks)
|
||||
CMD_OPEN,
|
||||
CMD_OPEN_ALL,
|
||||
CMD_EXPLORER,
|
||||
CMD_OPEN_PINNED,
|
||||
};
|
||||
|
||||
// right-click on the start button - open the context menu (Settings, Help, Exit)
|
||||
@@ -3821,6 +3877,8 @@ if (!g_bTrimHooks)
|
||||
AppendMenu(menu,MF_STRING,CMD_OPEN,FindTranslation(L"Menu.Open",L"&Open"));
|
||||
if (!SHRestricted(REST_NOCOMMONGROUPS))
|
||||
AppendMenu(menu,MF_STRING,CMD_OPEN_ALL,FindTranslation(L"Menu.OpenAll",L"O&pen All Users"));
|
||||
if (GetSettingInt(L"PinnedPrograms")==PINNED_PROGRAMS_PINNED)
|
||||
AppendMenu(menu,MF_STRING,CMD_OPEN_PINNED,FindTranslation(L"Menu.OpenPinned",L"O&pen Pinned"));
|
||||
AppendMenu(menu,MF_SEPARATOR,0,0);
|
||||
}
|
||||
if (GetSettingBool(L"EnableSettings"))
|
||||
@@ -3867,6 +3925,16 @@ if (!g_bTrimHooks)
|
||||
if (SUCCEEDED(ShGetKnownFolderPath((res==CMD_OPEN)?FOLDERID_StartMenu:FOLDERID_CommonStartMenu,&pPath)))
|
||||
ShellExecute(NULL,L"open",pPath,NULL,NULL,SW_SHOWNORMAL);
|
||||
}
|
||||
if (res==CMD_OPEN_PINNED) // open pinned folder
|
||||
{
|
||||
SHELLEXECUTEINFO execute={sizeof(execute)};
|
||||
CString path=GetSettingString(L"PinnedItemsPath");
|
||||
execute.lpVerb=L"open";
|
||||
execute.lpFile=path;
|
||||
execute.nShow=SW_SHOWNORMAL;
|
||||
execute.fMask=SEE_MASK_DOENVSUBST;
|
||||
ShellExecuteEx(&execute);
|
||||
}
|
||||
if (res==CMD_EXPLORER)
|
||||
{
|
||||
CString path=GetSettingString(L"ExplorerPath");
|
||||
|
||||
@@ -369,19 +369,20 @@ IDI_START10 ICON "start10.ico"
|
||||
IDB_ARROWS BITMAP "menu_arrows.bmp"
|
||||
IDB_ARROWS150 BITMAP "menu_arrows150.bmp"
|
||||
IDB_SEARCH_ICONS BITMAP "search_icons.bmp"
|
||||
IDB_STYLE_CLASSIC1 BITMAP "style_classic.bmp"
|
||||
IDB_STYLE_CLASSIC2 BITMAP "style_vista.bmp"
|
||||
IDB_STYLE_WIN7 BITMAP "style_7.bmp"
|
||||
IDB_BTN_CLASSIC BITMAP "btn_classic.bmp"
|
||||
IDB_STYLE_CLASSIC1150 BITMAP "style_classic150.bmp"
|
||||
IDB_STYLE_CLASSIC2150 BITMAP "style_vista150.bmp"
|
||||
IDB_STYLE_WIN7150 BITMAP "style_7150.bmp"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMAGE
|
||||
//
|
||||
|
||||
IDB_STYLE_CLASSIC1 IMAGE "style_classic.png"
|
||||
IDB_STYLE_CLASSIC2 IMAGE "style_vista.png"
|
||||
IDB_STYLE_WIN7 IMAGE "style_7.png"
|
||||
IDB_STYLE_CLASSIC1150 IMAGE "style_classic150.png"
|
||||
IDB_STYLE_CLASSIC2150 IMAGE "style_vista150.png"
|
||||
IDB_STYLE_WIN7150 IMAGE "style_7150.png"
|
||||
|
||||
IDB_BUTTON96 IMAGE "button96.png"
|
||||
IDB_BUTTON120 IMAGE "button120.png"
|
||||
IDB_BUTTON144 IMAGE "button144.png"
|
||||
@@ -643,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"
|
||||
@@ -1037,7 +1044,7 @@ BEGIN
|
||||
IDS_FOLDERS_FIRST "Show folders first"
|
||||
IDS_FOLDERS_FIRST_TIP "When this is checked, the All Programs tree will show the folders first and the programs last"
|
||||
IDS_PINNED_PROGRAMS "Pinned Programs folder"
|
||||
IDS_PINNED_PROGRAMS_TIP "Select the location to store the pinned programs"
|
||||
IDS_PINNED_PROGRAMS_TIP "Select the location to store pinned programs. After updating this setting, close this window in order to pin items through the context menu again"
|
||||
IDS_FAST_ITEMS "Use Start Menu folder"
|
||||
END
|
||||
|
||||
@@ -1153,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
|
||||
@@ -1288,6 +1295,34 @@ BEGIN
|
||||
IDS_CLEAR_CACHE "Clear cached information"
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_NO_DBLCLICK "Single-click to open folder shortcuts"
|
||||
IDS_NO_DBLCLICK_TIP "When this is checked, single-clicking shortcuts (links) to folders will open them in explorer. Hovering over the shortcut will still expand sub-menus"
|
||||
IDS_BOLD_SETTINGS "Highlight modified settings"
|
||||
IDS_BOLD_SETTINGS_TIP "When this is checked, settings that have been modified from their defaults will be highlighted in bold"
|
||||
IDS_SEARCH_HINT "Custom search hint"
|
||||
IDS_SEARCH_HINT_TIP "When this is checked, the hint text in the search box will be replaced"
|
||||
IDS_NEW_SEARCH_HINT "Custom search hint text"
|
||||
IDS_NEW_SEARCH_HINT_TIP "The text to replace the search hint with. Empty text is a valid option"
|
||||
IDS_MORE_RESULTS "Enable ""See more results"" option"
|
||||
IDS_MORE_RESULTS_TIP "When this is checked, the search results will include an option to do a more advanced search"
|
||||
IDS_OPEN_CMD "Custom command"
|
||||
IDS_OPEN_CMD_TIP "The action will run a user-defined command"
|
||||
IDS_OPEN_CMD_TEXT "Command to run"
|
||||
IDS_OPEN_CMD_TEXT_TIP "Enter the command to run when you use this control"
|
||||
IDS_ITEM_LINKS "Display as a list of links"
|
||||
IDS_ITEM_LINKS_TIP "This item will appear as a sub-menu showing only its top-level contents"
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_OPEN_TRUE_PATH "Open pinned folders to their true path"
|
||||
IDS_OPEN_TRUE_PATH_TIP "When this is checked, pinned folders will open to their true path instead of the path to their shortcut in the Pinned Programs folder"
|
||||
IDS_PINNED_PATH "Pinned folder path"
|
||||
IDS_PINNED_PATH_TIP "The path to use as the Pinned folder. If the path does not exist, it will be created (if possible) after opening the start menu. Close this window after updating this setting to update your context menu.\n\nNote: If you do not have permissions for the selected path, you will not be able to pin items until you take ownership of the new folder"
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -136,7 +136,6 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CLASSICSTARTMENUDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
@@ -161,7 +160,6 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CLASSICSTARTMENUDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
|
||||
@@ -754,6 +754,32 @@
|
||||
#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_NO_DBLCLICK 3666
|
||||
#define IDS_NO_DBLCLICK_TIP 3667
|
||||
#define IDS_BOLD_SETTINGS 3668
|
||||
#define IDS_BOLD_SETTINGS_TIP 3669
|
||||
#define IDS_SEARCH_HINT 3670
|
||||
#define IDS_SEARCH_HINT_TIP 3671
|
||||
#define IDS_NEW_SEARCH_HINT 3672
|
||||
#define IDS_NEW_SEARCH_HINT_TIP 3673
|
||||
#define IDS_MORE_RESULTS 3674
|
||||
#define IDS_MORE_RESULTS_TIP 3675
|
||||
#define IDS_OPEN_CMD 3676
|
||||
#define IDS_OPEN_CMD_TIP 3677
|
||||
#define IDS_OPEN_CMD_TEXT 3678
|
||||
#define IDS_OPEN_CMD_TEXT_TIP 3679
|
||||
#define IDS_ITEM_LINKS 3680
|
||||
#define IDS_ITEM_LINKS_TIP 3681
|
||||
#define IDS_OPEN_TRUE_PATH 3682
|
||||
#define IDS_OPEN_TRUE_PATH_TIP 3683
|
||||
#define IDS_PINNED_PATH 3684
|
||||
#define IDS_PINNED_PATH_TIP 3685
|
||||
#define IDS_STRING7001 7001
|
||||
#define IDS_STRING7002 7002
|
||||
#define IDS_STRING7003 7003
|
||||
|
||||
|
Before Width: | Height: | Size: 125 KiB |
BIN
Src/StartMenu/StartMenuDLL/style_7.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 270 KiB |
BIN
Src/StartMenu/StartMenuDLL/style_7150.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 84 KiB |
BIN
Src/StartMenu/StartMenuDLL/style_classic.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 182 KiB |
BIN
Src/StartMenu/StartMenuDLL/style_classic150.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 120 KiB |
BIN
Src/StartMenu/StartMenuDLL/style_vista.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 259 KiB |
BIN
Src/StartMenu/StartMenuDLL/style_vista150.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
434
Src/StartMenu/StartMenuHelper/ModernSettings.cpp
Normal file
@@ -0,0 +1,434 @@
|
||||
// Modern settings helper
|
||||
|
||||
// - parse modern settings definitions from %windir%\ImmersiveControlPanel\Settings\AllSystemSettings_{253E530E-387D-4BC2-959D-E6F86122E5F2}.xml
|
||||
// - store cached data (parsed settings, localized strings) in %LOCALAPPDATA%\OpenShell\ModernSettings.dat
|
||||
// - provide mapped view over cached data
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ModernSettings.h"
|
||||
#include "ResourceHelper.h"
|
||||
#include <Shlobj.h>
|
||||
#include <Shlwapi.h>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <mutex>
|
||||
|
||||
enum class Id : uint32_t
|
||||
{
|
||||
Header = 'SMSO',
|
||||
Undef = 0,
|
||||
Blob,
|
||||
FileName,
|
||||
DeepLink,
|
||||
Icon,
|
||||
Glyph,
|
||||
PageId,
|
||||
HostId,
|
||||
GroupId,
|
||||
SettingId,
|
||||
Description,
|
||||
Keywords,
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
struct FileHdr
|
||||
{
|
||||
uint32_t openShellVersion = GetVersionEx(g_Instance);
|
||||
uint32_t windowsVersion = GetVersionEx(GetModuleHandle(L"user32.dll"));
|
||||
uint32_t userLanguageId = GetUserDefaultUILanguage();
|
||||
|
||||
bool operator==(const FileHdr& other) const
|
||||
{
|
||||
return (windowsVersion == other.windowsVersion) &&
|
||||
(openShellVersion == other.openShellVersion) &&
|
||||
(userLanguageId == other.userLanguageId);
|
||||
}
|
||||
};
|
||||
|
||||
struct ItemHdr
|
||||
{
|
||||
Id id;
|
||||
uint32_t size;
|
||||
|
||||
const uint8_t* data() const
|
||||
{
|
||||
return (const uint8_t*)this + sizeof(*this);
|
||||
}
|
||||
|
||||
const ItemHdr* next() const
|
||||
{
|
||||
return (const ItemHdr*)(data() + size);
|
||||
}
|
||||
|
||||
std::wstring_view asString() const
|
||||
{
|
||||
std::wstring_view retval((const wchar_t*)data(), size / sizeof(wchar_t));
|
||||
if (!retval.empty() && retval.back() == 0)
|
||||
{
|
||||
retval.remove_suffix(1);
|
||||
return retval;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
class AttributeWriter
|
||||
{
|
||||
public:
|
||||
std::vector<uint8_t> buffer()
|
||||
{
|
||||
return std::move(m_buffer);
|
||||
}
|
||||
|
||||
void addBlob(Id id, const void* data, size_t size)
|
||||
{
|
||||
ItemHdr hdr{ id, (uint32_t)size };
|
||||
append(&hdr, sizeof(hdr));
|
||||
append(data, size);
|
||||
}
|
||||
|
||||
void addString(Id id, const std::wstring& str)
|
||||
{
|
||||
if (!str.empty())
|
||||
addBlob(id, str.data(), (str.size() + 1) * sizeof(str[0]));
|
||||
}
|
||||
|
||||
private:
|
||||
void append(const void* data, size_t size)
|
||||
{
|
||||
m_buffer.insert(m_buffer.end(), (const uint8_t*)data, (const uint8_t*)data + size);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> m_buffer;
|
||||
};
|
||||
|
||||
static void ProcessAttributes(const void* buffer, size_t size, std::function<void(const ItemHdr&)> callback)
|
||||
{
|
||||
if (size < sizeof(ItemHdr))
|
||||
return;
|
||||
|
||||
auto item = (const ItemHdr*)buffer;
|
||||
auto last = (const ItemHdr*)((const uint8_t*)buffer + size);
|
||||
|
||||
while (item < last)
|
||||
{
|
||||
auto next = item->next();
|
||||
if (next <= item || next > last)
|
||||
break;
|
||||
|
||||
callback(*item);
|
||||
|
||||
item = next;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
static std::wstring TranslateIndirectString(const WCHAR* string)
|
||||
{
|
||||
std::wstring retval;
|
||||
retval.resize(1024);
|
||||
|
||||
if (SUCCEEDED(::SHLoadIndirectString(string, retval.data(), (UINT)retval.size(), nullptr)))
|
||||
{
|
||||
retval.resize(wcslen(retval.data()));
|
||||
return retval;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
static std::wstring TranslateIndirectMultiString(const WCHAR* string)
|
||||
{
|
||||
std::wstring retval;
|
||||
std::wstring_view str(string);
|
||||
|
||||
// remove '@'
|
||||
str.remove_prefix(1);
|
||||
|
||||
while (!str.empty())
|
||||
{
|
||||
auto len = str.find(L'@', 1);
|
||||
if (len == std::wstring::npos)
|
||||
len = str.length();
|
||||
|
||||
std::wstring tmp(str.substr(0, len));
|
||||
retval += TranslateIndirectString(tmp.c_str());
|
||||
|
||||
str.remove_prefix(len);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static std::wstring GetTranslatedString(CComPtr<IXMLDOMNode>& parent, const WCHAR* name)
|
||||
{
|
||||
CComPtr<IXMLDOMNode> node;
|
||||
if (parent->selectSingleNode(CComBSTR(name), &node) == S_OK)
|
||||
{
|
||||
CComBSTR value;
|
||||
if (node->get_text(&value) == S_OK)
|
||||
{
|
||||
if (value[0] == L'@')
|
||||
{
|
||||
if (value[1] == L'@')
|
||||
return TranslateIndirectMultiString(value);
|
||||
else
|
||||
return TranslateIndirectString(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (LPWSTR)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
static void ParseFileName(CComPtr<IXMLDOMNode>& parent, AttributeWriter& writer)
|
||||
{
|
||||
writer.addString(Id::FileName, GetTranslatedString(parent, L"Filename"));
|
||||
}
|
||||
|
||||
static void ParseApplicationInformation(CComPtr<IXMLDOMNode>& parent, AttributeWriter& writer)
|
||||
{
|
||||
CComPtr<IXMLDOMNode> node;
|
||||
if (parent->selectSingleNode(CComBSTR(L"ApplicationInformation"), &node) == S_OK)
|
||||
{
|
||||
writer.addString(Id::DeepLink, GetTranslatedString(node, L"DeepLink"));
|
||||
writer.addString(Id::Icon, GetTranslatedString(node, L"Icon"));
|
||||
writer.addString(Id::Glyph, GetTranslatedString(node, L"Glyph"));
|
||||
}
|
||||
}
|
||||
|
||||
static void ParseSettingIdentity(CComPtr<IXMLDOMNode>& parent, AttributeWriter& writer)
|
||||
{
|
||||
CComPtr<IXMLDOMNode> node;
|
||||
if (parent->selectSingleNode(CComBSTR(L"SettingIdentity"), &node) == S_OK)
|
||||
{
|
||||
writer.addString(Id::PageId, GetTranslatedString(node, L"PageID"));
|
||||
writer.addString(Id::HostId, GetTranslatedString(node, L"HostID"));
|
||||
writer.addString(Id::GroupId, GetTranslatedString(node, L"GroupID"));
|
||||
writer.addString(Id::SettingId, GetTranslatedString(node, L"SettingID"));
|
||||
}
|
||||
}
|
||||
|
||||
static void ParseSettingInformation(CComPtr<IXMLDOMNode>& parent, AttributeWriter& writer)
|
||||
{
|
||||
CComPtr<IXMLDOMNode> node;
|
||||
if (parent->selectSingleNode(CComBSTR(L"SettingInformation"), &node) == S_OK)
|
||||
{
|
||||
auto description = GetTranslatedString(node, L"Description");
|
||||
if (description.empty())
|
||||
description = GetTranslatedString(node, L"Name");
|
||||
|
||||
writer.addString(Id::Description, description);
|
||||
|
||||
auto keywords = GetTranslatedString(node, L"HighKeywords");
|
||||
keywords += GetTranslatedString(node, L"LowKeywords");
|
||||
keywords += GetTranslatedString(node, L"Keywords");
|
||||
|
||||
writer.addString(Id::Keywords, keywords);
|
||||
}
|
||||
}
|
||||
|
||||
static std::vector<uint8_t> ParseSetting(CComPtr<IXMLDOMNode>& parent)
|
||||
{
|
||||
AttributeWriter writer;
|
||||
|
||||
ParseFileName(parent, writer);
|
||||
ParseApplicationInformation(parent, writer);
|
||||
ParseSettingIdentity(parent, writer);
|
||||
ParseSettingInformation(parent, writer);
|
||||
|
||||
return writer.buffer();
|
||||
}
|
||||
|
||||
static std::vector<uint8_t> ParseModernSettings()
|
||||
{
|
||||
AttributeWriter writer;
|
||||
|
||||
CComPtr<IXMLDOMDocument> doc;
|
||||
if (SUCCEEDED(doc.CoCreateInstance(L"Msxml2.FreeThreadedDOMDocument")))
|
||||
{
|
||||
doc->put_async(VARIANT_FALSE);
|
||||
|
||||
wchar_t path[MAX_PATH]{};
|
||||
wcscpy_s(path, LR"(%windir%\ImmersiveControlPanel\Settings\AllSystemSettings_{253E530E-387D-4BC2-959D-E6F86122E5F2}.xml)");
|
||||
DoEnvironmentSubst(path, _countof(path));
|
||||
|
||||
VARIANT_BOOL loaded;
|
||||
if (SUCCEEDED(doc->load(CComVariant(path), &loaded)) && loaded)
|
||||
{
|
||||
CComPtr<IXMLDOMNode> root;
|
||||
if (doc->selectSingleNode(CComBSTR(L"PCSettings"), &root) == S_OK)
|
||||
{
|
||||
FileHdr hdr{};
|
||||
writer.addBlob(Id::Header, &hdr, sizeof(hdr));
|
||||
|
||||
CComPtr<IXMLDOMNode> node;
|
||||
root->get_firstChild(&node);
|
||||
while (node)
|
||||
{
|
||||
auto buffer = ParseSetting(node);
|
||||
if (!buffer.empty())
|
||||
writer.addBlob(Id::Blob, buffer.data(), buffer.size());
|
||||
|
||||
CComPtr<IXMLDOMNode> next;
|
||||
if (FAILED(node->get_nextSibling(&next)))
|
||||
break;
|
||||
node = std::move(next);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return writer.buffer();
|
||||
}
|
||||
|
||||
ModernSettings::ModernSettings(const wchar_t* fname) : m_storage(fname)
|
||||
{
|
||||
if (m_storage)
|
||||
{
|
||||
bool valid = false;
|
||||
auto s = m_storage.get();
|
||||
ProcessAttributes(s.data, s.size, [&](const ItemHdr& item) {
|
||||
switch (item.id)
|
||||
{
|
||||
case Id::Header:
|
||||
if (item.size >= sizeof(FileHdr))
|
||||
{
|
||||
const auto hdr = (const FileHdr*)item.data();
|
||||
if (FileHdr() == *hdr)
|
||||
valid = true;
|
||||
}
|
||||
break;
|
||||
case Id::Blob:
|
||||
if (valid)
|
||||
{
|
||||
const Blob blob = { item.data(), item.size };
|
||||
ModernSettings::Setting s(blob);
|
||||
if (s)
|
||||
m_settings.emplace(s.fileName, blob);
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ModernSettings::Setting::Setting(const Blob& blob)
|
||||
{
|
||||
ProcessAttributes(blob.data, blob.size, [&](const ItemHdr& item) {
|
||||
switch (item.id)
|
||||
{
|
||||
case Id::FileName:
|
||||
fileName = item.asString();
|
||||
break;
|
||||
case Id::DeepLink:
|
||||
deepLink = item.asString();
|
||||
break;
|
||||
case Id::Glyph:
|
||||
glyph = item.asString();
|
||||
break;
|
||||
case Id::Icon:
|
||||
icon = item.asString();
|
||||
break;
|
||||
case Id::PageId:
|
||||
pageId = item.asString();
|
||||
break;
|
||||
case Id::HostId:
|
||||
hostId = item.asString();
|
||||
break;
|
||||
case Id::GroupId:
|
||||
groupId = item.asString();
|
||||
break;
|
||||
case Id::SettingId:
|
||||
settingId = item.asString();
|
||||
break;
|
||||
case Id::Description:
|
||||
description = item.asString();;
|
||||
break;
|
||||
case Id::Keywords:
|
||||
keywords = item.asString();
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<std::wstring_view> ModernSettings::enumerate() const
|
||||
{
|
||||
std::vector<std::wstring_view> retval;
|
||||
retval.reserve(m_settings.size());
|
||||
|
||||
for (const auto& i : m_settings)
|
||||
retval.emplace_back(i.first);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
ModernSettings::Setting ModernSettings::get(const std::wstring_view& name) const
|
||||
{
|
||||
auto it = m_settings.find(name);
|
||||
if (it != m_settings.end())
|
||||
return { (*it).second };
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
static std::mutex s_lock;
|
||||
static std::shared_ptr<ModernSettings> s_settings;
|
||||
|
||||
std::wstring GetLocalAppData()
|
||||
{
|
||||
WCHAR path[MAX_PATH]{};
|
||||
wcscpy_s(path, L"%LOCALAPPDATA%\\OpenShell");
|
||||
DoEnvironmentSubst(path, _countof(path));
|
||||
|
||||
// make sure directory exists
|
||||
SHCreateDirectory(nullptr, path);
|
||||
|
||||
return { path };
|
||||
}
|
||||
|
||||
std::shared_ptr<ModernSettings> GetModernSettings()
|
||||
{
|
||||
std::unique_lock l(s_lock);
|
||||
|
||||
if (!s_settings)
|
||||
{
|
||||
auto path = GetLocalAppData();
|
||||
path += L"\\ModernSettings.dat";
|
||||
|
||||
// try to open cached settings
|
||||
s_settings = std::make_shared<ModernSettings>(path.c_str());
|
||||
if (s_settings->size() == 0)
|
||||
{
|
||||
// file doesn't exist or wrong format
|
||||
s_settings.reset();
|
||||
|
||||
// re-parse settings
|
||||
auto buffer = ParseModernSettings();
|
||||
if (!buffer.empty())
|
||||
{
|
||||
// store to file
|
||||
{
|
||||
File f(path.c_str(), GENERIC_WRITE, 0, CREATE_ALWAYS);
|
||||
if (f)
|
||||
{
|
||||
DWORD written;
|
||||
::WriteFile(f, buffer.data(), (DWORD)buffer.size(), &written, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
// and try again
|
||||
s_settings = std::make_shared<ModernSettings>(path.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s_settings;
|
||||
}
|
||||
139
Src/StartMenu/StartMenuHelper/ModernSettings.h
Normal file
@@ -0,0 +1,139 @@
|
||||
// Modern settings helper
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct Blob
|
||||
{
|
||||
const void* data = nullptr;
|
||||
size_t size = 0;
|
||||
};
|
||||
|
||||
class File
|
||||
{
|
||||
public:
|
||||
File(const WCHAR* fileName, DWORD desiredAccess, DWORD shareMode, DWORD creationDisposition = OPEN_EXISTING, DWORD flagsAndAttributes = FILE_ATTRIBUTE_NORMAL)
|
||||
{
|
||||
m_handle = ::CreateFile(fileName, desiredAccess, shareMode, nullptr, creationDisposition, flagsAndAttributes, nullptr);
|
||||
}
|
||||
|
||||
~File()
|
||||
{
|
||||
if (m_handle != INVALID_HANDLE_VALUE)
|
||||
::CloseHandle(m_handle);
|
||||
}
|
||||
|
||||
File(const File&) = delete;
|
||||
File& operator=(const File&) = delete;
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
return (m_handle != INVALID_HANDLE_VALUE);
|
||||
}
|
||||
|
||||
operator HANDLE() const
|
||||
{
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
uint64_t size() const
|
||||
{
|
||||
LARGE_INTEGER li = {};
|
||||
return ::GetFileSizeEx(m_handle, &li) ? li.QuadPart : (uint64_t)-1;
|
||||
}
|
||||
|
||||
private:
|
||||
HANDLE m_handle;
|
||||
};
|
||||
|
||||
class MappedFile
|
||||
{
|
||||
public:
|
||||
MappedFile(const WCHAR* fileName) : m_file(fileName, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_DELETE)
|
||||
{
|
||||
if (m_file)
|
||||
{
|
||||
auto mapping = ::CreateFileMapping(m_file, nullptr, PAGE_READONLY, 0, 0, nullptr);
|
||||
if (mapping)
|
||||
{
|
||||
m_view.data = ::MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
|
||||
if (m_view.data)
|
||||
m_view.size = (size_t)m_file.size();
|
||||
|
||||
::CloseHandle(mapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~MappedFile()
|
||||
{
|
||||
if (m_view.data)
|
||||
::UnmapViewOfFile(m_view.data);
|
||||
}
|
||||
|
||||
MappedFile(const MappedFile&) = delete;
|
||||
MappedFile& operator=(const MappedFile&) = delete;
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
return (m_view.data != nullptr);
|
||||
}
|
||||
|
||||
Blob get() const
|
||||
{
|
||||
return m_view;
|
||||
}
|
||||
|
||||
private:
|
||||
File m_file;
|
||||
Blob m_view;
|
||||
};
|
||||
|
||||
class ModernSettings
|
||||
{
|
||||
public:
|
||||
ModernSettings(const wchar_t* fname);
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
return m_settings.size();
|
||||
}
|
||||
|
||||
struct Setting
|
||||
{
|
||||
std::wstring_view fileName;
|
||||
|
||||
std::wstring_view deepLink;
|
||||
std::wstring_view icon;
|
||||
std::wstring_view glyph;
|
||||
|
||||
std::wstring_view pageId;
|
||||
std::wstring_view hostId;
|
||||
std::wstring_view groupId;
|
||||
std::wstring_view settingId;
|
||||
std::wstring_view description;
|
||||
std::wstring_view keywords;
|
||||
|
||||
Setting() = default;
|
||||
Setting(const Blob& blob);
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
return !fileName.empty();
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<std::wstring_view> enumerate() const;
|
||||
Setting get(const std::wstring_view& name) const;
|
||||
|
||||
private:
|
||||
MappedFile m_storage;
|
||||
std::map<std::wstring_view, Blob> m_settings;
|
||||
};
|
||||
|
||||
// retrieve actual instance of ModernSettings
|
||||
std::shared_ptr<ModernSettings> GetModernSettings();
|
||||
210
Src/StartMenu/StartMenuHelper/ModernSettingsContextMenu.cpp
Normal file
@@ -0,0 +1,210 @@
|
||||
// Context menu handler for Open-Shell Modern Settings shell folder
|
||||
|
||||
// Based on Explorer Data Provider Sample (https://docs.microsoft.com/en-us/windows/win32/shell/samples-explorerdataprovider)
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ModernSettings.h"
|
||||
#include "ModernSettingsContextMenu.h"
|
||||
#include "ComHelper.h"
|
||||
|
||||
#define MENUVERB_OPEN 0
|
||||
|
||||
struct ICIVERBTOIDMAP
|
||||
{
|
||||
LPCWSTR pszCmd; // verbW
|
||||
LPCSTR pszCmdA; // verbA
|
||||
UINT idCmd; // hmenu id
|
||||
};
|
||||
|
||||
static const ICIVERBTOIDMAP g_ContextMenuIDMap[] =
|
||||
{
|
||||
{ L"open", "open", MENUVERB_OPEN },
|
||||
};
|
||||
|
||||
HRESULT _MapICIVerbToCmdID(LPCMINVOKECOMMANDINFO pici, UINT* pid)
|
||||
{
|
||||
if (IS_INTRESOURCE(pici->lpVerb))
|
||||
{
|
||||
*pid = LOWORD((UINT_PTR)pici->lpVerb);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (pici->fMask & CMIC_MASK_UNICODE)
|
||||
{
|
||||
for (const auto& i : g_ContextMenuIDMap)
|
||||
{
|
||||
if (StrCmpIC(((LPCMINVOKECOMMANDINFOEX)pici)->lpVerbW, i.pszCmd) == 0)
|
||||
{
|
||||
*pid = i.idCmd;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto& i : g_ContextMenuIDMap)
|
||||
{
|
||||
if (StrCmpICA(pici->lpVerb, i.pszCmdA) == 0)
|
||||
{
|
||||
*pid = i.idCmd;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static bool ActivateModernSettingPage(const WCHAR* page)
|
||||
{
|
||||
CComPtr<IApplicationActivationManager> mgr;
|
||||
mgr.CoCreateInstance(CLSID_ApplicationActivationManager);
|
||||
if (mgr)
|
||||
{
|
||||
DWORD pid = 0;
|
||||
return SUCCEEDED(mgr->ActivateApplication(L"windows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel", page, AO_NONE, &pid));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
extern ModernSettings::Setting GetModernSetting(LPCITEMIDLIST pidl);
|
||||
|
||||
static HRESULT Execute(const wchar_t* cmd)
|
||||
{
|
||||
return (intptr_t)::ShellExecute(nullptr, L"open", cmd, nullptr, nullptr, SW_SHOWNORMAL) > 32 ? S_OK : E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT OpenItemByPidl(LPCITEMIDLIST pidl)
|
||||
{
|
||||
auto child = ILFindLastID(pidl);
|
||||
auto setting = GetModernSetting(child);
|
||||
|
||||
if (!setting)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (setting.hostId == L"{6E6DDBCB-9C89-434B-A994-D5F22239523B}")
|
||||
{
|
||||
if (setting.deepLink.empty())
|
||||
return E_INVALIDARG;
|
||||
|
||||
std::wstring cmd(L"windowsdefender://");
|
||||
cmd += setting.deepLink;
|
||||
|
||||
return Execute(cmd.c_str());
|
||||
}
|
||||
|
||||
if (setting.hostId == L"{7E0522FC-1AC4-41CA-AFD0-3610417A9C41}")
|
||||
{
|
||||
if (setting.pageId.empty())
|
||||
return E_INVALIDARG;
|
||||
|
||||
std::wstring cmd(L"shell:::");
|
||||
cmd += setting.pageId;
|
||||
|
||||
return Execute(cmd.c_str());
|
||||
}
|
||||
|
||||
if (setting.hostId == L"{12B1697E-D3A0-4DBC-B568-CCF64A3F934D}")
|
||||
{
|
||||
if (setting.deepLink.empty())
|
||||
return E_INVALIDARG;
|
||||
|
||||
std::wstring cmd(setting.deepLink);
|
||||
|
||||
if (cmd.compare(0, 8, L"shell:::") == 0)
|
||||
return Execute(cmd.c_str());
|
||||
|
||||
cmd.resize(MAX_PATH);
|
||||
DoEnvironmentSubst(cmd.data(), (UINT)cmd.size());
|
||||
|
||||
STARTUPINFO startupInfo = { sizeof(startupInfo) };
|
||||
PROCESS_INFORMATION processInfo{};
|
||||
|
||||
if (!CreateProcess(nullptr, cmd.data(), nullptr, nullptr, FALSE, 0, nullptr, nullptr, &startupInfo, &processInfo))
|
||||
return E_FAIL;
|
||||
|
||||
CloseHandle(processInfo.hThread);
|
||||
CloseHandle(processInfo.hProcess);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (setting.pageId.empty())
|
||||
return E_INVALIDARG;
|
||||
|
||||
std::wstring page;
|
||||
|
||||
page += L"page=";
|
||||
page += setting.pageId;
|
||||
|
||||
if (!setting.settingId.empty())
|
||||
{
|
||||
page += L"&target=";
|
||||
page += setting.settingId;
|
||||
}
|
||||
else if (!setting.groupId.empty())
|
||||
{
|
||||
page += L"&group=";
|
||||
page += setting.groupId;
|
||||
}
|
||||
|
||||
page += L"&ActivationType=Search";
|
||||
|
||||
ActivateModernSettingPage(page.c_str());
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
// CModernSettingsContextMenu
|
||||
|
||||
HRESULT CModernSettingsContextMenu::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT /* idCmdLast */, UINT /* uFlags */)
|
||||
{
|
||||
InsertMenu(hmenu, indexMenu++, MF_BYPOSITION, idCmdFirst + MENUVERB_OPEN, L"Open");
|
||||
// other verbs could go here...
|
||||
|
||||
// indicate that we added one verb.
|
||||
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, (USHORT)(1));
|
||||
}
|
||||
|
||||
HRESULT CModernSettingsContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO pici)
|
||||
{
|
||||
HRESULT hr = E_INVALIDARG;
|
||||
UINT uID;
|
||||
// Is this command for us?
|
||||
if (SUCCEEDED(_MapICIVerbToCmdID(pici, &uID)))
|
||||
{
|
||||
if (uID == MENUVERB_OPEN && m_pdtobj)
|
||||
{
|
||||
CAbsolutePidl pidl;
|
||||
hr = SHGetIDListFromObject(m_pdtobj, &pidl);
|
||||
if (SUCCEEDED(hr))
|
||||
hr = OpenItemByPidl(pidl);
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CModernSettingsContextMenu::GetCommandString(UINT_PTR /* idCmd */, UINT /* uType */, UINT* /* pRes */, LPSTR /* pszName */, UINT /* cchMax */)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT CModernSettingsContextMenu::Initialize(PCIDLIST_ABSOLUTE /* pidlFolder */, IDataObject* pdtobj, HKEY /* hkeyProgID */)
|
||||
{
|
||||
m_pdtobj = pdtobj;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CModernSettingsContextMenu::SetSite(IUnknown* punkSite)
|
||||
{
|
||||
m_punkSite = punkSite;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CModernSettingsContextMenu::GetSite(REFIID riid, void** ppvSite)
|
||||
{
|
||||
return m_punkSite ? m_punkSite->QueryInterface(riid, ppvSite) : E_FAIL;
|
||||
}
|
||||
60
Src/StartMenu/StartMenuHelper/ModernSettingsContextMenu.h
Normal file
@@ -0,0 +1,60 @@
|
||||
// Context menu handler for Open-Shell Modern Settings shell folder
|
||||
|
||||
#pragma once
|
||||
#include "resource.h"
|
||||
#include "StartMenuHelper_i.h"
|
||||
#include <shlobj.h>
|
||||
|
||||
// CModernSettingsContextMenu
|
||||
|
||||
class ATL_NO_VTABLE CModernSettingsContextMenu :
|
||||
public CComObjectRootEx<CComSingleThreadModel>,
|
||||
public CComCoClass<CModernSettingsContextMenu, &CLSID_ModernSettingsContextMenu>,
|
||||
public IContextMenu,
|
||||
public IShellExtInit,
|
||||
public IObjectWithSite
|
||||
{
|
||||
public:
|
||||
CModernSettingsContextMenu()
|
||||
{
|
||||
}
|
||||
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_MODERNSETTINGSCONTEXTMENU)
|
||||
|
||||
DECLARE_NOT_AGGREGATABLE(CModernSettingsContextMenu)
|
||||
|
||||
BEGIN_COM_MAP(CModernSettingsContextMenu)
|
||||
COM_INTERFACE_ENTRY(IContextMenu)
|
||||
COM_INTERFACE_ENTRY(IShellExtInit)
|
||||
COM_INTERFACE_ENTRY(IObjectWithSite)
|
||||
END_COM_MAP()
|
||||
|
||||
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||||
|
||||
HRESULT FinalConstruct()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void FinalRelease()
|
||||
{
|
||||
}
|
||||
|
||||
// IContextMenu
|
||||
IFACEMETHODIMP QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
|
||||
IFACEMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO lpici);
|
||||
IFACEMETHODIMP GetCommandString(UINT_PTR idCmd, UINT uType, UINT* pRes, LPSTR pszName, UINT cchMax);
|
||||
|
||||
// IShellExtInit
|
||||
IFACEMETHODIMP Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject* pdtobj, HKEY hkeyProgID);
|
||||
|
||||
// IObjectWithSite
|
||||
IFACEMETHODIMP SetSite(IUnknown* punkSite);
|
||||
IFACEMETHODIMP GetSite(REFIID riid, void** ppvSite);
|
||||
|
||||
private:
|
||||
CComPtr<IDataObject> m_pdtobj;
|
||||
CComPtr<IUnknown> m_punkSite;
|
||||
};
|
||||
|
||||
OBJECT_ENTRY_AUTO(__uuidof(ModernSettingsContextMenu), CModernSettingsContextMenu)
|
||||
19
Src/StartMenu/StartMenuHelper/ModernSettingsContextMenu.rgs
Normal file
@@ -0,0 +1,19 @@
|
||||
HKCR
|
||||
{
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {5ab14324-c087-42c1-b905-a0bfdb4e9532} = s 'Open-Shell Modern Settings Context Menu'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%'
|
||||
{
|
||||
val ThreadingModel = s 'Apartment'
|
||||
}
|
||||
ShellEx
|
||||
{
|
||||
MayChangeDefaultMenu = s ''
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
593
Src/StartMenu/StartMenuHelper/ModernSettingsShellFolder.cpp
Normal file
@@ -0,0 +1,593 @@
|
||||
// Open-Shell Modern Settings shell folder
|
||||
// Provides folder that contains all modern settings
|
||||
//
|
||||
// To open the folder press Win+R and type:
|
||||
// shell:::{82E749ED-B971-4550-BAF7-06AA2BF7E836}
|
||||
|
||||
// Based on Explorer Data Provider Sample (https://docs.microsoft.com/en-us/windows/win32/shell/samples-explorerdataprovider)
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ModernSettings.h"
|
||||
#include "ModernSettingsShellFolder.h"
|
||||
#include <propkey.h>
|
||||
#include <strsafe.h>
|
||||
#include <Uxtheme.h>
|
||||
|
||||
struct ColumnDescription
|
||||
{
|
||||
const wchar_t* name;
|
||||
PROPERTYKEY key;
|
||||
};
|
||||
|
||||
static const ColumnDescription g_columnDescriptions[] =
|
||||
{
|
||||
{L"Name", PKEY_ItemNameDisplay},
|
||||
{L"Keywords", PKEY_Keywords},
|
||||
{L"Filename", PKEY_FileName},
|
||||
};
|
||||
|
||||
#define MAGIC 'SMSO'
|
||||
|
||||
#pragma pack(1)
|
||||
struct FVITEMID
|
||||
{
|
||||
USHORT cb;
|
||||
DWORD magic;
|
||||
WORD size;
|
||||
wchar_t data[1];
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
static const FVITEMID* PidlToItem(LPCITEMIDLIST pidl)
|
||||
{
|
||||
if (pidl)
|
||||
{
|
||||
auto item = (const FVITEMID*)pidl;
|
||||
if (item->cb && item->magic == MAGIC)
|
||||
return item;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ModernSettings::Setting GetModernSetting(LPCITEMIDLIST pidl)
|
||||
{
|
||||
auto item = PidlToItem(pidl);
|
||||
if (item)
|
||||
{
|
||||
auto settings = GetModernSettings();
|
||||
if (settings)
|
||||
return settings->get({ item->data, item->size / sizeof(wchar_t) });
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
STDAPI StringToStrRet(PCWSTR pszName, STRRET* pStrRet)
|
||||
{
|
||||
pStrRet->uType = STRRET_WSTR;
|
||||
return SHStrDup(pszName, &pStrRet->pOleStr);
|
||||
}
|
||||
|
||||
// CModernSettingsShellFolderEnumIDList
|
||||
|
||||
class ATL_NO_VTABLE CModernSettingsShellFolderEnumIDList :
|
||||
public CComObjectRoot,
|
||||
public IEnumIDList
|
||||
{
|
||||
public:
|
||||
BEGIN_COM_MAP(CModernSettingsShellFolderEnumIDList)
|
||||
COM_INTERFACE_ENTRY(IEnumIDList)
|
||||
END_COM_MAP()
|
||||
|
||||
// IEnumIDList
|
||||
IFACEMETHODIMP Next(ULONG celt, PITEMID_CHILD* rgelt, ULONG* pceltFetched)
|
||||
{
|
||||
ULONG celtFetched = 0;
|
||||
|
||||
HRESULT hr = (pceltFetched || celt <= 1) ? S_OK : E_INVALIDARG;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ULONG i = 0;
|
||||
while (SUCCEEDED(hr) && i < celt && m_item < m_items.size())
|
||||
{
|
||||
hr = m_parent->CreateChildID(m_items[m_item], &rgelt[i]);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
celtFetched++;
|
||||
i++;
|
||||
}
|
||||
|
||||
m_item++;
|
||||
}
|
||||
}
|
||||
|
||||
if (pceltFetched)
|
||||
*pceltFetched = celtFetched;
|
||||
|
||||
return (celtFetched == celt) ? S_OK : S_FALSE;
|
||||
}
|
||||
IFACEMETHODIMP Skip(DWORD celt)
|
||||
{
|
||||
m_item += celt;
|
||||
return S_OK;
|
||||
}
|
||||
IFACEMETHODIMP Reset()
|
||||
{
|
||||
m_item = 0;
|
||||
return S_OK;
|
||||
}
|
||||
IFACEMETHODIMP Clone(IEnumIDList** ppenum)
|
||||
{
|
||||
// this method is rarely used and it's acceptable to not implement it.
|
||||
*ppenum = NULL;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
void Initialize(CModernSettingsShellFolder* parent)
|
||||
{
|
||||
m_parent = parent;
|
||||
|
||||
m_settings = GetModernSettings();
|
||||
if (m_settings)
|
||||
m_items = m_settings->enumerate();
|
||||
}
|
||||
|
||||
private:
|
||||
CComPtr<CModernSettingsShellFolder> m_parent;
|
||||
std::shared_ptr<ModernSettings> m_settings;
|
||||
std::vector<std::wstring_view> m_items;
|
||||
DWORD m_item = 0;
|
||||
};
|
||||
|
||||
// Extract icon
|
||||
|
||||
static void BitmapDataToStraightAlpha(void* bits, UINT width, UINT height)
|
||||
{
|
||||
RGBQUAD* data = (RGBQUAD*)bits;
|
||||
for (UINT y = 0; y < height; y++)
|
||||
{
|
||||
for (UINT x = 0; x < width; x++)
|
||||
{
|
||||
auto alpha = data->rgbReserved;
|
||||
if (alpha)
|
||||
{
|
||||
data->rgbBlue = (BYTE)((DWORD)data->rgbBlue * 255 / alpha);
|
||||
data->rgbGreen = (BYTE)((DWORD)data->rgbGreen * 255 / alpha);
|
||||
data->rgbRed = (BYTE)((DWORD)data->rgbRed * 255 / alpha);
|
||||
}
|
||||
data++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HICON IconFromGlyph(UINT glyph, UINT size)
|
||||
{
|
||||
ICONINFO info{};
|
||||
|
||||
info.fIcon = TRUE;
|
||||
info.hbmMask = CreateBitmap(size, size, 1, 1, nullptr);
|
||||
|
||||
BITMAPINFO bi{};
|
||||
bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
|
||||
bi.bmiHeader.biWidth = size;
|
||||
bi.bmiHeader.biHeight = -((LONG)size);
|
||||
bi.bmiHeader.biPlanes = 1;
|
||||
bi.bmiHeader.biBitCount = 32;
|
||||
|
||||
void* bits = nullptr;
|
||||
info.hbmColor = CreateDIBSection(nullptr, &bi, 0, &bits, nullptr, 0);
|
||||
|
||||
HDC dc = CreateCompatibleDC(nullptr);
|
||||
SelectObject(dc, info.hbmColor);
|
||||
|
||||
HFONT font = CreateFontW(size, 0, 0, 0, 400, 0, 0, 0, 1, 0, 0, 0, 0, L"Segoe MDL2 Assets");
|
||||
SelectObject(dc, font);
|
||||
|
||||
RECT rc{};
|
||||
rc.right = size;
|
||||
rc.bottom = size;
|
||||
|
||||
auto theme = OpenThemeData(nullptr, L"CompositedWindow::Window");
|
||||
DTTOPTS opts{};
|
||||
opts.dwSize = sizeof(opts);
|
||||
opts.dwFlags = DTT_TEXTCOLOR | DTT_COMPOSITED;
|
||||
opts.crText = 0x00FFFFFF;
|
||||
DrawThemeTextEx(theme, dc, 0, 0, (LPCWSTR)&glyph, 1, DT_CENTER | DT_VCENTER | DT_SINGLELINE, &rc, &opts);
|
||||
CloseThemeData(theme);
|
||||
|
||||
DeleteObject(font);
|
||||
DeleteDC(dc);
|
||||
|
||||
BitmapDataToStraightAlpha(bits, size, size);
|
||||
|
||||
HICON retval = CreateIconIndirect(&info);
|
||||
|
||||
DeleteObject(info.hbmColor);
|
||||
DeleteObject(info.hbmMask);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
class ATL_NO_VTABLE GlyphExtractIcon :
|
||||
public CComObjectRoot,
|
||||
public IExtractIconW
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_COM_MAP(GlyphExtractIcon)
|
||||
COM_INTERFACE_ENTRY(IExtractIconW)
|
||||
END_COM_MAP()
|
||||
|
||||
void SetGlyph(USHORT glyph)
|
||||
{
|
||||
m_glyph = glyph;
|
||||
}
|
||||
|
||||
// IExtractIconW methods
|
||||
IFACEMETHODIMP GetIconLocation(UINT uFlags, _Out_writes_(cchMax) PWSTR pszIconFile, UINT cchMax, _Out_ int* piIndex, _Out_ UINT* pwFlags)
|
||||
{
|
||||
StringCchCopy(pszIconFile, cchMax, L"OpenShell-ModernSettingIcon");
|
||||
*piIndex = m_glyph;
|
||||
*pwFlags = GIL_NOTFILENAME;
|
||||
return S_OK;
|
||||
}
|
||||
IFACEMETHODIMP Extract(_In_ PCWSTR pszFile, UINT nIconIndex, _Out_opt_ HICON* phiconLarge, _Out_opt_ HICON* phiconSmall, UINT nIconSize)
|
||||
{
|
||||
if (phiconLarge)
|
||||
*phiconLarge = IconFromGlyph(nIconIndex, LOWORD(nIconSize));
|
||||
if (phiconSmall)
|
||||
*phiconSmall = IconFromGlyph(nIconIndex, HIWORD(nIconSize));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
USHORT m_glyph = 0;
|
||||
};
|
||||
|
||||
|
||||
// CModernSettingsShellFolder
|
||||
|
||||
// IShellFolder methods
|
||||
|
||||
// Translates a display name into an item identifier list.
|
||||
HRESULT CModernSettingsShellFolder::ParseDisplayName(HWND hwnd, IBindCtx* pbc, PWSTR pszName, ULONG* pchEaten, PIDLIST_RELATIVE* ppidl, ULONG* pdwAttributes)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// Allows a client to determine the contents of a folder by
|
||||
// creating an item identifier enumeration object and returning
|
||||
// its IEnumIDList interface. The methods supported by that
|
||||
// interface can then be used to enumerate the folder's contents.
|
||||
HRESULT CModernSettingsShellFolder::EnumObjects(HWND /* hwnd */, DWORD grfFlags, IEnumIDList** ppenumIDList)
|
||||
{
|
||||
CComObject<CModernSettingsShellFolderEnumIDList>* enumIdList;
|
||||
auto hr = CComObject<CModernSettingsShellFolderEnumIDList>::CreateInstance(&enumIdList);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
enumIdList->Initialize(this);
|
||||
hr = enumIdList->QueryInterface(IID_PPV_ARGS(ppenumIDList));
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Factory for handlers for the specified item.
|
||||
HRESULT CModernSettingsShellFolder::BindToObject(PCUIDLIST_RELATIVE pidl, IBindCtx* pbc, REFIID riid, void** ppv)
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
HRESULT CModernSettingsShellFolder::BindToStorage(PCUIDLIST_RELATIVE pidl, IBindCtx* pbc, REFIID riid, void** ppv)
|
||||
{
|
||||
return BindToObject(pidl, pbc, riid, ppv);
|
||||
}
|
||||
|
||||
// Called to determine the equivalence and/or sort order of two idlists.
|
||||
HRESULT CModernSettingsShellFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
|
||||
{
|
||||
UINT column = LOWORD(lParam);
|
||||
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, (USHORT)(StrCmp(GetColumnDisplayName(pidl1, column).data(), GetColumnDisplayName(pidl2, column).data())));
|
||||
}
|
||||
|
||||
// Called by the Shell to create the View Object and return it.
|
||||
HRESULT CModernSettingsShellFolder::CreateViewObject(HWND hwnd, REFIID riid, void** ppv)
|
||||
{
|
||||
HRESULT hr = E_NOINTERFACE;
|
||||
*ppv = NULL;
|
||||
|
||||
if (riid == IID_IShellView)
|
||||
{
|
||||
SFV_CREATE csfv = { sizeof(csfv), 0 };
|
||||
hr = QueryInterface(IID_PPV_ARGS(&csfv.pshf));
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = SHCreateShellFolderView(&csfv, (IShellView**)ppv);
|
||||
csfv.pshf->Release();
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Retrieves the attributes of one or more file objects or subfolders.
|
||||
HRESULT CModernSettingsShellFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, ULONG* rgfInOut)
|
||||
{
|
||||
*rgfInOut &= SFGAO_CANLINK;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Retrieves an OLE interface that can be used to carry out
|
||||
// actions on the specified file objects or folders.
|
||||
HRESULT CModernSettingsShellFolder::GetUIObjectOf(HWND hwnd, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT* /* prgfInOut */, void** ppv)
|
||||
{
|
||||
HRESULT hr = E_NOINTERFACE;
|
||||
*ppv = nullptr;
|
||||
|
||||
if (riid == IID_IContextMenu)
|
||||
{
|
||||
// The default context menu will call back for IQueryAssociations to determine the
|
||||
// file associations with which to populate the menu.
|
||||
const DEFCONTEXTMENU dcm = { hwnd, nullptr, m_pidl, static_cast<IShellFolder2*>(this), cidl, apidl, nullptr, 0, nullptr };
|
||||
hr = SHCreateDefaultContextMenu(&dcm, riid, ppv);
|
||||
}
|
||||
else if (riid == IID_IExtractIconW)
|
||||
{
|
||||
hr = E_INVALIDARG;
|
||||
|
||||
auto s = GetModernSetting(*apidl);
|
||||
if (s)
|
||||
{
|
||||
if (!s.icon.empty())
|
||||
{
|
||||
CComPtr<IDefaultExtractIconInit> pdxi;
|
||||
hr = SHCreateDefaultExtractIcon(IID_PPV_ARGS(&pdxi));
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
WCHAR icon_path[MAX_PATH];
|
||||
|
||||
StringCchCopy(icon_path, _countof(icon_path), s.icon.data());
|
||||
auto location = PathParseIconLocation(icon_path);
|
||||
|
||||
hr = pdxi->SetNormalIcon(icon_path, location);
|
||||
if (SUCCEEDED(hr))
|
||||
hr = pdxi->QueryInterface(riid, ppv);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto glyph = !s.glyph.empty() ? s.glyph.front() : 0xe115;
|
||||
|
||||
CComObject<GlyphExtractIcon>* extract;
|
||||
hr = CComObject<GlyphExtractIcon>::CreateInstance(&extract);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
extract->SetGlyph(glyph);
|
||||
hr = extract->QueryInterface(riid, ppv);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (riid == IID_IDataObject)
|
||||
{
|
||||
hr = SHCreateDataObject(m_pidl, cidl, apidl, nullptr, riid, ppv);
|
||||
}
|
||||
else if (riid == IID_IQueryAssociations)
|
||||
{
|
||||
WCHAR szFolderViewImplClassID[64];
|
||||
hr = StringFromGUID2(CLSID_ModernSettingsShellFolder, szFolderViewImplClassID, ARRAYSIZE(szFolderViewImplClassID));
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
const ASSOCIATIONELEMENT assocItem = { ASSOCCLASS_CLSID_STR, nullptr, szFolderViewImplClassID };
|
||||
hr = AssocCreateForClasses(&assocItem, 1, riid, ppv);
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Retrieves the display name for the specified file object or subfolder.
|
||||
HRESULT CModernSettingsShellFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, SHGDNF shgdnFlags, STRRET* pName)
|
||||
{
|
||||
auto setting = GetModernSetting(pidl);
|
||||
if (!setting)
|
||||
return E_INVALIDARG;
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (shgdnFlags & SHGDN_FORPARSING)
|
||||
{
|
||||
if (shgdnFlags & SHGDN_INFOLDER)
|
||||
{
|
||||
// This form of the display name needs to be handled by ParseDisplayName.
|
||||
hr = StringToStrRet(setting.fileName.data(), pName);
|
||||
}
|
||||
else
|
||||
{
|
||||
WCHAR szDisplayName[MAX_PATH];
|
||||
CComString pszThisFolder;
|
||||
hr = SHGetNameFromIDList(m_pidl, (shgdnFlags & SHGDN_FORADDRESSBAR) ? SIGDN_DESKTOPABSOLUTEEDITING : SIGDN_DESKTOPABSOLUTEPARSING, &pszThisFolder);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
StringCchCopy(szDisplayName, ARRAYSIZE(szDisplayName), pszThisFolder);
|
||||
StringCchCat(szDisplayName, ARRAYSIZE(szDisplayName), L"\\");
|
||||
StringCchCat(szDisplayName, ARRAYSIZE(szDisplayName), setting.fileName.data());
|
||||
|
||||
hr = StringToStrRet(szDisplayName, pName);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = StringToStrRet(setting.description.data(), pName);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Sets the display name of a file object or subfolder, changing the item identifier in the process.
|
||||
HRESULT CModernSettingsShellFolder::SetNameOf(HWND /* hwnd */, PCUITEMID_CHILD /* pidl */, PCWSTR /* pszName */, DWORD /* uFlags */, PITEMID_CHILD* ppidlOut)
|
||||
{
|
||||
*ppidlOut = NULL;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
// IShellFolder2 methods
|
||||
|
||||
// Requests the GUID of the default search object for the folder.
|
||||
HRESULT CModernSettingsShellFolder::GetDefaultSearchGUID(GUID* /* pguid */)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT CModernSettingsShellFolder::EnumSearches(IEnumExtraSearch** ppEnum)
|
||||
{
|
||||
*ppEnum = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
// Retrieves the default sorting and display column (indices from GetDetailsOf).
|
||||
HRESULT CModernSettingsShellFolder::GetDefaultColumn(DWORD /* dwRes */, ULONG* pSort, ULONG* pDisplay)
|
||||
{
|
||||
*pSort = 0;
|
||||
*pDisplay = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Retrieves the default state for a specified column.
|
||||
HRESULT CModernSettingsShellFolder::GetDefaultColumnState(UINT iColumn, SHCOLSTATEF* pcsFlags)
|
||||
{
|
||||
if (iColumn < _countof(g_columnDescriptions))
|
||||
{
|
||||
*pcsFlags = SHCOLSTATE_ONBYDEFAULT | SHCOLSTATE_TYPE_STR;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// Retrieves detailed information, identified by a property set ID (FMTID) and property ID (PID), on an item in a Shell folder.
|
||||
HRESULT CModernSettingsShellFolder::GetDetailsEx(PCUITEMID_CHILD pidl, const PROPERTYKEY* pkey, VARIANT* pv)
|
||||
{
|
||||
for (const auto& desc : g_columnDescriptions)
|
||||
{
|
||||
if (IsEqualPropertyKey(*pkey, desc.key))
|
||||
{
|
||||
auto str = GetColumnDisplayName(pidl, (UINT)std::distance(g_columnDescriptions, &desc));
|
||||
|
||||
pv->vt = VT_BSTR;
|
||||
pv->bstrVal = SysAllocString(str.data());
|
||||
return pv->bstrVal ? S_OK : E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Retrieves detailed information, identified by a column index, on an item in a Shell folder.
|
||||
HRESULT CModernSettingsShellFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS* pDetails)
|
||||
{
|
||||
pDetails->cxChar = 24;
|
||||
|
||||
if (!pidl)
|
||||
{
|
||||
// No item means we're returning information about the column itself.
|
||||
|
||||
if (iColumn >= _countof(g_columnDescriptions))
|
||||
{
|
||||
// GetDetailsOf is called with increasing column indices until failure.
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
pDetails->fmt = LVCFMT_LEFT;
|
||||
return StringToStrRet(g_columnDescriptions[iColumn].name, &pDetails->str);
|
||||
}
|
||||
|
||||
auto str = GetColumnDisplayName(pidl, iColumn);
|
||||
return StringToStrRet(str.data(), &pDetails->str);
|
||||
}
|
||||
|
||||
// Converts a column name to the appropriate property set ID (FMTID) and property ID (PID).
|
||||
HRESULT CModernSettingsShellFolder::MapColumnToSCID(UINT iColumn, PROPERTYKEY* pkey)
|
||||
{
|
||||
if (iColumn < _countof(g_columnDescriptions))
|
||||
{
|
||||
*pkey = g_columnDescriptions[iColumn].key;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// IPersist method
|
||||
HRESULT CModernSettingsShellFolder::GetClassID(CLSID* pClassID)
|
||||
{
|
||||
*pClassID = CLSID_ModernSettingsShellFolder;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// IPersistFolder method
|
||||
HRESULT CModernSettingsShellFolder::Initialize(PCIDLIST_ABSOLUTE pidl)
|
||||
{
|
||||
m_pidl = pidl;
|
||||
return m_pidl ? S_OK : E_FAIL;
|
||||
}
|
||||
|
||||
// IPersistFolder2 methods
|
||||
// Retrieves the PIDLIST_ABSOLUTE for the folder object.
|
||||
HRESULT CModernSettingsShellFolder::GetCurFolder(PIDLIST_ABSOLUTE* ppidl)
|
||||
{
|
||||
*ppidl = NULL;
|
||||
HRESULT hr = m_pidl ? S_OK : E_FAIL;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
*ppidl = ILCloneFull(m_pidl);
|
||||
hr = *ppidl ? S_OK : E_OUTOFMEMORY;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CModernSettingsShellFolder::CreateChildID(const std::wstring_view& fileName, PITEMID_CHILD* ppidl)
|
||||
{
|
||||
auto size = fileName.size() * sizeof(wchar_t);
|
||||
|
||||
// Sizeof an object plus the next cb plus the characters in the string.
|
||||
UINT nIDSize = sizeof(FVITEMID) + sizeof(USHORT) + (WORD)size;
|
||||
|
||||
// Allocate and zero the memory.
|
||||
FVITEMID* lpMyObj = (FVITEMID*)CoTaskMemAlloc(nIDSize);
|
||||
|
||||
HRESULT hr = lpMyObj ? S_OK : E_OUTOFMEMORY;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ZeroMemory(lpMyObj, nIDSize);
|
||||
lpMyObj->cb = static_cast<short>(nIDSize - sizeof(lpMyObj->cb));
|
||||
lpMyObj->magic = MAGIC;
|
||||
lpMyObj->size = (WORD)size;
|
||||
memcpy(lpMyObj->data, fileName.data(), size);
|
||||
|
||||
*ppidl = (PITEMID_CHILD)lpMyObj;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
std::wstring_view CModernSettingsShellFolder::GetColumnDisplayName(PCUITEMID_CHILD pidl, UINT iColumn)
|
||||
{
|
||||
auto setting = GetModernSetting(pidl);
|
||||
if (setting)
|
||||
{
|
||||
switch (iColumn)
|
||||
{
|
||||
case 0:
|
||||
return setting.description;
|
||||
case 1:
|
||||
return setting.keywords;
|
||||
case 2:
|
||||
return setting.fileName;
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
85
Src/StartMenu/StartMenuHelper/ModernSettingsShellFolder.h
Normal file
@@ -0,0 +1,85 @@
|
||||
// Open-Shell Modern Settings shell folder
|
||||
// Provides folder that contains all modern settings
|
||||
|
||||
#pragma once
|
||||
#include "resource.h"
|
||||
#include "ComHelper.h"
|
||||
#include "StartMenuHelper_i.h"
|
||||
#include <shlobj.h>
|
||||
#include <string>
|
||||
|
||||
// CModernSettingsShellFolder
|
||||
|
||||
class ATL_NO_VTABLE CModernSettingsShellFolder :
|
||||
public CComObjectRootEx<CComSingleThreadModel>,
|
||||
public CComCoClass<CModernSettingsShellFolder, &CLSID_ModernSettingsShellFolder>,
|
||||
public IShellFolder2,
|
||||
public IPersistFolder2
|
||||
{
|
||||
public:
|
||||
CModernSettingsShellFolder()
|
||||
{
|
||||
}
|
||||
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_MODERNSETTINGSSHELLFOLDER)
|
||||
|
||||
DECLARE_NOT_AGGREGATABLE(CModernSettingsShellFolder)
|
||||
|
||||
BEGIN_COM_MAP(CModernSettingsShellFolder)
|
||||
COM_INTERFACE_ENTRY(IShellFolder)
|
||||
COM_INTERFACE_ENTRY(IShellFolder2)
|
||||
COM_INTERFACE_ENTRY(IPersist)
|
||||
COM_INTERFACE_ENTRY(IPersistFolder)
|
||||
COM_INTERFACE_ENTRY(IPersistFolder2)
|
||||
END_COM_MAP()
|
||||
|
||||
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||||
|
||||
HRESULT FinalConstruct()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void FinalRelease()
|
||||
{
|
||||
}
|
||||
|
||||
// IShellFolder
|
||||
IFACEMETHODIMP ParseDisplayName(HWND hwnd, IBindCtx* pbc, PWSTR pszName, ULONG* pchEaten, PIDLIST_RELATIVE* ppidl, ULONG* pdwAttributes);
|
||||
IFACEMETHODIMP EnumObjects(HWND hwnd, DWORD grfFlags, IEnumIDList** ppenumIDList);
|
||||
IFACEMETHODIMP BindToObject(PCUIDLIST_RELATIVE pidl, IBindCtx* pbc, REFIID riid, void** ppv);
|
||||
IFACEMETHODIMP BindToStorage(PCUIDLIST_RELATIVE pidl, IBindCtx* pbc, REFIID riid, void** ppv);
|
||||
IFACEMETHODIMP CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2);
|
||||
IFACEMETHODIMP CreateViewObject(HWND hwnd, REFIID riid, void** ppv);
|
||||
IFACEMETHODIMP GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, ULONG* rgfInOut);
|
||||
IFACEMETHODIMP GetUIObjectOf(HWND hwnd, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT* prgfInOut, void** ppv);
|
||||
IFACEMETHODIMP GetDisplayNameOf(PCUITEMID_CHILD pidl, SHGDNF shgdnFlags, STRRET* pName);
|
||||
IFACEMETHODIMP SetNameOf(HWND hwnd, PCUITEMID_CHILD pidl, PCWSTR pszName, DWORD uFlags, PITEMID_CHILD* ppidlOut);
|
||||
|
||||
// IShellFolder2
|
||||
IFACEMETHODIMP GetDefaultSearchGUID(GUID* pGuid);
|
||||
IFACEMETHODIMP EnumSearches(IEnumExtraSearch** ppenum);
|
||||
IFACEMETHODIMP GetDefaultColumn(DWORD dwRes, ULONG* pSort, ULONG* pDisplay);
|
||||
IFACEMETHODIMP GetDefaultColumnState(UINT iColumn, SHCOLSTATEF* pbState);
|
||||
IFACEMETHODIMP GetDetailsEx(PCUITEMID_CHILD pidl, const PROPERTYKEY* pkey, VARIANT* pv);
|
||||
IFACEMETHODIMP GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS* pDetails);
|
||||
IFACEMETHODIMP MapColumnToSCID(UINT iColumn, PROPERTYKEY* pkey);
|
||||
|
||||
// IPersist
|
||||
IFACEMETHODIMP GetClassID(CLSID* pClassID);
|
||||
|
||||
// IPersistFolder
|
||||
IFACEMETHODIMP Initialize(PCIDLIST_ABSOLUTE pidl);
|
||||
|
||||
// IPersistFolder2
|
||||
IFACEMETHODIMP GetCurFolder(PIDLIST_ABSOLUTE* ppidl);
|
||||
|
||||
HRESULT CreateChildID(const std::wstring_view& fileName, PITEMID_CHILD* ppidl);
|
||||
|
||||
private:
|
||||
std::wstring_view GetColumnDisplayName(PCUITEMID_CHILD pidl, UINT iColumn);
|
||||
|
||||
CAbsolutePidl m_pidl; // where this folder is in the name space
|
||||
};
|
||||
|
||||
OBJECT_ENTRY_AUTO(__uuidof(ModernSettingsShellFolder), CModernSettingsShellFolder)
|
||||
26
Src/StartMenu/StartMenuHelper/ModernSettingsShellFolder.rgs
Normal file
@@ -0,0 +1,26 @@
|
||||
HKCR
|
||||
{
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {82e749ed-b971-4550-baf7-06aa2bf7e836} = s 'Open-Shell Modern Settings'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%'
|
||||
{
|
||||
val ThreadingModel = s 'Apartment'
|
||||
}
|
||||
ShellFolder
|
||||
{
|
||||
val Attributes = d '&HA0000000'
|
||||
}
|
||||
ShellEx
|
||||
{
|
||||
ContextMenuHandlers
|
||||
{
|
||||
Default = s '{5ab14324-c087-42c1-b905-a0bfdb4e9532}'
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,7 +91,7 @@ STDMETHODIMP CStartMenuExt::Initialize( PCIDLIST_ABSOLUTE pidlFolder, IDataObjec
|
||||
bUsePinned=(setting==1);
|
||||
if (bUsePinned)
|
||||
{
|
||||
Strcpy(m_PinFolder1,_countof(m_PinFolder1),L"%APPDATA%\\OpenShell\\Pinned\\");
|
||||
Sprintf(m_PinFolder1,_countof(m_PinFolder1),L"%s\\",GetSettingString(L"PinnedItemsPath"));
|
||||
DoEnvironmentSubst(m_PinFolder1,_countof(m_PinFolder1));
|
||||
m_PinFolder2[0]=0;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ const CLSID g_ExplorerClsid= {0xECD4FC4D, 0x521C, 0x11D0, {0xB7, 0x92, 0x00, 0xA
|
||||
const CLSID g_EmulationClsid= {0xD3214FBB, 0x3CA1, 0x406A, {0xB3, 0xE8, 0x3E, 0xB7, 0xC3, 0x93, 0xA1, 0x5E}};
|
||||
#define EMULATION_KEY L"TreatAs"
|
||||
|
||||
#define SHELLEXT_NAME L"StartMenuExt"
|
||||
|
||||
static void AdjustPrivileges( void )
|
||||
{
|
||||
HANDLE hToken;
|
||||
@@ -46,6 +48,18 @@ static void AdjustPrivileges( void )
|
||||
}
|
||||
}
|
||||
|
||||
static void AddShellExt(const wchar_t* progID, const LPSECURITY_ATTRIBUTES sa)
|
||||
{
|
||||
HKEY hkey = NULL;
|
||||
|
||||
if (RegCreateKeyEx(HKEY_CLASSES_ROOT, CString(progID) + L"\\ShellEx\\ContextMenuHandlers\\" SHELLEXT_NAME, NULL, NULL, REG_OPTION_BACKUP_RESTORE, KEY_WRITE, sa, &hkey, NULL) == ERROR_SUCCESS)
|
||||
{
|
||||
wchar_t val[] = L"{E595F05F-903F-4318-8B0A-7F633B520D2B}";
|
||||
RegSetValueEx(hkey, NULL, NULL, REG_SZ, (BYTE*)val, sizeof(val));
|
||||
RegCloseKey(hkey);
|
||||
}
|
||||
}
|
||||
|
||||
static void AddRegistryKeys( bool bPin )
|
||||
{
|
||||
AdjustPrivileges();
|
||||
@@ -103,21 +117,12 @@ static void AddRegistryKeys( bool bPin )
|
||||
RegSetValueEx(hkey,NULL,NULL,REG_SZ,(BYTE*)val,sizeof(val));
|
||||
RegCloseKey(hkey);
|
||||
}
|
||||
hkey=NULL;
|
||||
|
||||
if (bPin)
|
||||
{
|
||||
if (RegCreateKeyEx(HKEY_CLASSES_ROOT,L"Launcher.ImmersiveApplication\\ShellEx\\ContextMenuHandlers\\StartMenuExt",NULL,NULL,REG_OPTION_BACKUP_RESTORE,KEY_WRITE,&sa,&hkey,NULL)==ERROR_SUCCESS)
|
||||
{
|
||||
wchar_t val[]=L"{E595F05F-903F-4318-8B0A-7F633B520D2B}";
|
||||
RegSetValueEx(hkey,NULL,NULL,REG_SZ,(BYTE*)val,sizeof(val));
|
||||
RegCloseKey(hkey);
|
||||
}
|
||||
if (RegCreateKeyEx(HKEY_CLASSES_ROOT,L"Launcher.SystemSettings\\ShellEx\\ContextMenuHandlers\\StartMenuExt",NULL,NULL,REG_OPTION_BACKUP_RESTORE,KEY_WRITE,&sa,&hkey,NULL)==ERROR_SUCCESS)
|
||||
{
|
||||
wchar_t val[]=L"{E595F05F-903F-4318-8B0A-7F633B520D2B}";
|
||||
RegSetValueEx(hkey,NULL,NULL,REG_SZ,(BYTE*)val,sizeof(val));
|
||||
RegCloseKey(hkey);
|
||||
}
|
||||
AddShellExt(L"Launcher.ImmersiveApplication", &sa);
|
||||
AddShellExt(L"Launcher.DesktopPackagedApplication", &sa);
|
||||
AddShellExt(L"Launcher.SystemSettings", &sa);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -127,6 +132,16 @@ static void AddRegistryKeys( bool bPin )
|
||||
FreeSid(pAdminSID);
|
||||
}
|
||||
|
||||
static void RemoveShellExt(const wchar_t* progID)
|
||||
{
|
||||
HKEY hkey = NULL;
|
||||
if (RegCreateKeyEx(HKEY_CLASSES_ROOT, CString(progID) + L"\\ShellEx\\ContextMenuHandlers", NULL, NULL, REG_OPTION_BACKUP_RESTORE, KEY_WRITE | DELETE, NULL, &hkey, NULL) == ERROR_SUCCESS)
|
||||
{
|
||||
RegDeleteTree(hkey, SHELLEXT_NAME);
|
||||
RegCloseKey(hkey);
|
||||
}
|
||||
}
|
||||
|
||||
static void RemoveRegistryKeys( bool bPin )
|
||||
{
|
||||
AdjustPrivileges();
|
||||
@@ -136,19 +151,12 @@ static void RemoveRegistryKeys( bool bPin )
|
||||
RegDeleteTree(hkey,EMULATION_KEY);
|
||||
RegCloseKey(hkey);
|
||||
}
|
||||
hkey=NULL;
|
||||
|
||||
if (bPin)
|
||||
{
|
||||
if (RegCreateKeyEx(HKEY_CLASSES_ROOT,L"Launcher.ImmersiveApplication\\ShellEx\\ContextMenuHandlers",NULL,NULL,REG_OPTION_BACKUP_RESTORE,KEY_WRITE|DELETE,NULL,&hkey,NULL)==ERROR_SUCCESS)
|
||||
{
|
||||
RegDeleteTree(hkey,L"StartMenuExt");
|
||||
RegCloseKey(hkey);
|
||||
}
|
||||
if (RegCreateKeyEx(HKEY_CLASSES_ROOT,L"Launcher.SystemSettings\\ShellEx\\ContextMenuHandlers",NULL,NULL,REG_OPTION_BACKUP_RESTORE,KEY_WRITE|DELETE,NULL,&hkey,NULL)==ERROR_SUCCESS)
|
||||
{
|
||||
RegDeleteTree(hkey,L"StartMenuExt");
|
||||
RegCloseKey(hkey);
|
||||
}
|
||||
RemoveShellExt(L"Launcher.ImmersiveApplication");
|
||||
RemoveShellExt(L"Launcher.DesktopPackagedApplication");
|
||||
RemoveShellExt(L"Launcher.SystemSettings");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
import "oaidl.idl";
|
||||
import "ocidl.idl";
|
||||
import "shobjidl.idl";
|
||||
|
||||
[
|
||||
object,
|
||||
@@ -31,4 +32,21 @@ library StartMenuHelperLib
|
||||
{
|
||||
[default] interface IStartMenuExt;
|
||||
};
|
||||
[
|
||||
uuid(82e749ed-b971-4550-baf7-06aa2bf7e836)
|
||||
]
|
||||
coclass ModernSettingsShellFolder
|
||||
{
|
||||
interface IShellFolder2;
|
||||
interface IPersistFolder2;
|
||||
};
|
||||
[
|
||||
uuid(5ab14324-c087-42c1-b905-a0bfdb4e9532)
|
||||
]
|
||||
coclass ModernSettingsContextMenu
|
||||
{
|
||||
interface IContextMenu;
|
||||
interface IShellExtInit;
|
||||
interface IObjectWithSite;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -98,6 +98,8 @@ END
|
||||
|
||||
IDR_STARTMENUHELPER REGISTRY "StartMenuHelper.rgs"
|
||||
IDR_STARTMENUEXT REGISTRY "StartMenuExt.rgs"
|
||||
IDR_MODERNSETTINGSSHELLFOLDER REGISTRY "ModernSettingsShellFolder.rgs"
|
||||
IDR_MODERNSETTINGSCONTEXTMENU REGISTRY "ModernSettingsContextMenu.rgs"
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -157,7 +157,6 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
@@ -177,6 +176,7 @@
|
||||
<ModuleDefinitionFile>.\$(TargetName).def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<PerUserRedirection>true</PerUserRedirection>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
@@ -192,7 +192,6 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
@@ -212,6 +211,7 @@
|
||||
<ModuleDefinitionFile>.\$(TargetName).def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<PerUserRedirection>true</PerUserRedirection>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
@@ -248,6 +248,7 @@
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<PerUserRedirection>true</PerUserRedirection>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
@@ -283,6 +284,7 @@
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<PerUserRedirection>true</PerUserRedirection>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Setup|Win32'">
|
||||
@@ -356,6 +358,9 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="ModernSettings.cpp" />
|
||||
<ClCompile Include="ModernSettingsContextMenu.cpp" />
|
||||
<ClCompile Include="ModernSettingsShellFolder.cpp" />
|
||||
<ClCompile Include="StartMenuExt.cpp" />
|
||||
<ClCompile Include="StartMenuHelper.cpp" />
|
||||
<ClCompile Include="StartMenuHelper_i.c">
|
||||
@@ -369,6 +374,8 @@
|
||||
<Midl Include="StartMenuHelper.idl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="ModernSettingsContextMenu.rgs" />
|
||||
<None Include="ModernSettingsShellFolder.rgs" />
|
||||
<None Include="StartMenuExt.rgs" />
|
||||
<None Include="StartMenuHelper.rgs" />
|
||||
<None Include="StartMenuHelper32.def" />
|
||||
@@ -377,6 +384,9 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="dllmain.h" />
|
||||
<ClInclude Include="ModernSettings.h" />
|
||||
<ClInclude Include="ModernSettingsContextMenu.h" />
|
||||
<ClInclude Include="ModernSettingsShellFolder.h" />
|
||||
<ClInclude Include="Resource.h" />
|
||||
<ClInclude Include="StartMenuExt.h" />
|
||||
<ClInclude Include="StartMenuHelper_i.h" />
|
||||
|
||||
@@ -34,6 +34,15 @@
|
||||
<ClCompile Include="StartMenuHelper_i.c">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ModernSettingsShellFolder.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ModernSettings.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ModernSettingsContextMenu.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Midl Include="StartMenuHelper.idl">
|
||||
@@ -56,6 +65,12 @@
|
||||
<None Include="StartMenuHelperL10N.ini">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="ModernSettingsShellFolder.rgs">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="ModernSettingsContextMenu.rgs">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="dllmain.h">
|
||||
@@ -76,6 +91,15 @@
|
||||
<ClInclude Include="StartMenuHelper_i.h">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ModernSettingsShellFolder.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ModernSettings.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ModernSettingsContextMenu.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="StartMenuHelper.rc">
|
||||
|
||||
@@ -57,6 +57,7 @@ CSetting g_Settings[]={
|
||||
{L"DisablePinExt",CSetting::TYPE_BOOL,0,0,0},
|
||||
{L"FolderStartMenu",CSetting::TYPE_STRING,0,0,L""},
|
||||
{L"FolderCommonStartMenu",CSetting::TYPE_STRING,0,0,L""},
|
||||
{L"PinnedItemsPath",CSetting::TYPE_DIRECTORY,0,0,L"%APPDATA%\\OpenShell\\Pinned"},
|
||||
|
||||
{L"Language",CSetting::TYPE_GROUP},
|
||||
{L"Language",CSetting::TYPE_STRING,0,0,L"",CSetting::FLAG_COLD|CSetting::FLAG_SHARED},
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
//
|
||||
#define IDR_STARTMENUHELPER 101
|
||||
#define IDR_STARTMENUEXT 102
|
||||
#define IDR_MODERNSETTINGSSHELLFOLDER 103
|
||||
#define IDR_MODERNSETTINGSCONTEXTMENU 104
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
@@ -12,6 +14,6 @@
|
||||
#define _APS_NEXT_RESOURCE_VALUE 201
|
||||
#define _APS_NEXT_COMMAND_VALUE 32768
|
||||
#define _APS_NEXT_CONTROL_VALUE 201
|
||||
#define _APS_NEXT_SYMED_VALUE 103
|
||||
#define _APS_NEXT_SYMED_VALUE 105
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -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 = Документи
|
||||
|
||||
291
Src/Update/DesktopToasts/DesktopNotificationManagerCompat.cpp
Normal 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::make_unique<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 = std::move(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());
|
||||
}
|
||||
}
|
||||
108
Src/Update/DesktopToasts/DesktopNotificationManagerCompat.h
Normal 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;
|
||||
};
|
||||
5
Src/Update/DesktopToasts/DesktopToasts.def
Normal file
@@ -0,0 +1,5 @@
|
||||
LIBRARY "DesktopToasts.dll"
|
||||
|
||||
EXPORTS
|
||||
Initialize
|
||||
DisplaySimpleToast
|
||||
59
Src/Update/DesktopToasts/DesktopToasts.h
Normal 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;
|
||||
};
|
||||
61
Src/Update/DesktopToasts/DesktopToasts.rc
Normal 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
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||