29 Commits

Author SHA1 Message Date
ge0rdi
61d05b49c5 Improve search logging 2020-09-01 19:28:04 +02:00
ge0rdi
9752afbebc ModernSettings: Use smart pointers 2020-09-01 19:28:04 +02:00
ge0rdi
e210b4a65a CAbsolutePidl: Allow copy from PCIDLIST_ABSOLUTE 2020-09-01 19:28:04 +02:00
ge0rdi
6581868336 ModernSettings: Add support for more settings
Based on `HostId`:
* {7E0522FC-1AC4-41CA-AFD0-3610417A9C41}
  execute `shell:::{PageId}`
* {12B1697E-D3A0-4DBC-B568-CCF64A3F934D}
  execute command in `DeepLink`
2020-09-01 19:28:04 +02:00
ge0rdi
7ee668e474 Installer: Fix URLs
Fixes #404
2020-09-01 19:28:04 +02:00
ge0rdi
62b949679b Respect Use multiple columns setting for all folder items
Currently it was used only in some cases (like Programs/Apps folder).
It will be more consistent to respect the setting for all folder
items.

Fixes #436.
2020-09-01 19:28:04 +02:00
ge0rdi
6242e8d9b9 Settings: Use images in PNG format
It makes StartmenuDLL.dll ~830kB smaller.
2020-09-01 19:28:04 +02:00
ge0rdi
ee59bb76de Setup: Don't add symbols for unused update.exe 2020-09-01 19:28:04 +02:00
ge0rdi
3eb134a280 Setup: Store symbols in symstore compatible way
This way they can be directly extracted to symbol server cache.
So any tool that uses _NT_SYMBOL_PATH will be able to use them
automatically.
2020-09-01 19:28:04 +02:00
ge0rdi
257023209b Update README.md
- Few text adjustments
- Minor formatting changes
2020-09-01 19:18:48 +02:00
ge0rdi
0da20180ac Search modern settings using our new shell folder
Use our modern settings shell folder (`shell:::{82E749ED-B971-4550-BAF7-06AA2BF7E836}`)
to search (enumerate) modern settings.

Fixes #57
2020-08-29 14:03:59 +02:00
ge0rdi
1f57c782e5 Modern settings shell folder
Adds virtual shell folder that contains items representing modern settings parsed from
`%windir%\ImmersiveControlPanel\Settings\AllSystemSettings_{253E530E-387D-4BC2-959D-E6F86122E5F2}.xml`.

It can be accessed via `shell:::{82E749ED-B971-4550-BAF7-06AA2BF7E836}` (in explorer).

Item in folder will open given setting page in `Settings` application.
2020-08-29 14:03:59 +02:00
ge0rdi
1f6e06fc85 Use proper flag in LoadMetroIcon 2020-08-29 14:03:59 +02:00
ge0rdi
ed3675ca7f Remove non-working update component from installation
We can add it later once it will be ready and working.
2020-08-18 15:28:09 +02:00
ge0rdi
695e419722 Setup: Use high version when doing local build
This way the build can be installed over existing older installation.
2020-08-14 18:05:56 +02:00
ge0rdi
3bceac1515 ProgramsTree: Fix theme usage
Obtain theme data for proper window.

Fixes #415
2020-08-12 14:16:14 +02:00
rkagerer
473f7e1445 Null check in PremultiplyBitmap()
Blind attempt to eliminate a crash which seems to occur when PremultiplyBitmap() is called after LoadImage() fails.
I'm hoping this might fix the issue reported here: https://github.com/Open-Shell/Open-Shell-Menu/issues/400
2020-07-13 12:14:22 +02:00
ale5000
fcf95a3ea6 Readme: Fix folder for translations 2020-06-15 21:15:39 +02:00
ge0rdi
cc02e38aef StartMenuHelper: Add shell extension to desktop packaged applications
This will allow `Pin to start` for desktop applications downloaded from
Microsoft Store (such as Windows Terminal).
2020-06-07 07:21:19 +02:00
ge0rdi
9c119c6e29 StartMenuHelper: Simplify shell extension registration 2020-06-07 07:21:19 +02:00
ge0rdi
9e297866ed Register server with per-user redirection
Some projects do register COM server in Debug/Release sonfigurations.
We should do it with per-user redirection so that there is no need to
run elevated Visual Studio.

This has no effect on COM server registering in installed Opne-Shell.
It is related only to local development.
2020-06-07 07:21:18 +02:00
ge0rdi
261929f4c3 Don't use obsolete /Gm switch
`cl : command line warning D9035: option 'Gm' has been deprecated and will be removed in a future release`
2020-06-07 07:21:17 +02:00
ge0rdi
9976e134ca Fix 'Invert Metro icon color' option for grayscale icons
When `Invert Metro icon color` is enabled `Open-Shell` needs to
distinguish full color icons from monochromatic ones.

Color icons are displayed normally. Monochromatic ones are displayed
inverted (original background becomes transparent and foreground will
get Metro accent color).

Metro icon is loaded from Metro app resources (usually PNG image) as
bitmap with premultiplied alpha channel.
This causes monochromatic image to essentially become grayscale (because
RGB values are multiplied with alpha channel value).

Function `DetectGrayscaleImage` is used to distinguish such images.

Unfortunatelly if original image is grayscale (such as new Windows
Terminal icon) it is recognized as monochromatic and thus inverted.

To prevent this we will take into account also alpha channel in
`DetectGrayscaleImage`.

In monochromatic images alpha channel value will be the same as the rest of
channel values.
For color images alpha channel value will be different than other
channel values.

Fixes #364.
2020-06-07 06:47:03 +02:00
ge0rdi
1b410e5a80 Fix compilation with VS16.6 2020-06-07 06:47:03 +02:00
ge0rdi
9ebe53fdbf Fix issue with confirmation dialog being blocked
Delete confirmation dialog may be (partially) hidden behing start menu.
As a result the dialog may be not accessible because start menu(s) are
displayed as top-most windows.

Thus when executing menu command we will make menu(s) non-topmost. So that
other windows can be drawn on top of menu(s).

Fixes #257
2020-02-08 11:23:05 +01:00
coddec
5f59aab40a fix typo classic shell -> Open-Shell 2020-01-29 18:22:08 +11:00
coddec
4f46134f10 Add Temporary Translation/Language Solution 2020-01-29 15:41:23 +11:00
Kaleb Klein
519f4afe17 ignore vscode generated files
Added generated files/folders in gitignore from vscode
2019-12-05 10:27:59 +01:00
Kaleb Klein
30ffce6939 Change homepage url in settings
Changed the homepage text and link on the settings dialog to link to the Open-Shell home page.
2019-12-05 10:27:59 +01:00
60 changed files with 1867 additions and 186 deletions

4
.gitignore vendored
View File

@@ -4,6 +4,10 @@
## ##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# ignore vscode stuff
.vscode/
.ionide/
# User-specific files # User-specific files
*.suo *.suo
*.user *.user

View File

@@ -4,14 +4,11 @@
[![GitHub Release](https://img.shields.io/github/release/Open-Shell/Open-Shell-Menu.svg)](https://github.com/Open-Shell/Open-Shell-Menu/releases) [![GitHub Pre-Release](https://img.shields.io/github/release/Open-Shell/Open-Shell-Menu/all.svg)](https://github.com/Open-Shell/Open-Shell-Menu/releases) [![Build status](https://ci.appveyor.com/api/projects/status/2wj5x5qoypfjj0tr/branch/master?svg=true)](https://ci.appveyor.com/project/passionate-coder/open-shell-menu/branch/master) [![GitQ](https://gitq.com/badge.svg)](https://gitq.com/passionate-coder/Classic-Start) [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/open-shell/Lobby) [![GitHub Release](https://img.shields.io/github/release/Open-Shell/Open-Shell-Menu.svg)](https://github.com/Open-Shell/Open-Shell-Menu/releases) [![GitHub Pre-Release](https://img.shields.io/github/release/Open-Shell/Open-Shell-Menu/all.svg)](https://github.com/Open-Shell/Open-Shell-Menu/releases) [![Build status](https://ci.appveyor.com/api/projects/status/2wj5x5qoypfjj0tr/branch/master?svg=true)](https://ci.appveyor.com/project/passionate-coder/open-shell-menu/branch/master) [![GitQ](https://gitq.com/badge.svg)](https://gitq.com/passionate-coder/Classic-Start) [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/open-shell/Lobby)
[Home Page](https://open-shell.github.io/Open-Shell-Menu) [Home Page](https://open-shell.github.io/Open-Shell-Menu)
[Discussion room](https://gitter.im/Open-Shell)
[Discussion room](https://gitter.im/Open-Shell) [Latest nightly build](https://ci.appveyor.com/project/passionate-coder/open-shell-menu/branch/master/artifacts)
[Latest nightly build](https://ci.appveyor.com/project/passionate-coder/open-shell-menu/branch/master/artifacts)
### Features ### Features
- Classic style Start Menu for Windows 7, 8, 8.1, 10 - Classic style Start Menu for Windows 7, 8, 8.1, 10
- Toolbar for Windows Explorer - Toolbar for Windows Explorer
- Classic copy UI (Windows 7 only) - Classic copy UI (Windows 7 only)
@@ -19,16 +16,18 @@
- Title bar and status bar for Internet Explorer - Title bar and status bar for Internet Explorer
### Download ### 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:
[![GitHub All Releases](https://img.shields.io/github/downloads/Open-Shell/Open-Shell-Menu/total?style=for-the-badge)](https://github.com/Open-Shell/Open-Shell-Menu/releases) [![GitHub All Releases](https://img.shields.io/github/downloads/Open-Shell/Open-Shell-Menu/total?style=for-the-badge)](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/).* *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) [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)
[Classic Shell - Custom Start Buttons](https://coddec.github.io/Classic-Shell/www.classicshell.net/tutorials/buttontutorial.html)
[Report a bug/issue or submit a feature request](https://github.com/Open-Shell/Open-Shell-Menu/issues) [Report a bug/issue or submit a feature request](https://github.com/Open-Shell/Open-Shell-Menu/issues)

View File

@@ -158,7 +158,6 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
@@ -178,6 +177,7 @@
<ModuleDefinitionFile>.\$(TargetName).def</ModuleDefinitionFile> <ModuleDefinitionFile>.\$(TargetName).def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<PerUserRedirection>true</PerUserRedirection>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -194,7 +194,6 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
@@ -214,6 +213,7 @@
<ModuleDefinitionFile>.\$(TargetName).def</ModuleDefinitionFile> <ModuleDefinitionFile>.\$(TargetName).def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<PerUserRedirection>true</PerUserRedirection>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -251,6 +251,7 @@
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<PerUserRedirection>true</PerUserRedirection>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -287,6 +288,7 @@
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<PerUserRedirection>true</PerUserRedirection>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Setup|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Setup|Win32'">

View File

@@ -77,7 +77,6 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>

View File

@@ -142,7 +142,6 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>NotUsing</PrecompiledHeader> <PrecompiledHeader>NotUsing</PrecompiledHeader>
@@ -163,7 +162,6 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>NotUsing</PrecompiledHeader> <PrecompiledHeader>NotUsing</PrecompiledHeader>

View File

@@ -152,7 +152,6 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_USRDLL;CLASSICIEDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_USRDLL;CLASSICIEDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
@@ -171,6 +170,7 @@
<ModuleDefinitionFile>.\$(TargetName).def</ModuleDefinitionFile> <ModuleDefinitionFile>.\$(TargetName).def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<PerUserRedirection>true</PerUserRedirection>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -187,7 +187,6 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_USRDLL;CLASSICIEDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_USRDLL;CLASSICIEDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
@@ -206,6 +205,7 @@
<ModuleDefinitionFile>.\$(TargetName).def</ModuleDefinitionFile> <ModuleDefinitionFile>.\$(TargetName).def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<PerUserRedirection>true</PerUserRedirection>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -242,6 +242,7 @@
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<PerUserRedirection>true</PerUserRedirection>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -277,6 +278,7 @@
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<PerUserRedirection>true</PerUserRedirection>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Setup|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Setup|Win32'">

View File

@@ -14,6 +14,7 @@ public:
CAbsolutePidl( const CAbsolutePidl &pidl ) { m_Pidl=pidl?ILCloneFull(pidl):NULL; } CAbsolutePidl( const CAbsolutePidl &pidl ) { m_Pidl=pidl?ILCloneFull(pidl):NULL; }
~CAbsolutePidl( void ) { Clear(); } ~CAbsolutePidl( void ) { Clear(); }
void operator=( const CAbsolutePidl &pidl ) { Clone(pidl); } 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; } void Clear( void ) { if (m_Pidl) ILFree(m_Pidl); m_Pidl=NULL; }
operator PIDLIST_ABSOLUTE( void ) const { return m_Pidl; } 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 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; } void Attach( PIDLIST_ABSOLUTE pidl ) { Clear(); m_Pidl=pidl; }
PIDLIST_ABSOLUTE Detach( void ) { PIDLIST_ABSOLUTE pidl=m_Pidl; m_Pidl=NULL; return 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: private:
PIDLIST_ABSOLUTE m_Pidl; PIDLIST_ABSOLUTE m_Pidl;

View File

@@ -71,7 +71,7 @@ BEGIN
CONTROL "Show all settings",IDC_CHECKALL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,154,7,79,12 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 "<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 "",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, 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 "SysLink",NOT WS_VISIBLE | WS_TABSTOP,80,195,111,10
PUSHBUTTON "&Backup",IDC_BUTTONBACKUP,200,192,60,14,WS_GROUP PUSHBUTTON "&Backup",IDC_BUTTONBACKUP,200,192,60,14,WS_GROUP
@@ -277,7 +277,7 @@ BEGIN
IDS_BMP_TITLE "Select Image File" IDS_BMP_TITLE "Select Image File"
IDS_SEARCH_PROMPT "Search Settings" IDS_SEARCH_PROMPT "Search Settings"
IDS_SETTING_SEARCH "Search Results" 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_LOCATE_SETTING "Locate setting"
IDS_LANGUAGE_UPDATED "The language %s is up to date." IDS_LANGUAGE_UPDATED "The language %s is up to date."
IDS_LANGUAGE_MISSING "Update for language %s is not available." IDS_LANGUAGE_MISSING "Update for language %s is not available."

View File

@@ -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 // Premultiplies a DIB section by the alpha channel and a given color
void PremultiplyBitmap( HBITMAP hBitmap, COLORREF rgb ) void PremultiplyBitmap( HBITMAP hBitmap, COLORREF rgb )
{ {
if (hBitmap == NULL) return;
BITMAP info; BITMAP info;
GetObject(hBitmap,sizeof(info),&info); GetObject(hBitmap,sizeof(info),&info);
int n=info.bmWidth*info.bmHeight; int n=info.bmWidth*info.bmHeight;

View File

@@ -1810,7 +1810,7 @@ LRESULT CSettingsDlg::OnHelp( int idCtrl, LPNMHDR pnmh, BOOL& bHandled )
LRESULT CSettingsDlg::OnWeb( 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; return 0;
} }

Binary file not shown.

View File

@@ -3,9 +3,7 @@ REM ***** Collect PDBs
echo -- Creating symbols package echo -- Creating symbols package
set CS_SYMBOLS_NAME=OpenShellPDB_%CS_VERSION_STR%.7z set CS_SYMBOLS_NAME=OpenShellPDB_%CS_VERSION_STR%.7z
cd Output 7z a -mx9 .\Final\%CS_SYMBOLS_NAME% .\Output\symbols\* > nul
7z a -mx9 ..\Final\%CS_SYMBOLS_NAME% PDB32 PDB64 > nul
cd ..
if defined APPVEYOR ( if defined APPVEYOR (
appveyor PushArtifact Final\%CS_SYMBOLS_NAME% appveyor PushArtifact Final\%CS_SYMBOLS_NAME%

View File

@@ -1,8 +1,6 @@
if exist Output rd /Q /S Output if exist Output rd /Q /S Output
md Output md Output
md Output\x64 md Output\x64
md Output\PDB32
md Output\PDB64
echo -- Compiling echo -- Compiling
@@ -39,7 +37,6 @@ copy /B ..\ClassicIE\Setup\ClassicIEDLL_32.dll Output > nul
copy /B ..\ClassicIE\Setup\ClassicIE_32.exe Output > nul copy /B ..\ClassicIE\Setup\ClassicIE_32.exe Output > nul
copy /B ..\StartMenu\Setup\StartMenu.exe Output > nul copy /B ..\StartMenu\Setup\StartMenu.exe Output > nul
copy /B ..\StartMenu\Setup\StartMenuDLL.dll Output > nul copy /B ..\StartMenu\Setup\StartMenuDLL.dll Output > nul
copy /B ..\Update\Release\Update.exe Output > nul
copy /B ..\StartMenu\StartMenuHelper\Setup\StartMenuHelper32.dll Output > nul copy /B ..\StartMenu\StartMenuHelper\Setup\StartMenuHelper32.dll Output > nul
copy /B ..\Setup\SetupHelper\Release\SetupHelper.exe Output > nul copy /B ..\Setup\SetupHelper\Release\SetupHelper.exe Output > nul
@@ -67,6 +64,8 @@ copy /B "..\StartMenu\Skins\Metallic.skin7" Output > nul
REM ********* Collect debug info REM ********* Collect debug info
md Output\PDB32
md Output\PDB64
REM Explorer 32 REM Explorer 32
copy /B ..\ClassicExplorer\Setup\ClassicExplorer32.pdb Output\PDB32 > nul copy /B ..\ClassicExplorer\Setup\ClassicExplorer32.pdb Output\PDB32 > nul
@@ -97,8 +96,6 @@ copy /B ..\StartMenu\Setup\StartMenuDLL.pdb Output\PDB32 > nul
copy /B Output\StartMenuDLL.dll Output\PDB32 > nul copy /B Output\StartMenuDLL.dll Output\PDB32 > nul
copy /B ..\StartMenu\StartMenuHelper\Setup\StartMenuHelper32.pdb Output\PDB32 > nul copy /B ..\StartMenu\StartMenuHelper\Setup\StartMenuHelper32.pdb Output\PDB32 > nul
copy /B Output\StartMenuHelper32.dll Output\PDB32 > nul copy /B Output\StartMenuHelper32.dll Output\PDB32 > nul
copy /B ..\Update\Release\Update.pdb Output\PDB32 > nul
copy /B Output\Update.exe Output\PDB32 > nul
REM Menu 64 REM Menu 64
copy /B ..\StartMenu\Setup64\StartMenu.pdb Output\PDB64 > nul copy /B ..\StartMenu\Setup64\StartMenu.pdb Output\PDB64 > nul
@@ -126,6 +123,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 REM ********* Build ADMX
echo --- ADMX echo --- ADMX
if exist Output\PolicyDefinitions.zip ( if exist Output\PolicyDefinitions.zip (

View File

@@ -55,7 +55,6 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>NotUsing</PrecompiledHeader> <PrecompiledHeader>NotUsing</PrecompiledHeader>

View File

@@ -103,10 +103,6 @@
<ComponentRef Id="IESettingsLink" /> <ComponentRef Id="IESettingsLink" />
<Condition Level="1">IE_BUILD&gt;=90000</Condition> <Condition Level="1">IE_BUILD&gt;=90000</Condition>
</Feature> </Feature>
<Feature Id="Update" Level="1" Title="!(loc.UpdateTitle)" ConfigurableDirectory="APPLICATIONFOLDER" AllowAdvertise="no" Description="!(loc.UpdateDesc)">
<ComponentRef Id="Update.exe" />
<ComponentRef Id="UpdateSettingsLink" />
</Feature>
</Feature> </Feature>
<UI> <UI>
<TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" /> <TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
@@ -388,8 +384,8 @@
<Control Type="Icon" Id="Icon1" Width="12" Height="12" X="7" Y="203" Hidden="yes" Text="web.ico"> <Control Type="Icon" Id="Icon1" Width="12" Height="12" X="7" Y="203" Hidden="yes" Text="web.ico">
<Condition Action="show">NOT Installed</Condition> <Condition Action="show">NOT Installed</Condition>
</Control> </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"> <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://github.com/Open-Shell/Open-Shell-Menu">!(loc.WebLink)</a>]]></Text> <Text><![CDATA[<a href="https://open-shell.github.io/Open-Shell-Menu">!(loc.WebLink)</a>]]></Text>
<Condition Action="show">NOT Installed</Condition> <Condition Action="show">NOT Installed</Condition>
</Control> </Control>
</Dialog> </Dialog>
@@ -473,9 +469,6 @@
<Component Id="StartMenuHelperL10N.ini" Guid="144CE4DC-0C77-4793-B79A-A32E48A90E64" Win64="$(var.CS_WIN64)"> <Component Id="StartMenuHelperL10N.ini" Guid="144CE4DC-0C77-4793-B79A-A32E48A90E64" Win64="$(var.CS_WIN64)">
<File Id="StartMenuHelperL10N.ini" KeyPath="yes" Source="..\StartMenu\StartMenuHelper\StartMenuHelperL10N.ini" Vital="yes" /> <File Id="StartMenuHelperL10N.ini" KeyPath="yes" Source="..\StartMenu\StartMenuHelper\StartMenuHelperL10N.ini" Vital="yes" />
</Component> </Component>
<Component Id="Update.exe" Guid="FB6C213F-B670-4888-8B2C-12E807E335A7" Win64="$(var.CS_WIN64)">
<File Id="Update" KeyPath="yes" Source="Output\Update.exe" Checksum="yes" Vital="yes" />
</Component>
<Component Id="PolicyDefinitions.zip" Guid="580A15D0-4023-471d-9D82-9D63FBA42B5D" Win64="$(var.CS_WIN64)"> <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" /> <File Id="PolicyDefinitions.zip" KeyPath="yes" Source="Output\PolicyDefinitions.zip" Vital="yes" />
</Component> </Component>
@@ -563,11 +556,6 @@
<CreateFolder /> <CreateFolder />
<Condition>START_MENU_FOLDER=1</Condition> <Condition>START_MENU_FOLDER=1</Condition>
</Component> </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" />
<CreateFolder />
<Condition>START_MENU_FOLDER=1</Condition>
</Component>
<Component Id="ExplorerSettingsLink" Guid="6EC027F2-115D-4110-8189-DDAFC78169EC"> <Component Id="ExplorerSettingsLink" Guid="6EC027F2-115D-4110-8189-DDAFC78169EC">
<Shortcut Id="ExplorerSettingsLink" Name="!(loc.ExplorerItem)" Advertise="no" Description="!(loc.ExplorerSettingsDesc)" Target="[APPLICATIONFOLDER]ClassicExplorerSettings.exe" WorkingDirectory="APPLICATIONFOLDER"> <Shortcut Id="ExplorerSettingsLink" Name="!(loc.ExplorerItem)" Advertise="no" Description="!(loc.ExplorerSettingsDesc)" Target="[APPLICATIONFOLDER]ClassicExplorerSettings.exe" WorkingDirectory="APPLICATIONFOLDER">
<ShortcutProperty Key="System.AppUserModel.ID" Value="OpenShell.ClassicExplorer.Settings" /> <ShortcutProperty Key="System.AppUserModel.ID" Value="OpenShell.ClassicExplorer.Settings" />
@@ -607,9 +595,9 @@
<Property Id="ApplicationFolderName" Value="Open-Shell" /> <Property Id="ApplicationFolderName" Value="Open-Shell" />
<Property Id="WixAppFolder" Value="WixPerMachineFolder" /> <Property Id="WixAppFolder" Value="WixPerMachineFolder" />
<Property Id="ALLUSERS" Value="1" /> <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="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="ARPNOMODIFY" Value="1" />
<Property Id="ARPNOREPAIR" Value="1" /> <Property Id="ARPNOREPAIR" Value="1" />
<Property Id="START_MENU_FOLDER" Value="1" /> <Property Id="START_MENU_FOLDER" Value="1" />

View File

@@ -53,7 +53,6 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>NotUsing</PrecompiledHeader> <PrecompiledHeader>NotUsing</PrecompiledHeader>

View File

@@ -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 ) static bool RemoveRegistryKeys( bool bPin )
{ {
HKEY hkey=NULL; HKEY hkey=NULL;
@@ -489,40 +515,11 @@ static bool RemoveRegistryKeys( bool bPin )
} }
} }
hkey=NULL;
if (bPin) if (bPin)
{ {
if (RegOpenKeyEx(HKEY_CLASSES_ROOT,L"Launcher.ImmersiveApplication\\ShellEx\\ContextMenuHandlers\\StartMenuExt",0,KEY_READ|KEY_WOW64_64KEY,&hkey)==ERROR_SUCCESS) RemoveShellExtKey(L"Launcher.ImmersiveApplication");
{ RemoveShellExtKey(L"Launcher.DesktopPackagedApplication");
RegCloseKey(hkey); RemoveShellExtKey(L"Launcher.SystemSettings");
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.");
}
} }
return true; return true;

View File

@@ -92,7 +92,6 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>NotUsing</PrecompiledHeader> <PrecompiledHeader>NotUsing</PrecompiledHeader>
@@ -112,7 +111,6 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>NotUsing</PrecompiledHeader> <PrecompiledHeader>NotUsing</PrecompiledHeader>

View File

@@ -7,7 +7,7 @@ rem Clean repository and build fresh. Will erase current changes so disabled by
rem git clean -dfx rem git clean -dfx
rem Default version rem Default version
set CS_VERSION=4.4.110 set CS_VERSION=4.4.1000
if defined APPVEYOR_BUILD_VERSION ( if defined APPVEYOR_BUILD_VERSION (
set CS_VERSION=%APPVEYOR_BUILD_VERSION% set CS_VERSION=%APPVEYOR_BUILD_VERSION%

View File

@@ -9,7 +9,7 @@ rem Clean repository and build fresh. Will erase current changes so disabled by
rem git clean -dfx rem git clean -dfx
rem Default version rem Default version
set CS_VERSION=4.3.2 set CS_VERSION=4.4.1000
if defined APPVEYOR_BUILD_VERSION ( if defined APPVEYOR_BUILD_VERSION (
set CS_VERSION=%APPVEYOR_BUILD_VERSION% set CS_VERSION=%APPVEYOR_BUILD_VERSION%

View File

@@ -136,7 +136,6 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
@@ -159,7 +158,6 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>

View File

@@ -182,7 +182,7 @@ HRESULT STDMETHODCALLTYPE CMenuAccessible::accSelect( long flagsSelect, VARIANT
int index=varChild.lVal-1; int index=varChild.lVal-1;
if (index<0 || index>=(int)m_pOwner->m_Items.size()) if (index<0 || index>=(int)m_pOwner->m_Items.size())
return S_FALSE; return S_FALSE;
m_pOwner->ActivateItem(index,CMenuContainer::ACTIVATE_SELECT,NULL,false); m_pOwner->ActivateItem(index,CMenuContainer::ACTIVATE_SELECT,NULL);
} }
return S_OK; return S_OK;
} }

View File

@@ -852,9 +852,14 @@ HRESULT STDMETHODCALLTYPE CMenuContainer::Drop( IDataObject *pDataObj, DWORD grf
CComQIPtr<IDataObjectAsyncCapability> pAsync=pDataObj; CComQIPtr<IDataObjectAsyncCapability> pAsync=pDataObj;
if (pAsync) if (pAsync)
pAsync->SetAsyncMode(FALSE); pAsync->SetAsyncMode(FALSE);
for (std::vector<CMenuContainer*>::iterator it=s_Menus.begin();it!=s_Menus.end();++it) for (auto& it : s_Menus)
if (!(*it)->m_bDestroyed) {
(*it)->EnableWindow(FALSE); // disable all 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; bool bAllPrograms=s_bAllPrograms;
if (bAllPrograms) ::EnableWindow(g_TopWin7Menu,FALSE); if (bAllPrograms) ::EnableWindow(g_TopWin7Menu,FALSE);
bool bOld=s_bPreventClosing; bool bOld=s_bPreventClosing;
@@ -862,9 +867,14 @@ HRESULT STDMETHODCALLTYPE CMenuContainer::Drop( IDataObject *pDataObj, DWORD grf
AddRef(); AddRef();
pTarget->Drop(pDataObj,grfKeyState,pt,pdwEffect); pTarget->Drop(pDataObj,grfKeyState,pt,pdwEffect);
s_bPreventClosing=bOld; s_bPreventClosing=bOld;
for (std::vector<CMenuContainer*>::iterator it=s_Menus.begin();it!=s_Menus.end();++it) for (auto& it : s_Menus)
if (!(*it)->m_bDestroyed) {
(*it)->EnableWindow(TRUE); // enable all 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 (bAllPrograms) ::EnableWindow(g_TopWin7Menu,TRUE);
} }
else else

View File

@@ -142,10 +142,11 @@ static bool DetectGrayscaleImage( const unsigned int *bits, int stride, int widt
for (int x=0;x<width;x++) for (int x=0;x<width;x++)
{ {
unsigned int pixel=bits[x]; unsigned int pixel=bits[x];
int a=(pixel>>24)&255;
int r=(pixel>>16)&255; int r=(pixel>>16)&255;
int g=(pixel>>8)&255; int g=(pixel>>8)&255;
int b=(pixel)&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 return false; // found colored pixel
if (!(pixel&0xFF000000)) if (!(pixel&0xFF000000))
transparent++; transparent++;
@@ -2441,7 +2442,7 @@ void CItemManager::LoadMetroIcon( IShellItem *pItem, int &refreshFlags, const Ic
StoreInCache(hash,L"",NULL,hLargeBitmap,NULL,INFO_LARGE_ICON,smallIcon,largeIcon,extraLargeIcon,false,true); 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-delta))
{ {
CComString pLocation; CComString pLocation;
if (SUCCEEDED(pResMap->GetFilePath(iconName,&pLocation))) if (SUCCEEDED(pResMap->GetFilePath(iconName,&pLocation)))

View File

@@ -402,7 +402,7 @@ void CMenuContainer::OpenSubMenu( int index, TActivateType type, bool bShift )
if (m_Options&CONTAINER_NOEXTENSIONS) if (m_Options&CONTAINER_NOEXTENSIONS)
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; options|=CONTAINER_MULTICOL_REC;
if ((options&CONTAINER_MULTICOL_REC) && !bShift) if ((options&CONTAINER_MULTICOL_REC) && !bShift)
options|=CONTAINER_MULTICOLUMN; options|=CONTAINER_MULTICOLUMN;
@@ -2192,11 +2192,15 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p
if (res==CMD_PINSETTING) if (res==CMD_PINSETTING)
{ {
CSearchManager::TItemCategory cat=(CSearchManager::TItemCategory)(item.categoryHash&CSearchManager::CATEGORY_MASK); CString iconPath;
if (cat==CSearchManager::CATEGORY_SETTING) if (item.pItemInfo)
CreatePinLink(pItemPidl1,item.name,NULL,0); {
else if (cat==CSearchManager::CATEGORY_METROSETTING) CItemManager::RWLock lock(&g_ItemManager, false, CItemManager::RWLOCK_ITEMS);
CreatePinLink(pItemPidl1,item.name,L"%windir%\\ImmersiveControlPanel\\systemsettings.exe",0); 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; m_bRefreshItems=true;
} }
@@ -2800,8 +2804,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 info.fMask|=CMIC_MASK_NOASYNC; // wait for delete/link commands to finish so we can refresh the menu
s_bPreventClosing=true; s_bPreventClosing=true;
for (std::vector<CMenuContainer*>::iterator it=s_Menus.begin();it!=s_Menus.end();++it) for (auto& it : s_Menus)
(*it)->EnableWindow(FALSE); // disable all 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; bool bAllPrograms=s_bAllPrograms;
if (bAllPrograms) ::EnableWindow(g_TopWin7Menu,FALSE); if (bAllPrograms) ::EnableWindow(g_TopWin7Menu,FALSE);
info.hwnd=g_OwnerWindow; info.hwnd=g_OwnerWindow;
@@ -2846,9 +2853,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) for (auto& it : s_Menus)
if (!(*it)->m_bDestroyed) {
(*it)->EnableWindow(TRUE); // enable all 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 (bAllPrograms) ::EnableWindow(g_TopWin7Menu,TRUE);
if (bRefreshMain && m_bSubMenu) if (bRefreshMain && m_bSubMenu)
{ {

View File

@@ -2656,17 +2656,11 @@ int CMenuContainer::AddSearchItems( const std::vector<SearchItem> &items, const
if (!categoryName.IsEmpty()) if (!categoryName.IsEmpty())
{ {
MenuItem item(MENU_SEARCH_CATEGORY); MenuItem item(MENU_SEARCH_CATEGORY);
if (categoryHash==CSearchManager::CATEGORY_PROGRAM || categoryHash==CSearchManager::CATEGORY_SETTING) item.name.Format(L"%s (%d)",categoryName,originalCount);
{
item.name.Format(L"%s (%d)",categoryName,originalCount);
}
else
{
item.name=categoryName;
item.bSplit=(s_Skin.More_bitmap_Size.cx>0);
}
item.nameHash=CalcFNVHash(categoryName); item.nameHash=CalcFNVHash(categoryName);
item.categoryHash=categoryHash; 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); m_Items.push_back(item);
} }
} }
@@ -2724,7 +2718,7 @@ bool CMenuContainer::InitSearchItems( void )
unsigned int runCategoryHash=0; unsigned int runCategoryHash=0;
CString runCommand; CString runCommand;
CComString runExe; 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) if (s_bWin7Style)
m_SearchBox.GetWindowText(runCommand); m_SearchBox.GetWindowText(runCommand);
@@ -2787,6 +2781,12 @@ bool CMenuContainer::InitSearchItems( void )
if (m_SearchCategoryHash==CSearchManager::CATEGORY_SETTING) if (m_SearchCategoryHash==CSearchManager::CATEGORY_SETTING)
selectedCount=(int)s_SearchResults.settings.size(); selectedCount=(int)s_SearchResults.settings.size();
} }
if (!s_SearchResults.metrosettings.empty())
{
counts.push_back((int)s_SearchResults.metrosettings.size());
if (m_SearchCategoryHash==CSearchManager::CATEGORY_METROSETTING)
selectedCount=(int)s_SearchResults.metrosettings.size();
}
for (std::list<CSearchManager::SearchCategory>::const_iterator it=s_SearchResults.indexed.begin();it!=s_SearchResults.indexed.end();++it) for (std::list<CSearchManager::SearchCategory>::const_iterator it=s_SearchResults.indexed.begin();it!=s_SearchResults.indexed.end();++it)
{ {
if (!it->items.empty()) if (!it->items.empty())
@@ -2829,7 +2829,7 @@ bool CMenuContainer::InitSearchItems( void )
// add categories // add categories
std::list<CSearchManager::SearchCategory>::const_iterator it=s_SearchResults.indexed.begin(); 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(); items.clear();
unsigned int categoryHash; unsigned int categoryHash;
@@ -2837,6 +2837,8 @@ bool CMenuContainer::InitSearchItems( void )
categoryHash=CSearchManager::CATEGORY_PROGRAM; categoryHash=CSearchManager::CATEGORY_PROGRAM;
else if (idx==1) else if (idx==1)
categoryHash=CSearchManager::CATEGORY_SETTING; categoryHash=CSearchManager::CATEGORY_SETTING;
else if (idx==2)
categoryHash=CSearchManager::CATEGORY_METROSETTING;
else else
categoryHash=it->categoryHash; categoryHash=it->categoryHash;
@@ -2854,7 +2856,7 @@ bool CMenuContainer::InitSearchItems( void )
} }
if (count<=0) if (count<=0)
{ {
if (idx>=2) ++it; if (idx>=3) ++it;
continue; continue;
} }
@@ -2880,6 +2882,16 @@ bool CMenuContainer::InitSearchItems( void )
items.push_back(SearchItem(*it)); items.push_back(SearchItem(*it));
name=FindTranslation(L"Search.CategorySettings",L"Settings"); name=FindTranslation(L"Search.CategorySettings",L"Settings");
} }
else if (idx==2)
{
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"Modern Settings");
}
else else
{ {
originalCount=(int)it->items.size(); originalCount=(int)it->items.size();

View File

@@ -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); 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); TreeView_SetExtendedStyle(hWnd,TVS_EX_AUTOHSCROLL,TVS_EX_AUTOHSCROLL);
const MenuSkin &skin=CMenuContainer::s_Skin; const MenuSkin &skin=CMenuContainer::s_Skin;
m_TreeTheme=OpenThemeData(m_hWnd,L"treeview"); m_TreeTheme=OpenThemeData(hWnd,L"treeview");
if (skin.BHasScrollbar) 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]; const MenuSkin::ItemDrawSettings &settings=skin.ItemSettings[MenuSkin::PROGRAMS_TREE_ITEM];

View File

@@ -139,18 +139,25 @@ void CSearchManager::CloseMenu( void )
Lock lock(this,LOCK_DATA); Lock lock(this,LOCK_DATA);
m_LastRequestId++; m_LastRequestId++;
m_LastProgramsRequestId=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) if (item.category == CATEGORY_PROGRAM)
LOG_MENU(LOG_SEARCH,L"Program: '%s', %d",it->name,it->rank); 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) if (item.category == CATEGORY_SETTING)
LOG_MENU(LOG_SEARCH,L"Setting: '%s', %d",it->name,it->rank); 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) if (m_bProgramsFound)
@@ -170,6 +177,7 @@ void CSearchManager::CloseMenu( void )
m_SettingsItems.clear(); m_SettingsItems.clear();
m_SettingsHash=FNV_HASH0; m_SettingsHash=FNV_HASH0;
m_bSettingsFound=false; m_bSettingsFound=false;
m_bMetroSettingsFound = false;
m_IndexedItems.clear(); m_IndexedItems.clear();
m_AutoCompleteItems.clear(); m_AutoCompleteItems.clear();
@@ -310,7 +318,9 @@ bool CSearchManager::AddSearchItem( IShellItem *pItem, const wchar_t *name, int
PROPVARIANT val; PROPVARIANT val;
PropVariantInit(&val); PropVariantInit(&val);
pItem2->GetProperty(PKEY_Keywords,&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; int len=0;
if (val.vt==VT_BSTR || val.vt==VT_LPWSTR) 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); 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) if (searchRequest.requestId<m_LastProgramsRequestId)
return false; return false;
@@ -345,10 +355,10 @@ bool CSearchManager::AddSearchItem( IShellItem *pItem, const wchar_t *name, int
return false; return false;
} }
bool res=true; 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; 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 // remove duplicate settings
for (std::vector<SearchItem>::const_iterator it=items.begin();it!=items.end();++it) 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); items.push_back(item);
if (item.category==CATEGORY_METROSETTING)
m_bMetroSettingsFound=true;
} }
else if (category==CATEGORY_AUTOCOMPLETE) else if (category==CATEGORY_AUTOCOMPLETE)
{ {
@@ -409,7 +421,7 @@ void CSearchManager::CollectSearchItems( IShellItem *pFolder, int flags, TItemCa
CComPtr<IShellItem> pChild; CComPtr<IShellItem> pChild;
while (pChild=NULL,pEnum->Next(1,&pChild,NULL)==S_OK) 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) if (searchRequest.requestId<m_LastProgramsRequestId)
break; break;
@@ -428,7 +440,7 @@ void CSearchManager::CollectSearchItems( IShellItem *pFolder, int flags, TItemCa
{ {
// go into subfolders but not archives or links to folders // go into subfolders but not archives or links to folders
CollectSearchItems(pChild,flags,category,searchRequest); 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) if (searchRequest.requestId<m_LastProgramsRequestId)
break; break;
@@ -670,7 +682,7 @@ void CSearchManager::SearchThread( void )
if (GetWinVersion()>=WIN_VER_WIN8 && searchRequest.bSearchMetroApps) if (GetWinVersion()>=WIN_VER_WIN8 && searchRequest.bSearchMetroApps)
{ {
std::vector<MetroLink> links; std::vector<MetroLink> links;
GetMetroLinks(links,false); GetMetroLinks(links,true);
for (std::vector<MetroLink>::const_iterator it=links.begin();it!=links.end();++it) for (std::vector<MetroLink>::const_iterator it=links.begin();it!=links.end();++it)
{ {
if (GetWinVersion()<WIN_VER_WIN10) if (GetWinVersion()<WIN_VER_WIN10)
@@ -733,6 +745,14 @@ void CSearchManager::SearchThread( void )
if (searchRequest.requestId<m_LastProgramsRequestId) if (searchRequest.requestId<m_LastProgramsRequestId)
continue; 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; bool bRefresh=false;
{ {
@@ -780,12 +800,12 @@ void CSearchManager::SearchThread( void )
{ {
std::list<SearchScope> scopeList; std::list<SearchScope> scopeList;
if (searchRequest.bSearchMetroSettings) if (searchRequest.bSearchMetroSettings && !m_bMetroSettingsFound)
{ {
scopeList.push_back(SearchScope()); scopeList.push_back(SearchScope());
SearchScope &scope=*scopeList.rbegin(); SearchScope &scope=*scopeList.rbegin();
scope.bFiles=true; scope.bFiles=true;
scope.name=FindTranslation(L"Search.CategoryPCSettings",L"Settings"); scope.name=FindTranslation(L"Search.CategoryPCSettings",L"Modern Settings");
scope.categoryHash=CATEGORY_METROSETTING; scope.categoryHash=CATEGORY_METROSETTING;
scope.roots.push_back(L"FILE:"); scope.roots.push_back(L"FILE:");
} }
@@ -1240,7 +1260,7 @@ void CSearchManager::SearchThread( void )
Lock lock(this,LOCK_DATA); Lock lock(this,LOCK_DATA);
m_IndexedItems.push_back(SearchCategory()); m_IndexedItems.push_back(SearchCategory());
pCategory=&*m_IndexedItems.rbegin(); pCategory=&*m_IndexedItems.rbegin();
pCategory->name.Format(L"%s (%d)",it->name,it->resultCount); pCategory->name=it->name;
pCategory->categoryHash=it->categoryHash; pCategory->categoryHash=it->categoryHash;
pCategory->search.Clone(it->search); pCategory->search.Clone(it->search);
} }
@@ -1348,6 +1368,7 @@ void CSearchManager::GetSearchResults( SearchResults &results )
{ {
results.programs.clear(); results.programs.clear();
results.settings.clear(); results.settings.clear();
results.metrosettings.clear();
results.indexed.clear(); results.indexed.clear();
results.autocomplete.clear(); results.autocomplete.clear();
results.autoCompletePath.Empty(); results.autoCompletePath.Empty();
@@ -1397,14 +1418,19 @@ void CSearchManager::GetSearchResults( SearchResults &results )
std::vector<SearchItem> &settings=m_bSettingsFound?m_SettingsItems:m_SettingsItemsOld; std::vector<SearchItem> &settings=m_bSettingsFound?m_SettingsItems:m_SettingsItemsOld;
for (std::vector<SearchItem>::iterator it=settings.begin();it!=settings.end();++it) 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); it->rank=(it->rank&0xFFFFFFFE)|(match>>1);
} }
std::sort(settings.begin(),settings.end()); std::sort(settings.begin(),settings.end());
for (std::vector<SearchItem>::const_iterator it=settings.begin();it!=settings.end();++it) for (std::vector<SearchItem>::const_iterator it=settings.begin();it!=settings.end();++it)
{ {
if (it->category==CATEGORY_SETTING && it->MatchText(m_SearchText,bSearchSubWord)) if (it->MatchText(m_SearchText, bSearchSubWord))
results.settings.push_back(it->pInfo); {
if (it->category==CATEGORY_SETTING)
results.settings.push_back(it->pInfo);
if (it->category==CATEGORY_METROSETTING)
results.metrosettings.push_back(it->pInfo);
}
} }
} }
@@ -1423,7 +1449,7 @@ void CSearchManager::GetSearchResults( SearchResults &results )
results.autocomplete.push_back(it->pInfo); 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); results.bSearching=(m_LastCompletedId!=m_LastRequestId);
} }

View File

@@ -63,6 +63,7 @@ public:
CString autoCompletePath; CString autoCompletePath;
std::vector<const CItemManager::ItemInfo*> programs; std::vector<const CItemManager::ItemInfo*> programs;
std::vector<const CItemManager::ItemInfo*> settings; std::vector<const CItemManager::ItemInfo*> settings;
std::vector<const CItemManager::ItemInfo*> metrosettings;
std::vector<const CItemManager::ItemInfo*> autocomplete; std::vector<const CItemManager::ItemInfo*> autocomplete;
std::list<SearchCategory> indexed; std::list<SearchCategory> indexed;
}; };
@@ -149,6 +150,7 @@ private:
unsigned int m_SettingsHashOld; unsigned int m_SettingsHashOld;
bool m_bProgramsFound; bool m_bProgramsFound;
bool m_bSettingsFound; bool m_bSettingsFound;
bool m_bMetroSettingsFound = false;
std::vector<SearchItem> m_AutoCompleteItems; std::vector<SearchItem> m_AutoCompleteItems;
std::list<SearchCategory> m_IndexedItems; std::list<SearchCategory> m_IndexedItems;
std::vector<ItemRank> m_ItemRanks; std::vector<ItemRank> m_ItemRanks;

View File

@@ -3718,7 +3718,6 @@ protected:
CWindow m_ImageClassic1, m_ImageClassic2, m_ImageWin7; CWindow m_ImageClassic1, m_ImageClassic2, m_ImageWin7;
CWindow m_Tooltip; CWindow m_Tooltip;
CWindow m_ButtonAero, m_ButtonClassic, m_ButtonCustom; CWindow m_ButtonAero, m_ButtonClassic, m_ButtonCustom;
bool m_bLargeBitmaps;
HICON m_hIcon; HICON m_hIcon;
CString m_IconPath; CString m_IconPath;
@@ -3737,14 +3736,13 @@ LRESULT CMenuStyleDlg::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BO
HDC hdc=::GetDC(NULL); HDC hdc=::GetDC(NULL);
int dpi=GetDeviceCaps(hdc,LOGPIXELSY); int dpi=GetDeviceCaps(hdc,LOGPIXELSY);
::ReleaseDC(NULL,hdc); ::ReleaseDC(NULL,hdc);
m_bLargeBitmaps=dpi>=144; bool bLargeBitmaps=dpi>=144;
if (m_bLargeBitmaps)
{ {
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); 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); 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); m_ImageWin7.SendMessage(STM_SETIMAGE,IMAGE_BITMAP,(LPARAM)bmp);
} }
@@ -3779,7 +3777,6 @@ LRESULT CMenuStyleDlg::OnDestroy( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&
{ {
if (m_hIcon) DestroyIcon(m_hIcon); if (m_hIcon) DestroyIcon(m_hIcon);
m_hIcon=NULL; m_hIcon=NULL;
if (m_bLargeBitmaps)
{ {
HBITMAP bmp=(HBITMAP)m_ImageClassic1.SendMessage(STM_GETIMAGE,IMAGE_BITMAP); HBITMAP bmp=(HBITMAP)m_ImageClassic1.SendMessage(STM_GETIMAGE,IMAGE_BITMAP);
if (bmp) DeleteObject(bmp); if (bmp) DeleteObject(bmp);

View File

@@ -369,19 +369,20 @@ IDI_START10 ICON "start10.ico"
IDB_ARROWS BITMAP "menu_arrows.bmp" IDB_ARROWS BITMAP "menu_arrows.bmp"
IDB_ARROWS150 BITMAP "menu_arrows150.bmp" IDB_ARROWS150 BITMAP "menu_arrows150.bmp"
IDB_SEARCH_ICONS BITMAP "search_icons.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_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 // 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_BUTTON96 IMAGE "button96.png"
IDB_BUTTON120 IMAGE "button120.png" IDB_BUTTON120 IMAGE "button120.png"
IDB_BUTTON144 IMAGE "button144.png" IDB_BUTTON144 IMAGE "button144.png"

View File

@@ -136,7 +136,6 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CLASSICSTARTMENUDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CLASSICSTARTMENUDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
@@ -161,7 +160,6 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CLASSICSTARTMENUDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CLASSICSTARTMENUDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View 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 = 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;
}

View 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();

View File

@@ -0,0 +1,211 @@
// 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 },
{ NULL, NULL, (UINT)-1 }
};
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;
}

View 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)

View 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 ''
{
}
}
}
}
}

View 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 {};
}

View 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)

View 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}'
{
}
}
}
}
}
}

View File

@@ -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}}; const CLSID g_EmulationClsid= {0xD3214FBB, 0x3CA1, 0x406A, {0xB3, 0xE8, 0x3E, 0xB7, 0xC3, 0x93, 0xA1, 0x5E}};
#define EMULATION_KEY L"TreatAs" #define EMULATION_KEY L"TreatAs"
#define SHELLEXT_NAME L"StartMenuExt"
static void AdjustPrivileges( void ) static void AdjustPrivileges( void )
{ {
HANDLE hToken; 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 ) static void AddRegistryKeys( bool bPin )
{ {
AdjustPrivileges(); AdjustPrivileges();
@@ -103,21 +117,12 @@ static void AddRegistryKeys( bool bPin )
RegSetValueEx(hkey,NULL,NULL,REG_SZ,(BYTE*)val,sizeof(val)); RegSetValueEx(hkey,NULL,NULL,REG_SZ,(BYTE*)val,sizeof(val));
RegCloseKey(hkey); RegCloseKey(hkey);
} }
hkey=NULL;
if (bPin) 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) AddShellExt(L"Launcher.ImmersiveApplication", &sa);
{ AddShellExt(L"Launcher.DesktopPackagedApplication", &sa);
wchar_t val[]=L"{E595F05F-903F-4318-8B0A-7F633B520D2B}"; AddShellExt(L"Launcher.SystemSettings", &sa);
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);
}
} }
} }
} }
@@ -127,6 +132,16 @@ static void AddRegistryKeys( bool bPin )
FreeSid(pAdminSID); 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 ) static void RemoveRegistryKeys( bool bPin )
{ {
AdjustPrivileges(); AdjustPrivileges();
@@ -136,19 +151,12 @@ static void RemoveRegistryKeys( bool bPin )
RegDeleteTree(hkey,EMULATION_KEY); RegDeleteTree(hkey,EMULATION_KEY);
RegCloseKey(hkey); RegCloseKey(hkey);
} }
hkey=NULL;
if (bPin) 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) RemoveShellExt(L"Launcher.ImmersiveApplication");
{ RemoveShellExt(L"Launcher.DesktopPackagedApplication");
RegDeleteTree(hkey,L"StartMenuExt"); RemoveShellExt(L"Launcher.SystemSettings");
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);
}
} }
} }

View File

@@ -6,6 +6,7 @@
import "oaidl.idl"; import "oaidl.idl";
import "ocidl.idl"; import "ocidl.idl";
import "shobjidl.idl";
[ [
object, object,
@@ -31,4 +32,21 @@ library StartMenuHelperLib
{ {
[default] interface IStartMenuExt; [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;
};
}; };

View File

@@ -98,6 +98,8 @@ END
IDR_STARTMENUHELPER REGISTRY "StartMenuHelper.rgs" IDR_STARTMENUHELPER REGISTRY "StartMenuHelper.rgs"
IDR_STARTMENUEXT REGISTRY "StartMenuExt.rgs" IDR_STARTMENUEXT REGISTRY "StartMenuExt.rgs"
IDR_MODERNSETTINGSSHELLFOLDER REGISTRY "ModernSettingsShellFolder.rgs"
IDR_MODERNSETTINGSCONTEXTMENU REGISTRY "ModernSettingsContextMenu.rgs"
#endif // English (U.S.) resources #endif // English (U.S.) resources
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View File

@@ -157,7 +157,6 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
@@ -177,6 +176,7 @@
<ModuleDefinitionFile>.\$(TargetName).def</ModuleDefinitionFile> <ModuleDefinitionFile>.\$(TargetName).def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<PerUserRedirection>true</PerUserRedirection>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -192,7 +192,6 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
@@ -212,6 +211,7 @@
<ModuleDefinitionFile>.\$(TargetName).def</ModuleDefinitionFile> <ModuleDefinitionFile>.\$(TargetName).def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<PerUserRedirection>true</PerUserRedirection>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -248,6 +248,7 @@
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<PerUserRedirection>true</PerUserRedirection>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -283,6 +284,7 @@
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<PerUserRedirection>true</PerUserRedirection>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Setup|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Setup|Win32'">
@@ -356,6 +358,9 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="dllmain.cpp" /> <ClCompile Include="dllmain.cpp" />
<ClCompile Include="ModernSettings.cpp" />
<ClCompile Include="ModernSettingsContextMenu.cpp" />
<ClCompile Include="ModernSettingsShellFolder.cpp" />
<ClCompile Include="StartMenuExt.cpp" /> <ClCompile Include="StartMenuExt.cpp" />
<ClCompile Include="StartMenuHelper.cpp" /> <ClCompile Include="StartMenuHelper.cpp" />
<ClCompile Include="StartMenuHelper_i.c"> <ClCompile Include="StartMenuHelper_i.c">
@@ -369,6 +374,8 @@
<Midl Include="StartMenuHelper.idl" /> <Midl Include="StartMenuHelper.idl" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="ModernSettingsContextMenu.rgs" />
<None Include="ModernSettingsShellFolder.rgs" />
<None Include="StartMenuExt.rgs" /> <None Include="StartMenuExt.rgs" />
<None Include="StartMenuHelper.rgs" /> <None Include="StartMenuHelper.rgs" />
<None Include="StartMenuHelper32.def" /> <None Include="StartMenuHelper32.def" />
@@ -377,6 +384,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="dllmain.h" /> <ClInclude Include="dllmain.h" />
<ClInclude Include="ModernSettings.h" />
<ClInclude Include="ModernSettingsContextMenu.h" />
<ClInclude Include="ModernSettingsShellFolder.h" />
<ClInclude Include="Resource.h" /> <ClInclude Include="Resource.h" />
<ClInclude Include="StartMenuExt.h" /> <ClInclude Include="StartMenuExt.h" />
<ClInclude Include="StartMenuHelper_i.h" /> <ClInclude Include="StartMenuHelper_i.h" />

View File

@@ -34,6 +34,15 @@
<ClCompile Include="StartMenuHelper_i.c"> <ClCompile Include="StartMenuHelper_i.c">
<Filter>Generated Files</Filter> <Filter>Generated Files</Filter>
</ClCompile> </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>
<ItemGroup> <ItemGroup>
<Midl Include="StartMenuHelper.idl"> <Midl Include="StartMenuHelper.idl">
@@ -56,6 +65,12 @@
<None Include="StartMenuHelperL10N.ini"> <None Include="StartMenuHelperL10N.ini">
<Filter>Resource Files</Filter> <Filter>Resource Files</Filter>
</None> </None>
<None Include="ModernSettingsShellFolder.rgs">
<Filter>Resource Files</Filter>
</None>
<None Include="ModernSettingsContextMenu.rgs">
<Filter>Resource Files</Filter>
</None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="dllmain.h"> <ClInclude Include="dllmain.h">
@@ -76,6 +91,15 @@
<ClInclude Include="StartMenuHelper_i.h"> <ClInclude Include="StartMenuHelper_i.h">
<Filter>Generated Files</Filter> <Filter>Generated Files</Filter>
</ClInclude> </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>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="StartMenuHelper.rc"> <ResourceCompile Include="StartMenuHelper.rc">

View File

@@ -4,6 +4,8 @@
// //
#define IDR_STARTMENUHELPER 101 #define IDR_STARTMENUHELPER 101
#define IDR_STARTMENUEXT 102 #define IDR_STARTMENUEXT 102
#define IDR_MODERNSETTINGSSHELLFOLDER 103
#define IDR_MODERNSETTINGSCONTEXTMENU 104
// Next default values for new objects // Next default values for new objects
// //
@@ -12,6 +14,6 @@
#define _APS_NEXT_RESOURCE_VALUE 201 #define _APS_NEXT_RESOURCE_VALUE 201
#define _APS_NEXT_COMMAND_VALUE 32768 #define _APS_NEXT_COMMAND_VALUE 32768
#define _APS_NEXT_CONTROL_VALUE 201 #define _APS_NEXT_CONTROL_VALUE 201
#define _APS_NEXT_SYMED_VALUE 103 #define _APS_NEXT_SYMED_VALUE 105
#endif #endif
#endif #endif

View File

@@ -57,7 +57,6 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>NotUsing</PrecompiledHeader> <PrecompiledHeader>NotUsing</PrecompiledHeader>

View File

@@ -4,7 +4,7 @@
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup> <PropertyGroup>
<!-- Default product version to use if CS_VERSION environment variable is not defined --> <!-- Default product version to use if CS_VERSION environment variable is not defined -->
<CS_VERSION Condition="'$(CS_VERSION)'==''">4.3.2</CS_VERSION> <CS_VERSION Condition="'$(CS_VERSION)'==''">4.4.1000</CS_VERSION>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup> <ItemDefinitionGroup>
<ResourceCompile> <ResourceCompile>