120 Commits

Author SHA1 Message Date
ge0rdi
b0c1d9a229 Fix for potential crash introduced in 1b013c3
Fixes #1245
2022-12-14 16:10:10 +01:00
Eli Farmer
ac80080f90 Update README.md
- General grammar/format/convention improvements
 - Switch to shields.io for gitter badge and change color of Discord badge
2022-12-08 15:23:34 +01:00
bonzibudd
d28c8e512a New icons and installer artwork
This adds the new artwork for the main icon and installer screens.
Addresses #31.

Update classic button thumbnail

Improve setup banner icon

Fix web.ico size

New installer art

Fix dialog2
2022-12-07 11:58:37 +01:00
bonzibudd
be57a43589 Format ReadMe icon 2022-12-07 11:58:37 +01:00
ge0rdi
0465ac9c1b Use Segoe Fluent Icons font for modern settings icons on Win11
It seems that Windows 11 prefers `Segoe Fluent Icons` over `Segoe MDL2 Assets` font.
https://learn.microsoft.com/en-us/windows/apps/design/style/segoe-fluent-icons-font

Most of settings defined in `AllSystemSettings_{253E530E-387D-4BC2-959D-E6F86122E5F2}.xml` now refer to the new font.
2022-12-06 19:17:18 +01:00
ge0rdi
77d2d3a01d Don't show Windows Shell Experience Host in list of frequent programs
It is not a program that user will use explicitly.
No need to show it in the list even if Windows tracks it as frequent
program for some reason.

Fixes #1164
2022-12-06 19:17:18 +01:00
ge0rdi
704459225b Properly handle automatically hiding taskbar on multi-monitor setup
When taskbar is hidden its window is moved off the screen (except for
few pixels at border). It may happen that the taskbar window actually
spans to another monitor (though still not visible).

MonitorFromWindow API may thus return different monitor handle than the
one visible taskbar is on.

We will use GetTaskbarPosition function that correctly identifies taskbar's
monitor by checking rectangle of visible taskbar.

Fixes #908
2022-12-06 19:17:18 +01:00
ge0rdi
04770c403d Windows 11 start menu button support
- handling of `Taskbar alignment` setting (left/center)
  - start menu position is based on position of start button
  - mouse clicks to original button now work properly (without triggering original menu)
  - custom button is properly positioned
  - Win+X works properly
2022-12-06 19:17:18 +01:00
ge0rdi
f42980e090 Make debugging more skin friendly
Debug StartMenuDLL used to not find skins when put to Open-Shell
installation folder.

Now it will try to look for skins in default location (Skins folder in
the same folder as DLL) and use alternative (Skins folder one level up)
if not present.
2022-12-06 19:17:18 +01:00
ge0rdi
7ad33f509e Fix skin options default values
Multi-string settings have to be terminated by new line.
Otherwise there may be some garbage (following the string)
stored in registry.
2022-12-06 19:17:18 +01:00
ge0rdi
1b013c3590 Don't track usage of Open-Shell modern settings folder
This way `Open-Shell Modern Settings` folder won't appear in File
Explorer's frequent list.

Fixes #744.
2022-12-06 19:17:18 +01:00
ge0rdi
cef27bdfa0 Use more convenient format for color settings
We are storing color settings in BBGGRR format (for historical reasons).
This may be confusing for people that are used to (more widely used) RRGGBB format.

Thus we will present color settings in RRGGBB format when editing.

We will still use BBGGRR format for those settings internally. To
maintain backward compatibility with existing settings stored in
registry/xml.

Also setting descriptions now contain hint about expected color format.
This way it should be more clear what values `Open-Shell` expects.

Fixes #82, #1141.
2022-12-06 19:17:18 +01:00
ge0rdi
f7334882c3 Fix image rendering on Win7
Fixes #1023 #90.
2022-12-06 19:17:18 +01:00
ge0rdi
9397d58986 Show Open-Shell version in start context menu
Fixes #888.
2022-12-06 19:17:18 +01:00
ge0rdi
7f6b7229f6 Get proper branding string on Windows 11
Based on info from https://dennisbabkin.com/blog/?t=how-to-tell-the-real-version-of-windows-your-app-is-running-on#ver_string .

Fixes #878, #960, #1063.
2022-12-06 19:17:18 +01:00
ge0rdi
a0a03760cd Build: Fix source indexing
x64 version of pdbstr doesn't work (because of missing __CxxFrameHandler4 on Windows Server 2019).
Fortunately it seems that x86 version works well, so we can use that one.
2022-12-06 19:17:18 +01:00
among-us-official
9606e11e0e Restore Main_no_icons2 behavior for inline subitems (#1172) 2022-10-15 10:53:16 +02:00
ge0rdi
7f04293361 Update README.md
Download link should point to latest official release.
2022-10-14 20:02:19 +02:00
ge0rdi
e6b33a70e4 Add -reloadsettings command line switch
It will force Open-Shell to reload settings from registry.

Fixes #1157.
2022-10-08 07:48:50 +02:00
ge0rdi
179a59ac1b Revert "Auto-detect when setting is back to default value"
This reverts commit 998d83c15c.

This change was wrong and it shouldn't get merged in first place.
See https://github.com/Open-Shell/Open-Shell-Menu/pull/829#issuecomment-907667829 for further explanation.

Fixes #1135.
2022-09-12 16:17:06 +02:00
ge0rdi
2a5ed14599 Fix 'Highlight modified settings' option tooltip 2022-09-12 16:17:06 +02:00
ge0rdi
1cc5d2eb53 Fix broken menu sorting
It was broken in bb26cec commit.

Fixes #1111
2022-09-09 17:07:29 +02:00
coddec
687e50914f Update appveyor.yml
Change secure,hashed auth token as suggested by @ge0rdi
2022-09-08 13:31:28 +10:00
floppyD
a165ba38a6 Update StartMenuL10N.ini (#1125)
That's how it's called on Windows. "Configurações do computador" also makes the start menu way larger than it should be.
2022-09-01 19:27:25 -04:00
ge0rdi
6b7cfc5ab2 Update: Remove unused code for checking nightly build on AppVeyor
We have nightly builds on Github already.
2022-08-21 22:51:18 +02:00
ge0rdi
1f2c3d43a6 Update: Get nightly (prerelease) builds from Github
We are now deploying official builds from master to Github releases page
(as Prerelease).
So we should get these build from there.

This is also related to AppVeyor's rather tight download limits that
make it quite challenge to obtain nightly builds.
2022-08-21 22:51:18 +02:00
ge0rdi
5bee5ae143 Update JSON library to latest version (3.11.2) 2022-08-21 22:51:18 +02:00
ge0rdi
f01c126b36 AppVeyor: Deploy only if build was done under official account 2022-08-21 22:47:52 +02:00
ge0rdi
3d1fa11973 Update README.md
- Updated "release" badge to point to latest release version directly
- Removed "Latest nightly build" link as nightly builds are now part of standard Releases page
2022-08-21 22:20:32 +02:00
ge0rdi
93245dc4d6 AppVeyor: deploy build to GitHub releases page 2022-08-21 14:01:21 +02:00
ge0rdi
86447299b1 AppVeyor: build only from master
We want to do official builds from master only.
PR builds should be not affected by this.
2022-08-21 14:00:12 +02:00
thisismy-github
64259f73e8 Various single-click option fixes
Fixed single-click option ignoring split arrows
Fixed Apps folder being clickable
2022-08-13 16:00:26 -04:00
thisismy-github
8031739110 Added option to customize Pinned folder location
Items can be pinned to directories that require administative privileges
(such as Open-Shell's default installation directory), so long as users
take ownership of the pinned folder. Also adds a command to Open-Shell's
context menu that opens the current pinned folder.

Adds general support for directory-based settings by creating a new
setting type called TYPE_DIRECTORY which uses a new bool added to
BrowseLinkHelper, called bFoldersOnly. START_MENU_PINNED_ROOT
has been removed, and all instances of both it and BrowseLinkHelper
have been adjusted accordingly. To create your own directory-based
settings, use CSetting::TYPE_DIRECTORY. Empty directory paths are
reset to their default value as they can cause unexpected behavior.
2022-08-13 16:00:26 -04:00
thisismy-github
27e5c2bc74 Added option to open folders to their true path
Adds a new function called GetFakeFolder which attempts to find and get
the target.lnk file from a fake folder (what Open-Shell uses to pin
folders). If detected, InvokeCommand is swapped for a ShellExecute call
to the target shortcut. Fixes #555, #653, and by extension, #691.
2022-08-13 16:00:26 -04:00
thisismy-github
bb26cec0ec Added option to single-expand any Win7 style item
Expands the "display as a list of drives" option from This PC to work on
almost any item in the Windows 7 style. Incompatible items have a new
setting called ITEM_NODRIVES which blocks the option from appearing.
This PC still uses the original "list of drives" text, while other items
use "list of links" instead. Sorting has been updated to account for
this option by adding a property called bFolderLink which marks any
folder, even if it is not explicitly expandable.
2022-08-13 16:00:26 -04:00
thisismy-github
ef663d2051 Added option to set custom commands for controls
Includes a unique option for each control and supports environment
variables.
2022-08-13 16:00:26 -04:00
thisismy-github
be8568ce00 Added option to hide "see more results" in search
Hides the item in both start menu styles and adjusts search height to
ensure the empty space is used. Partially fixes #660, but currently
does not honor group policy settings.
2022-08-13 16:00:26 -04:00
thisismy-github
5399e3ad8c Added option to use a custom search hint
If set, intercepts the search hint's DrawText function and swaps out the
default text for user-defined text. Leaving the text blank results in an
empty search box.
2022-08-13 16:00:26 -04:00
thisismy-github
68379f4098 Fixed bug between XML files and active edit boxes
When loading XML files, settings with active edit boxes open will not be
adjusted. This adds an additional tab-reload before the load begins to
forcibly close any active edit boxes.
2022-08-13 16:00:26 -04:00
thisismy-github
daa1d96f12 Added option to never highlight modified settings
Prevents settings from appearing in bold. Does not change the helper
text at the bottom of the window.
2022-08-13 16:00:26 -04:00
thisismy-github
998d83c15c Auto-detect when setting is back to default value
Intercepts *most* instances of FLAG_DEFAULT getting set, including
when XML files are loaded and when Open-Shell starts, adding
if-statements to those spots to check if a new value is actually
different from the setting's default value. Ensures more consistency
behind the scenes and gets rid of inaccurate bold highlights.
2022-08-13 16:00:26 -04:00
thisismy-github
0cb43dd17c Added option to always single-click folders
Opens pinned items on both sides of the start menu in just one click,
while preserving hover functionality. Ignores the All Programs button
for now as the All Programs folder is rarely accessed and this option
can obstruct its use, especially for the inline menu style. Fixes #692.
2022-08-13 16:00:26 -04:00
among-us-official
b89aaed785 Fix corrupted icons in second column (#1088)
When using skin with a different second column icon size, all of the
icons in it would become blank.

Because m_bTwoColumns is set after AddStandardItems, it is still false
in the column break check. As a workaround, use the value it's assigned
later in InitWindowInternal instead.

Fix Open-Shell/Open-Shell-Menu#980
2022-08-11 16:46:12 -04:00
Let's All Love Lain
47cc2b2304 Replacing 'scopeList' contiguous placement of elements in memory more efficient and std::make_unique c++17
Signed-off-by: germanaizek <GermanAizek@yandex.ru>
2022-05-12 20:54:42 +02:00
germanaizek
a20215d9da Replace 'push*' -> 'emplace*' if possible and use std::move() 2022-05-12 20:54:42 +02:00
germanaizek
4f362760b6 Remove unused vars, usage '= default;' and fixed lower scope 2022-05-12 20:54:42 +02:00
Ibuprophen
2e43d4c7a1 Update README.md 2022-05-10 11:05:42 -04:00
bonzibudd
4b2688245f Don't change Taskbar text color/texture until relaunch
This will accurately represent when these changes are able to take effect. Currently, the settings don't make any immediate changes or are broken when applied, and this should fix that.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Process messages for some time after displaying toast.
Otherwise toast may be not displayed at all.
2020-09-26 08:14:56 +02:00
ge0rdi
e2ff745949 Skin: Add support for Immersive* color names 2020-09-25 20:10:39 +02:00
ge0rdi
fbcf85559e Update: Add option to check for nightly updates
Use Appveyor REST API to obtain information about latest build from master.
2020-09-24 18:52:24 +02:00
ge0rdi
ed3da927cc Update: Use desktop toast notifications on Windows 10
Use toast notification to announce new update on modern Windows
versions.

The advantage of toasts is that they look more natural and they are
persistent. So one can find the information about new update in action
center even after notification timed out.
2020-09-24 18:52:24 +02:00
ge0rdi
225d0ba8f9 Update: Add library for Desktop Toast notifications
Based on sample code in:
https://github.com/WindowsNotifications/desktop-toasts

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

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

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

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

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

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

Fixes #458 .
2020-09-22 07:08:37 +02:00
Xenhat
1bfbe09c6f Add discord server badge :) (#462)
Squashing because appveyor is stuck, also useless for a readme change
2020-09-21 17:51:15 -04:00
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
126 changed files with 28991 additions and 1147 deletions

4
.gitignore vendored
View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

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

View File

@@ -1,17 +1,13 @@
## Open-Shell ![Open-Shell](/Src/Setup/OpenShell.ico)
## Open-Shell <img src=/Src/Setup/OpenShell.ico width="64" />
*Originally* **[Classic Shell](http://www.classicshell.net)** *by [Ivo Beltchev](https://sourceforge.net/u/ibeltchev/profile/)*
[![GitHub Release](https://img.shields.io/github/release/Open-Shell/Open-Shell-Menu.svg)](https://github.com/Open-Shell/Open-Shell-Menu/releases) [![GitHub Pre-Release](https://img.shields.io/github/release/Open-Shell/Open-Shell-Menu/all.svg)](https://github.com/Open-Shell/Open-Shell-Menu/releases) [![Build status](https://ci.appveyor.com/api/projects/status/2wj5x5qoypfjj0tr/branch/master?svg=true)](https://ci.appveyor.com/project/passionate-coder/open-shell-menu/branch/master) [![GitQ](https://gitq.com/badge.svg)](https://gitq.com/passionate-coder/Classic-Start) [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/open-shell/Lobby)
[![GitHub Release](https://img.shields.io/github/release/Open-Shell/Open-Shell-Menu.svg)](https://github.com/Open-Shell/Open-Shell-Menu/releases/latest) [![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://img.shields.io/gitter/room/badges/shields.svg?color=lightseagreen)](https://gitter.im/open-shell/Lobby) [![Discord](https://img.shields.io/discord/757701054782636082?color=mediumslateblue&label=Discord&logo=discord&logoColor=white)](https://discord.gg/7H6arr5)
[Home Page](https://open-shell.github.io/Open-Shell-Menu)
[Discussion room](https://gitter.im/Open-Shell)
[Latest nightly build](https://ci.appveyor.com/project/passionate-coder/open-shell-menu/branch/master/artifacts)
[Homepage](https://open-shell.github.io/Open-Shell-Menu)
[Gitter Discussion rooms](https://gitter.im/Open-Shell)
### Features
- Classic style Start Menu for Windows 7, 8, 8.1, 10
- Toolbar for Windows Explorer
- Classic copy UI (Windows 7 only)
@@ -19,16 +15,19 @@
- Title bar and status bar for Internet Explorer
### Download
If you just want to use it or looking for setup file, click here to download!!!
You can find the latest stable version here:
[![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/latest)
---
### Temporary Translation/Language Solution
1. Download [language DLL](https://coddec.github.io/Classic-Shell/www.classicshell.net/translations/index.html)
2. Place it either in the Open-Shell's __install folder__ or in the `%ALLUSERSPROFILE%\OpenShell\Languages` folder
----
*For archival reasons, we have a mirror of `www.classicshell.net` [here](https://coddec.github.io/Classic-Shell/www.classicshell.net/).*
[How To Skin a Start Menu](https://coddec.github.io/Classic-Shell/www.classicshell.net/tutorials/skintutorial.html)
[Classic Shell - Custom Start Buttons](https://coddec.github.io/Classic-Shell/www.classicshell.net/tutorials/buttontutorial.html)
[Report a bug/issue or submit a feature request](https://github.com/Open-Shell/Open-Shell-Menu/issues)
[How To Skin a Start Menu](https://coddec.github.io/Classic-Shell/www.classicshell.net/tutorials/skintutorial.html)
[Classic Shell: Custom Start Buttons](https://coddec.github.io/Classic-Shell/www.classicshell.net/tutorials/buttontutorial.html)
[Questions? Ask on the Discussions section](https://github.com/Open-Shell/Open-Shell-Menu/discussions) or on [Discord](https://discord.gg/7H6arr5)
[Submit a bug report/feature request](https://github.com/Open-Shell/Open-Shell-Menu/issues)

View File

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

View File

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

View File

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

View File

@@ -380,7 +380,7 @@ LRESULT CEditToolbarDlg::OnBrowseLink( WORD wNotifyCode, WORD wID, HWND hWndCtl,
{
wchar_t text[_MAX_PATH];
GetDlgItemText(IDC_COMBOLINK,text,_countof(text));
if (BrowseLinkHelper(m_hWnd,text))
if (BrowseLinkHelper(m_hWnd,text,false))
{
SetDlgItemText(IDC_COMBOLINK,text);
SendMessage(WM_COMMAND,MAKEWPARAM(IDC_COMBOLINK,CBN_KILLFOCUS));

View File

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

View File

@@ -135,17 +135,17 @@ BEGIN
IDS_LANGUAGE_SETTINGS "Language"
IDS_CAPTION_FONT "Caption font"
IDS_CAPTION_FONT_TIP "Select the font and text size to use for the caption"
IDS_TEXT_COLOR "Text color"
IDS_TEXT_COLOR "Text color (RRGGBB)"
IDS_TEXT_COLOR_TIP "Select the color for the caption text"
IDS_MAXTEXT_COLOR "Text color (maximized)"
IDS_MAXTEXT_COLOR "Text color (maximized) (RRGGBB)"
IDS_MAXTEXT_COLOR_TIP "Select the color for the caption text when the window is maximized"
IDS_INTEXT_COLOR "Text color (inactive)"
IDS_INTEXT_COLOR "Text color (inactive) (RRGGBB)"
IDS_INTEXT_COLOR_TIP "Select the color for the caption text when the window is inactive"
IDS_MAXINTEXT_COLOR "Text color (maximized, inactive)"
IDS_MAXINTEXT_COLOR "Text color (maximized, inactive) (RRGGBB)"
IDS_MAXINTEXT_COLOR_TIP "Select the color for the caption text when the window is maximized and inactive"
IDS_GLOW "Text glow"
IDS_GLOW_TIP "When this is checked, the text will have a glow around it"
IDS_GLOW_COLOR "Glow color"
IDS_GLOW_COLOR "Glow color (RRGGBB)"
IDS_GLOW_COLOR_TIP "Select the color for the caption glow"
END
@@ -153,7 +153,7 @@ STRINGTABLE
BEGIN
IDS_MAXGLOW "Text glow (maximized)"
IDS_MAXGLOW_TIP "When this is checked, the text in the maximized window will have a glow around it"
IDS_MAXGLOW_COLOR "Glow color (maximized)"
IDS_MAXGLOW_COLOR "Glow color (maximized) (RRGGBB)"
IDS_MAXGLOW_COLOR_TIP "Select the color for the caption glow when the window is maximized"
IDS_STATUS_SETTINGS "Status Bar"
IDS_SHOW_PROGRESS "Show progress"

View File

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

View File

@@ -14,6 +14,7 @@ public:
CAbsolutePidl( const CAbsolutePidl &pidl ) { m_Pidl=pidl?ILCloneFull(pidl):NULL; }
~CAbsolutePidl( void ) { Clear(); }
void operator=( const CAbsolutePidl &pidl ) { Clone(pidl); }
void operator=( PCIDLIST_ABSOLUTE pidl ) { Clone(pidl); }
void Clear( void ) { if (m_Pidl) ILFree(m_Pidl); m_Pidl=NULL; }
operator PIDLIST_ABSOLUTE( void ) const { return m_Pidl; }
@@ -21,7 +22,7 @@ public:
void Swap( CAbsolutePidl &pidl ) { PIDLIST_ABSOLUTE q=pidl.m_Pidl; pidl.m_Pidl=m_Pidl; m_Pidl=q; }
void Attach( PIDLIST_ABSOLUTE pidl ) { Clear(); m_Pidl=pidl; }
PIDLIST_ABSOLUTE Detach( void ) { PIDLIST_ABSOLUTE pidl=m_Pidl; m_Pidl=NULL; return pidl; }
void Clone( PIDLIST_ABSOLUTE pidl ) { Clear(); m_Pidl=pidl?ILCloneFull(pidl):NULL; }
void Clone( PCIDLIST_ABSOLUTE pidl ) { Clear(); m_Pidl=pidl?ILCloneFull(pidl):NULL; }
private:
PIDLIST_ABSOLUTE m_Pidl;

View File

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

View File

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

View File

@@ -60,3 +60,17 @@ bool IsFakeFolder( const wchar_t *fname )
}
return false;
}
bool GetFakeFolder( wchar_t *dst, int len, const wchar_t *src )
{
Sprintf(dst,len,L"%s\\target.lnk",src);
if (GetFileAttributes(dst)!=INVALID_FILE_ATTRIBUTES)
{
wchar_t path[_MAX_PATH];
Sprintf(path,_countof(path),L"%s\\desktop.ini",src);
DWORD attrib=GetFileAttributes(path);
if (attrib!=INVALID_FILE_ATTRIBUTES && (attrib&FILE_ATTRIBUTE_SYSTEM))
return true;
}
return false;
}

View File

@@ -7,3 +7,4 @@
bool CreateFakeFolder( const wchar_t *source, const wchar_t *fname );
void DeleteFakeFolder( const wchar_t *fname );
bool IsFakeFolder( const wchar_t *fname );
bool GetFakeFolder( wchar_t *dst, int len, const wchar_t *src );

View File

@@ -127,7 +127,6 @@ VersionData CLanguageSettingsDlg::s_VersionData;
void CLanguageSettingsDlg::AddFlag( const wchar_t *langName, int langId, HBITMAP bmp )
{
std::vector<LangInfo>::iterator it=m_LanguageIDs.begin()+1;
int idx=1;
for (;idx<(int)m_LanguageIDs.size();idx++)
{
@@ -205,8 +204,6 @@ void CLanguageSettingsDlg::UpdateFlags( void )
DoEnvironmentSubst(path,_countof(path));
}
CWindow list=GetDlgItem(IDC_LISTLANGUAGE);
wchar_t find[_MAX_PATH];
Sprintf(find,_countof(find),L"%s\\*.dll",path);
WIN32_FIND_DATA data;
@@ -408,7 +405,7 @@ LRESULT CLanguageSettingsDlg::OnSelChange( int idCtrl, LPNMHDR pnmh, BOOL& bHand
CComVariant val(name);
if (m_pSetting->value!=val)
SetSettingsDirty();
m_pSetting->value=val;
m_pSetting->value=std::move(val);
if (_wcsicmp(m_pSetting->value.bstrVal,m_pSetting->defValue.bstrVal)==0)
m_pSetting->flags|=CSetting::FLAG_DEFAULT;

View File

@@ -71,7 +71,7 @@ BEGIN
CONTROL "Show all settings",IDC_CHECKALL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,154,7,79,12
CONTROL "<a>Help...</a>",IDC_LINKHELP,"SysLink",WS_TABSTOP,348,9,26,10,WS_EX_TRANSPARENT
CONTROL "",IDC_TABSETTINGS,"SysTabControl32",TCS_MULTILINE | TCS_FOCUSNEVER,7,20,367,169
CONTROL "<a>www.classicshell.net</a>",IDC_LINKWEB,"SysLink",WS_TABSTOP,7,195,66,10,WS_EX_TRANSPARENT
CONTROL "<a>Open-Shell Homepage</a>",IDC_LINKWEB,"SysLink",WS_TABSTOP,7,195,75,10,WS_EX_TRANSPARENT
CONTROL "Name of translator goes <a href=""http://www.yoursite.com"">here</a>",IDC_SYSLINKLOC,
"SysLink",NOT WS_VISIBLE | WS_TABSTOP,80,195,111,10
PUSHBUTTON "&Backup",IDC_BUTTONBACKUP,200,192,60,14,WS_GROUP
@@ -277,7 +277,7 @@ BEGIN
IDS_BMP_TITLE "Select Image File"
IDS_SEARCH_PROMPT "Search Settings"
IDS_SETTING_SEARCH "Search Results"
IDS_WEBSITE_TIP "Visit Open-Shell on the web - http://www.classicshell.net"
IDS_WEBSITE_TIP "Visit Open-Shell on the web - https://open-shell.github.io/Open-Shell-Menu"
IDS_LOCATE_SETTING "Locate setting"
IDS_LANGUAGE_UPDATED "The language %s is up to date."
IDS_LANGUAGE_MISSING "Update for language %s is not available."

View File

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

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
void PremultiplyBitmap( HBITMAP hBitmap, COLORREF rgb )
{
if (hBitmap == NULL) return;
BITMAP info;
GetObject(hBitmap,sizeof(info),&info);
int n=info.bmWidth*info.bmHeight;
@@ -395,8 +396,11 @@ HBITMAP LoadImageFile( const wchar_t *path, const SIZE *pSize, bool bUseAlpha, b
CComPtr<IWICImagingFactory> pFactory;
if (FAILED(pFactory.CoCreateInstance(CLSID_WICImagingFactory)))
{
if (srcBmp) DeleteObject(srcBmp);
return NULL;
if (FAILED(pFactory.CoCreateInstance(CLSID_WICImagingFactory1)))
{
if (srcBmp) DeleteObject(srcBmp);
return NULL;
}
}
CComPtr<IWICBitmapSource> pBitmap;
@@ -533,7 +537,10 @@ HBITMAP LoadImageResource( HMODULE hModule, const wchar_t *name, bool bTopDown,
{
CComPtr<IWICImagingFactory> pFactory;
if (FAILED(pFactory.CoCreateInstance(CLSID_WICImagingFactory)))
return NULL;
{
if (FAILED(pFactory.CoCreateInstance(CLSID_WICImagingFactory1)))
return NULL;
}
CComPtr<IWICBitmapSource> pBitmap;
if (hModule)
@@ -726,6 +733,19 @@ bool IsWin10RS4( void )
return bIsRS4;
}
static bool IsWin11Helper()
{
auto version = GetOSVersion();
return version.dwMajorVersion >= 10 && version.dwBuildNumber >= 22000;
}
// Returns true if the version is Windows11 or later
bool IsWin11(void)
{
static bool bIsWin11 = IsWin11Helper();
return bIsWin11;
}
// Wrapper for IShellFolder::ParseDisplayName
HRESULT ShParseDisplayName( const wchar_t *pszName, PIDLIST_ABSOLUTE *ppidl, SFGAOF sfgaoIn, SFGAOF *psfgaoOut )
{
@@ -902,3 +922,31 @@ HFONT CreateFontSetting( const wchar_t *fontStr, int dpi )
int size=-_wtol(token);
return CreateFont(size*dpi/72,0,0,0,weight,bItalic?1:0,0,0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,name);
}
static UINT WINAPI GetDpiForWindow(HWND hwnd)
{
static auto p = static_cast<decltype(&GetDpiForWindow)>((void*)GetProcAddress(GetModuleHandle(L"user32.dll"), "GetDpiForWindow"));
if (p)
return p(hwnd);
return 0;
}
UINT GetDpi(HWND hwnd)
{
UINT dpi = GetDpiForWindow(hwnd);
if (!dpi)
{
// fall-back for older systems
HDC hdc = GetDC(nullptr);
dpi = GetDeviceCaps(hdc, LOGPIXELSY);
ReleaseDC(nullptr, hdc);
}
return dpi;
}
int ScaleForDpi(HWND hwnd, int value)
{
return MulDiv(value, GetDpi(hwnd), USER_DEFAULT_SCREEN_DPI);
}

View File

@@ -67,6 +67,9 @@ bool IsWin10RS1( void );
// Returns true if the version is Windows10 RS4 (Spring Creator Update) or later
bool IsWin10RS4( void );
// Returns true if the version is Windows11 or later
bool IsWin11();
// Wrapper for IShellFolder::ParseDisplayName
HRESULT ShParseDisplayName( const wchar_t *pszName, PIDLIST_ABSOLUTE *ppidl, SFGAOF sfgaoIn, SFGAOF *psfgaoOut );
@@ -82,6 +85,12 @@ void StringUpper( CString &str );
// Create a font from the user settings
HFONT CreateFontSetting( const wchar_t *fontStr, int dpi );
// Return DPI of given window (or system DPI on older systems)
UINT GetDpi(HWND hwnd = nullptr);
// Scale given value according to DPI of window
int ScaleForDpi(HWND hwnd, int value);
extern HINSTANCE g_Instance;
const int ANIM_BUTTON_TAG1='ANM';

View File

@@ -125,7 +125,7 @@ bool CSetting::IsEnabled( void ) const
if (operation=='>' && pSetting->GetValue().intVal<=val)
return false;
}
if ((pSetting->type==CSetting::TYPE_STRING || pSetting->type==CSetting::TYPE_BITMAP || pSetting->type==CSetting::TYPE_BITMAP_JPG) && pSetting->GetValue().vt==VT_BSTR)
if ((pSetting->type==CSetting::TYPE_STRING || pSetting->type==CSetting::TYPE_BITMAP || pSetting->type==CSetting::TYPE_BITMAP_JPG || pSetting->type==CSetting::TYPE_DIRECTORY) && pSetting->GetValue().vt==VT_BSTR)
{
if (operation=='~' && *pSetting->GetValue().bstrVal==0)
return false;
@@ -202,7 +202,7 @@ bool CSetting::ReadValue( CRegKey &regKey, const wchar_t *valName )
}
// string
if (type>=CSetting::TYPE_STRING && type<CSetting::TYPE_MULTISTRING)
if (type>=CSetting::TYPE_STRING && type!=CSetting::TYPE_MULTISTRING)
{
ULONG len;
if (regKey.QueryStringValue(valName,NULL,&len)==ERROR_SUCCESS)
@@ -789,7 +789,7 @@ CString CSettingsManager::LoadSettingsXml( const wchar_t *fname )
}
CComPtr<IXMLDOMNode> next;
child2->get_nextSibling(&next);
child2=next;
child2=std::move(next);
}
string.push_back(0);
pSetting->value=CComVariant(&string[0]);
@@ -839,7 +839,7 @@ CString CSettingsManager::LoadSettingsXml( const wchar_t *fname )
CComPtr<IXMLDOMNode> next;
if (child->get_nextSibling(&next)!=S_OK)
break;
child=next;
child=std::move(next);
}
if (ver<0x03090000)
UpgradeSettings(false);
@@ -1701,6 +1701,7 @@ LRESULT CSettingsDlg::OnBackup( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL&
ofn.Flags=OFN_DONTADDTORECENT|OFN_ENABLESIZING|OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_NOCHANGEDIR;
if (GetOpenFileName(&ofn))
{
SetCurTab(m_Index,true); // reload tab once to force-close any active edit boxes
CString error=g_SettingsManager.LoadSettingsXml(path);
if (!error.IsEmpty())
{
@@ -1710,7 +1711,7 @@ LRESULT CSettingsDlg::OnBackup( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL&
::MessageBox(m_hWnd,text,LoadStringEx(IDS_ERROR_TITLE),MB_OK|MB_ICONERROR);
}
SetSettingsDirty();
SetCurTab(m_Index,true);
SetCurTab(m_Index,true); // reload tab again to show the new settings
}
}
if (res==3)
@@ -1810,7 +1811,7 @@ LRESULT CSettingsDlg::OnHelp( int idCtrl, LPNMHDR pnmh, BOOL& bHandled )
LRESULT CSettingsDlg::OnWeb( int idCtrl, LPNMHDR pnmh, BOOL& bHandled )
{
ShellExecute(m_hWnd,NULL,L"http://www.classicshell.net",NULL,NULL,SW_SHOWNORMAL);
ShellExecute(m_hWnd,NULL,L"https://open-shell.github.io/Open-Shell-Menu",NULL,NULL,SW_SHOWNORMAL);
return 0;
}
@@ -2208,7 +2209,7 @@ bool GetSettingBool( const CSetting &setting )
CString GetSettingString( const CSetting &setting )
{
Assert(setting.type==CSetting::TYPE_STRING);
Assert(setting.type==CSetting::TYPE_STRING || setting.type==CSetting::TYPE_DIRECTORY);
if (setting.value.vt!=VT_BSTR)
return CString();
return setting.value.bstrVal;
@@ -2709,7 +2710,7 @@ bool SaveAdmx( TSettingsComponent component, const char *admxFile, const char *a
{
fprintf_s(fAdmx,"\t\t\t\t<decimal id=\"Value\" valueName=\"%S\"/>\r\n",pSetting->name);
}
else if (pSetting->type==CSetting::TYPE_STRING || pSetting->type==CSetting::TYPE_ICON || pSetting->type==CSetting::TYPE_BITMAP || pSetting->type==CSetting::TYPE_BITMAP_JPG || pSetting->type==CSetting::TYPE_SOUND || pSetting->type==CSetting::TYPE_FONT)
else if (pSetting->type==CSetting::TYPE_STRING || pSetting->type==CSetting::TYPE_ICON || pSetting->type==CSetting::TYPE_BITMAP || pSetting->type==CSetting::TYPE_BITMAP_JPG || pSetting->type==CSetting::TYPE_SOUND || pSetting->type==CSetting::TYPE_FONT || pSetting->type==CSetting::TYPE_DIRECTORY)
{
fprintf_s(fAdmx,"\t\t\t\t<text id=\"Value\" valueName=\"%S\"/>\r\n",pSetting->name);
}
@@ -2769,7 +2770,7 @@ bool SaveAdmx( TSettingsComponent component, const char *admxFile, const char *a
{
fprintf_s(fAdml,"\t\t\t\t<decimalTextBox refId=\"Value\" spin=\"false\">%s</decimalTextBox>\r\n",(const char*)name);
}
else if (pSetting->type==CSetting::TYPE_STRING || pSetting->type==CSetting::TYPE_ICON || pSetting->type==CSetting::TYPE_BITMAP || pSetting->type==CSetting::TYPE_BITMAP_JPG || pSetting->type==CSetting::TYPE_SOUND || pSetting->type==CSetting::TYPE_FONT)
else if (pSetting->type==CSetting::TYPE_STRING || pSetting->type==CSetting::TYPE_ICON || pSetting->type==CSetting::TYPE_BITMAP || pSetting->type==CSetting::TYPE_BITMAP_JPG || pSetting->type==CSetting::TYPE_SOUND || pSetting->type==CSetting::TYPE_FONT || pSetting->type==CSetting::TYPE_DIRECTORY)
{
fprintf_s(fAdml,"\t\t\t\t<textBox refId=\"Value\"><label>%s</label></textBox>\r\n",(const char*)name);
}

View File

@@ -32,6 +32,7 @@ struct CSetting
TYPE_SOUND,
TYPE_FONT,
TYPE_MULTISTRING,
TYPE_DIRECTORY,
};
enum

View File

@@ -1156,7 +1156,7 @@ HRESULT STDMETHODCALLTYPE CBrowseLinkEvents::OnButtonClicked( IFileDialogCustomi
{
pfd->GetFolder(&pItem);
}
m_pResult=pItem;
m_pResult=std::move(pItem);
pfd->Close(S_FALSE);
return S_OK;
}
@@ -1216,7 +1216,7 @@ bool BrowseCommandHelper( HWND parent, wchar_t *text )
return false;
}
bool BrowseLinkHelper( HWND parent, wchar_t *text )
bool BrowseLinkHelper( HWND parent, wchar_t *text, bool bFoldersOnly )
{
DoEnvironmentSubst(text,_MAX_PATH);
@@ -1227,16 +1227,22 @@ bool BrowseLinkHelper( HWND parent, wchar_t *text )
if (!pCustomize)
return false;
pDialog->SetTitle(LoadStringEx(IDS_PICK_LINK_TITLE));
pDialog->SetOkButtonLabel(LoadStringEx(IDS_PICK_LINK_FILE));
wchar_t button[256];
Sprintf(button,_countof(button),L" %s ",LoadStringEx(IDS_PICK_LINK_FOLDER));
pCustomize->AddPushButton(101,button);
pDialog->SetTitle(LoadStringEx(bFoldersOnly?IDS_PICK_LINK_FOLDER:IDS_PICK_LINK_TITLE));
if (!bFoldersOnly) // add separate buttons for selecting files/folders to the dialog
{
pDialog->SetOkButtonLabel(LoadStringEx(IDS_PICK_LINK_FILE));
wchar_t button[256];
Sprintf(button,_countof(button),L" %s ",LoadStringEx(IDS_PICK_LINK_FOLDER));
pCustomize->AddPushButton(101,button);
}
CBrowseLinkEvents events;
DWORD cookie;
pDialog->Advise(&events,&cookie);
pDialog->SetOptions(FOS_ALLNONSTORAGEITEMS|FOS_FILEMUSTEXIST|FOS_DONTADDTORECENT|FOS_DEFAULTNOMINIMODE|FOS_NODEREFERENCELINKS);
if (bFoldersOnly) // set FOS_PICKFOLDERS option to use dialog in folder-only mode
pDialog->SetOptions(FOS_PICKFOLDERS|FOS_ALLNONSTORAGEITEMS|FOS_DONTADDTORECENT|FOS_DEFAULTNOMINIMODE);
else
pDialog->SetOptions(FOS_ALLNONSTORAGEITEMS|FOS_FILEMUSTEXIST|FOS_DONTADDTORECENT|FOS_DEFAULTNOMINIMODE|FOS_NODEREFERENCELINKS);
{
const wchar_t *c=wcschr(text,'|');
if (c)
@@ -2271,6 +2277,7 @@ public:
EDIT_HOTKEY_ANY,
EDIT_COLOR,
EDIT_FONT,
EDIT_DIRECTORY,
};
BEGIN_MSG_MAP( CTreeSettingsDlg )
@@ -2644,15 +2651,14 @@ LRESULT CTreeSettingsDlg::OnBrowse( WORD wNotifyCode, WORD wID, HWND hWndCtl, BO
CString str;
m_EditBox.GetWindowText(str);
str.TrimLeft(); str.TrimRight();
wchar_t *end;
COLORREF val=wcstol(str,&end,16)&0xFFFFFF;
COLORREF val=RgbToBgr(ParseColor(str));
static COLORREF customColors[16];
CHOOSECOLOR choose={sizeof(choose),m_hWnd,NULL,val,customColors};
choose.Flags=CC_ANYCOLOR|CC_FULLOPEN|CC_RGBINIT;
if (ChooseColor(&choose))
{
wchar_t text[100];
Sprintf(text,_countof(text),L"%06X",choose.rgbResult);
Sprintf(text,_countof(text),L"%06X",BgrToRgb(choose.rgbResult));
m_EditBox.SetWindowText(text);
ApplyEditBox();
UpdateGroup(m_pEditSetting);
@@ -2714,6 +2720,29 @@ LRESULT CTreeSettingsDlg::OnBrowse( WORD wNotifyCode, WORD wID, HWND hWndCtl, BO
m_EditBox.SetFocus();
m_bIgnoreFocus=false;
}
else if (m_EditMode==EDIT_DIRECTORY)
{
m_bIgnoreFocus=true;
CString str;
m_EditBox.GetWindowText(str);
str.TrimLeft(); str.TrimRight();
wchar_t text[1024];
DWORD dwAttrs=GetFileAttributes(str); // ensure directory exists before passing it to dialog
if (dwAttrs!=INVALID_FILE_ATTRIBUTES && dwAttrs&FILE_ATTRIBUTE_DIRECTORY)
{
Strcpy(text,_countof(text),str);
DoEnvironmentSubst(text,_countof(text));
}
else
text[0]=0;
Strcpy(text,_countof(text),str);
DoEnvironmentSubst(text,_countof(text));
if (BrowseLinkHelper(m_hWnd,text,true))
m_EditBox.SetWindowText(text);
SendMessage(WM_NEXTDLGCTL,(LPARAM)m_EditBox.m_hWnd,TRUE);
m_EditBox.SetFocus();
m_bIgnoreFocus=false;
}
return 0;
}
@@ -3018,8 +3047,7 @@ void CTreeSettingsDlg::ApplyEditBox( void )
}
else if (pSetting->type==CSetting::TYPE_COLOR)
{
wchar_t *end;
int val=wcstol(str,&end,16)&0xFFFFFF;
int val=RgbToBgr(ParseColor(str));
if (pSetting->value.vt!=VT_I4 || pSetting->value.intVal!=val)
{
pSetting->value=CComVariant(val);
@@ -3034,6 +3062,20 @@ void CTreeSettingsDlg::ApplyEditBox( void )
pSetting->flags&=~CSetting::FLAG_DEFAULT;
}
}
else if (pSetting->type==CSetting::TYPE_DIRECTORY)
{
if (pSetting->value.vt!=VT_BSTR || str!=pSetting->value.bstrVal)
{
if (str.IsEmpty()) // empty directory strings cause unexpected behavior, so we reset to avoid this
pSetting->value=pSetting->defValue;
else // otherwise we are very lenient about what users can input as a path
pSetting->value=CComVariant(str);
if (pSetting->value==pSetting->defValue)
pSetting->flags|=CSetting::FLAG_DEFAULT;
else
pSetting->flags&=~CSetting::FLAG_DEFAULT;
}
}
else
{
if (pSetting->value.vt!=VT_BSTR || str!=pSetting->value.bstrVal)
@@ -3074,7 +3116,7 @@ void CTreeSettingsDlg::ItemSelected( HTREEITEM hItem, CSetting *pSetting, bool b
val=valVar.intVal;
Sprintf(text,_countof(text),L"%d",val);
}
else if (pSetting->type==CSetting::TYPE_STRING || pSetting->type==CSetting::TYPE_ICON || pSetting->type==CSetting::TYPE_BITMAP || pSetting->type==CSetting::TYPE_BITMAP_JPG || pSetting->type==CSetting::TYPE_SOUND || pSetting->type==CSetting::TYPE_FONT)
else if (pSetting->type==CSetting::TYPE_STRING || pSetting->type==CSetting::TYPE_ICON || pSetting->type==CSetting::TYPE_BITMAP || pSetting->type==CSetting::TYPE_BITMAP_JPG || pSetting->type==CSetting::TYPE_SOUND || pSetting->type==CSetting::TYPE_FONT || pSetting->type==CSetting::TYPE_DIRECTORY)
{
if (valVar.vt==VT_BSTR)
Strcpy(text,_countof(text),valVar.bstrVal);
@@ -3090,8 +3132,10 @@ void CTreeSettingsDlg::ItemSelected( HTREEITEM hItem, CSetting *pSetting, bool b
mode=EDIT_BITMAP_JPG;
else if (pSetting->type==CSetting::TYPE_SOUND)
mode=EDIT_SOUND;
else
else if (pSetting->type==CSetting::TYPE_FONT)
mode=EDIT_FONT;
else
mode=EDIT_DIRECTORY;
}
else if (pSetting->type==CSetting::TYPE_HOTKEY || pSetting->type==CSetting::TYPE_HOTKEY_ANY)
{
@@ -3110,7 +3154,7 @@ void CTreeSettingsDlg::ItemSelected( HTREEITEM hItem, CSetting *pSetting, bool b
mode=EDIT_COLOR;
int val=0;
if (valVar.vt==VT_I4)
val=valVar.intVal;
val=BgrToRgb(valVar.intVal);
Sprintf(text,_countof(text),L"%06X",val);
}
}
@@ -3131,7 +3175,7 @@ void CTreeSettingsDlg::ItemSelected( HTREEITEM hItem, CSetting *pSetting, bool b
m_pEditSetting=pSetting;
}
if (mode==EDIT_ICON || mode==EDIT_BITMAP || mode==EDIT_BITMAP_JPG || mode==EDIT_SOUND || mode==EDIT_FONT || mode==EDIT_COLOR)
if (mode==EDIT_ICON || mode==EDIT_BITMAP || mode==EDIT_BITMAP_JPG || mode==EDIT_SOUND || mode==EDIT_FONT || mode==EDIT_COLOR || mode==EDIT_DIRECTORY)
{
RECT rc2=rc;
int width=(rc2.bottom-rc2.top)*3/2;
@@ -3189,14 +3233,15 @@ void CTreeSettingsDlg::UpdateEditPosition( void )
DeleteDC(hdc);
DWORD margins=(DWORD)m_EditBox.SendMessage(EM_GETMARGINS);
size.cx+=HIWORD(margins)+LOWORD(margins)+12;
if (m_EditMode==EDIT_ICON || m_EditMode==EDIT_BITMAP || m_EditMode==EDIT_BITMAP_JPG || m_EditMode==EDIT_FONT || m_EditMode==EDIT_COLOR)
// adjust size and position of edit boxes for settings that use browse/play buttons
if (m_EditMode==EDIT_ICON || m_EditMode==EDIT_BITMAP || m_EditMode==EDIT_BITMAP_JPG || m_EditMode==EDIT_FONT || m_EditMode==EDIT_COLOR || m_EditMode==EDIT_DIRECTORY)
size.cx+=width;
if (m_EditMode==EDIT_SOUND)
size.cx+=width*2;
if (size.cx<w)
rc.right=rc.left+size.cx;
if (m_EditMode==EDIT_ICON || m_EditMode==EDIT_BITMAP || m_EditMode==EDIT_BITMAP_JPG || m_EditMode==EDIT_SOUND || m_EditMode==EDIT_FONT || m_EditMode==EDIT_COLOR)
if (m_EditMode==EDIT_ICON || m_EditMode==EDIT_BITMAP || m_EditMode==EDIT_BITMAP_JPG || m_EditMode==EDIT_SOUND || m_EditMode==EDIT_FONT || m_EditMode==EDIT_COLOR || m_EditMode==EDIT_DIRECTORY)
{
RECT rc2=rc;
rc2.left=rc2.right-width;
@@ -3376,6 +3421,9 @@ void CTreeSettingsDlg::UpdateGroup( const CSetting *pModified )
bool bDefault=pSetting->IsDefault();
const CComVariant &valVar=pSetting->GetValue();
// check if modified items should be bold
bool bBoldSettings=GetSettingBool(L"BoldSettings");
// calculate text
if (pSetting!=m_pEditSetting)
{
@@ -3412,7 +3460,7 @@ void CTreeSettingsDlg::UpdateGroup( const CSetting *pModified )
CString str=LoadStringEx(pSetting->nameID);
int val=0;
if (valVar.vt==VT_I4)
val=valVar.intVal;
val=BgrToRgb(valVar.intVal);
Sprintf(text,_countof(text),L"%s: %06X",str,val);
item.mask|=TVIF_TEXT;
}
@@ -3458,7 +3506,7 @@ void CTreeSettingsDlg::UpdateGroup( const CSetting *pModified )
DeleteDC(hdc);
DeleteDC(hdcMask);
}
int state=bDefault?0:TVIS_BOLD;
int state=bDefault||!bBoldSettings?0:TVIS_BOLD; // check if item should be highlighted in bold
if (!bEnabled)
{
if (pSetting->type!=CSetting::TYPE_COLOR) image|=SETTING_STATE_DISABLED;
@@ -3566,3 +3614,19 @@ bool CDefaultSettingsPanel::Validate( HWND parent )
s_Dialog.Validate();
return true;
}
DWORD RgbToBgr(DWORD val)
{
return ((val & 0xFF) << 16) | (val & 0xFF00) | ((val >> 16) & 0xFF);
}
DWORD BgrToRgb(DWORD val)
{
return RgbToBgr(val);
}
DWORD ParseColor(const wchar_t* str)
{
wchar_t* end;
return wcstoul(str, &end, 16) & 0xFFFFFF;
}

View File

@@ -385,5 +385,13 @@ const wchar_t *GetSettingsRegPath( void );
extern const GUID FOLDERID_DesktopRoot;
bool BrowseCommandHelper( HWND parent, wchar_t *text );
bool BrowseLinkHelper( HWND parent, wchar_t *text );
bool BrowseLinkHelper( HWND parent, wchar_t *text, bool bFoldersOnly );
bool BrowseIconHelper( HWND parent, wchar_t *text );
// convert color in RRGGBB format to BBGGRR
DWORD RgbToBgr(DWORD val);
// convert color in BBGGRR format to RRGGBB
DWORD BgrToRgb(DWORD val);
// parse color from hexadecimal string
DWORD ParseColor(const wchar_t* str);

24596
Src/Lib/json.hpp Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

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

View File

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

View File

@@ -1,8 +1,6 @@
if exist Output rd /Q /S Output
md Output
md Output\x64
md Output\PDB32
md Output\PDB64
echo -- Compiling
@@ -40,6 +38,7 @@ copy /B ..\ClassicIE\Setup\ClassicIE_32.exe Output > nul
copy /B ..\StartMenu\Setup\StartMenu.exe Output > nul
copy /B ..\StartMenu\Setup\StartMenuDLL.dll Output > nul
copy /B ..\Update\Release\Update.exe Output > nul
copy /B ..\Update\DesktopToasts\Release\DesktopToasts.dll Output > nul
copy /B ..\StartMenu\StartMenuHelper\Setup\StartMenuHelper32.dll Output > nul
copy /B ..\Setup\SetupHelper\Release\SetupHelper.exe Output > nul
@@ -67,6 +66,8 @@ copy /B "..\StartMenu\Skins\Metallic.skin7" Output > nul
REM ********* Collect debug info
md Output\PDB32
md Output\PDB64
REM Explorer 32
copy /B ..\ClassicExplorer\Setup\ClassicExplorer32.pdb Output\PDB32 > nul
@@ -99,6 +100,8 @@ copy /B ..\StartMenu\StartMenuHelper\Setup\StartMenuHelper32.pdb Output\PDB32 >
copy /B Output\StartMenuHelper32.dll Output\PDB32 > nul
copy /B ..\Update\Release\Update.pdb Output\PDB32 > nul
copy /B Output\Update.exe Output\PDB32 > nul
copy /B ..\Update\DesktopToasts\Release\DesktopToasts.pdb Output\PDB32 > nul
copy /B Output\DesktopToasts.dll Output\PDB32 > nul
REM Menu 64
copy /B ..\StartMenu\Setup64\StartMenu.pdb Output\PDB64 > nul
@@ -111,7 +114,7 @@ copy /B Output\x64\StartMenuHelper64.dll Output\PDB64 > nul
REM ********* Source Index PDBs
set PDBSTR_PATH="C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\srcsrv\pdbstr.exe"
set PDBSTR_PATH="C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\srcsrv\pdbstr.exe"
if exist %PDBSTR_PATH% (
echo --- Adding source index to PDBs
@@ -119,13 +122,33 @@ if exist %PDBSTR_PATH% (
for %%f in (Output\PDB32\*.pdb) do (
%PDBSTR_PATH% -w -p:%%f -s:srcsrv -i:Output\pdbstr.txt
if not ERRORLEVEL 0 (
echo Error adding source index to PDB
exit /b 1
)
)
for %%f in (Output\PDB64\*.pdb) do (
%PDBSTR_PATH% -w -p:%%f -s:srcsrv -i:Output\pdbstr.txt
if not ERRORLEVEL 0 (
echo Error adding source index to PDB
exit /b 1
)
)
)
REM ********* Prepare symbols
set SYMSTORE_PATH="C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\symstore.exe"
%SYMSTORE_PATH% add /r /f Output\PDB32 /s Output\symbols /t OpenShell -:NOREFS > nul
%SYMSTORE_PATH% add /r /f Output\PDB64 /s Output\symbols /t OpenShell -:NOREFS > nul
rd /Q /S Output\symbols\000Admin > nul
del Output\symbols\pingme.txt > nul
rd /Q /S Output\PDB32
rd /Q /S Output\PDB64
REM ********* Build ADMX
echo --- ADMX
if exist Output\PolicyDefinitions.zip (

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 401 KiB

View File

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

View File

@@ -105,7 +105,9 @@
</Feature>
<Feature Id="Update" Level="1" Title="!(loc.UpdateTitle)" ConfigurableDirectory="APPLICATIONFOLDER" AllowAdvertise="no" Description="!(loc.UpdateDesc)">
<ComponentRef Id="Update.exe" />
<ComponentRef Id="DesktopToasts.dll" />
<ComponentRef Id="UpdateSettingsLink" />
<ComponentRef Id="ToastActivator" />
</Feature>
</Feature>
<UI>
@@ -388,8 +390,8 @@
<Control Type="Icon" Id="Icon1" Width="12" Height="12" X="7" Y="203" Hidden="yes" Text="web.ico">
<Condition Action="show">NOT Installed</Condition>
</Control>
<Control Type="Hyperlink" Id="Link1" Width="131" Height="10" X="22" Y="204" Hidden="yes" ToolTip="https://github.com/Open-Shell/Open-Shell-Menu">
<Text><![CDATA[<a href="https://github.com/Open-Shell/Open-Shell-Menu">!(loc.WebLink)</a>]]></Text>
<Control Type="Hyperlink" Id="Link1" Width="131" Height="10" X="22" Y="204" Hidden="yes" ToolTip="https://open-shell.github.io/Open-Shell-Menu">
<Text><![CDATA[<a href="https://open-shell.github.io/Open-Shell-Menu">!(loc.WebLink)</a>]]></Text>
<Condition Action="show">NOT Installed</Condition>
</Control>
</Dialog>
@@ -476,6 +478,9 @@
<Component Id="Update.exe" Guid="FB6C213F-B670-4888-8B2C-12E807E335A7" Win64="$(var.CS_WIN64)">
<File Id="Update" KeyPath="yes" Source="Output\Update.exe" Checksum="yes" Vital="yes" />
</Component>
<Component Id="DesktopToasts.dll" Guid="B42157AF-3984-4796-8BD6-501FC5450FF1" Win64="$(var.CS_WIN64)">
<File Id="DesktopToasts.dll" KeyPath="yes" Source="Output\DesktopToasts.dll" Checksum="yes" Vital="yes" />
</Component>
<Component Id="PolicyDefinitions.zip" Guid="580A15D0-4023-471d-9D82-9D63FBA42B5D" Win64="$(var.CS_WIN64)">
<File Id="PolicyDefinitions.zip" KeyPath="yes" Source="Output\PolicyDefinitions.zip" Vital="yes" />
</Component>
@@ -551,6 +556,11 @@
<Component Id="TreatAs" Guid="B1E7462A-E1E2-47eb-A42C-7BD272D738AA" Win64="$(var.CS_WIN64)">
<RegistryKey Root="HKCR" Key="CLSID\{ECD4FC4D-521C-11D0-B792-00A0C90312E1}\TreatAs" ForceDeleteOnUninstall="yes" />
</Component>
<Component Id="ToastActivator" Guid="3A0FDC31-D5D3-4C2E-9A0B-292CAB46DA87" Win64="$(var.CS_WIN64)">
<RegistryKey Root="HKCR" Key="CLSID\{E407B70A-1FBD-4D5E-8822-231C69102472}\LocalServer32" ForceDeleteOnUninstall="yes">
<RegistryValue Value="&quot;[APPLICATIONFOLDER]Update.exe&quot; -ToastActivated" Type="string" />
</RegistryKey>
</Component>
</DirectoryRef>
<DirectoryRef Id="StartMenuDir">
<Component Id="HelpLink" Guid="D631C351-7BD4-42CE-813C-5D46347068AF">
@@ -564,7 +574,11 @@
<Condition>START_MENU_FOLDER=1</Condition>
</Component>
<Component Id="UpdateSettingsLink" Guid="10B5A082-6C92-4EA7-AFF8-21AE3D2D7FE0">
<Shortcut Id="UpdateSettingsLink" Name="!(loc.UpdateItem)" Advertise="no" Description="!(loc.UpdateSettingsDesc)" Target="[APPLICATIONFOLDER]Update.exe" WorkingDirectory="APPLICATIONFOLDER" />
<Shortcut Id="UpdateSettingsLink" Name="!(loc.UpdateItem)" Advertise="no" Description="!(loc.UpdateSettingsDesc)" Target="[APPLICATIONFOLDER]Update.exe" WorkingDirectory="APPLICATIONFOLDER">
<ShortcutProperty Key="System.AppUserModel.ID" Value="OpenShell.Update"/>
<!-- Windows 7 doesn't recognize `System.AppUserModel.ToastActivatorCLSID` name so we have to use GUID directly -->
<ShortcutProperty Key="{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}, 26" Value="{E407B70A-1FBD-4D5E-8822-231C69102472}"/>
</Shortcut>
<CreateFolder />
<Condition>START_MENU_FOLDER=1</Condition>
</Component>
@@ -607,9 +621,9 @@
<Property Id="ApplicationFolderName" Value="Open-Shell" />
<Property Id="WixAppFolder" Value="WixPerMachineFolder" />
<Property Id="ALLUSERS" Value="1" />
<Property Id="ARPHELPLINK" Value="http://www.classicshell.net/forum/" />
<Property Id="ARPHELPLINK" Value="https://github.com/Open-Shell/Open-Shell-Menu/issues" />
<Property Id="ARPSIZE" Value="9000" />
<Property Id="ARPURLINFOABOUT" Value="http://www.classicshell.net/" />
<Property Id="ARPURLINFOABOUT" Value="https://open-shell.github.io/Open-Shell-Menu" />
<Property Id="ARPNOMODIFY" Value="1" />
<Property Id="ARPNOREPAIR" Value="1" />
<Property Id="START_MENU_FOLDER" Value="1" />

View File

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

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 )
{
HKEY hkey=NULL;
@@ -489,40 +515,11 @@ static bool RemoveRegistryKeys( bool bPin )
}
}
hkey=NULL;
if (bPin)
{
if (RegOpenKeyEx(HKEY_CLASSES_ROOT,L"Launcher.ImmersiveApplication\\ShellEx\\ContextMenuHandlers\\StartMenuExt",0,KEY_READ|KEY_WOW64_64KEY,&hkey)==ERROR_SUCCESS)
{
RegCloseKey(hkey);
LogMessage(-1,L"Deleting registry key HKEY_CLASSES_ROOT\\Launcher.ImmersiveApplication\\ShellEx\\ContextMenuHandlers\\StartMenuExt");
error=RegCreateKeyEx(HKEY_CLASSES_ROOT,L"Launcher.ImmersiveApplication\\ShellEx\\ContextMenuHandlers",NULL,NULL,REG_OPTION_BACKUP_RESTORE,KEY_WRITE|DELETE|KEY_WOW64_64KEY,NULL,&hkey,NULL);
if (error==ERROR_SUCCESS)
{
error=RegDeleteTree2(hkey,L"StartMenuExt");
if (error!=ERROR_SUCCESS && error!=ERROR_FILE_NOT_FOUND)
LogMessage(error,L"Failed to delete registry key HKEY_CLASSES_ROOT\\Launcher.ImmersiveApplication\\ShellEx\\ContextMenuHandlers\\StartMenuExt.");
RegCloseKey(hkey);
}
else if (error!=ERROR_FILE_NOT_FOUND)
LogMessage(error,L"Failed to open registry key HKEY_CLASSES_ROOT\\Launcher.ImmersiveApplication\\ShellEx\\ContextMenuHandlers for writing.");
}
if (RegOpenKeyEx(HKEY_CLASSES_ROOT,L"Launcher.SystemSettings\\ShellEx\\ContextMenuHandlers\\StartMenuExt",0,KEY_READ|KEY_WOW64_64KEY,&hkey)==ERROR_SUCCESS)
{
RegCloseKey(hkey);
LogMessage(-1,L"Deleting registry key HKEY_CLASSES_ROOT\\Launcher.SystemSettings\\ShellEx\\ContextMenuHandlers\\StartMenuExt");
error=RegCreateKeyEx(HKEY_CLASSES_ROOT,L"Launcher.SystemSettings\\ShellEx\\ContextMenuHandlers",NULL,NULL,REG_OPTION_BACKUP_RESTORE,KEY_WRITE|DELETE|KEY_WOW64_64KEY,NULL,&hkey,NULL);
if (error==ERROR_SUCCESS)
{
error=RegDeleteTree2(hkey,L"StartMenuExt");
if (error!=ERROR_SUCCESS && error!=ERROR_FILE_NOT_FOUND)
LogMessage(error,L"Failed to delete registry key HKEY_CLASSES_ROOT\\Launcher.SystemSettings\\ShellEx\\ContextMenuHandlers\\StartMenuExt.");
RegCloseKey(hkey);
}
else if (error!=ERROR_FILE_NOT_FOUND)
LogMessage(error,L"Failed to open registry key HKEY_CLASSES_ROOT\\Launcher.SystemSettings\\ShellEx\\ContextMenuHandlers for writing.");
}
RemoveShellExtKey(L"Launcher.ImmersiveApplication");
RemoveShellExtKey(L"Launcher.DesktopPackagedApplication");
RemoveShellExtKey(L"Launcher.SystemSettings");
}
return true;

View File

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

View File

@@ -943,7 +943,7 @@ static BOOL CALLBACK EnumResLangProc( HMODULE hModule, LPCTSTR lpszType, LPCTSTR
if (IS_INTRESOURCE(lpszName))
{
std::vector<std::pair<int,WORD>> &oldStrings=*(std::vector<std::pair<int,WORD>>*)lParam;
oldStrings.push_back(std::pair<int,WORD>(PtrToInt(lpszName),wIDLanguage));
oldStrings.emplace_back(PtrToInt(lpszName),wIDLanguage);
}
return TRUE;
}

View File

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

View File

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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@@ -561,6 +561,7 @@ int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpstrC
else if (wcsstr(lpstrCmdLine,L"-toggle")!=NULL) open=MSG_TOGGLE;
else if (wcsstr(lpstrCmdLine,L"-open")!=NULL) open=MSG_OPEN;
else if (wcsstr(lpstrCmdLine,L"-settings")!=NULL) open=MSG_SETTINGS;
else if (wcsstr(lpstrCmdLine,L"-reloadsettings")!=NULL) open=MSG_RELOADSETTINGS;
else if (wcsstr(lpstrCmdLine,L"-exit")!=NULL) open=MSG_EXIT;
{

View File

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

View File

@@ -16,9 +16,7 @@ CMenuAccessible::CMenuAccessible( CMenuContainer *pOwner )
CreateStdAccessibleObject(pOwner->m_hWnd,OBJID_CLIENT,IID_IAccessible,(void**)&m_pStdAccessible);
}
CMenuAccessible::~CMenuAccessible( void )
{
}
CMenuAccessible::~CMenuAccessible( void ) = default;
void CMenuAccessible::Reset( void )
{
@@ -182,7 +180,7 @@ HRESULT STDMETHODCALLTYPE CMenuAccessible::accSelect( long flagsSelect, VARIANT
int index=varChild.lVal-1;
if (index<0 || index>=(int)m_pOwner->m_Items.size())
return S_FALSE;
m_pOwner->ActivateItem(index,CMenuContainer::ACTIVATE_SELECT,NULL,false);
m_pOwner->ActivateItem(index,CMenuContainer::ACTIVATE_SELECT,NULL);
}
return S_OK;
}

View File

@@ -95,13 +95,13 @@ CStdCommand7 g_StdCommands7[]={
{L"user_videos",0,NULL,L"$Menu.UserVideosTip",NULL,&FOLDERID_Videos},
{L"control_panel",0,L"$Menu.ControlPanel",L"$Menu.ControlPanelTip",NULL,&FOLDERID_ControlPanelFolder,NULL,StdMenuItem::MENU_TRACK},
{L"pc_settings",IDS_PCSETTINGS,L"$Menu.PCSettings",L"",L"%windir%\\ImmersiveControlPanel\\SystemSettings.exe,10",NULL,NULL,StdMenuItem::MENU_TRACK,CStdCommand7::ITEM_SINGLE},
{L"network_connections",0,NULL,L"$Menu.NetworkTip",NULL,&FOLDERID_ConnectionsFolder},
{L"network_connections",0,NULL,L"$Menu.NetworkTip",NULL,&FOLDERID_ConnectionsFolder,NULL,0,CStdCommand7::ITEM_NODRIVES},
{L"network",0,NULL,NULL,NULL,&FOLDERID_NetworkFolder,NULL,0,CStdCommand7::ITEM_SINGLE},
{L"printers",0,NULL,L"$Menu.PrintersTip",NULL,&FOLDERID_PrintersFolder},
{L"printers",0,NULL,L"$Menu.PrintersTip",NULL,&FOLDERID_PrintersFolder,NULL,0,CStdCommand7::ITEM_NODRIVES},
{L"fonts",0,NULL,NULL,NULL,&FOLDERID_Fonts},
{L"desktop",0,NULL,NULL,NULL,&FOLDERID_Desktop},
{L"admin",0,NULL,L"$Menu.AdminToolsTip",L"imageres.dll,114",&FOLDERID_CommonAdminTools,NULL,StdMenuItem::MENU_TRACK},
{L"startup",0,NULL,NULL,NULL,&FOLDERID_Startup,NULL,StdMenuItem::MENU_TRACK},
{L"admin",0,NULL,L"$Menu.AdminToolsTip",L"imageres.dll,114",&FOLDERID_CommonAdminTools,NULL,StdMenuItem::MENU_TRACK,CStdCommand7::ITEM_NODRIVES},
{L"startup",0,NULL,NULL,NULL,&FOLDERID_Startup,NULL,StdMenuItem::MENU_TRACK,CStdCommand7::ITEM_NODRIVES},
{L"downloads",0,NULL,L"$Menu.DownloadTip",NULL,&FOLDERID_Downloads},
{L"games",0,NULL,L"$Menu.GamesTip",NULL,&FOLDERID_Games,NULL,StdMenuItem::MENU_TRACK},
{L"links",0,NULL,NULL,NULL,&FOLDERID_Links},
@@ -112,7 +112,7 @@ CStdCommand7 g_StdCommands7[]={
{L"lib_videos",IDS_LIB_VIDEOS_ITEM,NULL,L"$Menu.VideosLibTip",NULL,&FOLDERID_VideosLibrary},
{L"lib_tv",IDS_LIB_TV_ITEM,NULL,L"$Menu.RecordingsLibTip",NULL,&FOLDERID_RecordedTVLibrary},
{L"homegroup",0,NULL,L"$Menu.HomegroupTip",NULL,&FOLDERID_HomeGroup,NULL,0,CStdCommand7::ITEM_SINGLE},
{L"devices",0,NULL,NULL,NULL,NULL,L"::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{A8A91A66-3A7D-4424-8D24-04E180695C7A}"},
{L"devices",0,NULL,NULL,NULL,NULL,L"::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{A8A91A66-3A7D-4424-8D24-04E180695C7A}",0,CStdCommand7::ITEM_NODRIVES},
{L"defaults",0,NULL,NULL,NULL,NULL,L"::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{17CD9488-1228-4B2F-88CE-4298E93E0966}",0,CStdCommand7::ITEM_SINGLE},
{L"apps",IDS_METRO_APPS,L"$Menu.Apps",NULL,L",2",NULL,NULL,StdMenuItem::MENU_TRACK,CStdCommand7::ITEM_FOLDER},

View File

@@ -15,6 +15,7 @@ struct CStdCommand7
ITEM_SINGLE=1, // this item never has sub-menu
ITEM_FOLDER=2, // this item always has sub-menu
ITEM_COMPUTER=4, // this item can be expanded only one level
ITEM_NODRIVES=8, // this item can never be expanded only one level
};
const wchar_t *command;
int nameID;

View File

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

View File

@@ -15,9 +15,7 @@ public:
m_RefCount=0;
}
~CDropTargetProxy( void )
{
}
~CDropTargetProxy( void ) = default;
void Reset( void )
{

View File

@@ -55,8 +55,8 @@ GUID IID_IApplicationResolver8={0xde25675a,0x72de,0x44b4,{0x93,0x73,0x05,0x17,0x
interface IResourceContext;
const GUID IID_IResourceMap={0x6e21e72b, 0xb9b0, 0x42ae, {0xa6, 0x86, 0x98, 0x3c, 0xf7, 0x84, 0xed, 0xcd}};
interface IResourceMap : public IUnknown
MIDL_INTERFACE("6e21e72b-b9b0-42ae-a686-983cf784edcd")
IResourceMap : public IUnknown
{
virtual HRESULT STDMETHODCALLTYPE GetUri(const wchar_t **pUri ) = 0;
virtual HRESULT STDMETHODCALLTYPE GetSubtree(const wchar_t *propName, IResourceMap **pSubTree ) = 0;
@@ -76,8 +76,8 @@ enum RESOURCE_SCALE
RES_SCALE_80 =3,
};
const GUID IID_ResourceContext={0xe3c22b30, 0x8502, 0x4b2f, {0x91, 0x33, 0x55, 0x96, 0x74, 0x58, 0x7e, 0x51}};
interface IResourceContext : public IUnknown
MIDL_INTERFACE("e3c22b30-8502-4b2f-9133-559674587e51")
IResourceContext : public IUnknown
{
virtual HRESULT STDMETHODCALLTYPE GetLanguage( void ) = 0;
virtual HRESULT STDMETHODCALLTYPE GetHomeRegion( wchar_t *pRegion ) = 0;
@@ -142,10 +142,11 @@ static bool DetectGrayscaleImage( const unsigned int *bits, int stride, int widt
for (int x=0;x<width;x++)
{
unsigned int pixel=bits[x];
int a=(pixel>>24)&255;
int r=(pixel>>16)&255;
int g=(pixel>>8)&255;
int b=(pixel)&255;
if (abs(r-g)>2 || abs(r-b)>2 || abs(g-b)>2)
if (abs(a-r)>2 || abs(r-g)>2 || abs(r-b)>2 || abs(g-b)>2)
return false; // found colored pixel
if (!(pixel&0xFF000000))
transparent++;
@@ -175,6 +176,27 @@ static void CreateMonochromeImage( unsigned int *bits, int stride, int width, in
}
}
HBITMAP ColorizeMonochromeImage(HBITMAP bitmap, DWORD color)
{
{
BITMAP info{};
GetObject(bitmap, sizeof(info), &info);
if (!DetectGrayscaleImage((const unsigned int*)info.bmBits, info.bmWidth, info.bmWidth, info.bmHeight))
return nullptr;
}
HBITMAP bmp = (HBITMAP)CopyImage(bitmap, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
if (bmp)
{
BITMAP info{};
GetObject(bmp, sizeof(info), &info);
CreateMonochromeImage((unsigned int*)info.bmBits, info.bmWidth, info.bmWidth, info.bmHeight, color);
}
return bmp;
}
static HBITMAP BitmapFromMetroIcon( HICON hIcon, int bitmapSize, int iconSize, DWORD metroColor, bool bDestroyIcon=true )
{
ICONINFO info;
@@ -258,7 +280,6 @@ static HBITMAP BitmapFromMetroBitmap( HBITMAP hBitmap, int bitmapSize, DWORD met
HGDIOBJ bmp0=SelectObject(hdc,bmp);
HGDIOBJ bmp02=SelectObject(hsrc,hBitmap);
int offset=(bitmapSize-info.bmWidth)/2;
bool bInvert=g_bInvertMetroIcons;
if (g_bInvertMetroIcons && bGrayscale)
{
FillRect(hdc,&rc,(HBRUSH)GetStockObject(BLACK_BRUSH));
@@ -299,10 +320,9 @@ static HBITMAP BitmapFromMetroBitmap( HBITMAP hBitmap, int bitmapSize, DWORD met
///////////////////////////////////////////////////////////////////////////////
static HBITMAP LoadMetroBitmap0( const wchar_t *path, int bitmapSize, DWORD metroColor )
static HBITMAP LoadMetroBitmap0(const wchar_t *path, int bitmapSize, DWORD metroColor = 0xFFFFFFFF)
{
int iconSize=g_bInvertMetroIcons?bitmapSize:(bitmapSize-2);
SIZE size={-iconSize,iconSize};
SIZE size={-bitmapSize,bitmapSize};
HBITMAP hBitmap=LoadImageFile(path,&size,true,true,NULL);
if (hBitmap)
{
@@ -439,16 +459,8 @@ static HBITMAP LoadMetroBitmap2( const wchar_t *location, int bitmapSize, DWORD
}
if (iconSize)
{
if (g_bInvertMetroIcons)
{
if (iconSize>bitmapSize)
iconSize=bitmapSize;
}
else
{
if (iconSize>bitmapSize-2)
iconSize=bitmapSize-2;
}
if (iconSize>bitmapSize)
iconSize=bitmapSize;
SIZE size={iconSize,iconSize};
HBITMAP hBitmap=LoadImageFile(path,&size,true,true,NULL);
if (hBitmap)
@@ -477,7 +489,8 @@ void CItemManager::LoadIconData::Init( void )
HIMAGELIST_QueryInterface(m_TempLists[i],IID_IImageList2,(void**)&m_pTempLists[i]);
}
}
m_pFactory.CoCreateInstance(CLSID_WICImagingFactory);
if (FAILED(m_pFactory.CoCreateInstance(CLSID_WICImagingFactory)))
m_pFactory.CoCreateInstance(CLSID_WICImagingFactory1);
}
void CItemManager::LoadIconData::Close( void )
@@ -577,7 +590,7 @@ void CItemManager::Init( void )
m_RootGames=L"::{ED228FDF-9EA8-4870-83B1-96B02CFE0D52}\\";
wchar_t text[_MAX_PATH];
Strcpy(text,_countof(text),START_MENU_PINNED_ROOT L"\\");
Sprintf(text,_countof(text),L"%s\\",GetSettingString(L"PinnedItemsPath"));
DoEnvironmentSubst(text,_countof(text));
m_RootStartMenu3=text;
StringUpper(m_RootStartMenu3);
@@ -597,7 +610,7 @@ void CItemManager::Init( void )
{
int width, height;
pList->GetIconSize(&width,&height);
m_ListSizes.push_back(std::pair<int,int>(width,i));
m_ListSizes.emplace_back(width,i);
}
}
std::sort(m_ListSizes.begin(),m_ListSizes.end());
@@ -605,7 +618,7 @@ void CItemManager::Init( void )
CreateDefaultIcons();
LoadCacheFile();
ItemInfo &item=m_ItemInfos.insert(std::pair<unsigned int,ItemInfo>(0,ItemInfo()))->second;
ItemInfo &item=m_ItemInfos.emplace(0,ItemInfo())->second;
item.bIconOnly=true;
item.smallIcon=m_DefaultSmallIcon;
item.largeIcon=m_DefaultLargeIcon;
@@ -692,21 +705,21 @@ void CItemManager::CreateDefaultIcons( void )
icon.bitmap=BitmapFromIcon(LoadShellIcon(index,SMALL_ICON_SIZE),SMALL_ICON_SIZE);
else
icon.bitmap=NULL;
m_DefaultSmallIcon=&m_IconInfos.insert(std::pair<unsigned int,IconInfo>(0,icon))->second;
m_DefaultSmallIcon=&m_IconInfos.emplace(0,icon)->second;
icon.sizeType=ICON_SIZE_TYPE_LARGE;
if (index>=0)
icon.bitmap=BitmapFromIcon(LoadShellIcon(index,LARGE_ICON_SIZE),LARGE_ICON_SIZE);
else
icon.bitmap=NULL;
m_DefaultLargeIcon=&m_IconInfos.insert(std::pair<unsigned int,IconInfo>(0,icon))->second;
m_DefaultLargeIcon=&m_IconInfos.emplace(0,icon)->second;
icon.sizeType=ICON_SIZE_TYPE_EXTRA_LARGE;
if (index>=0)
icon.bitmap=BitmapFromIcon(LoadShellIcon(index,EXTRA_LARGE_ICON_SIZE),EXTRA_LARGE_ICON_SIZE);
else
icon.bitmap=NULL;
m_DefaultExtraLargeIcon=&m_IconInfos.insert(std::pair<unsigned int,IconInfo>(0,icon))->second;
m_DefaultExtraLargeIcon=&m_IconInfos.emplace(0,icon)->second;
}
CItemManager::LoadIconData &CItemManager::GetLoadIconData( void )
@@ -884,7 +897,7 @@ const CItemManager::ItemInfo *CItemManager::GetItemInfo( IShellItem *pItem, PIDL
}
if (!pInfo)
{
pInfo=&m_ItemInfos.insert(std::pair<unsigned int,ItemInfo>(hash,ItemInfo()))->second;
pInfo=&m_ItemInfos.emplace(hash,ItemInfo())->second;
pInfo->pidl.Clone(pidl);
pInfo->path=path;
pInfo->PATH=PATH;
@@ -966,7 +979,7 @@ const CItemManager::ItemInfo *CItemManager::GetItemInfo( CString path, int refre
}
if (!pInfo)
{
pInfo=&m_ItemInfos.insert(std::pair<unsigned int,ItemInfo>(hash,ItemInfo()))->second;
pInfo=&m_ItemInfos.emplace(hash,ItemInfo())->second;
if (!PATH.IsEmpty())
MenuParseDisplayName(path,&pInfo->pidl,NULL,NULL);
if (pInfo->pidl)
@@ -1064,7 +1077,7 @@ const CItemManager::ItemInfo *CItemManager::GetCustomIcon( const wchar_t *locati
}
if (!pInfo)
{
pInfo=&m_ItemInfos.insert(std::pair<unsigned int,ItemInfo>(hash,ItemInfo()))->second;
pInfo=&m_ItemInfos.emplace(hash,ItemInfo())->second;
pInfo->bIconOnly=true;
pInfo->bTemp=bTemp;
pInfo->iconPath=location;
@@ -1113,6 +1126,49 @@ const CItemManager::ItemInfo *CItemManager::GetCustomIcon( const wchar_t *path,
return GetCustomIcon(text,index,iconSizeType,false);
}
const CItemManager::ItemInfo* CItemManager::GetLinkIcon(IShellLink* link, TIconSizeType iconSizeType)
{
wchar_t location[_MAX_PATH];
int index;
if (link->GetIconLocation(location, _countof(location), &index) == S_OK && location[0])
return GetCustomIcon(location, index, iconSizeType, (index == 0)); // assuming that if index!=0 the icon comes from a permanent location like a dll or exe
CComQIPtr<IPropertyStore> store(link);
if (store)
{
// Name: System.AppUserModel.DestListLogoUri -- PKEY_AppUserModel_DestListLogoUri
// Type: String -- VT_LPWSTR
// FormatID: {9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}, 29
static const PROPERTYKEY PKEY_AppUserModel_DestListLogoUri = { {0x9F4C2855, 0x9F79, 0x4B39, {0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3}}, 29 };
auto logoUri = GetPropertyStoreString(store, PKEY_AppUserModel_DestListLogoUri);
if (!logoUri.IsEmpty())
{
auto appId = GetPropertyStoreString(store, PKEY_AppUserModel_ID);
if (!appId.IsEmpty())
{
CComPtr<IResourceManager> resManager;
if (SUCCEEDED(resManager.CoCreateInstance(CLSID_ResourceManager)))
{
if (SUCCEEDED(resManager->InitializeForPackage(GetPackageFullName(appId))))
{
CComPtr<IResourceMap> resMap;
if (SUCCEEDED(resManager->GetMainResourceMap(IID_PPV_ARGS(&resMap))))
{
CComString location;
if (SUCCEEDED(resMap->GetFilePath(logoUri, &location)))
return GetCustomIcon(location, -65536, iconSizeType, true);
}
}
}
}
}
}
return nullptr;
}
const CItemManager::ItemInfo *CItemManager::GetMetroAppInfo10( const wchar_t *appid )
{
wchar_t APPID[256];
@@ -1823,7 +1879,11 @@ void CItemManager::RefreshItemInfo( ItemInfo *pInfo, int refreshFlags, IShellIte
{
newInfo.bLink=true;
pStore=pLink;
#ifdef _DEBUG
LOG_MENU(LOG_OPEN, L"Link: %s", newInfo.path);
LOG_MENU(LOG_OPEN, L"Link property store:");
LogPropertyStore(LOG_OPEN, pStore);
#endif
if (SUCCEEDED(pLink->GetIDList(&newInfo.targetPidl)))
{
wchar_t path[_MAX_PATH];
@@ -1832,6 +1892,28 @@ void CItemManager::RefreshItemInfo( ItemInfo *pInfo, int refreshFlags, IShellIte
CharUpper(path);
newInfo.targetPATH=path;
}
CComPtr<IShellItem> target;
if (SUCCEEDED(SHCreateItemFromIDList(newInfo.targetPidl, IID_PPV_ARGS(&target))))
{
CComPtr<IPropertyStore> store;
if (SUCCEEDED(target->BindToHandler(nullptr, BHID_PropertyStore, IID_PPV_ARGS(&store))))
{
#ifdef _DEBUG
LOG_MENU(LOG_OPEN, L"Target property store:");
LogPropertyStore(LOG_OPEN, store);
#endif
PROPVARIANT val;
PropVariantInit(&val);
if (SUCCEEDED(store->GetValue(PKEY_MetroAppLauncher, &val)) && (val.vt == VT_I4 || val.vt == VT_UI4) && val.intVal)
{
newInfo.bLink = false;
pItem = std::move(target);
pStore = store;
}
PropVariantClear(&val);
}
}
}
}
}
@@ -1923,7 +2005,6 @@ void CItemManager::RefreshItemInfo( ItemInfo *pInfo, int refreshFlags, IShellIte
{
newInfo.targetPidl.Clear();
newInfo.targetPATH.Empty();
newInfo.metroName.Empty();
newInfo.iconPath.Empty();
newInfo.bNoPin=newInfo.bNoNew=false;
if (!newInfo.bMetroApp)
@@ -2296,12 +2377,6 @@ void CItemManager::LoadShellIcon( IShellItem *pItem, int refreshFlags, const Ico
int smallIconSize=SMALL_ICON_SIZE;
int largeIconSize=LARGE_ICON_SIZE;
int extraLargeIconSize=EXTRA_LARGE_ICON_SIZE;
if (pMetroColor)
{
smallIconSize-=2;
largeIconSize-=2;
extraLargeIconSize-=2;
}
HICON hSmallIcon=NULL, hLargeIcon=NULL, hExtraLargeIcon=NULL;
if (bNotFileName)
{
@@ -2414,14 +2489,13 @@ void CItemManager::LoadMetroIcon( IShellItem *pItem, int &refreshFlags, const Ic
if (FAILED(pResManager->InitializeForPackage(packageName)))
return;
CComPtr<IResourceMap> pResMap;
if (FAILED(pResManager->GetMainResourceMap(IID_IResourceMap,(void**)&pResMap)))
if (FAILED(pResManager->GetMainResourceMap(IID_PPV_ARGS(&pResMap))))
return;
CComPtr<IResourceContext> pResContext;
if (FAILED(pResManager->GetDefaultContext(IID_ResourceContext,(void**)&pResContext)))
if (FAILED(pResManager->GetDefaultContext(IID_PPV_ARGS(&pResContext))))
return;
int iconFlags=0;
int delta=g_bInvertMetroIcons?0:2;
if ((refreshFlags&INFO_SMALL_ICON) && SetResContextTargetSize(pResContext,SMALL_ICON_SIZE-delta))
if ((refreshFlags&INFO_SMALL_ICON) && SetResContextTargetSize(pResContext,SMALL_ICON_SIZE))
{
CComString pLocation;
if (SUCCEEDED(pResMap->GetFilePath(iconName,&pLocation)))
@@ -2431,7 +2505,7 @@ void CItemManager::LoadMetroIcon( IShellItem *pItem, int &refreshFlags, const Ic
StoreInCache(hash,L"",hSmallBitmap,NULL,NULL,INFO_SMALL_ICON,smallIcon,largeIcon,extraLargeIcon,false,true);
}
}
if ((refreshFlags&INFO_LARGE_ICON) && SetResContextTargetSize(pResContext,LARGE_ICON_SIZE-delta))
if ((refreshFlags&INFO_LARGE_ICON) && SetResContextTargetSize(pResContext,LARGE_ICON_SIZE))
{
CComString pLocation;
if (SUCCEEDED(pResMap->GetFilePath(iconName,&pLocation)))
@@ -2441,7 +2515,7 @@ void CItemManager::LoadMetroIcon( IShellItem *pItem, int &refreshFlags, const Ic
StoreInCache(hash,L"",NULL,hLargeBitmap,NULL,INFO_LARGE_ICON,smallIcon,largeIcon,extraLargeIcon,false,true);
}
}
if ((refreshFlags&INFO_SMALL_ICON) && SetResContextTargetSize(pResContext,EXTRA_LARGE_ICON_SIZE-delta))
if ((refreshFlags&INFO_EXTRA_LARGE_ICON) && SetResContextTargetSize(pResContext,EXTRA_LARGE_ICON_SIZE))
{
CComString pLocation;
if (SUCCEEDED(pResMap->GetFilePath(iconName,&pLocation)))
@@ -2524,7 +2598,7 @@ void CItemManager::StoreInCache( unsigned int hash, const wchar_t *path, HBITMAP
if ((refreshFlags&INFO_SMALL_ICON) && hSmallBitmap)
{
IconInfo *pInfo=&m_IconInfos.insert(std::pair<unsigned int,IconInfo>(hash,IconInfo()))->second;
IconInfo *pInfo=&m_IconInfos.emplace(hash,IconInfo())->second;
pInfo->sizeType=ICON_SIZE_TYPE_SMALL;
pInfo->bTemp=bTemp;
pInfo->bMetro=bMetro;
@@ -2534,7 +2608,7 @@ void CItemManager::StoreInCache( unsigned int hash, const wchar_t *path, HBITMAP
}
if ((refreshFlags&INFO_LARGE_ICON) && hLargeBitmap)
{
IconInfo *pInfo=&m_IconInfos.insert(std::pair<unsigned int,IconInfo>(hash,IconInfo()))->second;
IconInfo *pInfo=&m_IconInfos.emplace(hash,IconInfo())->second;
pInfo->sizeType=ICON_SIZE_TYPE_LARGE;
pInfo->bTemp=bTemp;
pInfo->bMetro=bMetro;
@@ -2544,7 +2618,7 @@ void CItemManager::StoreInCache( unsigned int hash, const wchar_t *path, HBITMAP
}
if ((refreshFlags&INFO_EXTRA_LARGE_ICON) && hExtraLargeBitmap)
{
IconInfo *pInfo=&m_IconInfos.insert(std::pair<unsigned int,IconInfo>(hash,IconInfo()))->second;
IconInfo *pInfo=&m_IconInfos.emplace(hash,IconInfo())->second;
pInfo->sizeType=ICON_SIZE_TYPE_EXTRA_LARGE;
pInfo->bTemp=bTemp;
pInfo->bMetro=bMetro;
@@ -2586,49 +2660,45 @@ void CItemManager::IconInfo::SetPath( const wchar_t *path )
timestamp.dwHighDateTime=timestamp.dwLowDateTime=0;
}
void CItemManager::LoadCustomIcon( const wchar_t *iconPath, int iconIndex, int refreshFlags, const IconInfo *&smallIcon, const IconInfo *&largeIcon, const IconInfo *&extraLargeIcon, bool bTemp )
void CItemManager::LoadCustomIcon(const wchar_t *iconPath, int iconIndex, int refreshFlags, const IconInfo *&smallIcon, const IconInfo *&largeIcon, const IconInfo *&extraLargeIcon, bool bTemp)
{
unsigned int hash=CalcFNVHash(iconPath,CalcFNVHash(&iconIndex,4));
unsigned int hash = CalcFNVHash(iconPath, CalcFNVHash(&iconIndex, 4));
FindInCache(hash,refreshFlags,smallIcon,largeIcon,extraLargeIcon);
if (!refreshFlags) return;
FindInCache(hash, refreshFlags, smallIcon, largeIcon, extraLargeIcon);
if (!refreshFlags)
return;
auto ExtractIconAsBitmap = [&](int iconSize) -> HBITMAP {
if (iconIndex == -65536)
return LoadMetroBitmap0(iconPath, iconSize);
HICON hIcon;
if (!*iconPath)
hIcon = (HICON)LoadImage(g_Instance, MAKEINTRESOURCE(-iconIndex), IMAGE_ICON, iconSize, iconSize, LR_DEFAULTCOLOR);
else
hIcon = ShExtractIcon(iconPath, iconIndex == -1 ? 0 : iconIndex, iconSize);
if (hIcon)
return BitmapFromIcon(hIcon, iconSize);
return nullptr;
};
// extract icon
HBITMAP hSmallBitmap=NULL, hLargeBitmap=NULL, hExtraLargeBitmap=NULL;
if (refreshFlags&INFO_SMALL_ICON)
{
HICON hIcon;
if (!*iconPath)
hIcon=(HICON)LoadImage(g_Instance,MAKEINTRESOURCE(-iconIndex),IMAGE_ICON,SMALL_ICON_SIZE,SMALL_ICON_SIZE,LR_DEFAULTCOLOR);
else
hIcon=ShExtractIcon(iconPath,iconIndex==-1?0:iconIndex,SMALL_ICON_SIZE);
if (hIcon)
hSmallBitmap=BitmapFromIcon(hIcon,SMALL_ICON_SIZE);
}
HBITMAP hSmallBitmap = nullptr, hLargeBitmap = nullptr, hExtraLargeBitmap = nullptr;
if (refreshFlags&INFO_LARGE_ICON)
{
HICON hIcon;
if (!*iconPath)
hIcon=(HICON)LoadImage(g_Instance,MAKEINTRESOURCE(-iconIndex),IMAGE_ICON,LARGE_ICON_SIZE,LARGE_ICON_SIZE,LR_DEFAULTCOLOR);
else
hIcon=ShExtractIcon(iconPath,iconIndex==-1?0:iconIndex,LARGE_ICON_SIZE);
if (hIcon)
hLargeBitmap=BitmapFromIcon(hIcon,LARGE_ICON_SIZE);
}
if (refreshFlags & INFO_SMALL_ICON)
hSmallBitmap = ExtractIconAsBitmap(SMALL_ICON_SIZE);
if (refreshFlags&INFO_EXTRA_LARGE_ICON)
{
HICON hIcon;
if (!*iconPath)
hIcon=(HICON)LoadImage(g_Instance,MAKEINTRESOURCE(-iconIndex),IMAGE_ICON,EXTRA_LARGE_ICON_SIZE,EXTRA_LARGE_ICON_SIZE,LR_DEFAULTCOLOR);
else
hIcon=ShExtractIcon(iconPath,iconIndex==-1?0:iconIndex,EXTRA_LARGE_ICON_SIZE);
if (hIcon)
hExtraLargeBitmap=BitmapFromIcon(hIcon,EXTRA_LARGE_ICON_SIZE);
}
if (refreshFlags & INFO_LARGE_ICON)
hLargeBitmap = ExtractIconAsBitmap(LARGE_ICON_SIZE);
StoreInCache(hash,bTemp?NULL:iconPath,hSmallBitmap,hLargeBitmap,hExtraLargeBitmap,refreshFlags,smallIcon,largeIcon,extraLargeIcon,bTemp,false);
if (refreshFlags & INFO_EXTRA_LARGE_ICON)
hExtraLargeBitmap = ExtractIconAsBitmap(EXTRA_LARGE_ICON_SIZE);
StoreInCache(hash, bTemp ? nullptr : iconPath, hSmallBitmap, hLargeBitmap, hExtraLargeBitmap, refreshFlags, smallIcon, largeIcon, extraLargeIcon, bTemp, false);
}
// Recursive function to preload the items for a folder
@@ -2798,7 +2868,8 @@ void CItemManager::PreloadItemsThread( void )
else if (g_CacheFolders[i].folder==FOLDERID_ClassicPinned)
{
if (GetSettingInt(L"PinnedPrograms")!=PINNED_PROGRAMS_PINNED) continue;
wchar_t path[_MAX_PATH]=START_MENU_PINNED_ROOT;
wchar_t path[_MAX_PATH];
Strcpy(path,_countof(path),GetSettingString(L"PinnedItemsPath"));
DoEnvironmentSubst(path,_countof(path));
if (FAILED(SHParseDisplayName(path,NULL,&pidl,0,NULL)) || !pidl) continue;
if (FAILED(SHCreateItemFromIDList(pidl,IID_IShellItem,(void**)&pFolder)) || !pFolder) continue;
@@ -3204,7 +3275,7 @@ void CItemManager::LoadCacheFile( void )
bError=true;
break;
}
remapIcons.push_back(&m_IconInfos.insert(std::pair<unsigned int,IconInfo>(data.key,info))->second);
remapIcons.push_back(&m_IconInfos.emplace(data.key,info)->second);
}
else
{
@@ -3235,7 +3306,7 @@ void CItemManager::LoadCacheFile( void )
bError=true;
break;
}
ItemInfo &info=m_ItemInfos.insert(std::pair<unsigned int,ItemInfo>(data.key,ItemInfo()))->second;
ItemInfo &info=m_ItemInfos.emplace(data.key,ItemInfo())->second;
info.writestamp=data.writestamp;
info.createstamp=data.createstamp;
@@ -3499,7 +3570,7 @@ void CItemManager::ClearCache( void )
m_IconInfos.clear();
m_MetroItemInfos10.clear();
CreateDefaultIcons();
ItemInfo &item=m_ItemInfos.insert(std::pair<unsigned int,ItemInfo>(0,ItemInfo()))->second;
ItemInfo &item=m_ItemInfos.emplace(0,ItemInfo())->second;
item.bIconOnly=true;
item.smallIcon=m_DefaultSmallIcon;
item.largeIcon=m_DefaultLargeIcon;

View File

@@ -173,6 +173,7 @@ public:
const ItemInfo *GetItemInfo( CString path, int refreshFlags, TLocation location=LOCATION_UNKNOWN );
const ItemInfo *GetCustomIcon( const wchar_t *location, int index, TIconSizeType iconSizeType, bool bTemp );
const ItemInfo *GetCustomIcon( const wchar_t *path, TIconSizeType iconSizeType );
const ItemInfo* GetLinkIcon(IShellLink* link, TIconSizeType iconSizeType);
const ItemInfo *GetMetroAppInfo10( const wchar_t *appid );
void UpdateItemInfo( const ItemInfo *pInfo, int refreshFlags, bool bHasWriteLock=false );
void WaitForShortcuts( const POINT &balloonPos );
@@ -466,9 +467,9 @@ bool MenuGetFileTimestamp( const wchar_t *path, FILETIME *pWriteTime, FILETIME *
STDAPI ShGetKnownFolderPath( REFKNOWNFOLDERID rfid, PWSTR *pPath );
STDAPI ShGetKnownFolderIDList(REFKNOWNFOLDERID rfid, PIDLIST_ABSOLUTE *pPidl );
STDAPI ShGetKnownFolderItem(REFKNOWNFOLDERID rfid, IShellItem **ppItem );
HBITMAP ColorizeMonochromeImage(HBITMAP bitmap, DWORD color);
#define TASKBAR_PINNED_ROOT L"%APPDATA%\\Microsoft\\Internet Explorer\\Quick Launch\\User Pinned\\TaskBar"
#define START_MENU_PINNED_ROOT L"%APPDATA%\\OpenShell\\Pinned"
#define STARTSCREEN_COMMAND L"startscreen.lnk"
#define USERASSIST_LINKS_KEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\UserAssist\\{F4E57C4B-2036-45F0-A9AB-443BCFE33D9F}\\Count"
#define USERASSIST_APPIDS_KEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\UserAssist\\{CEBFF5CD-ACE2-4F4F-9178-9926F41749EA}\\Count"

View File

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

View File

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

View File

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

View File

@@ -11,6 +11,7 @@
#include "Settings.h"
#include "SettingsUI.h"
#include "SettingsUIHelper.h"
#include "FileHelper.h"
#include "Translations.h"
#include "LogManager.h"
#include "FNVHash.h"
@@ -402,7 +403,7 @@ void CMenuContainer::OpenSubMenu( int index, TActivateType type, bool bShift )
if (m_Options&CONTAINER_NOEXTENSIONS)
options|=CONTAINER_NOEXTENSIONS;
if (item.id==MENU_PROGRAMS || item.id==MENU_APPS || (m_Options&CONTAINER_MULTICOL_REC))
if (item.id==MENU_PROGRAMS || item.id==MENU_APPS || item.bFolder || (m_Options&CONTAINER_MULTICOL_REC))
options|=CONTAINER_MULTICOL_REC;
if ((options&CONTAINER_MULTICOL_REC) && !bShift)
options|=CONTAINER_MULTICOLUMN;
@@ -2192,11 +2193,15 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p
if (res==CMD_PINSETTING)
{
CSearchManager::TItemCategory cat=(CSearchManager::TItemCategory)(item.categoryHash&CSearchManager::CATEGORY_MASK);
if (cat==CSearchManager::CATEGORY_SETTING)
CreatePinLink(pItemPidl1,item.name,NULL,0);
else if (cat==CSearchManager::CATEGORY_METROSETTING)
CreatePinLink(pItemPidl1,item.name,L"%windir%\\ImmersiveControlPanel\\systemsettings.exe",0);
CString iconPath;
if (item.pItemInfo)
{
CItemManager::RWLock lock(&g_ItemManager, false, CItemManager::RWLOCK_ITEMS);
if (_wcsicmp(PathFindExtension(item.pItemInfo->GetPath()), L".settingcontent-ms") == 0)
iconPath = L"%windir%\\ImmersiveControlPanel\\systemsettings.exe";
}
CreatePinLink(pItemPidl1, item.name, iconPath.IsEmpty() ? nullptr : iconPath.GetString(), 0);
m_bRefreshItems=true;
}
@@ -2778,12 +2783,19 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p
info.lpVerb=MAKEINTRESOURCEA(res-verbOffset);
info.lpVerbW=MAKEINTRESOURCEW(res-verbOffset);
info.nShow=SW_SHOWNORMAL;
bool bOpenTruePath=false;
wchar_t targetlnkPath[_MAX_PATH]; // path to target.lnk in a fake folder
wchar_t dir[_MAX_PATH];
if (SHGetPathFromIDList(pItemPidl1,dir))
{
PathRemoveFileSpec(dir);
if (GetFileAttributes(dir)!=INVALID_FILE_ATTRIBUTES)
info.lpDirectoryW=dir;
if (_stricmp(command,"open")==0 && GetSettingBool(L"OpenTruePath") && GetFakeFolder(targetlnkPath,_countof(targetlnkPath),dir))
bOpenTruePath=true;
else
{
PathRemoveFileSpec(dir);
if (GetFileAttributes(dir)!=INVALID_FILE_ATTRIBUTES)
info.lpDirectoryW=dir;
}
}
if (pPt)
{
@@ -2799,9 +2811,16 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p
if (bRefresh || bRefreshMain)
info.fMask|=CMIC_MASK_NOASYNC; // wait for delete/link commands to finish so we can refresh the menu
// we don't want our virtual folder to appear in Explorer's frequent list
if (item.pItemInfo && wcsncmp(item.pItemInfo->PATH, L"::{82E749ED-B971-4550-BAF7-06AA2BF7E836}", 40) == 0)
info.fMask &= ~CMIC_MASK_FLAG_LOG_USAGE;
s_bPreventClosing=true;
for (std::vector<CMenuContainer*>::iterator it=s_Menus.begin();it!=s_Menus.end();++it)
(*it)->EnableWindow(FALSE); // disable all menus
for (auto& it : s_Menus)
{
it->EnableWindow(FALSE); // disable all menus
it->SetWindowPos(HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
bool bAllPrograms=s_bAllPrograms;
if (bAllPrograms) ::EnableWindow(g_TopWin7Menu,FALSE);
info.hwnd=g_OwnerWindow;
@@ -2811,9 +2830,20 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p
::SetForegroundWindow(g_OwnerWindow);
::SetWindowPos(g_OwnerWindow,HWND_TOPMOST,rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top,0);
LOG_MENU(LOG_EXECUTE,L"Invoke command, ptr=%p, command='%S'",this,command);
HRESULT hr=pInvokeMenu->InvokeCommand((LPCMINVOKECOMMANDINFO)&info);
LOG_MENU(LOG_EXECUTE,L"Invoke command, ptr=%p, res=%d",this,hr);
if (type==ACTIVATE_EXECUTE && SUCCEEDED(hr))
bool executeSuccess;
if (bOpenTruePath) // we are trying to open a fake folder, directly open target.lnk instead
{
HINSTANCE hinst=ShellExecute(NULL,NULL,targetlnkPath,NULL,NULL,SW_SHOWNORMAL);
LOG_MENU(LOG_EXECUTE,L"Invoke command, ptr=%p, res=%d",this,hinst);
executeSuccess=static_cast<int>(reinterpret_cast<uintptr_t>(hinst))>=32;
}
else
{
HRESULT hr=pInvokeMenu->InvokeCommand((LPCMINVOKECOMMANDINFO)&info);
LOG_MENU(LOG_EXECUTE,L"Invoke command, ptr=%p, res=%d",this,hr);
executeSuccess=SUCCEEDED(hr);
}
if (type==ACTIVATE_EXECUTE && executeSuccess)
{
if (bTrackRecent)
{
@@ -2846,9 +2876,14 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p
}
}
}
for (std::vector<CMenuContainer*>::iterator it=s_Menus.begin();it!=s_Menus.end();++it)
if (!(*it)->m_bDestroyed)
(*it)->EnableWindow(TRUE); // enable all menus
for (auto& it : s_Menus)
{
if (!it->m_bDestroyed)
{
it->EnableWindow(TRUE); // enable all menus
it->SetWindowPos(HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
}
if (bAllPrograms) ::EnableWindow(g_TopWin7Menu,TRUE);
if (bRefreshMain && m_bSubMenu)
{

View File

@@ -315,6 +315,7 @@ bool CMenuContainer::s_bShowTopEmpty=false;
bool CMenuContainer::s_bNoDragDrop=false;
bool CMenuContainer::s_bNoContextMenu=false;
bool CMenuContainer::s_bExpandLinks=false;
bool CMenuContainer::s_bSingleClickFolders=false;
bool CMenuContainer::s_bLogicalSort=false;
bool CMenuContainer::s_bExtensionSort=false;
bool CMenuContainer::s_bAllPrograms=false;
@@ -334,6 +335,7 @@ bool CMenuContainer::s_bDragMovable;
bool CMenuContainer::s_bRightDrag;
bool CMenuContainer::s_bLockWorkArea;
bool CMenuContainer::s_bPendingSearchEnter;
bool CMenuContainer::s_bMoreResults;
std::vector<CMenuContainer*> CMenuContainer::s_Menus;
volatile HWND CMenuContainer::s_FirstMenu, CMenuContainer::s_SearchMenu;
CSearchManager::SearchResults CMenuContainer::s_SearchResults;
@@ -343,7 +345,8 @@ bool CMenuContainer::s_bMRULoaded=false;
const CItemManager::ItemInfo *CMenuContainer::s_JumpAppInfo;
CJumpList CMenuContainer::s_JumpList;
int CMenuContainer::s_TaskBarId;
HWND CMenuContainer::s_TaskBar, CMenuContainer::s_StartButton;
HWND CMenuContainer::s_TaskBar;
HWND CMenuContainer::s_StartButton; // custom start button (if any)
UINT CMenuContainer::s_TaskBarEdge;
RECT CMenuContainer::s_StartRect;
HWND CMenuContainer::s_LastFGWindow;
@@ -443,7 +446,10 @@ LRESULT CALLBACK CMenuContainer::SubclassSearchBox( HWND hWnd, UINT uMsg, WPARAM
SetBkColor(hdc,GetSysColor(COLOR_WINDOW));
SetBkMode(hdc,TRANSPARENT);
SetTextColor(hdc,s_Skin.Search_text_colors[1]);
DrawText(hdc,pParent->m_Items[pParent->m_SearchIndex].name,-1,&rc,DT_SINGLELINE|DT_EDITCONTROL|(s_bRTL?DT_RIGHT:DT_LEFT));
if (GetSettingBool(L"SearchHint"))
DrawText(hdc,GetSettingString(L"SearchHintText"),-1,&rc,DT_SINGLELINE|DT_EDITCONTROL|(s_bRTL?DT_RIGHT:DT_LEFT));
else
DrawText(hdc,pParent->m_Items[pParent->m_SearchIndex].name,-1,&rc,DT_SINGLELINE|DT_EDITCONTROL|(s_bRTL?DT_RIGHT:DT_LEFT));
SelectObject(hdc,font0);
}
return res;
@@ -1066,7 +1072,7 @@ void CMenuContainer::AddStandardItems( void )
const StdMenuItem *pInlineParent=NULL;
int searchProviderIndex=-1;
m_SearchProvidersCount=0;
MenuSkin::TIconSize mainIconSize=s_Skin.Main_icon_size;
bool bSecondColumn=false;
for (const StdMenuItem *pStdItem=m_pStdItem;;pStdItem++)
{
if (pStdItem->id==MENU_LAST)
@@ -1084,8 +1090,8 @@ void CMenuContainer::AddStandardItems( void )
if (m_bSubMenu && pStdItem->id==s_ShutdownCommand)
continue;
if (pStdItem->id==MENU_COLUMN_BREAK && m_bTwoColumns)
mainIconSize=s_Skin.Main2_icon_size;
if (pStdItem->id==MENU_COLUMN_BREAK && !m_bSubMenu && s_Skin.TwoColumns)
bSecondColumn=true;
int stdOptions=GetStdOptions(pStdItem->id);
if (!(stdOptions&MENU_ENABLED)) continue;
@@ -1266,6 +1272,10 @@ void CMenuContainer::AddStandardItems( void )
item.bSplit=item.bFolder && (item.pStdItem->settings&StdMenuItem::MENU_SPLIT_BUTTON)!=0;
// get icon
MenuSkin::TIconSize mainIconSize=!bSecondColumn ? s_Skin.Main_icon_size : s_Skin.Main2_icon_size;
if (item.bInline && mainIconSize==MenuSkin::ICON_SIZE_NONE)
mainIconSize=s_Skin.Main_icon_size;
CItemManager::TIconSizeType iconSizeType;
int refreshFlags;
if (bSearchProvider7 || m_bSubMenu)
@@ -1579,6 +1589,23 @@ static const wchar_t *g_MfuIgnoreExes[]={
L"WUAPP.EXE",
};
static bool IgnoreUserAssistItem(const UserAssistItem& uaItem)
{
static constexpr const wchar_t* ignoredNames[] =
{
DESKTOP_APP_ID,
L"Microsoft.Windows.ShellExperienceHost_cw5n1h2txyewy!App",
};
for (const auto& name : ignoredNames)
{
if (_wcsicmp(uaItem.name, name) == 0)
return true;
}
return false;
}
void CMenuContainer::GetRecentPrograms( std::vector<MenuItem> &items, int maxCount )
{
bool bShowMetro=GetSettingBool(L"RecentMetroApps");
@@ -1931,21 +1958,12 @@ void CMenuContainer::GetRecentPrograms( std::vector<MenuItem> &items, int maxCou
continue;
}
if (_wcsicmp(uaItem.name,DESKTOP_APP_ID)==0)
if (IgnoreUserAssistItem(uaItem))
{
LOG_MENU(LOG_MFU,L"UserAssist: Dropping: Ignore desktop");
LOG_MENU(LOG_MFU,L"UserAssist: Dropping: Ignore '%s'",uaItem.name);
continue;
}
{
CComPtr<IShellItem> pAppItem;
if (FAILED(SHCreateItemInKnownFolder(FOLDERID_AppsFolder2,0,uaItem.name,IID_IShellItem,(void**)&pAppItem)))
continue;
CComString pName;
if (FAILED(pAppItem->GetDisplayName(SIGDN_NORMALDISPLAY,&pName)) || wcsncmp(pName,L"@{",2)==0)
continue;
}
uaItem.pLinkInfo=g_ItemManager.GetMetroAppInfo10(uaItem.name);
if (!uaItem.pLinkInfo)
{
@@ -1956,6 +1974,11 @@ void CMenuContainer::GetRecentPrograms( std::vector<MenuItem> &items, int maxCou
LOG_MENU(LOG_MFU,L"UserAssist: '%s', %d, %.3f",uaItem.name,data.count,uaItem.rank);
{
CItemManager::RWLock lock(&g_ItemManager,false,CItemManager::RWLOCK_ITEMS);
if (uaItem.pLinkInfo->GetMetroName().IsEmpty() || wcsncmp(uaItem.pLinkInfo->GetMetroName(), L"@{",2)==0)
{
LOG_MENU(LOG_MFU, L"UserAssist: Dropping: No metro name");
continue;
}
if (uaItem.pLinkInfo->IsNoPin())
{
LOG_MENU(LOG_MFU,L"UserAssist: Dropping: No pin");
@@ -2207,10 +2230,7 @@ void CMenuContainer::AddJumpListItems( std::vector<MenuItem> &items )
if (pLink)
{
pLink->GetIDList(&item.pItem1);
wchar_t location[_MAX_PATH];
int index;
if (pLink->GetIconLocation(location,_countof(location),&index)==S_OK && location[0])
item.pItemInfo=g_ItemManager.GetCustomIcon(location,index,CItemManager::ICON_SIZE_TYPE_SMALL,(index==0)); // assuming that if index!=0 the icon comes from a permanent location like a dll or exe
item.pItemInfo = g_ItemManager.GetLinkIcon(pLink, CItemManager::ICON_SIZE_TYPE_SMALL);
}
}
else if (jumpItem.type==CJumpItem::TYPE_ITEM)
@@ -2244,7 +2264,7 @@ void CMenuContainer::AddJumpListItems( std::vector<MenuItem> &items )
{
ILFree(item.pItem1);
item.pItem1=pidl2.Detach();
pItem=pItem2;
pItem=std::move(pItem2);
}
}
}
@@ -2506,9 +2526,9 @@ void CMenuContainer::InitItems( void )
m_Items.resize(MAX_MENU_ITEMS);
}
if (m_Options&CONTAINER_CONTROLPANEL)
if (m_Options&CONTAINER_CONTROLPANEL && !(m_Options&CONTAINER_NOSUBFOLDERS))
{
// expand Administrative Tools. must be done after the sorting because we don't want the folder to jump to the top
// expand Administrative Tools when displaying as a menu. must be done after the sorting because we don't want the folder to jump to the top
unsigned int AdminToolsHash=CalcFNVHash(L"::{D20EA4E1-3957-11D2-A40B-0C5020524153}");
for (std::vector<MenuItem>::iterator it=m_Items.begin();it!=m_Items.end();++it)
if (it->nameHash==AdminToolsHash)
@@ -2656,17 +2676,11 @@ int CMenuContainer::AddSearchItems( const std::vector<SearchItem> &items, const
if (!categoryName.IsEmpty())
{
MenuItem item(MENU_SEARCH_CATEGORY);
if (categoryHash==CSearchManager::CATEGORY_PROGRAM || categoryHash==CSearchManager::CATEGORY_SETTING)
{
item.name.Format(L"%s (%d)",categoryName,originalCount);
}
else
{
item.name=categoryName;
item.bSplit=(s_Skin.More_bitmap_Size.cx>0);
}
item.name.Format(L"%s (%d)",categoryName,originalCount);
item.nameHash=CalcFNVHash(categoryName);
item.categoryHash=categoryHash;
if (categoryHash!=CSearchManager::CATEGORY_PROGRAM || categoryHash!=CSearchManager::CATEGORY_SETTING)
item.bSplit=(s_Skin.More_bitmap_Size.cx>0);
m_Items.push_back(item);
}
}
@@ -2724,7 +2738,7 @@ bool CMenuContainer::InitSearchItems( void )
unsigned int runCategoryHash=0;
CString runCommand;
CComString runExe;
if (!bAutoComlpete && !s_bNoRun && s_SearchResults.programs.empty() && s_SearchResults.settings.empty())
if (!bAutoComlpete && !s_bNoRun && s_SearchResults.programs.empty() && s_SearchResults.settings.empty() && s_SearchResults.metrosettings.empty())
{
if (s_bWin7Style)
m_SearchBox.GetWindowText(runCommand);
@@ -2753,9 +2767,9 @@ bool CMenuContainer::InitSearchItems( void )
{
sepHeight=s_Skin.ItemSettings[s_Skin.More_bitmap_Size.cx?MenuSkin::LIST_SEPARATOR_SPLIT:MenuSkin::LIST_SEPARATOR].itemHeight;
itemHeight=s_Skin.ItemSettings[MenuSkin::LIST_ITEM].itemHeight;
// total height minus the search box and the "more results"/"search internet"
// total height minus the search box and the "more results"/"search internet", if present
maxHeight=m_Items[m_SearchIndex].itemRect.top-s_Skin.Main_search_padding.top-s_Skin.Search_padding.top;
maxHeight-=itemHeight*(m_SearchItemCount-1);
maxHeight-=itemHeight*(m_SearchItemCount-(s_bMoreResults?1:2));
if (!s_SearchResults.bSearching && !HasMoreResults())
maxHeight+=itemHeight;
}
@@ -2781,6 +2795,12 @@ bool CMenuContainer::InitSearchItems( void )
if (m_SearchCategoryHash==CSearchManager::CATEGORY_PROGRAM)
selectedCount=(int)s_SearchResults.programs.size();
}
if (!s_SearchResults.metrosettings.empty())
{
counts.push_back((int)s_SearchResults.metrosettings.size());
if (m_SearchCategoryHash==CSearchManager::CATEGORY_METROSETTING)
selectedCount=(int)s_SearchResults.metrosettings.size();
}
if (!s_SearchResults.settings.empty())
{
counts.push_back((int)s_SearchResults.settings.size());
@@ -2829,13 +2849,15 @@ bool CMenuContainer::InitSearchItems( void )
// add categories
std::list<CSearchManager::SearchCategory>::const_iterator it=s_SearchResults.indexed.begin();
for (size_t idx=0;idx<s_SearchResults.indexed.size()+2;idx++)
for (size_t idx=0;idx<s_SearchResults.indexed.size()+3;idx++)
{
items.clear();
unsigned int categoryHash;
if (idx==0)
categoryHash=CSearchManager::CATEGORY_PROGRAM;
else if (idx==1)
categoryHash=CSearchManager::CATEGORY_METROSETTING;
else if (idx==2)
categoryHash=CSearchManager::CATEGORY_SETTING;
else
categoryHash=it->categoryHash;
@@ -2854,7 +2876,7 @@ bool CMenuContainer::InitSearchItems( void )
}
if (count<=0)
{
if (idx>=2) ++it;
if (idx>=3) ++it;
continue;
}
@@ -2871,6 +2893,16 @@ bool CMenuContainer::InitSearchItems( void )
name=FindTranslation(L"Search.CategoryPrograms",L"Programs");
}
else if (idx==1)
{
originalCount=(int)s_SearchResults.metrosettings.size();
if (count>originalCount)
count=originalCount;
items.reserve(count);
for (std::vector<const CItemManager::ItemInfo*>::const_iterator it=s_SearchResults.metrosettings.begin();it!=s_SearchResults.metrosettings.end() && (int)items.size()<count;++it)
items.push_back(SearchItem(*it));
name=FindTranslation(L"Search.CategoryPCSettings", L"Settings");
}
else if (idx==2)
{
originalCount=(int)s_SearchResults.settings.size();
if (count>originalCount)
@@ -2878,7 +2910,7 @@ bool CMenuContainer::InitSearchItems( void )
items.reserve(count);
for (std::vector<const CItemManager::ItemInfo*>::const_iterator it=s_SearchResults.settings.begin();it!=s_SearchResults.settings.end() && (int)items.size()<count;++it)
items.push_back(SearchItem(*it));
name=FindTranslation(L"Search.CategorySettings",L"Settings");
name=FindTranslation(L"Search.CategorySettings",L"Control Panel");
}
else
{
@@ -2931,25 +2963,28 @@ bool CMenuContainer::InitSearchItems( void )
if (s_bWin7Style)
{
UpdateAccelerators(m_OriginalCount,(int)m_Items.size());
MenuItem &item=m_Items[m_SearchIndex-m_SearchItemCount+1];
if (s_SearchResults.bSearching)
if (s_bMoreResults)
{
item.id=MENU_SEARCH_EMPTY;
item.name=FindTranslation(L"Menu.Searching",L"Searching...");
item.pItemInfo=g_ItemManager.GetCustomIcon(L"imageres.dll,8",CItemManager::ICON_SIZE_TYPE_SMALL);
}
else
{
item.id=MENU_MORE_RESULTS;
item.name=FindTranslation(L"Menu.MoreResults",L"See more results");
item.pItemInfo=g_ItemManager.GetCustomIcon(L"imageres.dll,177",CItemManager::ICON_SIZE_TYPE_SMALL);
MenuItem &item=m_Items[m_SearchIndex-m_SearchItemCount+1];
if (s_SearchResults.bSearching)
{
item.id=MENU_SEARCH_EMPTY;
item.name=FindTranslation(L"Menu.Searching",L"Searching...");
item.pItemInfo=g_ItemManager.GetCustomIcon(L"imageres.dll,8",CItemManager::ICON_SIZE_TYPE_SMALL);
}
else
{
item.id=MENU_MORE_RESULTS;
item.name=FindTranslation(L"Menu.MoreResults",L"See more results");
item.pItemInfo=g_ItemManager.GetCustomIcon(L"imageres.dll,177",CItemManager::ICON_SIZE_TYPE_SMALL);
}
}
}
else
{
m_ScrollCount=(int)m_Items.size();
bool bInternet=GetSettingBool(L"SearchInternet");
if (s_SearchResults.bSearching)
bool bInternet=GetSettingBool(L"SearchInternet");
if (s_bMoreResults && s_SearchResults.bSearching)
{
MenuItem item(MENU_SEARCH_EMPTY);
item.name=FindTranslation(L"Menu.Searching",L"Searching...");
@@ -2964,7 +2999,7 @@ bool CMenuContainer::InitSearchItems( void )
item.name=FindTranslation(L"Menu.NoMatch",L"No items match your search.");
m_Items.push_back(item);
}
if (HasMoreResults())
if (s_bMoreResults && HasMoreResults())
{
{
MenuItem item(MENU_SEPARATOR);
@@ -5052,7 +5087,7 @@ void CMenuContainer::UpdateSearchResults( bool bForceShowAll )
g_SearchManager.BeginSearch(s_SearchResults.currentString);
s_SearchResults.bSearching=true;
s_bPendingSearchEnter=false;
if (s_bWin7Style)
if (s_bWin7Style && s_bMoreResults)
{
MenuItem &item=m_Items[m_SearchIndex-m_SearchItemCount+1];
item.id=MENU_SEARCH_EMPTY;
@@ -6660,8 +6695,7 @@ bool CMenuContainer::GetDescription( int index, wchar_t *text, int size )
{
if (SUCCEEDED(pLink->GetDescription(text,size)) && text[0])
return true;
wchar_t args[256];
if (SUCCEEDED(pLink->GetArguments(args,_countof(args))) && args[0])
if (jumpItem.bHasArguments)
{
// don't use default tip for items with arguments
Strcpy(text,size,item.name);
@@ -6794,7 +6828,7 @@ LRESULT CMenuContainer::OnLButtonDblClick( UINT uMsg, WPARAM wParam, LPARAM lPar
ClientToScreen(&pt);
if (s_bWin7Style && item.id==MENU_PROGRAMS) // only single clicks for All Programs
OnLButtonDown(WM_LBUTTONDOWN,wParam,lParam,bHandled);
else if (!bArrow) // ignore double-click on the split arrow
else if (!bArrow && item.id!=MENU_APPS) // ignore double-click on the split arrow and Apps folder
ActivateItem(index,ACTIVATE_EXECUTE,&pt);
return 0;
}
@@ -6818,7 +6852,7 @@ LRESULT CMenuContainer::OnLButtonUp( UINT uMsg, WPARAM wParam, LPARAM lParam, BO
const MenuItem &item=m_Items[index];
POINT pt2=pt;
ClientToScreen(&pt2);
if (!item.bFolder)
if (!item.bFolder || (s_bSingleClickFolders && item.id!=MENU_PROGRAMS && item.id!=MENU_APPS && !bArrow)) // never open All Programs, Apps folder, or jumplists with single click
{
if (item.jumpIndex>=0 && m_bHotArrow)
{
@@ -7319,8 +7353,9 @@ static void NewVersionCallback( VersionData &data )
wchar_t cmdLine[1024];
Sprintf(cmdLine,_countof(cmdLine),L"\"%s\" -popup",path);
STARTUPINFO startupInfo={sizeof(startupInfo)};
PROCESS_INFORMATION processInfo;
memset(&processInfo,0,sizeof(processInfo));
// don't display busy cursor as we are doing this on background
startupInfo.dwFlags=STARTF_FORCEOFFFEEDBACK;
PROCESS_INFORMATION processInfo{};
if (CreateProcess(path,cmdLine,NULL,NULL,TRUE,0,NULL,NULL,&startupInfo,&processInfo))
{
CloseHandle(processInfo.hThread);
@@ -7396,35 +7431,46 @@ bool CMenuContainer::HasMoreResults( void )
RECT CMenuContainer::CalculateWorkArea( const RECT &taskbarRect )
{
RECT rc=s_MenuLimits;
if ((s_TaskBarEdge==ABE_LEFT || s_TaskBarEdge==ABE_RIGHT) && GetSettingBool(L"ShowNextToTaskbar"))
RECT rc;
if (!GetSettingBool(L"AlignToWorkArea"))
{
// when the taskbar is on the side and the menu is not on top of it
// the start button is assumed at the top
if (s_TaskBarEdge==ABE_LEFT)
rc.left=taskbarRect.right;
rc = s_MenuLimits;
if ((s_TaskBarEdge == ABE_LEFT || s_TaskBarEdge == ABE_RIGHT) && GetSettingBool(L"ShowNextToTaskbar"))
{
// when the taskbar is on the side and the menu is not on top of it
// the start button is assumed at the top
if (s_TaskBarEdge == ABE_LEFT)
rc.left = taskbarRect.right;
else
rc.right = taskbarRect.left;
}
else
rc.right=taskbarRect.left;
{
if (s_TaskBarEdge == ABE_BOTTOM)
{
// taskbar is at the bottom
rc.bottom = taskbarRect.top;
}
else if (s_TaskBarEdge == ABE_TOP)
{
// taskbar is at the top
rc.top = taskbarRect.bottom;
}
else
{
// taskbar is on the side, start button must be at the top
rc.top = s_StartRect.bottom;
}
}
}
else
{
if (s_TaskBarEdge==ABE_BOTTOM)
{
// taskbar is at the bottom
rc.bottom=taskbarRect.top;
}
else if (s_TaskBarEdge==ABE_TOP)
{
// taskbar is at the top
rc.top=taskbarRect.bottom;
}
else
{
// taskbar is on the side, start button must be at the top
rc.top=s_StartRect.bottom;
}
// Get working area of the monitor the specified taskbar is on
MONITORINFO info{ sizeof(MONITORINFO) };
HMONITOR mon = MonitorFromRect(&taskbarRect, 0);
GetMonitorInfo(mon, &info);
rc = info.rcWork;
}
if (!s_bLockWorkArea)
{
// exclude floating keyboard
@@ -7450,9 +7496,36 @@ RECT CMenuContainer::CalculateWorkArea( const RECT &taskbarRect )
}
}
}
//calculate offsets
int xOff = GetSettingInt(L"HorizontalMenuOffset");
int yOff = GetSettingInt(L"VerticalMenuOffset");
if (s_TaskBarEdge == ABE_BOTTOM)
{
if (xOff != 0)
rc.left += xOff;
if (yOff != 0)
rc.bottom += yOff;
}
else if (s_TaskBarEdge == ABE_TOP || s_TaskBarEdge == ABE_LEFT)
{
if (xOff != 0)
rc.left += xOff;
if (yOff != 0)
rc.top += yOff;
}
else
{
if (xOff != 0)
rc.right += xOff;
if (yOff != 0)
rc.top += yOff;
}
return rc;
}
// Calculates start menu position
POINT CMenuContainer::CalculateCorner( void )
{
RECT margin={0,0,0,0};
@@ -7460,10 +7533,24 @@ POINT CMenuContainer::CalculateCorner( void )
AdjustWindowRect(&margin,GetWindowLong(GWL_STYLE),FALSE);
POINT corner;
if (m_Options&CONTAINER_LEFT)
corner.x=s_MainMenuLimits.left+margin.left;
if (IsWin11())
{
// start button can be in the center on Win11
// we want to show menu at the position of start button
if (m_Options&CONTAINER_LEFT)
corner.x=s_StartRect.left+margin.left;
else
corner.x=s_StartRect.right+margin.right;
}
else
corner.x=s_MainMenuLimits.right+margin.right;
{
// start button can be only in corner on older systems
// we can use screen limits to determine menu position
if (m_Options&CONTAINER_LEFT)
corner.x=s_MainMenuLimits.left+margin.left;
else
corner.x=s_MainMenuLimits.right+margin.right;
}
if (m_Options&CONTAINER_TOP)
{
@@ -7582,6 +7669,9 @@ HWND CMenuContainer::ToggleStartMenu( int taskbarId, bool bKeyboard, bool bAllPr
// initialize all settings
bool bErr=false;
HMONITOR initialMonitor=MonitorFromWindow(s_TaskBar,MONITOR_DEFAULTTONEAREST);
// note: GetTaskbarPosition properly identifies monitor in case of multi-monitor setup and automatic taskbar hiding
GetTaskbarPosition(s_TaskBar,NULL,&initialMonitor,NULL);
int dpi=CItemManager::GetDPI(true);
if (!CItemManager::GetDPIOverride() && GetWinVersion()>=WIN_VER_WIN81)
{
@@ -7629,6 +7719,7 @@ HWND CMenuContainer::ToggleStartMenu( int taskbarId, bool bKeyboard, bool bAllPr
g_ItemManager.ResetTempIcons();
s_ScrollMenus=GetSettingInt(L"ScrollType");
s_bExpandLinks=GetSettingBool(L"ExpandFolderLinks");
s_bSingleClickFolders=GetSettingBool(L"SingleClickFolders");
s_bLogicalSort=GetSettingBool(L"NumericSort");
s_MaxRecentDocuments=GetSettingInt(L"MaxRecentDocuments");
s_ShellFormat=RegisterClipboardFormat(CFSTR_SHELLIDLIST);
@@ -7646,6 +7737,7 @@ HWND CMenuContainer::ToggleStartMenu( int taskbarId, bool bKeyboard, bool bAllPr
s_bDisableHover=false;
s_bDragClosed=false;
s_bPendingSearchEnter=false;
s_bMoreResults=GetSettingBool(L"MoreResults");
InitTouchHelper();
bool bRemote=GetSystemMetrics(SM_REMOTESESSION)!=0;
@@ -8014,7 +8106,8 @@ HWND CMenuContainer::ToggleStartMenu( int taskbarId, bool bKeyboard, bool bAllPr
}
else
{
wchar_t path[_MAX_PATH]=START_MENU_PINNED_ROOT;
wchar_t path[_MAX_PATH];
Strcpy(path,_countof(path),GetSettingString(L"PinnedItemsPath"));
DoEnvironmentSubst(path,_countof(path));
SHCreateDirectory(NULL,path);
s_PinFolder=path;
@@ -8026,7 +8119,8 @@ HWND CMenuContainer::ToggleStartMenu( int taskbarId, bool bKeyboard, bool bAllPr
{
bool bPinned=GetSettingInt(L"PinnedPrograms")==PINNED_PROGRAMS_PINNED;
bool bShortcut=GetSettingBool(L"StartScreenShortcut");
wchar_t path[_MAX_PATH]=START_MENU_PINNED_ROOT L"\\" STARTSCREEN_COMMAND;
wchar_t path[_MAX_PATH];
Sprintf(path,_countof(path),L"%s\\%s",GetSettingString(L"PinnedItemsPath"),STARTSCREEN_COMMAND);
DoEnvironmentSubst(path,_countof(path));
if (bPinned)
{

View File

@@ -876,6 +876,7 @@ private:
static bool s_bNoDragDrop; // disables drag/drop
static bool s_bNoContextMenu; // disables the context menu
static bool s_bExpandLinks; // expand links to folders
static bool s_bSingleClickFolders; // open links to folders with one click instead of two
static bool s_bLogicalSort; // use StrCmpLogical instead of CompareString
static bool s_bExtensionSort; // sort file names by extension
static bool s_bAllPrograms; // this is the All Programs menu of the Windows start menu
@@ -895,6 +896,7 @@ private:
static bool s_bRightDrag; // dragging with the right mouse button
static bool s_bLockWorkArea; // changes to the work area are ignored
static bool s_bPendingSearchEnter; // Enter was pressed before the search results were ready
static bool s_bMoreResults; // shows the "Show More Results" item at the bottom of searches
static RECT s_MenuLimits; // area of the main monitor accessible to all menus
static RECT s_MainMenuLimits; // area of the main monitor accessible by the main menu
static DWORD s_TaskbarState; // the state of the taskbar (ABS_AUTOHIDE and ABS_ALWAYSONTOP)

View File

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

View File

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

View File

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

View File

@@ -60,9 +60,9 @@ void CProgramsTree::Create( CMenuContainer *pOwner )
HWND hWnd=CreateWindowEx(0,WC_TREEVIEW,NULL,WS_CHILD|TVS_EDITLABELS|TVS_FULLROWSELECT|(CMenuContainer::s_TipHideTime?TVS_INFOTIP:0)|TVS_NOHSCROLL|TVS_SHOWSELALWAYS|TVS_NONEVENHEIGHT,0,0,0,0,pOwner->m_hWnd,NULL,g_Instance,NULL);
TreeView_SetExtendedStyle(hWnd,TVS_EX_AUTOHSCROLL,TVS_EX_AUTOHSCROLL);
const MenuSkin &skin=CMenuContainer::s_Skin;
m_TreeTheme=OpenThemeData(m_hWnd,L"treeview");
m_TreeTheme=OpenThemeData(hWnd,L"treeview");
if (skin.BHasScrollbar)
m_ScrollTheme=OpenThemeData(m_hWnd,L"scrollbar");
m_ScrollTheme=OpenThemeData(hWnd,L"scrollbar");
const MenuSkin::ItemDrawSettings &settings=skin.ItemSettings[MenuSkin::PROGRAMS_TREE_ITEM];

View File

@@ -139,18 +139,25 @@ void CSearchManager::CloseMenu( void )
Lock lock(this,LOCK_DATA);
m_LastRequestId++;
m_LastProgramsRequestId=m_LastRequestId;
if (g_LogCategories&LOG_SEARCH)
if (g_LogCategories & LOG_SEARCH)
{
for (std::vector<SearchItem>::const_iterator it=m_ProgramItems.begin();it!=m_ProgramItems.end();++it)
for (const auto& item : m_ProgramItems)
{
if (it->category==CATEGORY_PROGRAM)
LOG_MENU(LOG_SEARCH,L"Program: '%s', %d",it->name,it->rank);
if (item.category == CATEGORY_PROGRAM)
LOG_MENU(LOG_SEARCH, L"Program: '%s', %d", item.name, item.rank);
}
std::sort(m_SettingsItems.begin(),m_SettingsItems.end());
for (std::vector<SearchItem>::const_iterator it=m_SettingsItems.begin();it!=m_SettingsItems.end();++it)
std::sort(m_SettingsItems.begin(), m_SettingsItems.end());
for (const auto& item : m_SettingsItems)
{
if (it->category==CATEGORY_SETTING)
LOG_MENU(LOG_SEARCH,L"Setting: '%s', %d",it->name,it->rank);
if (item.category == CATEGORY_SETTING)
LOG_MENU(LOG_SEARCH, L"Setting: '%s', %d", item.name, item.rank);
}
for (const auto& item : m_SettingsItems)
{
if (item.category == CATEGORY_METROSETTING)
LOG_MENU(LOG_SEARCH, L"MetroSetting: '%s', %d", item.name, item.rank);
}
}
if (m_bProgramsFound)
@@ -170,6 +177,7 @@ void CSearchManager::CloseMenu( void )
m_SettingsItems.clear();
m_SettingsHash=FNV_HASH0;
m_bSettingsFound=false;
m_bMetroSettingsFound = false;
m_IndexedItems.clear();
m_AutoCompleteItems.clear();
@@ -310,7 +318,9 @@ bool CSearchManager::AddSearchItem( IShellItem *pItem, const wchar_t *name, int
PROPVARIANT val;
PropVariantInit(&val);
pItem2->GetProperty(PKEY_Keywords,&val);
wchar_t keywords[1024];
if (val.vt==VT_EMPTY)
pItem2->GetProperty(PKEY_HighKeywords,&val);
wchar_t keywords[2048];
int len=0;
if (val.vt==VT_BSTR || val.vt==VT_LPWSTR)
{
@@ -334,7 +344,7 @@ bool CSearchManager::AddSearchItem( IShellItem *pItem, const wchar_t *name, int
}
Lock lock(this,LOCK_DATA);
if (category==CATEGORY_PROGRAM || category==CATEGORY_SETTING)
if (category==CATEGORY_PROGRAM || category==CATEGORY_SETTING || category==CATEGORY_METROSETTING)
{
if (searchRequest.requestId<m_LastProgramsRequestId)
return false;
@@ -345,10 +355,10 @@ bool CSearchManager::AddSearchItem( IShellItem *pItem, const wchar_t *name, int
return false;
}
bool res=true;
if (category==CATEGORY_PROGRAM || category==CATEGORY_SETTING)
if (category==CATEGORY_PROGRAM || category==CATEGORY_SETTING || category==CATEGORY_METROSETTING)
{
std::vector<SearchItem> &items=(category==CATEGORY_PROGRAM)?m_ProgramItems:m_SettingsItems;
if (category==CATEGORY_SETTING)
if (category==CATEGORY_SETTING || category==CATEGORY_METROSETTING)
{
// remove duplicate settings
for (std::vector<SearchItem>::const_iterator it=items.begin();it!=items.end();++it)
@@ -381,6 +391,8 @@ bool CSearchManager::AddSearchItem( IShellItem *pItem, const wchar_t *name, int
}
items.push_back(item);
if (item.category==CATEGORY_METROSETTING)
m_bMetroSettingsFound=true;
}
else if (category==CATEGORY_AUTOCOMPLETE)
{
@@ -409,7 +421,7 @@ void CSearchManager::CollectSearchItems( IShellItem *pFolder, int flags, TItemCa
CComPtr<IShellItem> pChild;
while (pChild=NULL,pEnum->Next(1,&pChild,NULL)==S_OK)
{
if (category==CATEGORY_PROGRAM || category==CATEGORY_SETTING)
if (category==CATEGORY_PROGRAM || category==CATEGORY_SETTING || category==CATEGORY_METROSETTING)
{
if (searchRequest.requestId<m_LastProgramsRequestId)
break;
@@ -428,7 +440,7 @@ void CSearchManager::CollectSearchItems( IShellItem *pFolder, int flags, TItemCa
{
// go into subfolders but not archives or links to folders
CollectSearchItems(pChild,flags,category,searchRequest);
if (category==CATEGORY_PROGRAM || category==CATEGORY_SETTING)
if (category==CATEGORY_PROGRAM || category==CATEGORY_SETTING || category==CATEGORY_METROSETTING)
{
if (searchRequest.requestId<m_LastProgramsRequestId)
break;
@@ -514,7 +526,7 @@ bool CSearchManager::SearchScope::ParseSearchConnector( const wchar_t *fname )
CComPtr<IXMLDOMNode> pNext;
if (pScopeItem->get_nextSibling(&pNext)!=S_OK)
break;
pScopeItem=pNext;
pScopeItem=std::move(pNext);
}
return true;
}
@@ -627,7 +639,8 @@ void CSearchManager::SearchThread( void )
// pinned folder
if (searchRequest.bPinnedFolder)
{
wchar_t path[_MAX_PATH]=START_MENU_PINNED_ROOT;
wchar_t path[_MAX_PATH];
Strcpy(path,_countof(path),GetSettingString(L"PinnedItemsPath"));
DoEnvironmentSubst(path,_MAX_PATH);
CComPtr<IShellItem> pFolder;
if (SUCCEEDED(SHCreateItemFromParsingName(path,NULL,IID_IShellItem,(void**)&pFolder)))
@@ -670,7 +683,7 @@ void CSearchManager::SearchThread( void )
if (GetWinVersion()>=WIN_VER_WIN8 && searchRequest.bSearchMetroApps)
{
std::vector<MetroLink> links;
GetMetroLinks(links,false);
GetMetroLinks(links,true);
for (std::vector<MetroLink>::const_iterator it=links.begin();it!=links.end();++it)
{
if (GetWinVersion()<WIN_VER_WIN10)
@@ -733,6 +746,14 @@ void CSearchManager::SearchThread( void )
if (searchRequest.requestId<m_LastProgramsRequestId)
continue;
}
if (searchRequest.bSearchMetroSettings)
{
CComPtr<IShellItem> pFolder;
if (SUCCEEDED(SHCreateItemFromParsingName(L"shell:::{82E749ED-B971-4550-BAF7-06AA2BF7E836}",NULL,IID_IShellItem,(void**)&pFolder)))
CollectSearchItems(pFolder,(searchRequest.bSearchKeywords?COLLECT_KEYWORDS:0)|COLLECT_NOREFRESH,CATEGORY_METROSETTING,searchRequest);
if (searchRequest.requestId<m_LastProgramsRequestId)
continue;
}
}
bool bRefresh=false;
{
@@ -778,9 +799,9 @@ void CSearchManager::SearchThread( void )
CSession session;
if (SUCCEEDED(dataSource.OpenFromInitializationString(L"provider=Search.CollatorDSO.1;EXTENDED PROPERTIES=\"Application=Windows\"")) && SUCCEEDED(session.Open(dataSource)))
{
std::list<SearchScope> scopeList;
std::vector<SearchScope> scopeList;
if (searchRequest.bSearchMetroSettings)
if (searchRequest.bSearchMetroSettings && !m_bMetroSettingsFound)
{
scopeList.push_back(SearchScope());
SearchScope &scope=*scopeList.rbegin();
@@ -1084,7 +1105,7 @@ void CSearchManager::SearchThread( void )
command0.Close();
continue;
}
for (std::list<SearchScope>::iterator it=scopeList.begin();it!=scopeList.end();++it)
for (auto it=scopeList.begin();it!=scopeList.end();++it)
{
if (it->roots.empty())
continue;
@@ -1102,7 +1123,7 @@ void CSearchManager::SearchThread( void )
else
{
len+=Strcpy(query+len,_countof(query)-len,L" AND System.Search.Store='FILE' AND System.ItemType!='.settingcontent-ms'");
for (std::list<SearchScope>::iterator it2=scopeList.begin();it2!=it;++it2)
for (auto it2=scopeList.begin();it2!=it;++it2)
{
if (it2->categoryHash==CATEGORY_METROSETTING)
continue;
@@ -1240,7 +1261,7 @@ void CSearchManager::SearchThread( void )
Lock lock(this,LOCK_DATA);
m_IndexedItems.push_back(SearchCategory());
pCategory=&*m_IndexedItems.rbegin();
pCategory->name.Format(L"%s (%d)",it->name,it->resultCount);
pCategory->name=it->name;
pCategory->categoryHash=it->categoryHash;
pCategory->search.Clone(it->search);
}
@@ -1348,6 +1369,7 @@ void CSearchManager::GetSearchResults( SearchResults &results )
{
results.programs.clear();
results.settings.clear();
results.metrosettings.clear();
results.indexed.clear();
results.autocomplete.clear();
results.autoCompletePath.Empty();
@@ -1397,14 +1419,19 @@ void CSearchManager::GetSearchResults( SearchResults &results )
std::vector<SearchItem> &settings=m_bSettingsFound?m_SettingsItems:m_SettingsItemsOld;
for (std::vector<SearchItem>::iterator it=settings.begin();it!=settings.end();++it)
{
int match=(it->category==CATEGORY_SETTING)?it->MatchText(m_SearchText,bSearchSubWord):0;
int match=(it->category==CATEGORY_SETTING || it->category==CATEGORY_METROSETTING)?it->MatchText(m_SearchText,bSearchSubWord):0;
it->rank=(it->rank&0xFFFFFFFE)|(match>>1);
}
std::sort(settings.begin(),settings.end());
for (std::vector<SearchItem>::const_iterator it=settings.begin();it!=settings.end();++it)
{
if (it->category==CATEGORY_SETTING && it->MatchText(m_SearchText,bSearchSubWord))
results.settings.push_back(it->pInfo);
if (it->MatchText(m_SearchText, bSearchSubWord))
{
if (it->category==CATEGORY_SETTING)
results.settings.push_back(it->pInfo);
if (it->category==CATEGORY_METROSETTING)
results.metrosettings.push_back(it->pInfo);
}
}
}
@@ -1423,7 +1450,7 @@ void CSearchManager::GetSearchResults( SearchResults &results )
results.autocomplete.push_back(it->pInfo);
}
}
results.bResults=(!results.programs.empty() || !results.settings.empty() || !results.indexed.empty() || !results.autocomplete.empty());
results.bResults=(!results.programs.empty() || !results.settings.empty() || !results.metrosettings.empty() || !results.indexed.empty() || !results.autocomplete.empty());
results.bSearching=(m_LastCompletedId!=m_LastRequestId);
}

View File

@@ -36,7 +36,7 @@ public:
struct SearchCategory
{
SearchCategory( void ) {}
SearchCategory( void ) = default;
SearchCategory( const SearchCategory &cat )
{
search.Clone(cat.search);
@@ -63,6 +63,7 @@ public:
CString autoCompletePath;
std::vector<const CItemManager::ItemInfo*> programs;
std::vector<const CItemManager::ItemInfo*> settings;
std::vector<const CItemManager::ItemInfo*> metrosettings;
std::vector<const CItemManager::ItemInfo*> autocomplete;
std::list<SearchCategory> indexed;
};
@@ -149,6 +150,7 @@ private:
unsigned int m_SettingsHashOld;
bool m_bProgramsFound;
bool m_bSettingsFound;
bool m_bMetroSettingsFound = false;
std::vector<SearchItem> m_AutoCompleteItems;
std::list<SearchCategory> m_IndexedItems;
std::vector<ItemRank> m_ItemRanks;

View File

@@ -30,6 +30,19 @@ const int DEFAULT_TASK_OPACITY10=85; // 85%
///////////////////////////////////////////////////////////////////////////////
CString RgbToBgr(const wchar_t* str)
{
CString retval;
retval.Format(L"%06X", RgbToBgr(ParseColor(str)));
return retval;
}
CString BgrToRgb(const wchar_t* str)
{
return RgbToBgr(str);
}
class CSkinSettingsDlg: public CResizeableDlg<CSkinSettingsDlg>
{
public:
@@ -422,7 +435,7 @@ void CSkinSettingsDlg::UpdateSkinSettings( void )
if (!option.bEnabled || bLocked)
image|=SETTING_STATE_DISABLED;
if (option.bValue && option.type>SKIN_OPTION_BOOL)
Sprintf(text,_countof(text),L"%s: %s",option.label,option.sValue);
Sprintf(text,_countof(text),L"%s: %s",option.label,(option.type==SKIN_OPTION_COLOR)?BgrToRgb(option.sValue):option.sValue);
else
Sprintf(text,_countof(text),L"%s",option.label);
@@ -482,9 +495,7 @@ LRESULT CSkinSettingsDlg::OnCustomDraw( int idCtrl, LPNMHDR pnmh, BOOL& bHandled
if (TreeView_GetItemRect(m_Tree,(HTREEITEM)pDraw->nmcd.dwItemSpec,&rc,TRUE))
{
const wchar_t *str=m_CurrentSkin.Options[pDraw->nmcd.lItemlParam].sValue;
wchar_t *end;
COLORREF color=wcstoul(str,&end,16);
SetDCBrushColor(pDraw->nmcd.hdc,color&0xFFFFFF);
SetDCBrushColor(pDraw->nmcd.hdc,ParseColor(str));
SelectObject(pDraw->nmcd.hdc,GetStockObject(DC_BRUSH));
SelectObject(pDraw->nmcd.hdc,GetStockObject(BLACK_PEN));
Rectangle(pDraw->nmcd.hdc,rc.right,rc.top,rc.right+rc.bottom-rc.top,rc.bottom-1);
@@ -690,15 +701,14 @@ LRESULT CSkinSettingsDlg::OnBrowse( WORD wNotifyCode, WORD wID, HWND hWndCtl, BO
CString str;
m_EditBox.GetWindowText(str);
str.TrimLeft(); str.TrimRight();
wchar_t *end;
COLORREF val=wcstol(str,&end,16)&0xFFFFFF;
COLORREF val=RgbToBgr(ParseColor(str));
static COLORREF customColors[16];
CHOOSECOLOR choose={sizeof(choose),m_hWnd,NULL,val,customColors};
choose.Flags=CC_ANYCOLOR|CC_FULLOPEN|CC_RGBINIT;
if (ChooseColor(&choose))
{
wchar_t text[100];
Sprintf(text,_countof(text),L"%06X",choose.rgbResult);
Sprintf(text,_countof(text),L"%06X",BgrToRgb(choose.rgbResult));
m_EditBox.SetWindowText(text);
ApplyEditBox();
m_Tree.Invalidate();
@@ -717,7 +727,11 @@ void CSkinSettingsDlg::ApplyEditBox( void )
CString str;
m_EditBox.GetWindowText(str);
str.TrimLeft(); str.TrimRight();
m_CurrentSkin.Options[m_EditItemIndex].sValue=str;
auto& option=m_CurrentSkin.Options[m_EditItemIndex];
if (option.type==SKIN_OPTION_COLOR)
option.sValue=RgbToBgr(str);
else
option.sValue=str;
StoreSkinOptions();
}
}
@@ -730,7 +744,7 @@ void CSkinSettingsDlg::ItemSelected( HTREEITEM hItem, int index, bool bEnabled )
const MenuSkin::Option &option=m_CurrentSkin.Options[m_EditItemIndex];
wchar_t text[256];
if (option.bValue && option.type>SKIN_OPTION_BOOL)
Sprintf(text,_countof(text),L"%s: %s",option.label,option.sValue);
Sprintf(text,_countof(text),L"%s: %s",option.label,(option.type==SKIN_OPTION_COLOR)?BgrToRgb(option.sValue):option.sValue);
else
Sprintf(text,_countof(text),L"%s",option.label);
TVITEM item={TVIF_TEXT,m_EditItem,0,0,text};
@@ -745,7 +759,10 @@ void CSkinSettingsDlg::ItemSelected( HTREEITEM hItem, int index, bool bEnabled )
const MenuSkin::Option &option=m_CurrentSkin.Options[index];
if (option.type>SKIN_OPTION_BOOL)
mode=option.type;
text=option.sValue;
if (option.type==SKIN_OPTION_COLOR)
text=BgrToRgb(option.sValue);
else
text=option.sValue;
}
RECT rc;
@@ -1001,7 +1018,7 @@ static const CStdCommand g_StdCommands[]={
{L"settings",IDS_SETTINGS_ITEM,IDS_SETTINGS_MENU_TIP,L"SettingsMenu",L"$Menu.Settings",L"",L"shell32.dll,330"},
{L"search",IDS_SEARCH_MENU_ITEM,IDS_SEARCH_TIP,L"SearchMenu",L"$Menu.Search",L"",L"shell32.dll,323"},
{L"search_box",IDS_SEARCH_BOX_ITEM,IDS_SEARCH_BOX_TIP,L"SearchBoxItem",L"$Menu.SearchBox",NULL,L"none",NULL,StdMenuItem::MENU_TRACK|StdMenuItem::MENU_OPENUP},
{L"help",IDS_HELP_ITEM,IDS_HELP_TIP,L"HelpItem",L"$Menu.Help",L"$Menu.HelpTip",L"shell32.dll,324"},
{L"help",IDS_HELP_ITEM,IDS_HELP_TIP,L"HelpItem",L"$Menu.Help",L"$Menu.HelpTip",L"imageres.dll,99"},
{L"run",IDS_RUN_ITEM,IDS_RUN_TIP,L"RunItem",L"$Menu.Run",L"$Menu.RunTip",L"shell32.dll,328"},
{L"logoff",IDS_SHUTDOWN_LOGOFF,IDS_LOGOFF_TIP,L"LogOffItem",L"$Menu.Logoff",L"$Menu.LogOffTip",L"shell32.dll,325",NULL,StdMenuItem::MENU_STYLE_CLASSIC1},
{L"logoff",IDS_SHUTDOWN_LOGOFF,IDS_LOGOFF_TIP,L"LogOffItem",L"$Menu.Logoff",L"$Menu.LogOffTip",L"none",NULL,StdMenuItem::MENU_STYLE_CLASSIC2},
@@ -1057,7 +1074,7 @@ L"RecentDocumentsItem.Label=$Menu.Documents\n"
L"RecentDocumentsItem.Icon=shell32.dll,327\n"
L"RecentDocumentsItem.Settings=ITEMS_FIRST\n"
L"SettingsMenu.Command=settings\n"
L"SettingsMenu.Items=ControlPanelItem, PCSettingsItem, SEPARATOR, SecurityItem, NetworkItem, PrintersItem, TaskbarSettingsItem, ProgramsFeaturesItem, SEPARATOR, MenuSettingsItem\n"
L"SettingsMenu.Items=PCSettingsItem, ControlPanelItem, SEPARATOR, SecurityItem, NetworkItem, PrintersItem, TaskbarSettingsItem, ProgramsFeaturesItem, SEPARATOR, MenuSettingsItem\n"
L"SettingsMenu.Label=$Menu.Settings\n"
L"SettingsMenu.Icon=shell32.dll,330\n"
L"SearchMenu.Command=search\n"
@@ -1068,7 +1085,7 @@ L"ComputerItem.Command=computer\n"
L"HelpItem.Command=help\n"
L"HelpItem.Label=$Menu.Help\n"
L"HelpItem.Tip=$Menu.HelpTip\n"
L"HelpItem.Icon=shell32.dll,324\n"
L"HelpItem.Icon=imageres.dll,99\n"
L"RunItem.Command=run\n"
L"RunItem.Label=$Menu.Run\n"
L"RunItem.Tip=$Menu.RunTip\n"
@@ -1183,7 +1200,7 @@ L"ShutdownItem.Icon=none\n"
;
const wchar_t *g_DefaultStartMenu2=
L"Items=COLUMN_PADDING, ProgramsMenu, AppsMenu, SearchBoxItem, COLUMN_BREAK, FavoritesItem, UserFilesItem, UserDocumentsItem, UserPicturesItem, ComputerItem, RecentDocumentsItem, SEPARATOR, ControlPanelItem, PCSettingsItem, SecurityItem, NetworkItem, PrintersItem, SEPARATOR, SearchMenu, HelpItem, RunItem, COLUMN_PADDING, SEPARATOR, ShutdownBoxItem\n"
L"Items=COLUMN_PADDING, ProgramsMenu, AppsMenu, SearchBoxItem, COLUMN_BREAK, FavoritesItem, UserFilesItem, UserDocumentsItem, UserPicturesItem, ComputerItem, RecentDocumentsItem, SEPARATOR, PCSettingsItem, ControlPanelItem, SecurityItem, NetworkItem, PrintersItem, SEPARATOR, SearchMenu, HelpItem, RunItem, COLUMN_PADDING, SEPARATOR, ShutdownBoxItem\n"
L"ProgramsMenu.Command=programs\n"
L"ProgramsMenu.Label=$Menu.Programs\n"
L"ProgramsMenu.Icon=shell32.dll,326\n"
@@ -1203,7 +1220,7 @@ L"SearchMenu.Icon=shell32.dll,323\n"
L"HelpItem.Command=help\n"
L"HelpItem.Label=$Menu.Help\n"
L"HelpItem.Tip=$Menu.HelpTip\n"
L"HelpItem.Icon=shell32.dll,324\n"
L"HelpItem.Icon=imageres.dll,99\n"
L"RunItem.Command=run\n"
L"RunItem.Label=$Menu.Run\n"
L"RunItem.Tip=$Menu.RunTip\n"
@@ -1379,9 +1396,9 @@ L"Item13.Settings=ITEM_DISABLED\n"
L"Item14.Command=network_connections\n"
L"Item14.Settings=ITEM_DISABLED\n"
L"Item15.Command=separator\n"
L"Item16.Command=control_panel\n"
L"Item16.Command=pc_settings\n"
L"Item16.Settings=TRACK_RECENT\n"
L"Item17.Command=pc_settings\n"
L"Item17.Command=control_panel\n"
L"Item17.Settings=TRACK_RECENT\n"
L"Item18.Command=admin\n"
L"Item18.Settings=TRACK_RECENT|ITEM_DISABLED\n"
@@ -1742,7 +1759,7 @@ LRESULT CEditMenuDlg::OnBrowseLink( WORD wNotifyCode, WORD wID, HWND hWndCtl, BO
{
wchar_t text[_MAX_PATH];
GetDlgItemText(IDC_COMBOLINK,text,_countof(text));
if (BrowseLinkHelper(m_hWnd,text))
if (BrowseLinkHelper(m_hWnd,text,false))
{
SetDlgItemText(IDC_COMBOLINK,text);
SendMessage(WM_COMMAND,MAKEWPARAM(IDC_COMBOLINK,CBN_KILLFOCUS));
@@ -2437,7 +2454,7 @@ LRESULT CEditMenuDlg7::OnBrowseLink( WORD wNotifyCode, WORD wID, HWND hWndCtl, B
{
wchar_t text[_MAX_PATH];
GetDlgItemText(IDC_EDITLINK2,text,_countof(text));
if (BrowseLinkHelper(m_hWnd,text))
if (BrowseLinkHelper(m_hWnd,text,false))
{
SetDlgItemText(IDC_EDITLINK2,text);
SendMessage(WM_COMMAND,MAKEWPARAM(IDC_EDITLINK2,EN_KILLFOCUS));
@@ -2725,8 +2742,11 @@ void CCustomMenuDlg7::CItemList::UpdateItem( int index )
str=LoadStringEx(IDS_ITEM_SHOW2);
else if ((menuItem.settings&StdMenuItem::MENU_NOEXPAND) && !(g_StdCommands7[menuItem.stdItemIndex].flags&CStdCommand7::ITEM_FOLDER))
str=LoadStringEx(IDS_ITEM_SHOW);
else if ((menuItem.settings&StdMenuItem::MENU_SINGLE_EXPAND) && (g_StdCommands7[menuItem.stdItemIndex].flags&CStdCommand7::ITEM_COMPUTER))
str=LoadStringEx(IDS_ITEM_DRIVES);
else if ((menuItem.settings&StdMenuItem::MENU_SINGLE_EXPAND) && !(g_StdCommands7[menuItem.stdItemIndex].flags&CStdCommand7::ITEM_NODRIVES))
if (g_StdCommands7[menuItem.stdItemIndex].flags&CStdCommand7::ITEM_COMPUTER)
str=LoadStringEx(IDS_ITEM_DRIVES);
else
str=LoadStringEx(IDS_ITEM_LINKS);
else
str=LoadStringEx(IDS_ITEM_MENU);
ListView_SetItemText(m_hWnd,index,2,(wchar_t*)(const wchar_t*)str);
@@ -3155,13 +3175,12 @@ LRESULT CCustomMenuDlg7::CItemList::OnSelEndOk( WORD wNotifyCode, WORD wID, HWND
if (m_Column==2)
{
// state
CString str;
menuItem.settings&=~CEditMenuDlg7::SETTINGS_MASK;
if (sel==0)
menuItem.settings|=StdMenuItem::MENU_ITEM_DISABLED;
else if (sel==1 && !(g_StdCommands7[menuItem.stdItemIndex].flags&(CStdCommand7::ITEM_SINGLE|CStdCommand7::ITEM_FOLDER)))
menuItem.settings|=StdMenuItem::MENU_NOEXPAND;
else if (sel==3 && (g_StdCommands7[menuItem.stdItemIndex].flags&CStdCommand7::ITEM_COMPUTER))
else if (sel==3 && !(g_StdCommands7[menuItem.stdItemIndex].flags&CStdCommand7::ITEM_NODRIVES))
menuItem.settings|=StdMenuItem::MENU_SINGLE_EXPAND;
}
UpdateItem(m_Line);
@@ -3308,12 +3327,17 @@ void CCustomMenuDlg7::CItemList::CreateCombo( int line, int column )
str=LoadStringEx(IDS_ITEM_DRIVES);
m_Combo.SendMessage(CB_ADDSTRING,0,(LPARAM)(const wchar_t*)str);
}
else if (!(g_StdCommands7[menuItem.stdItemIndex].flags&CStdCommand7::ITEM_NODRIVES))
{
str=LoadStringEx(IDS_ITEM_LINKS);
m_Combo.SendMessage(CB_ADDSTRING,0,(LPARAM)(const wchar_t*)str);
}
}
if (menuItem.settings&StdMenuItem::MENU_ITEM_DISABLED)
m_Combo.SendMessage(CB_SETCURSEL,0);
else if ((g_StdCommands7[menuItem.stdItemIndex].flags&(CStdCommand7::ITEM_SINGLE|CStdCommand7::ITEM_FOLDER)) || (menuItem.settings&StdMenuItem::MENU_NOEXPAND))
m_Combo.SendMessage(CB_SETCURSEL,1);
else if ((g_StdCommands7[menuItem.stdItemIndex].flags&CStdCommand7::ITEM_COMPUTER) && (menuItem.settings&StdMenuItem::MENU_SINGLE_EXPAND))
else if (!(g_StdCommands7[menuItem.stdItemIndex].flags&CStdCommand7::ITEM_NODRIVES) && (menuItem.settings&StdMenuItem::MENU_SINGLE_EXPAND))
m_Combo.SendMessage(CB_SETCURSEL,3);
else
m_Combo.SendMessage(CB_SETCURSEL,2);
@@ -3718,7 +3742,6 @@ protected:
CWindow m_ImageClassic1, m_ImageClassic2, m_ImageWin7;
CWindow m_Tooltip;
CWindow m_ButtonAero, m_ButtonClassic, m_ButtonCustom;
bool m_bLargeBitmaps;
HICON m_hIcon;
CString m_IconPath;
@@ -3737,14 +3760,13 @@ LRESULT CMenuStyleDlg::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BO
HDC hdc=::GetDC(NULL);
int dpi=GetDeviceCaps(hdc,LOGPIXELSY);
::ReleaseDC(NULL,hdc);
m_bLargeBitmaps=dpi>=144;
if (m_bLargeBitmaps)
bool bLargeBitmaps=dpi>=144;
{
HBITMAP bmp=(HBITMAP)LoadImage(g_Instance,MAKEINTRESOURCE(IDB_STYLE_CLASSIC1150),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);
HBITMAP bmp=LoadImageResource(g_Instance,MAKEINTRESOURCE(bLargeBitmaps?IDB_STYLE_CLASSIC1150:IDB_STYLE_CLASSIC1),true,true);
m_ImageClassic1.SendMessage(STM_SETIMAGE,IMAGE_BITMAP,(LPARAM)bmp);
bmp=(HBITMAP)LoadImage(g_Instance,MAKEINTRESOURCE(IDB_STYLE_CLASSIC2150),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);
bmp=LoadImageResource(g_Instance,MAKEINTRESOURCE(bLargeBitmaps?IDB_STYLE_CLASSIC2150:IDB_STYLE_CLASSIC2),true,true);
m_ImageClassic2.SendMessage(STM_SETIMAGE,IMAGE_BITMAP,(LPARAM)bmp);
bmp=(HBITMAP)LoadImage(g_Instance,MAKEINTRESOURCE(IDB_STYLE_WIN7150),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);
bmp=LoadImageResource(g_Instance,MAKEINTRESOURCE(bLargeBitmaps?IDB_STYLE_WIN7150:IDB_STYLE_WIN7),true,true);
m_ImageWin7.SendMessage(STM_SETIMAGE,IMAGE_BITMAP,(LPARAM)bmp);
}
@@ -3779,7 +3801,6 @@ LRESULT CMenuStyleDlg::OnDestroy( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&
{
if (m_hIcon) DestroyIcon(m_hIcon);
m_hIcon=NULL;
if (m_bLargeBitmaps)
{
HBITMAP bmp=(HBITMAP)m_ImageClassic1.SendMessage(STM_GETIMAGE,IMAGE_BITMAP);
if (bmp) DeleteObject(bmp);
@@ -4143,38 +4164,50 @@ CSetting g_Settings[]={
{L"Nothing",CSetting::TYPE_RADIO,IDS_OPEN_NOTHING,IDS_OPEN_NOTHING_TIP},
{L"ClassicMenu",CSetting::TYPE_RADIO,IDS_OPEN_CSM,IDS_OPEN_CSM_TIP},
{L"WindowsMenu",CSetting::TYPE_RADIO,IDS_OPEN_WSM,IDS_OPEN_WSM_TIP},
{L"Command",CSetting::TYPE_RADIO,IDS_OPEN_CMD,IDS_OPEN_CMD_TIP},
{L"Both",CSetting::TYPE_RADIO,IDS_OPEN_BOTH,IDS_OPEN_BOTH_TIP,0,CSetting::FLAG_HIDDEN},
{L"MouseClickCommand",CSetting::TYPE_STRING,IDS_OPEN_CMD_TEXT,IDS_OPEN_CMD_TEXT_TIP,"%userprofile%",0,L"MouseClick=3",L"Command"},
{L"ShiftClick",CSetting::TYPE_INT,IDS_SHIFT_LCLICK,IDS_SHIFT_LCLICK_TIP,2,CSetting::FLAG_BASIC},
{L"Nothing",CSetting::TYPE_RADIO,IDS_OPEN_NOTHING,IDS_OPEN_NOTHING_TIP},
{L"ClassicMenu",CSetting::TYPE_RADIO,IDS_OPEN_CSM,IDS_OPEN_CSM_TIP},
{L"WindowsMenu",CSetting::TYPE_RADIO,IDS_OPEN_WSM,IDS_OPEN_WSM_TIP},
{L"Command",CSetting::TYPE_RADIO,IDS_OPEN_CMD,IDS_OPEN_CMD_TIP},
{L"Both",CSetting::TYPE_RADIO,IDS_OPEN_BOTH,IDS_OPEN_BOTH_TIP,0,CSetting::FLAG_HIDDEN},
/* {L"Desktop",CSetting::TYPE_RADIO,IDS_OPEN_DESKTOP,IDS_OPEN_DESKTOP_TIP,0,CSetting::FLAG_HIDDEN},
{L"Cortana",CSetting::TYPE_RADIO,IDS_OPEN_CORTANA,IDS_OPEN_CORTANA_TIP},*/
{L"ShiftClickCommand",CSetting::TYPE_STRING,IDS_OPEN_CMD_TEXT,IDS_OPEN_CMD_TEXT_TIP,"%systemdrive%",0,L"ShiftClick=3",L"Command"},
{L"WinKey",CSetting::TYPE_INT,IDS_WIN_KEY,IDS_WIN_KEY_TIP,1,CSetting::FLAG_BASIC},
{L"Nothing",CSetting::TYPE_RADIO,IDS_OPEN_NOTHING,IDS_OPEN_NOTHING_TIP},
{L"ClassicMenu",CSetting::TYPE_RADIO,IDS_OPEN_CSM,IDS_OPEN_CSM_TIP},
{L"WindowsMenu",CSetting::TYPE_RADIO,IDS_OPEN_WSM,IDS_OPEN_WSM_TIP},
{L"Command",CSetting::TYPE_RADIO,IDS_OPEN_CMD,IDS_OPEN_CMD_TIP},
{L"Both",CSetting::TYPE_RADIO,IDS_OPEN_BOTH,IDS_OPEN_BOTH_TIP},
{L"Desktop",CSetting::TYPE_RADIO,IDS_OPEN_DESKTOP,IDS_OPEN_DESKTOP_TIP},
{L"WinKeyCommand",CSetting::TYPE_STRING,IDS_OPEN_CMD_TEXT,IDS_OPEN_CMD_TEXT_TIP,"cmd",0,L"WinKey=3",L"Command"},
{L"ShiftWin",CSetting::TYPE_INT,IDS_SHIFT_WIN,IDS_SHIFT_WIN_TIP,2,CSetting::FLAG_BASIC},
{L"Nothing",CSetting::TYPE_RADIO,IDS_OPEN_NOTHING,IDS_OPEN_NOTHING_TIP},
{L"ClassicMenu",CSetting::TYPE_RADIO,IDS_OPEN_CSM,IDS_OPEN_CSM_TIP},
{L"WindowsMenu",CSetting::TYPE_RADIO,IDS_OPEN_WSM,IDS_OPEN_WSM_TIP},
{L"Command",CSetting::TYPE_RADIO,IDS_OPEN_CMD,IDS_OPEN_CMD_TIP},
{L"Both",CSetting::TYPE_RADIO,IDS_OPEN_BOTH,IDS_OPEN_BOTH_TIP},
/* {L"Desktop",CSetting::TYPE_RADIO,IDS_OPEN_DESKTOP,IDS_OPEN_DESKTOP_TIP,0,CSetting::FLAG_HIDDEN},
{L"Cortana",CSetting::TYPE_RADIO,IDS_OPEN_CORTANA,IDS_OPEN_CORTANA_TIP},*/
{L"ShiftWinCommand",CSetting::TYPE_STRING,IDS_OPEN_CMD_TEXT,IDS_OPEN_CMD_TEXT_TIP,"powershell",0,L"ShiftWin=3",L"Command"},
{L"MiddleClick",CSetting::TYPE_INT,IDS_MCLICK,IDS_MCLICK_TIP,0},
{L"Nothing",CSetting::TYPE_RADIO,IDS_OPEN_NOTHING,IDS_OPEN_NOTHING_TIP},
{L"ClassicMenu",CSetting::TYPE_RADIO,IDS_OPEN_CSM,IDS_OPEN_CSM_TIP},
{L"WindowsMenu",CSetting::TYPE_RADIO,IDS_OPEN_WSM,IDS_OPEN_WSM_TIP},
{L"Command",CSetting::TYPE_RADIO,IDS_OPEN_CMD,IDS_OPEN_CMD_TIP},
/* {L"Both",CSetting::TYPE_RADIO,IDS_OPEN_BOTH,IDS_OPEN_BOTH_TIP,0,CSetting::FLAG_HIDDEN},
{L"Desktop",CSetting::TYPE_RADIO,IDS_OPEN_DESKTOP,IDS_OPEN_DESKTOP_TIP,0,CSetting::FLAG_HIDDEN},
{L"Cortana",CSetting::TYPE_RADIO,IDS_OPEN_CORTANA,IDS_OPEN_CORTANA_TIP},*/
{L"MiddleClickCommand",CSetting::TYPE_STRING,IDS_OPEN_CMD_TEXT,IDS_OPEN_CMD_TEXT_TIP,"taskmgr",0,L"MiddleClick=3",L"Command"},
{L"Hover",CSetting::TYPE_INT,IDS_HOVER,IDS_HOVER_TIP,0},
{L"Nothing",CSetting::TYPE_RADIO,IDS_OPEN_NOTHING,IDS_OPEN_NOTHING_TIP},
{L"ClassicMenu",CSetting::TYPE_RADIO,IDS_OPEN_CSM,IDS_OPEN_CSM_TIP},
{L"WindowsMenu",CSetting::TYPE_RADIO,IDS_OPEN_WSM,IDS_OPEN_WSM_TIP},
{L"Command",CSetting::TYPE_RADIO,IDS_OPEN_CMD,IDS_OPEN_CMD_TIP},
{L"HoverCommand",CSetting::TYPE_STRING,IDS_OPEN_CMD_TEXT,IDS_OPEN_CMD_TEXT_TIP,"",0,L"Hover=3",L"Command"},
{L"StartHoverDelay",CSetting::TYPE_INT,IDS_HOVER_DELAY,IDS_HOVER_DELAY_TIP,1000,0,L"Hover",L"Hover"},
{L"ShiftRight",CSetting::TYPE_BOOL,IDS_RIGHT_SHIFT,IDS_RIGHT_SHIFT_TIP,0},
{L"CSMHotkey",CSetting::TYPE_HOTKEY,IDS_CSM_HOTKEY,IDS_CSM_HOTKEY_TIP,0},
@@ -4249,6 +4282,7 @@ CSetting g_Settings[]={
{L"PinnedPrograms",CSetting::TYPE_INT,IDS_PINNED_PROGRAMS,IDS_PINNED_PROGRAMS_TIP,PINNED_PROGRAMS_PINNED},
{L"FastItems",CSetting::TYPE_RADIO,IDS_FAST_ITEMS,IDS_FAST_ITEMS_TIP},
{L"PinnedItems",CSetting::TYPE_RADIO,IDS_PINNED_ITEMS,IDS_PINNED_ITEMS_TIP},
{L"PinnedItemsPath",CSetting::TYPE_DIRECTORY,IDS_PINNED_PATH,IDS_PINNED_PATH_TIP,L"%APPDATA%\\OpenShell\\Pinned",0,L"PinnedPrograms=1",L"PinnedItems"},
{L"RecentPrograms",CSetting::TYPE_INT,IDS_RECENT_PROGRAMS,IDS_RECENT_PROGRAMS_TIP,RECENT_PROGRAMS_RECENT,CSetting::FLAG_BASIC},
{L"None",CSetting::TYPE_RADIO,IDS_NO_RECENT,IDS_NO_RECENT_TIP},
{L"Recent",CSetting::TYPE_RADIO,IDS_SHOW_RECENT,IDS_SHOW_RECENT_TIP},
@@ -4317,11 +4351,14 @@ CSetting g_Settings[]={
{L"UserNameCommand",CSetting::TYPE_STRING,IDS_NAME_COMMAND,IDS_NAME_COMMAND_TIP,L"control nusrmgr.cpl"},
{L"SearchFilesCommand",CSetting::TYPE_STRING,IDS_SEARCH_COMMAND,IDS_SEARCH_COMMAND_TIP,L"search-ms:",CSetting::FLAG_MENU_CLASSIC_BOTH},
{L"ExpandFolderLinks",CSetting::TYPE_BOOL,IDS_EXPAND_LINKS,IDS_EXPAND_LINKS_TIP,1},
{L"SingleClickFolders",CSetting::TYPE_BOOL,IDS_NO_DBLCLICK,IDS_NO_DBLCLICK_TIP,0},
{L"OpenTruePath",CSetting::TYPE_BOOL,IDS_OPEN_TRUE_PATH,IDS_OPEN_TRUE_PATH_TIP,1},
{L"EnableTouch",CSetting::TYPE_BOOL,IDS_ENABLE_TOUCH,IDS_ENABLE_TOUCH_TIP,1},
{L"EnableAccessibility",CSetting::TYPE_BOOL,IDS_ACCESSIBILITY,IDS_ACCESSIBILITY_TIP,1},
{L"ShowNextToTaskbar",CSetting::TYPE_BOOL,IDS_NEXTTASKBAR,IDS_NEXTTASKBAR_TIP,0},
{L"PreCacheIcons",CSetting::TYPE_BOOL,IDS_CACHE_ICONS,IDS_CACHE_ICONS_TIP,1,CSetting::FLAG_COLD},
{L"DelayIcons",CSetting::TYPE_BOOL,IDS_DELAY_ICONS,IDS_DELAY_ICONS_TIP,1,CSetting::FLAG_COLD},
{L"BoldSettings",CSetting::TYPE_BOOL,IDS_BOLD_SETTINGS,IDS_BOLD_SETTINGS_TIP,1},
{L"ReportSkinErrors",CSetting::TYPE_BOOL,IDS_SKIN_ERRORS,IDS_SKIN_ERRORS_TIP,0},
{L"SearchBoxSettings",CSetting::TYPE_GROUP,IDS_SEARCH_BOX},
@@ -4330,6 +4367,8 @@ CSetting g_Settings[]={
{L"Normal",CSetting::TYPE_RADIO,IDS_SEARCH_BOX_SHOW,IDS_SEARCH_BOX_SHOW_TIP},
{L"Tab",CSetting::TYPE_RADIO,IDS_SEARCH_BOX_TAB,IDS_SEARCH_BOX_TAB_TIP},
{L"SearchSelect",CSetting::TYPE_BOOL,IDS_SEARCH_BOX_SEL,IDS_SEARCH_BOX_SEL_TIP,1,0,L"SearchBox=1",L"Normal"},
{L"SearchHint",CSetting::TYPE_BOOL,IDS_SEARCH_HINT,IDS_SEARCH_HINT_TIP,0,0,L"SearchBox"},
{L"SearchHintText",CSetting::TYPE_STRING,IDS_NEW_SEARCH_HINT,IDS_NEW_SEARCH_HINT_TIP,L"",0,L"#SearchHint",L"SearchHint"},
{L"SearchTrack",CSetting::TYPE_BOOL,IDS_SEARCH_TRACK,IDS_SEARCH_TRACK_TIP,1,0,L"SearchBox"},
{L"SearchResults",CSetting::TYPE_INT,IDS_SEARCH_MAX2,IDS_SEARCH_MAX_TIP2,5,CSetting::FLAG_MENU_CLASSIC_BOTH,L"SearchBox"},
{L"SearchResultsMax",CSetting::TYPE_INT,IDS_SEARCH_MAX3,IDS_SEARCH_MAX_TIP3,20,CSetting::FLAG_MENU_CLASSIC_BOTH,L"SearchBox"},
@@ -4344,6 +4383,7 @@ CSetting g_Settings[]={
{L"SearchContents",CSetting::TYPE_BOOL,IDS_SEARCH_CONTENTS,IDS_SEARCH_CONTENTS_TIP,1,0,L"#SearchFiles",L"SearchFiles"},
{L"SearchCategories",CSetting::TYPE_BOOL,IDS_SEARCH_CATEGORIES,IDS_SEARCH_CATEGORIES_TIP,1,0,L"#SearchFiles",L"SearchFiles"},
{L"SearchInternet",CSetting::TYPE_BOOL,IDS_SEARCH_INTERNET,IDS_SEARCH_INTERNET_TIP,1,0,L"SearchBox"},
{L"MoreResults",CSetting::TYPE_BOOL,IDS_MORE_RESULTS,IDS_MORE_RESULTS_TIP,1,0,L"SearchBox"},
{L"Look",CSetting::TYPE_GROUP,IDS_LOOK_SETTINGS},
{L"SmallIconSize",CSetting::TYPE_INT,IDS_SMALL_SIZE_SM,IDS_SMALL_SIZE_SM_TIP,-1,CSetting::FLAG_COLD}, // 16 for DPI<=96, 20 for DPI<=120, 24 otherwise
@@ -4351,6 +4391,9 @@ CSetting g_Settings[]={
{L"InvertMetroIcons",CSetting::TYPE_BOOL,IDS_INVERT_ICONS,IDS_INVERT_ICONS_TIP,0},
{L"MaxMainMenuWidth",CSetting::TYPE_INT,IDS_MENU_WIDTH,IDS_MENU_WIDTH_TIP,60,CSetting::FLAG_MENU_CLASSIC_BOTH},
{L"MaxMenuWidth",CSetting::TYPE_INT,IDS_SUBMENU_WIDTH,IDS_SUBMENU_WIDTH_TIP,60},
{L"AlignToWorkArea",CSetting::TYPE_BOOL,IDS_ALIGN_WORK_AREA,IDS_ALIGN_WORK_AREA_TIP,0},
{L"HorizontalMenuOffset",CSetting::TYPE_INT,IDS_HOR_OFFSET,IDS_HOR_OFFSET_TIP,0},
{L"VerticalMenuOffset",CSetting::TYPE_INT,IDS_VERT_OFFSET,IDS_VERT_OFFSET_TIP,0 },
{L"OverrideDPI",CSetting::TYPE_INT,IDS_DPI_OVERRIDE,IDS_DPI_OVERRIDE_TIP,0,CSetting::FLAG_COLD},
{L"MainMenuAnimate",CSetting::TYPE_BOOL,IDS_ANIMATION7,IDS_ANIMATION7_TIP,1,CSetting::FLAG_MENU_WIN7},
{L"MainMenuAnimation",CSetting::TYPE_INT,IDS_ANIMATION,IDS_ANIMATION_TIP,-1}, // system animation type
@@ -4416,7 +4459,7 @@ CSetting g_Settings[]={
{L"StartButtonIconSize",CSetting::TYPE_INT,IDS_BUTTON_ICON_SIZE,IDS_BUTTON_ICON_SIZE_TIP,0,0,L"#StartButtonType=1",L"ClasicButton"},
{L"StartButtonText",CSetting::TYPE_STRING,IDS_BUTTON_TEXT,IDS_BUTTON_TEXT_TIP,L"$Menu.Start",0,L"#StartButtonType=1",L"ClasicButton"},
{L"Taskbar",CSetting::TYPE_GROUP,IDS_TASKBAR_SETTINGS},
{L"Taskbar",CSetting::TYPE_GROUP,IDS_TASKBAR_SETTINGS,0,0,CSetting::FLAG_BASIC},
{L"CustomTaskbar",CSetting::TYPE_BOOL,IDS_TASK_CUSTOM,IDS_TASK_CUSTOM_TIP,0,CSetting::FLAG_CALLBACK},
{L"TaskbarLook",CSetting::TYPE_INT,IDS_TASK_LOOK,IDS_TASK_LOOK_TIP,1,CSetting::FLAG_CALLBACK,L"CustomTaskbar",L"CustomTaskbar"},
{L"Opaque",CSetting::TYPE_RADIO,IDS_TASK_OPAQUE,IDS_TASK_OPAQUE_TIP},
@@ -4425,8 +4468,8 @@ CSetting g_Settings[]={
{L"AeroGlass",CSetting::TYPE_RADIO,IDS_TASK_AEROGLASS,IDS_TASK_AEROGLASS_TIP,0,CSetting::FLAG_HIDDEN},
{L"TaskbarOpacity",CSetting::TYPE_INT,IDS_TASK_OPACITY,IDS_TASK_OPACITY_TIP,DEFAULT_TASK_OPACITY10,CSetting::FLAG_CALLBACK,L"TaskbarLook",L"CustomTaskbar"},
{L"TaskbarColor",CSetting::TYPE_COLOR,IDS_TASK_COLOR,IDS_TASK_COLOR_TIP,0,CSetting::FLAG_CALLBACK,L"CustomTaskbar",L"CustomTaskbar"},
{L"TaskbarTextColor",CSetting::TYPE_COLOR,IDS_TASK_TEXTCOLOR,IDS_TASK_TEXTCOLOR_TIP,0xFFFFFF,CSetting::FLAG_CALLBACK|(1<<24),L"CustomTaskbar",L"CustomTaskbar"},
{L"TaskbarTexture",CSetting::TYPE_BITMAP_JPG,IDS_TASK_TEXTURE,IDS_TASK_TEXTURE_TIP,L"",CSetting::FLAG_CALLBACK,L"CustomTaskbar",L"CustomTaskbar"},
{L"TaskbarTextColor",CSetting::TYPE_COLOR,IDS_TASK_TEXTCOLOR,IDS_TASK_TEXTCOLOR_TIP,0xFFFFFF,CSetting::FLAG_COLD|(1<<24),L"CustomTaskbar",L"CustomTaskbar"},
{L"TaskbarTexture",CSetting::TYPE_BITMAP_JPG,IDS_TASK_TEXTURE,IDS_TASK_TEXTURE_TIP,L"",CSetting::FLAG_COLD,L"CustomTaskbar",L"CustomTaskbar"},
{L"TaskbarTileH",CSetting::TYPE_INT,IDS_TASK_STRETCHH,IDS_TASK_STRETCHH_TIP,1,CSetting::FLAG_CALLBACK,L"#TaskbarTexture",L"TaskbarTexture"},
{L"Tile",CSetting::TYPE_RADIO,IDS_TASK_TILE,IDS_TASK_TILE_TIP},
{L"Stretch",CSetting::TYPE_RADIO,IDS_TASK_STRETCH,IDS_TASK_STRETCH_TIP},
@@ -4622,6 +4665,48 @@ void UpgradeSettings( bool bShared )
}
}
static CString GetWindowsBrandingString()
{
CString retval;
if (GetWinVersion() >= WIN_VER_WIN10)
{
auto winbrand = LoadLibraryEx(L"winbrand.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
if (winbrand)
{
PWSTR (WINAPI * BrandingFormatString)(PCWSTR pstrFormat);
BrandingFormatString = (decltype(BrandingFormatString))GetProcAddress(winbrand, "BrandingFormatString");
if (BrandingFormatString)
{
auto osName = BrandingFormatString(L"%WINDOWS_LONG%");
if (osName)
{
retval = osName;
GlobalFree(osName);
}
}
FreeLibrary(winbrand);
}
}
if (retval.IsEmpty())
{
// fallback for older Windows
wchar_t title[256] = L"Windows";
if (CRegKey reg; reg.Open(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion", KEY_READ) == ERROR_SUCCESS)
{
ULONG size = _countof(title);
reg.QueryStringValue(L"ProductName", title, &size);
}
retval = title;
}
return retval;
}
void UpdateSettings( void )
{
{
@@ -4659,11 +4744,19 @@ void UpdateSettings( void )
else if (dpi<96) dpi=96;
else if (dpi>480) dpi=480;
int iconSize=24;
if (dpi<=96)
iconSize=16;
else if (dpi<=120)
iconSize=20;
int iconSize=16;
if (dpi>=240)
iconSize=40; // for 250% scaling
else if (dpi>=216)
iconSize=36; // for 225% scaling
else if (dpi>=192)
iconSize=32; // for 200% scaling
else if (dpi>=168)
iconSize=28; // for 175% scaling
else if (dpi>=144)
iconSize=24; // for 150% scaling
else if (dpi>=120)
iconSize=20; // for 125% scaling
UpdateSetting(L"SmallIconSize",CComVariant(iconSize),false);
UpdateSetting(L"LargeIconSize",CComVariant(iconSize*2),false);
@@ -4736,16 +4829,10 @@ void UpdateSettings( void )
UpdateSetting(L"NumericSort",CComVariant(SHRestricted(REST_NOSTRCMPLOGICAL)?0:1),false);
wchar_t title[256]=L"Windows";
ULONG size=_countof(title);
{
CRegKey regTitle;
if (regTitle.Open(HKEY_LOCAL_MACHINE,L"Software\\Microsoft\\Windows NT\\CurrentVersion",KEY_READ)==ERROR_SUCCESS)
regTitle.QueryStringValue(L"ProductName",title,&size);
}
UpdateSetting(L"MenuCaption",CComVariant(title),false);
UpdateSetting(L"MenuCaption",CComVariant(GetWindowsBrandingString()),false);
size=_countof(title);
wchar_t title[256]{};
ULONG size=_countof(title);
if (!GetUserNameEx(NameDisplay,title,&size))
{
// GetUserNameEx may fail (for example on Home editions). use the login name
@@ -4876,7 +4963,7 @@ void UpdateSettings( void )
if (GetWinVersion()>WIN_VER_WIN7)
{
int color=GetSystemGlassColor8();
UpdateSetting(L"TaskbarColor",CComVariant(((color&0xFF)<<16)|(color&0xFF00)|((color>>16)&0xFF)),false);
UpdateSetting(L"TaskbarColor",CComVariant(RgbToBgr(color)),false);
}
if (GetWinVersion()<=WIN_VER_WIN7)
@@ -4976,15 +5063,15 @@ void UpdateSettings( void )
HIGHCONTRAST contrast={sizeof(contrast)};
if (SystemParametersInfo(SPI_GETHIGHCONTRAST,sizeof(contrast),&contrast,0) && (contrast.dwFlags&HCF_HIGHCONTRASTON))
{
options1=L"CAPTION=1\nUSER_IMAGE=0\nUSER_NAME=0\nCENTER_NAME=0\nSMALL_ICONS=0\nTHICK_BORDER=0\nSOLID_SELECTION=1";
options2=L"NO_ICONS=1\nUSER_IMAGE=1\nUSER_NAME=0\nCENTER_NAME=0\nSMALL_ICONS=0\nTHICK_BORDER=0\nSOLID_SELECTION=1";
options3=L"USER_IMAGE=1\nSMALL_ICONS=0\nTHICK_BORDER=0\nSOLID_SELECTION=1";
options1=L"CAPTION=1\nUSER_IMAGE=0\nUSER_NAME=0\nCENTER_NAME=0\nSMALL_ICONS=0\nTHICK_BORDER=0\nSOLID_SELECTION=1\n";
options2=L"NO_ICONS=1\nUSER_IMAGE=1\nUSER_NAME=0\nCENTER_NAME=0\nSMALL_ICONS=0\nTHICK_BORDER=0\nSOLID_SELECTION=1\n";
options3=L"USER_IMAGE=1\nSMALL_ICONS=0\nTHICK_BORDER=0\nSOLID_SELECTION=1\n";
}
else
{
options1=L"CAPTION=1\nUSER_IMAGE=0\nUSER_NAME=0\nCENTER_NAME=0\nSMALL_ICONS=0\nTHICK_BORDER=0\nSOLID_SELECTION=0";
options2=L"NO_ICONS=1\nUSER_IMAGE=1\nUSER_NAME=0\nCENTER_NAME=0\nSMALL_ICONS=0\nTHICK_BORDER=0\nSOLID_SELECTION=0";
options3=L"USER_IMAGE=1\nSMALL_ICONS=0\nTHICK_BORDER=0\nSOLID_SELECTION=0";
options1=L"CAPTION=1\nUSER_IMAGE=0\nUSER_NAME=0\nCENTER_NAME=0\nSMALL_ICONS=0\nTHICK_BORDER=0\nSOLID_SELECTION=0\n";
options2=L"NO_ICONS=1\nUSER_IMAGE=1\nUSER_NAME=0\nCENTER_NAME=0\nSMALL_ICONS=0\nTHICK_BORDER=0\nSOLID_SELECTION=0\n";
options3=L"USER_IMAGE=1\nSMALL_ICONS=0\nTHICK_BORDER=0\nSOLID_SELECTION=0\n";
}
}
else if (GetWinVersion()<WIN_VER_WIN8)
@@ -4992,25 +5079,25 @@ void UpdateSettings( void )
BOOL comp=FALSE;
skin12=(SUCCEEDED(DwmIsCompositionEnabled(&comp)) && comp)?L"Windows Aero":L"Windows Basic";
skin3=L"Windows Aero";
options1=L"CAPTION=1\nUSER_IMAGE=0\nUSER_NAME=0\nCENTER_NAME=0\nSMALL_ICONS=0\nLARGE_FONT=0\nDISABLE_MASK=0\nWHITE_SUBMENUS=1";
options2=L"NO_ICONS=1\nUSER_IMAGE=1\nUSER_NAME=0\nCENTER_NAME=0\nSMALL_ICONS=0\nLARGE_FONT=0\nDISABLE_MASK=0\nWHITE_SUBMENUS=1";
options3=L"USER_IMAGE=1\nSMALL_ICONS=0\nLARGE_FONT=0\nDISABLE_MASK=0\nWHITE_SUBMENUS=1";
options1=L"CAPTION=1\nUSER_IMAGE=0\nUSER_NAME=0\nCENTER_NAME=0\nSMALL_ICONS=0\nLARGE_FONT=0\nDISABLE_MASK=0\nWHITE_SUBMENUS=1\n";
options2=L"NO_ICONS=1\nUSER_IMAGE=1\nUSER_NAME=0\nCENTER_NAME=0\nSMALL_ICONS=0\nLARGE_FONT=0\nDISABLE_MASK=0\nWHITE_SUBMENUS=1\n";
options3=L"USER_IMAGE=1\nSMALL_ICONS=0\nLARGE_FONT=0\nDISABLE_MASK=0\nWHITE_SUBMENUS=1\n";
}
else if (GetWinVersion()<WIN_VER_WIN10)
{
skin12=L"Windows 8";
skin3=L"Windows 8";
options1=L"CAPTION=1\nUSER_IMAGE=0\nUSER_NAME=0\nCENTER_NAME=0\nSMALL_ICONS=0\nLARGE_FONT=0\nDISABLE_MASK=0\nOPAQUE=0\nWHITE_SUBMENUS=1";
options2=L"NO_ICONS=1\nUSER_IMAGE=1\nUSER_NAME=0\nCENTER_NAME=0\nSMALL_ICONS=0\nLARGE_FONT=0\nDISABLE_MASK=0\nOPAQUE=0\nGLASS_SHADOW=0\nBLACK_TEXT=0\nBLACK_FRAMES=0\nWHITE_SUBMENUS=1";
options3=L"USER_IMAGE=1\nSMALL_ICONS=0\nLARGE_FONT=0\nDISABLE_MASK=0\nOPAQUE=0\nGLASS_SHADOW=0\nBLACK_TEXT=0\nBLACK_FRAMES=0\nWHITE_SUBMENUS=1";
options1=L"CAPTION=1\nUSER_IMAGE=0\nUSER_NAME=0\nCENTER_NAME=0\nSMALL_ICONS=0\nLARGE_FONT=0\nDISABLE_MASK=0\nOPAQUE=0\nWHITE_SUBMENUS=1\n";
options2=L"NO_ICONS=1\nUSER_IMAGE=1\nUSER_NAME=0\nCENTER_NAME=0\nSMALL_ICONS=0\nLARGE_FONT=0\nDISABLE_MASK=0\nOPAQUE=0\nGLASS_SHADOW=0\nBLACK_TEXT=0\nBLACK_FRAMES=0\nWHITE_SUBMENUS=1\n";
options3=L"USER_IMAGE=1\nSMALL_ICONS=0\nLARGE_FONT=0\nDISABLE_MASK=0\nOPAQUE=0\nGLASS_SHADOW=0\nBLACK_TEXT=0\nBLACK_FRAMES=0\nWHITE_SUBMENUS=1\n";
}
else
{
skin12=L"Metro";
skin3=L"Metro";
options1=L"CAPTION=1\nUSER_IMAGE=0\nUSER_NAME=0\nCENTER_NAME=0\nSMALL_ICONS=0\nLARGE_FONT=0\nICON_FRAMES=1\nOPAQUE=0";
options2=L"NO_ICONS=1\nUSER_IMAGE=1\nUSER_NAME=0\nCENTER_NAME=0\nSMALL_ICONS=0\nLARGE_FONT=0\nICON_FRAMES=1\nOPAQUE=0";
options3=L"USER_IMAGE=1\nSMALL_ICONS=0\nLARGE_FONT=0\nICON_FRAMES=1\nOPAQUE=0";
options1=L"CAPTION=1\nUSER_IMAGE=0\nUSER_NAME=0\nCENTER_NAME=0\nSMALL_ICONS=0\nLARGE_FONT=0\nICON_FRAMES=1\nOPAQUE=0\n";
options2=L"NO_ICONS=1\nUSER_IMAGE=1\nUSER_NAME=0\nCENTER_NAME=0\nSMALL_ICONS=0\nLARGE_FONT=0\nICON_FRAMES=1\nOPAQUE=0\n";
options3=L"USER_IMAGE=1\nSMALL_ICONS=0\nLARGE_FONT=0\nICON_FRAMES=1\nOPAQUE=0\n";
}
UpdateSetting(L"SkinC1",CComVariant(skin12),false);
UpdateSetting(L"SkinOptionsC1",CComVariant(options1),false);

View File

@@ -375,7 +375,10 @@ COLORREF MenuSkin::GetMetroColor( const wchar_t *names ) const
if (GetImmersiveUserColorSetPreference!=NULL)
{
wchar_t text[256];
Sprintf(text,_countof(text),L"Immersive%s",name);
if (wcsncmp(name,L"Immersive",9)==0)
wcscpy_s(text,name);
else
Sprintf(text,_countof(text),L"Immersive%s",name);
int type=GetImmersiveColorTypeFromName(text);
data.colorType=type<0?-1:type;
if (type>=0)
@@ -1495,8 +1498,21 @@ bool MenuSkin::ComputeOptionStates( const std::map<CString,CString> &options, st
values.push_back(L"ALL_PROGRAMS");
if (SkinType==SKIN_TYPE_CLASSIC2)
values.push_back(L"TWO_COLUMNS");
// for compatibility with existing skins
if (Dpi>=144)
values.push_back(L"HIGH_DPI");
if (Dpi>=240)
values.push_back(L"240_DPI"); // 250% scaling
else if (Dpi>=216)
values.push_back(L"216_DPI"); // 225% scaling
else if (Dpi>=192)
values.push_back(L"192_DPI"); // 200% scaling
else if (Dpi>=168)
values.push_back(L"168_DPI"); // 175% scaling
else if (Dpi>=144)
values.push_back(L"144_DPI"); // 150% scaling
else if (Dpi>=120)
values.push_back(L"120_DPI"); // 125% scaling
if (ForceTouch || (GetWinVersion()>=WIN_VER_WIN8 && GetSettingBool(L"EnableTouch") && (GetSystemMetrics(SM_DIGITIZER)&NID_INTEGRATED_TOUCH)!=0))
values.push_back(L"TOUCH_ENABLED");
if (GetSettingInt(L"SearchBox")!=SEARCHBOX_HIDDEN)
@@ -1762,7 +1778,7 @@ bool MenuSkin::LoadSkin( HMODULE hMod, const wchar_t *variation, const wchar_t *
var.label=token;
if (var.labelEn.IsEmpty())
var.labelEn=var.label;
Variations.push_back(std::pair<int,Variation>(res,var));
Variations.emplace_back(res,var);
LOG_MENU(LOG_OPEN,L"Variation found: name=%s, id=%d",token,res);
}
else
@@ -3219,10 +3235,14 @@ void GetSkinsPath( wchar_t *path )
{
GetModuleFileName(g_Instance,path,_MAX_PATH);
*PathFindFileName(path)=0;
#ifdef BUILD_SETUP
Strcat(path,_MAX_PATH,L"Skins\\");
#else
Strcat(path,_MAX_PATH,L"..\\Skins\\");
#ifndef BUILD_SETUP
if (!PathIsDirectory(path))
{
*PathFindFileName(path) = 0;
Strcat(path,_MAX_PATH,L"..\\Skins\\");
}
#endif
}

View File

@@ -154,6 +154,7 @@ LRESULT CStartButton::OnCreate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& b
OnThemeChanged(WM_THEMECHANGED,0,0,bHandled);
m_bPressed=true;
SetPressed(false);
ResizeClient(m_Size.cx,m_Size.cy);
bHandled=FALSE;
return 0;
}
@@ -534,12 +535,12 @@ void CStartButton::LoadBitmap( void )
if (!m_Bitmap)
{
int id;
int dpi=CItemManager::GetDPI(false);
int dpi=GetDpi(GetParent());
if (dpi<120)
id=IDB_BUTTON96;
else if (dpi<144)
id=IDB_BUTTON120;
else if (dpi<180)
else if (dpi<168)
id=IDB_BUTTON144;
else
id=IDB_BUTTON180;
@@ -604,55 +605,12 @@ void CStartButton::LoadBitmap( void )
static std::map<int,CStartButton> g_StartButtons;
HWND CreateStartButton( int taskbarId, HWND taskBar, HWND rebar, const RECT &rcTask )
HWND CreateStartButton( int taskbarId, HWND taskBar, HWND rebar )
{
bool bRTL=(GetWindowLongPtr(rebar,GWL_EXSTYLE)&WS_EX_LAYOUTRTL)!=0;
DWORD styleTopmost=GetWindowLongPtr(taskBar,GWL_EXSTYLE)&WS_EX_TOPMOST;
CStartButton &button=g_StartButtons[taskbarId];
button.Create(taskBar,NULL,NULL,WS_POPUP,styleTopmost|WS_EX_TOOLWINDOW|WS_EX_LAYERED,0U,(void*)(intptr_t)(taskbarId*2+(bRTL?1:0)));
SIZE size=button.GetSize();
RECT rcButton;
MONITORINFO info;
UINT uEdge=GetTaskbarPosition(taskBar,&info,NULL,NULL);
if (uEdge==ABE_LEFT || uEdge==ABE_RIGHT)
{
if (GetSettingInt(L"StartButtonType")!=START_BUTTON_CUSTOM || !GetSettingBool(L"StartButtonAlign"))
rcButton.left=(rcTask.left+rcTask.right-size.cx)/2;
else if (uEdge==ABE_LEFT)
rcButton.left=rcTask.left;
else
rcButton.left=rcTask.right-size.cx;
rcButton.top=rcTask.top;
}
else
{
if (bRTL)
rcButton.left=rcTask.right-size.cx;
else
rcButton.left=rcTask.left;
if (GetSettingInt(L"StartButtonType")!=START_BUTTON_CUSTOM || !GetSettingBool(L"StartButtonAlign"))
rcButton.top=(rcTask.top+rcTask.bottom-size.cy)/2;
else if (uEdge==ABE_TOP)
rcButton.top=rcTask.top;
else
rcButton.top=rcTask.bottom-size.cy;
}
rcButton.right=rcButton.left+size.cx;
rcButton.bottom=rcButton.top+size.cy;
g_bAllowMoveButton=true;
button.SetWindowPos(HWND_TOP,&rcButton,SWP_SHOWWINDOW|SWP_NOOWNERZORDER|SWP_NOACTIVATE);
g_bAllowMoveButton=false;
RECT rc;
IntersectRect(&rc,&rcButton,&info.rcMonitor);
HRGN rgn=CreateRectRgn(rc.left-rcButton.left,rc.top-rcButton.top,rc.right-rcButton.left,rc.bottom-rcButton.top);
if (!SetWindowRgn(button,rgn,FALSE))
{
AddTrackedObject(rgn);
DeleteObject(rgn);
}
button.UpdateButton();
return button.m_hWnd;
}

View File

@@ -12,7 +12,7 @@ enum TStartButtonType
// START_BUTTON_METRO,
};
HWND CreateStartButton( int taskbarId, HWND taskBar, HWND rebar, const RECT &rcTask );
HWND CreateStartButton( int taskbarId, HWND taskBar, HWND rebar );
void DestroyStartButton( int taskbarId );
void UpdateStartButton( int taskbarId );
void PressStartButton( int taskbarId, bool bPressed );

View File

@@ -47,7 +47,7 @@ static HWND g_Tooltip;
static TOOLINFO g_StartButtonTool;
static bool g_bHotkeyShift;
static int g_HotkeyCSM, g_HotkeyWSM, g_HotkeyShiftID, g_HotkeyCSMID, g_HotkeyWSMID;
static HHOOK g_ProgHook, g_StartHook, g_AppManagerHook, g_NewWindowHook, g_StartMenuHook;
static HHOOK g_ProgHook, g_StartHook, g_StartMouseHook, g_AppManagerHook, g_NewWindowHook, g_StartMenuHook;
static bool g_bAllProgramsTimer;
static bool g_bInMenu;
static DWORD g_LastClickTime;
@@ -79,6 +79,7 @@ enum
OPEN_NOTHING,
OPEN_CLASSIC,
OPEN_WINDOWS,
OPEN_CUSTOM,
OPEN_BOTH,
OPEN_DESKTOP,
OPEN_CORTANA,
@@ -401,6 +402,7 @@ static TaskbarInfo *FindTaskBarInfoBar( HWND bar )
static LRESULT CALLBACK HookProgManThread( int code, WPARAM wParam, LPARAM lParam );
static LRESULT CALLBACK HookDesktopThread( int code, WPARAM wParam, LPARAM lParam );
static LRESULT CALLBACK HookDesktopThreadMouse(int code, WPARAM wParam, LPARAM lParam);
static BOOL CALLBACK FindTooltipEnum( HWND hwnd, LPARAM lParam )
{
@@ -615,12 +617,12 @@ UINT GetTaskbarPosition( HWND taskBar, MONITORINFO *pInfo, HMONITOR *pMonitor, R
if (pRc->right>rc.right) pRc->right=rc.right;
}
}
HMONITOR monitor=MonitorFromRect(&appbar.rc,MONITOR_DEFAULTTONEAREST);
if (pMonitor) *pMonitor=monitor;
if (pInfo)
{
pInfo->cbSize=sizeof(MONITORINFO);
HMONITOR monitor=MonitorFromRect(&appbar.rc,MONITOR_DEFAULTTONEAREST);
GetMonitorInfo(monitor,pInfo);
if (pMonitor) *pMonitor=monitor;
}
return appbar.uEdge;
}
@@ -670,21 +672,45 @@ UINT GetTaskbarPosition( HWND taskBar, MONITORINFO *pInfo, HMONITOR *pMonitor, R
bool PointAroundStartButton( size_t taskbarId, const CPoint &pt )
{
const TaskbarInfo *taskBar=GetTaskbarInfo(taskbarId);
if (!taskBar || !taskBar->startButton) return false;
RECT rc;
if (!taskBar || !(taskBar->startButton || taskBar->oldButton)) return false;
CRect rc;
GetWindowRect(taskBar->taskBar,&rc);
if (!PtInRect(&rc,pt))
return false;
UINT uEdge=GetTaskbarPosition(taskBar->taskBar,NULL,NULL,NULL);
bool rtl=GetWindowLongPtr(taskBar->taskBar,GWL_EXSTYLE)&WS_EX_LAYOUTRTL;
CRect rcStart;
if (taskBar->startButton)
GetWindowRect(taskBar->startButton,&rcStart);
CRect rcOld;
if (taskBar->oldButton)
{
GetWindowRect(taskBar->oldButton,&rcOld);
if (IsWin11())
{
// on Win11 the Start button rectangle is a bit smaller that actual XAML active area
// lets make it a bit wider to avoid accidental original Start menu triggers
const int adjust=ScaleForDpi(taskBar->taskBar,1);
if (rtl)
rcOld.left-=adjust;
else
rcOld.right+=adjust;
}
}
rc.UnionRect(&rcStart,&rcOld);
// check if the point is inside the start button rect
GetWindowRect(taskBar->startButton,&rc);
UINT uEdge=GetTaskbarPosition(taskBar->taskBar,NULL,NULL,NULL);
if (uEdge==ABE_LEFT || uEdge==ABE_RIGHT)
return pt.y<rc.bottom;
else if (GetWindowLongPtr(taskBar->taskBar,GWL_EXSTYLE)&WS_EX_LAYOUTRTL)
return pt.x>rc.left;
return pt.y>=rc.top && pt.y<rc.bottom;
else if (rtl)
return pt.x>rc.left && pt.x<=rc.right;
else
return pt.x<rc.right;
return pt.x>=rc.left && pt.x<rc.right;
}
// declare few interfaces so we don't need the Win8 SDK
@@ -1185,24 +1211,156 @@ void EnableHotkeys( THotkeys enable )
}
}
static void UpdateStartButtonPosition(const TaskbarInfo* taskBar, const WINDOWPOS* pPos)
{
if (IsStartButtonSmallIcons(taskBar->taskbarId) != IsTaskbarSmallIcons())
RecreateStartButton(taskBar->taskbarId);
RECT rcTask;
GetWindowRect(taskBar->taskBar, &rcTask);
MONITORINFO info;
UINT uEdge = GetTaskbarPosition(taskBar->taskBar, &info, NULL, NULL);
DWORD buttonFlags = SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE;
if (IsWindowVisible(taskBar->taskBar))
buttonFlags |= SWP_SHOWWINDOW;
else
buttonFlags |= SWP_HIDEWINDOW;
APPBARDATA appbar = { sizeof(appbar) };
if (SHAppBarMessage(ABM_GETSTATE, &appbar) & ABS_AUTOHIDE)
{
bool bHide = false;
if (uEdge == ABE_LEFT)
bHide = (rcTask.right < info.rcMonitor.left + 5);
else if (uEdge == ABE_RIGHT)
bHide = (rcTask.left > info.rcMonitor.right - 5);
else if (uEdge == ABE_TOP)
bHide = (rcTask.bottom < info.rcMonitor.top + 5);
else
bHide = (rcTask.top > info.rcMonitor.bottom - 5);
if (bHide)
buttonFlags = (buttonFlags & ~SWP_SHOWWINDOW) | SWP_HIDEWINDOW;
}
if (uEdge == ABE_TOP || uEdge == ABE_BOTTOM)
{
if (rcTask.left < info.rcMonitor.left) rcTask.left = info.rcMonitor.left;
if (rcTask.right > info.rcMonitor.right) rcTask.right = info.rcMonitor.right;
}
else
{
if (rcTask.top < info.rcMonitor.top) rcTask.top = info.rcMonitor.top;
}
HWND zPos = NULL;
if (pPos->flags & SWP_NOZORDER)
buttonFlags |= SWP_NOZORDER;
else
{
zPos = pPos->hwndInsertAfter;
if (zPos == HWND_TOP && !(GetWindowLongPtr(taskBar->startButton, GWL_EXSTYLE) & WS_EX_TOPMOST))
zPos = HWND_TOPMOST;
if (zPos == HWND_TOPMOST && !(GetWindowLongPtr(taskBar->taskBar, GWL_EXSTYLE) & WS_EX_TOPMOST))
zPos = HWND_TOP;
if (zPos == HWND_BOTTOM)
buttonFlags |= SWP_NOZORDER;
if (zPos == taskBar->startButton)
buttonFlags |= SWP_NOZORDER;
}
if (!IsStartButtonSmallIcons(taskBar->taskbarId))
{
bool bClassic;
if (GetWinVersion() < WIN_VER_WIN8)
bClassic = !IsAppThemed();
else
{
HIGHCONTRAST contrast = { sizeof(contrast) };
bClassic = (SystemParametersInfo(SPI_GETHIGHCONTRAST, sizeof(contrast), &contrast, 0) && (contrast.dwFlags & HCF_HIGHCONTRASTON));
}
if (!bClassic)
{
if (uEdge == ABE_TOP)
OffsetRect(&rcTask, 0, -1);
else if (uEdge == ABE_BOTTOM)
OffsetRect(&rcTask, 0, 1);
}
}
RECT rcOldButton;
if (taskBar->oldButton)
GetWindowRect(taskBar->oldButton, &rcOldButton);
int x, y;
if (uEdge == ABE_LEFT || uEdge == ABE_RIGHT)
{
if (GetSettingInt(L"StartButtonType") != START_BUTTON_CUSTOM || !GetSettingBool(L"StartButtonAlign"))
x = (rcTask.left + rcTask.right - taskBar->startButtonSize.cx) / 2;
else if (uEdge == ABE_LEFT)
x = rcTask.left;
else
x = rcTask.right - taskBar->startButtonSize.cx;
y = taskBar->oldButton ? rcOldButton.top : rcTask.top;
}
else
{
if (GetWindowLongPtr(taskBar->rebar, GWL_EXSTYLE) & WS_EX_LAYOUTRTL)
x = (taskBar->oldButton ? rcOldButton.right : rcTask.right) - taskBar->startButtonSize.cx;
else
x = taskBar->oldButton ? rcOldButton.left : rcTask.left;
if (GetSettingInt(L"StartButtonType") != START_BUTTON_CUSTOM || !GetSettingBool(L"StartButtonAlign"))
y = (rcTask.top + rcTask.bottom - taskBar->startButtonSize.cy) / 2;
else if (uEdge == ABE_TOP)
y = rcTask.top;
else
y = rcTask.bottom - taskBar->startButtonSize.cy;
}
// Start button on Win11 is a bit shifted to the right
// We will shift our Aero button to cover original button
if (IsWin11() && (x == 0) && (GetStartButtonType() == START_BUTTON_AERO))
x += ScaleForDpi(taskBar->taskBar, 6);
RECT rcButton = { x, y, x + taskBar->startButtonSize.cx, y + taskBar->startButtonSize.cy };
RECT rc;
IntersectRect(&rc, &rcButton, &info.rcMonitor);
HRGN rgn = CreateRectRgn(rc.left - x, rc.top - y, rc.right - x, rc.bottom - y);
if (!SetWindowRgn(taskBar->startButton, rgn, FALSE))
{
AddTrackedObject(rgn);
DeleteObject(rgn);
}
SetWindowPos(taskBar->startButton, zPos, x, y, 0, 0, buttonFlags);
if (buttonFlags & SWP_SHOWWINDOW)
UpdateStartButton(taskBar->taskbarId);
}
static LRESULT CALLBACK SubclassWin81StartButton( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData )
{
TaskbarInfo* taskBar = GetTaskbarInfo((int)dwRefData);
if (uMsg==WM_WINDOWPOSCHANGING)
{
// keep the original start button hidden at all times
const TaskbarInfo *taskBar=GetTaskbarInfo((int)dwRefData);
if (taskBar && taskBar->bHideButton)
{
((WINDOWPOS*)lParam)->flags&=~SWP_SHOWWINDOW;
}
}
if (uMsg==WM_WINDOWPOSCHANGED)
{
if (taskBar && taskBar->bReplaceButton)
{
UpdateStartButtonPosition(taskBar,(WINDOWPOS*)lParam);
}
}
if (uMsg==WM_SIZE)
{
RECT rc;
GetWindowRect(hWnd,&rc);
rc.right-=rc.left;
rc.bottom-=rc.top;
TaskbarInfo *taskBar=GetTaskbarInfo((int)dwRefData);
if (taskBar && (taskBar->oldButtonSize.cx!=rc.right || taskBar->oldButtonSize.cy!=rc.bottom))
{
taskBar->oldButtonSize.cx=rc.right;
@@ -1466,6 +1624,15 @@ static void ComputeTaskbarColors( int *data )
static void ShowWinX( void )
{
if (IsWin11())
{
HWND hwnd=FindWindowEx(NULL,NULL,L"Shell_TrayWnd",NULL);
if (hwnd)
PostMessage(hwnd,WM_HOTKEY,590,MAKELPARAM(MOD_WIN,'X'));
return;
}
if (GetWinVersion()>=WIN_VER_WIN10)
{
CComPtr<IUnknown> pImmersiveShell;
@@ -1650,116 +1817,7 @@ static LRESULT CALLBACK SubclassTaskBarProc( HWND hWnd, UINT uMsg, WPARAM wParam
{
if (taskBar->bReplaceButton)
{
if (IsStartButtonSmallIcons(taskBar->taskbarId)!=IsTaskbarSmallIcons())
RecreateStartButton((int)dwRefData);
WINDOWPOS *pPos=(WINDOWPOS*)lParam;
RECT rcTask;
GetWindowRect(hWnd,&rcTask);
MONITORINFO info;
UINT uEdge=GetTaskbarPosition(hWnd,&info,NULL,NULL);
DWORD buttonFlags=SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE;
if (IsWindowVisible(taskBar->taskBar))
buttonFlags|=SWP_SHOWWINDOW;
else
buttonFlags|=SWP_HIDEWINDOW;
APPBARDATA appbar={sizeof(appbar)};
if (SHAppBarMessage(ABM_GETSTATE,&appbar)&ABS_AUTOHIDE)
{
bool bHide=false;
if (uEdge==ABE_LEFT)
bHide=(rcTask.right<info.rcMonitor.left+5);
else if (uEdge==ABE_RIGHT)
bHide=(rcTask.left>info.rcMonitor.right-5);
else if (uEdge==ABE_TOP)
bHide=(rcTask.bottom<info.rcMonitor.top+5);
else
bHide=(rcTask.top>info.rcMonitor.bottom-5);
if (bHide)
buttonFlags=(buttonFlags&~SWP_SHOWWINDOW)|SWP_HIDEWINDOW;
}
if (uEdge==ABE_TOP || uEdge==ABE_BOTTOM)
{
if (rcTask.left<info.rcMonitor.left) rcTask.left=info.rcMonitor.left;
if (rcTask.right>info.rcMonitor.right) rcTask.right=info.rcMonitor.right;
}
else
{
if (rcTask.top<info.rcMonitor.top) rcTask.top=info.rcMonitor.top;
}
if (!IsStartButtonSmallIcons(taskBar->taskbarId))
{
bool bClassic;
if (GetWinVersion()<WIN_VER_WIN8)
bClassic=!IsAppThemed();
else
{
HIGHCONTRAST contrast={sizeof(contrast)};
bClassic=(SystemParametersInfo(SPI_GETHIGHCONTRAST,sizeof(contrast),&contrast,0) && (contrast.dwFlags&HCF_HIGHCONTRASTON));
}
if (!bClassic)
{
if (uEdge==ABE_TOP)
OffsetRect(&rcTask,0,-1);
else if (uEdge==ABE_BOTTOM)
OffsetRect(&rcTask,0,1);
}
}
HWND zPos=NULL;
if (pPos->flags&SWP_NOZORDER)
buttonFlags|=SWP_NOZORDER;
else
{
zPos=pPos->hwndInsertAfter;
if (zPos==HWND_TOP && !(GetWindowLongPtr(taskBar->startButton,GWL_EXSTYLE)&WS_EX_TOPMOST))
zPos=HWND_TOPMOST;
if (zPos==HWND_TOPMOST && !(GetWindowLongPtr(hWnd,GWL_EXSTYLE)&WS_EX_TOPMOST))
zPos=HWND_TOP;
if (zPos==HWND_BOTTOM)
buttonFlags|=SWP_NOZORDER;
if (zPos==taskBar->startButton)
buttonFlags|=SWP_NOZORDER;
}
int x, y;
if (uEdge==ABE_LEFT || uEdge==ABE_RIGHT)
{
if (GetSettingInt(L"StartButtonType")!=START_BUTTON_CUSTOM || !GetSettingBool(L"StartButtonAlign"))
x=(rcTask.left+rcTask.right-taskBar->startButtonSize.cx)/2;
else if (uEdge==ABE_LEFT)
x=rcTask.left;
else
x=rcTask.right-taskBar->startButtonSize.cx;
y=rcTask.top;
}
else
{
if (GetWindowLongPtr(taskBar->rebar,GWL_EXSTYLE)&WS_EX_LAYOUTRTL)
x=rcTask.right-taskBar->startButtonSize.cx;
else
x=rcTask.left;
if (GetSettingInt(L"StartButtonType")!=START_BUTTON_CUSTOM || !GetSettingBool(L"StartButtonAlign"))
y=(rcTask.top+rcTask.bottom-taskBar->startButtonSize.cy)/2;
else if (uEdge==ABE_TOP)
y=rcTask.top;
else
y=rcTask.bottom-taskBar->startButtonSize.cy;
}
RECT rcButton={x,y,x+taskBar->startButtonSize.cx,y+taskBar->startButtonSize.cy};
RECT rc;
IntersectRect(&rc,&rcButton,&info.rcMonitor);
HRGN rgn=CreateRectRgn(rc.left-x,rc.top-y,rc.right-x,rc.bottom-y);
if (!SetWindowRgn(taskBar->startButton,rgn,FALSE))
{
AddTrackedObject(rgn);
DeleteObject(rgn);
}
g_bAllowMoveButton=true;
SetWindowPos(taskBar->startButton,zPos,x,y,0,0,buttonFlags);
g_bAllowMoveButton=false;
if (buttonFlags&SWP_SHOWWINDOW)
UpdateStartButton(taskBar->taskbarId);
UpdateStartButtonPosition(taskBar,(WINDOWPOS*)lParam);
}
if (taskBar->oldButton && GetWinVersion()<WIN_VER_WIN10)
{
@@ -2790,6 +2848,9 @@ static void OpenCortana( void )
static void InitStartMenuDLL( void )
{
LogToFile(STARTUP_LOG, L"StartMenu DLL: InitStartMenuDLL");
WaitDllInitThread();
InitializeIatHooks();
if (IsWin81Update1())
{
@@ -2817,39 +2878,40 @@ static void InitStartMenuDLL( void )
}
}
if (GetWinVersion()>=WIN_VER_WIN10)
if (GetSettingBool(L"CustomTaskbar"))
{
HMODULE shlwapi=GetModuleHandle(L"shlwapi.dll");
if (shlwapi)
if (GetWinVersion()>=WIN_VER_WIN10)
{
g_SHFillRectClr=(tSHFillRectClr)GetProcAddress(shlwapi,MAKEINTRESOURCEA(197));
if (g_SHFillRectClr)
HMODULE shlwapi=GetModuleHandle(L"shlwapi.dll");
if (shlwapi)
{
g_SHFillRectClrHook=SetIatHook(GetModuleHandle(NULL),"shlwapi.dll",MAKEINTRESOURCEA(197),SHFillRectClr2);
if (!g_SHFillRectClrHook)
g_SHFillRectClrHook=SetIatHook(GetModuleHandle(NULL),"api-ms-win-shlwapi-winrt-storage-l1-1-1.dll",MAKEINTRESOURCEA(197),SHFillRectClr2);
g_SHFillRectClr=(tSHFillRectClr)GetProcAddress(shlwapi,MAKEINTRESOURCEA(197));
if (g_SHFillRectClr)
{
g_SHFillRectClrHook=SetIatHook(GetModuleHandle(NULL),"shlwapi.dll",MAKEINTRESOURCEA(197),SHFillRectClr2);
if (!g_SHFillRectClrHook)
g_SHFillRectClrHook=SetIatHook(GetModuleHandle(NULL),"api-ms-win-shlwapi-winrt-storage-l1-1-1.dll",MAKEINTRESOURCEA(197),SHFillRectClr2);
}
}
g_StretchDIBitsHook=SetIatHook(GetModuleHandle(NULL),"gdi32.dll","StretchDIBits",StretchDIBits2);
}
g_StretchDIBitsHook=SetIatHook(GetModuleHandle(NULL),"gdi32.dll","StretchDIBits",StretchDIBits2);
}
{
HWND dlg=CreateWindow(L"#32770",L"",WS_POPUP,0,0,0,0,NULL,0,0,0);
HWND toolbar=CreateWindow(TOOLBARCLASSNAME,L"",WS_CHILD|TBS_TOOLTIPS,0,0,0,0,dlg,0,0,0);
DestroyWindow(dlg);
}
{
HWND dlg=CreateWindow(L"#32770",L"",WS_POPUP,0,0,0,0,NULL,0,0,0);
HWND toolbar=CreateWindow(TOOLBARCLASSNAME,L"",WS_CHILD|TBS_TOOLTIPS,0,0,0,0,dlg,0,0,0);
DestroyWindow(dlg);
}
if (GetWinVersion()<=WIN_VER_WIN81)
g_DrawThemeBackgroundHook=SetIatHook(GetModuleHandle(NULL),"uxtheme.dll","DrawThemeBackground",DrawThemeBackground2);
g_DrawThemeTextHook=SetIatHook(GetModuleHandle(NULL),"uxtheme.dll","DrawThemeText",DrawThemeText2);
g_DrawThemeTextExHook=SetIatHook(GetModuleHandle(NULL),"uxtheme.dll","DrawThemeTextEx",DrawThemeTextEx2);
g_DrawThemeTextCtlHook=SetIatHook(GetModuleHandle(L"comctl32.dll"),"uxtheme.dll","DrawThemeText",DrawThemeText2);
if (GetWinVersion()>=WIN_VER_WIN10)
g_SetWindowCompositionAttributeHook=SetIatHook(GetModuleHandle(NULL),"user32.dll","SetWindowCompositionAttribute",SetWindowCompositionAttribute2);
if (GetWinVersion()<=WIN_VER_WIN81)
g_DrawThemeBackgroundHook=SetIatHook(GetModuleHandle(NULL),"uxtheme.dll","DrawThemeBackground",DrawThemeBackground2);
g_DrawThemeTextHook=SetIatHook(GetModuleHandle(NULL),"uxtheme.dll","DrawThemeText",DrawThemeText2);
g_DrawThemeTextExHook=SetIatHook(GetModuleHandle(NULL),"uxtheme.dll","DrawThemeTextEx",DrawThemeTextEx2);
g_DrawThemeTextCtlHook=SetIatHook(GetModuleHandle(L"comctl32.dll"),"uxtheme.dll","DrawThemeText",DrawThemeText2);
if (GetWinVersion()>=WIN_VER_WIN10)
g_SetWindowCompositionAttributeHook=SetIatHook(GetModuleHandle(NULL),"user32.dll","SetWindowCompositionAttribute",SetWindowCompositionAttribute2);
}
g_TaskbarThreadId=GetCurrentThreadId();
LogToFile(STARTUP_LOG,L"StartMenu DLL: InitStartMenuDLL");
WaitDllInitThread();
g_bTrimHooks=GetWinVersion()==WIN_VER_WIN7 && (GetSettingInt(L"CompatibilityFixes")&COMPATIBILITY_TRIM_HOOKS);
InitManagers(false);
int level=GetSettingInt(L"CrashDump");
@@ -2867,6 +2929,9 @@ static void InitStartMenuDLL( void )
DWORD progThread=GetWindowThreadProcessId(g_ProgWin,NULL);
g_ProgHook=SetWindowsHookEx(WH_GETMESSAGE,HookProgManThread,NULL,progThread);
g_StartHook=SetWindowsHookEx(WH_GETMESSAGE,HookDesktopThread,NULL,GetCurrentThreadId());
if (IsWin11())
g_StartMouseHook=SetWindowsHookEx(WH_MOUSE,HookDesktopThreadMouse,NULL,GetCurrentThreadId());
HWND hwnd=FindWindow(L"OpenShellMenu.CStartHookWindow",L"StartHookWindow");
LoadLibrary(L"StartMenuDLL.dll"); // keep the DLL from unloading
if (hwnd) PostMessage(hwnd,WM_CLEAR,0,0); // tell the exe to unhook this hook
@@ -2988,39 +3053,6 @@ static void RecreateStartButton( size_t taskbarId )
continue;
if (taskBar.bRecreatingButton)
continue;
RECT rcTask;
GetWindowRect(taskBar.taskBar,&rcTask);
RECT rcTask2=rcTask;
MONITORINFO info;
UINT uEdge=GetTaskbarPosition(taskBar.taskBar,&info,NULL,NULL);
if (uEdge==ABE_TOP || uEdge==ABE_BOTTOM)
{
if (rcTask2.left<info.rcMonitor.left) rcTask2.left=info.rcMonitor.left;
if (rcTask2.right>info.rcMonitor.right) rcTask2.right=info.rcMonitor.right;
}
else
{
if (rcTask2.top<info.rcMonitor.top) rcTask2.top=info.rcMonitor.top;
}
if (!IsTaskbarSmallIcons())
{
bool bClassic;
if (GetWinVersion()<WIN_VER_WIN8)
bClassic=!IsAppThemed();
else
{
HIGHCONTRAST contrast={sizeof(contrast)};
bClassic=(SystemParametersInfo(SPI_GETHIGHCONTRAST,sizeof(contrast),&contrast,0) && (contrast.dwFlags&HCF_HIGHCONTRASTON));
}
if (!bClassic)
{
if (uEdge==ABE_TOP)
OffsetRect(&rcTask2,0,-1);
else if (uEdge==ABE_BOTTOM)
OffsetRect(&rcTask2,0,1);
}
}
taskBar.bRecreatingButton=true;
{
@@ -3029,7 +3061,7 @@ static void RecreateStartButton( size_t taskbarId )
RevokeDragDrop(taskBar.startButton);
DestroyStartButton(taskBar.taskbarId);
}
taskBar.startButton=CreateStartButton(taskBar.taskbarId,taskBar.taskBar,taskBar.rebar,rcTask2);
taskBar.startButton=CreateStartButton(taskBar.taskbarId,taskBar.taskBar,taskBar.rebar);
CStartMenuTarget *pNewTarget=new CStartMenuTarget(taskBar.taskbarId);
RegisterDragDrop(taskBar.startButton,pNewTarget);
pNewTarget->Release();
@@ -3045,6 +3077,8 @@ static void RecreateStartButton( size_t taskbarId )
taskBar.oldButtonSize.cy=rc.bottom-rc.top;
}
RECT rcTask;
GetWindowRect(taskBar.taskBar,&rcTask);
PostMessage(taskBar.taskBar,WM_SIZE,SIZE_RESTORED,MAKELONG(rcTask.right-rcTask.left,rcTask.bottom-rcTask.top));
}
}
@@ -3094,6 +3128,8 @@ static void CleanStartMenuDLL( void )
HWND hwnd=FindWindow(L"OpenShellMenu.CStartHookWindow",L"StartHookWindow");
UnhookWindowsHookEx(g_ProgHook);
UnhookWindowsHookEx(g_StartHook);
if (g_StartMouseHook) UnhookWindowsHookEx(g_StartMouseHook);
g_StartMouseHook=NULL;
if (g_AppManagerHook) UnhookWindowsHookEx(g_AppManagerHook);
g_AppManagerHook=NULL;
if (g_NewWindowHook) UnhookWindowsHookEx(g_NewWindowHook);
@@ -3115,7 +3151,8 @@ static void CleanStartMenuDLL( void )
if (it->second.oldButton)
{
RemoveWindowSubclass(it->second.oldButton,SubclassWin81StartButton,'CLSH');
SetWindowPos(it->second.oldButton,NULL,0,0,0,0,SWP_NOSIZE|SWP_NOZORDER);
if (GetWinVersion()<WIN_VER_WIN10 && GetTaskbarPosition(it->second.taskBar,NULL,NULL,NULL)==ABE_BOTTOM)
SetWindowPos(it->second.oldButton,NULL,0,0,0,0,SWP_NOSIZE|SWP_NOZORDER);
RevokeDragDrop(it->second.oldButton);
if (it->second.pOriginalTarget)
RegisterDragDrop(it->second.oldButton,it->second.pOriginalTarget);
@@ -3344,6 +3381,16 @@ static LRESULT CALLBACK HookProgManThread( int code, WPARAM wParam, LPARAM lPara
msg->message=WM_NULL;
if (control==OPEN_CLASSIC)
PostMessage(g_TaskBar,g_StartMenuMsg,MSG_TOGGLE,0);
else if (control==OPEN_CUSTOM)
{
CString commandText=GetSettingString(L"WinKeyCommand");
if (!commandText.IsEmpty())
{
wchar_t expandedCommand[_MAX_PATH]{};
::ExpandEnvironmentStrings(commandText, expandedCommand, _countof(expandedCommand));
ShellExecute(NULL,NULL,expandedCommand,NULL,NULL,SW_SHOWNORMAL);
}
}
}
}
}
@@ -3368,6 +3415,35 @@ static LRESULT CALLBACK HookProgManThread( int code, WPARAM wParam, LPARAM lPara
return CallNextHookEx(NULL,code,wParam,lParam);
}
// WH_MOUSE hook for taskbar thread (Win11+)
static LRESULT CALLBACK HookDesktopThreadMouse(int code, WPARAM wParam, LPARAM lParam)
{
if (code == HC_ACTION)
{
// we need to steal mouse messages that are issues in start button area
// so that they won't get to XAML framework that is handling original start button
auto info = (const MOUSEHOOKSTRUCT*)lParam;
{
auto taskBar = FindTaskBarInfoButton(info->hwnd); // click on start button
if (!taskBar)
{
taskBar = FindTaskBarInfoBar(GetAncestor(info->hwnd, GA_ROOT)); // click on taskbar
if (taskBar && !PointAroundStartButton(taskBar->taskbarId))
taskBar = NULL;
}
if (taskBar && (info->hwnd != taskBar->startButton) && taskBar->oldButton)
{
// steal messages from other than our custom button window
PostMessage(taskBar->oldButton, (UINT)wParam, 0, MAKELPARAM(info->pt.x, info->pt.y));
return 1;
}
}
}
return CallNextHookEx(NULL, code, wParam, lParam);
}
// WH_GETMESSAGE hook for the taskbar thread
static LRESULT CALLBACK HookDesktopThread( int code, WPARAM wParam, LPARAM lParam )
{
@@ -3427,6 +3503,16 @@ if (!g_bTrimHooks)
PostMessage(g_ProgWin,WM_SYSCOMMAND,SC_TASKLIST,'WSMK');
else if (control==OPEN_CORTANA)
OpenCortana();
else if (control==OPEN_CUSTOM)
{
CString commandText=GetSettingString(L"ShiftWinCommand");
if (!commandText.IsEmpty())
{
wchar_t expandedCommand[_MAX_PATH]{};
::ExpandEnvironmentStrings(commandText, expandedCommand, _countof(expandedCommand));
ShellExecute(NULL,NULL,expandedCommand,NULL,NULL,SW_SHOWNORMAL);
}
}
}
else if (msg->wParam==MSG_DRAG || msg->wParam==MSG_SHIFTDRAG)
{
@@ -3586,12 +3672,22 @@ if (!g_bTrimHooks)
// left or middle click on start button
FindWindowsMenu();
const wchar_t *name;
const wchar_t *command;
if (bMiddle)
{
name=L"MiddleClick";
command=L"MiddleClickCommand";
}
else if (GetKeyState(VK_SHIFT)<0)
{
name=L"ShiftClick";
command=L"ShiftClickCommand";
}
else
{
name=L"MouseClick";
command=L"MouseClickCommand";
}
int control=GetSettingInt(name);
if (control==OPEN_BOTH && GetWinVersion()>=WIN_VER_WIN10)
@@ -3607,6 +3703,16 @@ if (!g_bTrimHooks)
PostMessage(g_ProgWin,WM_SYSCOMMAND,SC_TASKLIST,'WSMM');
else if (control==OPEN_CORTANA)
OpenCortana();
else if (control==OPEN_CUSTOM)
{
CString commandText=GetSettingString(command);
if (!commandText.IsEmpty())
{
wchar_t expandedCommand[_MAX_PATH]{};
::ExpandEnvironmentStrings(commandText, expandedCommand, _countof(expandedCommand));
ShellExecute(NULL,NULL,expandedCommand,NULL,NULL,SW_SHOWNORMAL);
}
}
msg->message=WM_NULL;
}
}
@@ -3747,6 +3853,16 @@ if (!g_bTrimHooks)
FindWindowsMenu();
PostMessage(g_ProgWin,WM_SYSCOMMAND,SC_TASKLIST,'WSMM');
}
else if (control==OPEN_CUSTOM)
{
CString commandText=GetSettingString(L"HoverCommand");
if (!commandText.IsEmpty())
{
wchar_t expandedCommand[_MAX_PATH]{};
::ExpandEnvironmentStrings(commandText, expandedCommand, _countof(expandedCommand));
ShellExecute(NULL,NULL,expandedCommand,NULL,NULL,SW_SHOWNORMAL);
}
}
}
}
taskBar->bTimer=false;
@@ -3756,7 +3872,6 @@ if (!g_bTrimHooks)
// context menu
if (msg->message==WM_NCRBUTTONUP || msg->message==WM_RBUTTONUP)
{
CPoint pt0(GetMessagePos());
TaskbarInfo *taskBar=FindTaskBarInfoButton(msg->hwnd);
DWORD winVer=GetWinVersion();
if (!taskBar && winVer>=WIN_VER_WIN8)
@@ -3767,6 +3882,7 @@ if (!g_bTrimHooks)
}
if (taskBar)
{
CPoint pt0(GetMessagePos());
if (msg->message==WM_RBUTTONUP && msg->hwnd==taskBar->startButton && msg->lParam==MAKELPARAM(-1,-1))
{
RECT rc;
@@ -3801,13 +3917,18 @@ if (!g_bTrimHooks)
CMD_OPEN,
CMD_OPEN_ALL,
CMD_EXPLORER,
CMD_OPEN_PINNED,
};
// right-click on the start button - open the context menu (Settings, Help, Exit)
HMENU menu=CreatePopupMenu();
CString title=LoadStringEx(IDS_MENU_TITLE);
if (!title.IsEmpty())
CString titleFmt=LoadStringEx(IDS_MENU_TITLE);
if (!titleFmt.IsEmpty())
{
CString title;
DWORD ver=GetVersionEx(g_Instance);
title.Format(titleFmt,ver>>24,(ver>>16)&0xFF,ver&0xFFFF);
AppendMenu(menu,MF_STRING,0,title);
EnableMenuItem(menu,0,MF_BYPOSITION|MF_DISABLED);
SetMenuDefaultItem(menu,0,TRUE);
@@ -3821,6 +3942,8 @@ if (!g_bTrimHooks)
AppendMenu(menu,MF_STRING,CMD_OPEN,FindTranslation(L"Menu.Open",L"&Open"));
if (!SHRestricted(REST_NOCOMMONGROUPS))
AppendMenu(menu,MF_STRING,CMD_OPEN_ALL,FindTranslation(L"Menu.OpenAll",L"O&pen All Users"));
if (GetSettingInt(L"PinnedPrograms")==PINNED_PROGRAMS_PINNED)
AppendMenu(menu,MF_STRING,CMD_OPEN_PINNED,FindTranslation(L"Menu.OpenPinned",L"O&pen Pinned"));
AppendMenu(menu,MF_SEPARATOR,0,0);
}
if (GetSettingBool(L"EnableSettings"))
@@ -3867,6 +3990,16 @@ if (!g_bTrimHooks)
if (SUCCEEDED(ShGetKnownFolderPath((res==CMD_OPEN)?FOLDERID_StartMenu:FOLDERID_CommonStartMenu,&pPath)))
ShellExecute(NULL,L"open",pPath,NULL,NULL,SW_SHOWNORMAL);
}
if (res==CMD_OPEN_PINNED) // open pinned folder
{
SHELLEXECUTEINFO execute={sizeof(execute)};
CString path=GetSettingString(L"PinnedItemsPath");
execute.lpVerb=L"open";
execute.lpFile=path;
execute.nShow=SW_SHOWNORMAL;
execute.fMask=SEE_MASK_DOENVSUBST;
ShellExecuteEx(&execute);
}
if (res==CMD_EXPLORER)
{
CString path=GetSettingString(L"ExplorerPath");

View File

@@ -51,7 +51,7 @@ struct TaskbarInfo
int taskbarId;
HWND taskBar;
HWND startButton; // either own start button or the win7 start button (depending on bReplaceButton)
HWND oldButton; // win81 start button (child of taskBar)
HWND oldButton; // win8.1+ start button (child of taskBar)
HWND rebar;
HWND taskList;
HWND chevron;
@@ -61,8 +61,8 @@ struct TaskbarInfo
int pointerId;
bool bTimer;
bool bCustomLook;
bool bReplaceButton;
bool bHideButton;
bool bReplaceButton; // replace start button with own one
bool bHideButton; // hide old start button (if we have own button)
bool bRecreatingButton;
bool bThemeChanging;
std::vector<HWND> trayButtons; // ordered by Z order (for win10)

View File

@@ -369,19 +369,20 @@ IDI_START10 ICON "start10.ico"
IDB_ARROWS BITMAP "menu_arrows.bmp"
IDB_ARROWS150 BITMAP "menu_arrows150.bmp"
IDB_SEARCH_ICONS BITMAP "search_icons.bmp"
IDB_STYLE_CLASSIC1 BITMAP "style_classic.bmp"
IDB_STYLE_CLASSIC2 BITMAP "style_vista.bmp"
IDB_STYLE_WIN7 BITMAP "style_7.bmp"
IDB_BTN_CLASSIC BITMAP "btn_classic.bmp"
IDB_STYLE_CLASSIC1150 BITMAP "style_classic150.bmp"
IDB_STYLE_CLASSIC2150 BITMAP "style_vista150.bmp"
IDB_STYLE_WIN7150 BITMAP "style_7150.bmp"
/////////////////////////////////////////////////////////////////////////////
//
// IMAGE
//
IDB_STYLE_CLASSIC1 IMAGE "style_classic.png"
IDB_STYLE_CLASSIC2 IMAGE "style_vista.png"
IDB_STYLE_WIN7 IMAGE "style_7.png"
IDB_STYLE_CLASSIC1150 IMAGE "style_classic150.png"
IDB_STYLE_CLASSIC2150 IMAGE "style_vista150.png"
IDB_STYLE_WIN7150 IMAGE "style_7150.png"
IDB_BUTTON96 IMAGE "button96.png"
IDB_BUTTON120 IMAGE "button120.png"
IDB_BUTTON144 IMAGE "button144.png"
@@ -426,7 +427,7 @@ BEGIN
IDS_SKIN_ERR_LOAD_FILE "Failed to load the variation skin file %s.\r\n"
IDS_SKIN_ERR_LOAD "Error loading %s\n%s"
IDS_SKIN_ERR_VERSION "The selected skin is not compatible with this version of the start menu.\r\n"
IDS_MENU_TITLE "== Open-Shell Menu =="
IDS_MENU_TITLE "Open-Shell Menu %d.%d.%d"
IDS_DEFAULT_SKIN "<No Skin>"
IDS_CONTROLS_SETTINGS "Controls"
IDS_OPEN_NOTHING "Nothing"
@@ -643,6 +644,12 @@ BEGIN
IDS_PIC_COMMAND_TIP "Enter the command you want to run when you click on the user picture"
IDS_NAME_COMMAND "User name command"
IDS_NAME_COMMAND_TIP "Enter the command you want to run when you click on the user name"
IDS_ALIGN_WORK_AREA "Align start menu to working area"
IDS_ALIGN_WORK_AREA_TIP "Align the start menu to the working area instead of to the taskbar. Use with custom taskbars"
IDS_HOR_OFFSET "Horizontal position offset"
IDS_HOR_OFFSET_TIP "Offset the start menu horizontally by the amount of pixels specified"
IDS_VERT_OFFSET "Vertical position offset"
IDS_VERT_OFFSET_TIP "Offset the start menu vertically by the amount of pixels specified"
IDS_SMALL_SIZE_SM "Small icon size"
IDS_SMALL_SIZE_SM_TIP "Set the small icon size. The default is 16 for DPI<=96, 20 for 96<DPI<=120 and 24 for DPI>120"
IDS_LARGE_SIZE_SM "Large icon size"
@@ -1037,7 +1044,7 @@ BEGIN
IDS_FOLDERS_FIRST "Show folders first"
IDS_FOLDERS_FIRST_TIP "When this is checked, the All Programs tree will show the folders first and the programs last"
IDS_PINNED_PROGRAMS "Pinned Programs folder"
IDS_PINNED_PROGRAMS_TIP "Select the location to store the pinned programs"
IDS_PINNED_PROGRAMS_TIP "Select the location to store pinned programs. After updating this setting, close this window in order to pin items through the context menu again"
IDS_FAST_ITEMS "Use Start Menu folder"
END
@@ -1075,7 +1082,7 @@ BEGIN
IDS_MIN_HEIGHT_TIP "The main menu will be at least as tall as this many search results"
IDS_GLASS_OVERRIDE "Override glass color"
IDS_GLASS_OVERRIDE_TIP "Check this to override the system glass color to use in the menu"
IDS_GLASS_COLOR "Menu glass color"
IDS_GLASS_COLOR "Menu glass color (RRGGBB)"
IDS_GLASS_COLOR_TIP "Select the glass color to use in the menu. How much this color affects the menu will depend on the selected skin"
IDS_GLASS_INTENSITY "Menu glass intensity"
IDS_GLASS_INTENSITY_TIP "Select the intensity (brightness) for the glass color in the menu (0 - dark, 100 - bright)"
@@ -1137,37 +1144,37 @@ BEGIN
IDS_STRING7024 "Shadows on glass#The text and the arrows in the second column of the main menu will have a drop shadow"
IDS_STRING7025 "Opaque"
IDS_STRING7026 "Main menu color"
IDS_STRING7027 "Custom color#Select custom color for the main menu"
IDS_STRING7027 "Custom color (RRGGBB)#Select custom color for the main menu"
IDS_STRING7028 "Sub-menu color"
IDS_STRING7029 "Custom color#Select custom color for the sub-menus"
IDS_STRING7029 "Custom color (RRGGBB)#Select custom color for the sub-menus"
IDS_STRING7030 "Silver"
IDS_STRING7031 "Gold"
IDS_STRING7032 "Steel"
IDS_STRING7033 "Titanium"
IDS_STRING7034 "Image for first column#Select custom image for the first column of the main menu"
IDS_STRING7035 "Image for second column#Select custom image for the second column of the main menu"
IDS_STRING7036 "Text color for first column#Select custom color for the first column of the main menu text"
IDS_STRING7037 "Text color for second column#Select custom color for the second column of the main menu text"
IDS_STRING7036 "Text color for first column (RRGGBB)#Select custom color for the first column of the main menu text"
IDS_STRING7037 "Text color for second column (RRGGBB)#Select custom color for the second column of the main menu text"
IDS_STRING7038 "Text size#Select custom size for the main menu text"
END
STRINGTABLE
BEGIN
IDS_STRING7100 "This is the default skin when no other skin is selected or if the selected skin fails to load.\n\nPart of <A HREF=""http://www.classicshell.net/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7101 "Windows Aero skin\n\nDefault skin to use for the Windows Aero theme.\n\nPart of <A HREF=""http://www.classicshell.net/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7102 "Windows Basic skin\n\nDefault skin to use for the Windows Basic theme.\n\nPart of <A HREF=""http://www.classicshell.net/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7103 "Classic skin\n\nClassic look with large or small icons.\n\nPart of <A HREF=""http://www.classicshell.net/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7100 "This is the default skin when no other skin is selected or if the selected skin fails to load.\n\nPart of <A HREF=""https://github.com/Open-Shell/Open-Shell-Menu/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7101 "Windows Aero skin\n\nDefault skin to use for the Windows Aero theme.\n\nPart of <A HREF=""https://github.com/Open-Shell/Open-Shell-Menu/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7102 "Windows Basic skin\n\nDefault skin to use for the Windows Basic theme.\n\nPart of <A HREF=""https://github.com/Open-Shell/Open-Shell-Menu/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7103 "Classic skin\n\nClassic look with large or small icons.\n\nPart of <A HREF=""https://github.com/Open-Shell/Open-Shell-Menu/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
END
STRINGTABLE
BEGIN
IDS_STRING7104 "Full Glass skin\n\nTransparent menu with large or small icons.\n\nPart of <A HREF=""http://www.classicshell.net/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7105 "Smoked Glass skin\n\nSimple transparent menu with dark background.\n\nPart of <A HREF=""http://www.classicshell.net/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7106 "Windows XP Luna skin\n\nA start menu similar to the one in Windows XP.\n\nPart of <A HREF=""http://www.classicshell.net/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7107 "Windows 8 skin\n\nDefault skin to use for Windows 8.\n\nPart of <A HREF=""http://www.classicshell.net/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7108 "Midnight skin\n\nSkin with dark background.\n\nPart of <A HREF=""http://www.classicshell.net/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7109 "Metro skin\n\nSkin that uses the start screen colors.\n\nPart of <A HREF=""http://www.classicshell.net/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7110 "Metallic skin\n\nA start menu skin with metallic look.\n\nPart of <A HREF=""http://www.classicshell.net/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7104 "Full Glass skin\n\nTransparent menu with large or small icons.\n\nPart of <A HREF=""https://github.com/Open-Shell/Open-Shell-Menu/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7105 "Smoked Glass skin\n\nSimple transparent menu with dark background.\n\nPart of <A HREF=""https://github.com/Open-Shell/Open-Shell-Menu/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7106 "Windows XP Luna skin\n\nA start menu similar to the one in Windows XP.\n\nPart of <A HREF=""https://github.com/Open-Shell/Open-Shell-Menu/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7107 "Windows 8 skin\n\nDefault skin to use for Windows 8.\n\nPart of <A HREF=""https://github.com/Open-Shell/Open-Shell-Menu/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7108 "Midnight skin\n\nSkin with dark background.\n\nPart of <A HREF=""https://github.com/Open-Shell/Open-Shell-Menu/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7109 "Metro skin\n\nSkin that uses the start screen colors.\n\nPart of <A HREF=""https://github.com/Open-Shell/Open-Shell-Menu/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
IDS_STRING7110 "Metallic skin\n\nA start menu skin with metallic look.\n\nPart of <A HREF=""https://github.com/Open-Shell/Open-Shell-Menu/"">Open-Shell</A> (c) 2009-2017, Ivo Beltchev"
END
STRINGTABLE
@@ -1242,7 +1249,7 @@ BEGIN
IDS_TASK_AEROGLASS_TIP "The taskbar will have glass transparency that is compatible with the Aero Glass mod"
IDS_TASK_OPACITY "Taskbar opacity"
IDS_TASK_OPACITY_TIP "Set the opacity for the taskbar (0 - transparent, 100 - opaque)"
IDS_TASK_COLOR "Taskbar color"
IDS_TASK_COLOR "Taskbar color (RRGGBB)"
IDS_TASK_COLOR_TIP "Set the color for the taskbar"
IDS_PCSETTINGS "Settings"
IDS_PCSETTINGS_TIP "Shows the modern Settings window"
@@ -1281,13 +1288,41 @@ BEGIN
IDS_TASK_BORDERS "Border sizes"
IDS_TASK_BORDERS_TIP "Select how many pixel on each side of the texture to exclude from stretching"
IDS_TASKBAR_SETTINGS "Taskbar"
IDS_TASK_TEXTCOLOR "Taskbar text color"
IDS_TASK_TEXTCOLOR "Taskbar text color (RRGGBB)"
IDS_TASK_TEXTCOLOR_TIP "Select the color for the text on the taskbar"
IDS_SELECT_LAST "Select the last item in shutdown menu"
IDS_SELECT_LAST_TIP "When this is checked, the last item will be selected by default when the shutdown menu is opened with the keyboard"
IDS_CLEAR_CACHE "Clear cached information"
END
STRINGTABLE
BEGIN
IDS_NO_DBLCLICK "Single-click to open folder shortcuts"
IDS_NO_DBLCLICK_TIP "When this is checked, single-clicking shortcuts (links) to folders will open them in explorer. Hovering over the shortcut will still expand sub-menus"
IDS_BOLD_SETTINGS "Highlight modified settings"
IDS_BOLD_SETTINGS_TIP "When this is checked, settings that have been modified will be highlighted in bold"
IDS_SEARCH_HINT "Custom search hint"
IDS_SEARCH_HINT_TIP "When this is checked, the hint text in the search box will be replaced"
IDS_NEW_SEARCH_HINT "Custom search hint text"
IDS_NEW_SEARCH_HINT_TIP "The text to replace the search hint with. Empty text is a valid option"
IDS_MORE_RESULTS "Enable ""See more results"" option"
IDS_MORE_RESULTS_TIP "When this is checked, the search results will include an option to do a more advanced search"
IDS_OPEN_CMD "Custom command"
IDS_OPEN_CMD_TIP "The action will run a user-defined command"
IDS_OPEN_CMD_TEXT "Command to run"
IDS_OPEN_CMD_TEXT_TIP "Enter the command to run when you use this control"
IDS_ITEM_LINKS "Display as a list of links"
IDS_ITEM_LINKS_TIP "This item will appear as a sub-menu showing only its top-level contents"
END
STRINGTABLE
BEGIN
IDS_OPEN_TRUE_PATH "Open pinned folders to their true path"
IDS_OPEN_TRUE_PATH_TIP "When this is checked, pinned folders will open to their true path instead of the path to their shortcut in the Pinned Programs folder"
IDS_PINNED_PATH "Pinned folder path"
IDS_PINNED_PATH_TIP "The path to use as the Pinned folder. If the path does not exist, it will be created (if possible) after opening the start menu. Close this window after updating this setting to update your context menu.\n\nNote: If you do not have permissions for the selected path, you will not be able to pin items until you take ownership of the new folder"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -754,6 +754,32 @@
#define IDS_SELECT_LAST 3657
#define IDS_SELECT_LAST_TIP 3658
#define IDS_CLEAR_CACHE 3659
#define IDS_ALIGN_WORK_AREA 3660
#define IDS_ALIGN_WORK_AREA_TIP 3661
#define IDS_HOR_OFFSET 3662
#define IDS_HOR_OFFSET_TIP 3663
#define IDS_VERT_OFFSET 3664
#define IDS_VERT_OFFSET_TIP 3665
#define IDS_NO_DBLCLICK 3666
#define IDS_NO_DBLCLICK_TIP 3667
#define IDS_BOLD_SETTINGS 3668
#define IDS_BOLD_SETTINGS_TIP 3669
#define IDS_SEARCH_HINT 3670
#define IDS_SEARCH_HINT_TIP 3671
#define IDS_NEW_SEARCH_HINT 3672
#define IDS_NEW_SEARCH_HINT_TIP 3673
#define IDS_MORE_RESULTS 3674
#define IDS_MORE_RESULTS_TIP 3675
#define IDS_OPEN_CMD 3676
#define IDS_OPEN_CMD_TIP 3677
#define IDS_OPEN_CMD_TEXT 3678
#define IDS_OPEN_CMD_TEXT_TIP 3679
#define IDS_ITEM_LINKS 3680
#define IDS_ITEM_LINKS_TIP 3681
#define IDS_OPEN_TRUE_PATH 3682
#define IDS_OPEN_TRUE_PATH_TIP 3683
#define IDS_PINNED_PATH 3684
#define IDS_PINNED_PATH_TIP 3685
#define IDS_STRING7001 7001
#define IDS_STRING7002 7002
#define IDS_STRING7003 7003

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 = std::move(next);
}
}
}
}
return writer.buffer();
}
ModernSettings::ModernSettings(const wchar_t* fname) : m_storage(fname)
{
if (m_storage)
{
bool valid = false;
auto s = m_storage.get();
ProcessAttributes(s.data, s.size, [&](const ItemHdr& item) {
switch (item.id)
{
case Id::Header:
if (item.size >= sizeof(FileHdr))
{
const auto hdr = (const FileHdr*)item.data();
if (FileHdr() == *hdr)
valid = true;
}
break;
case Id::Blob:
if (valid)
{
const Blob blob = { item.data(), item.size };
ModernSettings::Setting s(blob);
if (s)
m_settings.emplace(s.fileName, blob);
}
break;
}
});
}
}
ModernSettings::Setting::Setting(const Blob& blob)
{
ProcessAttributes(blob.data, blob.size, [&](const ItemHdr& item) {
switch (item.id)
{
case Id::FileName:
fileName = item.asString();
break;
case Id::DeepLink:
deepLink = item.asString();
break;
case Id::Glyph:
glyph = item.asString();
break;
case Id::Icon:
icon = item.asString();
break;
case Id::PageId:
pageId = item.asString();
break;
case Id::HostId:
hostId = item.asString();
break;
case Id::GroupId:
groupId = item.asString();
break;
case Id::SettingId:
settingId = item.asString();
break;
case Id::Description:
description = item.asString();;
break;
case Id::Keywords:
keywords = item.asString();
break;
}
});
}
std::vector<std::wstring_view> ModernSettings::enumerate() const
{
std::vector<std::wstring_view> retval;
retval.reserve(m_settings.size());
for (const auto& i : m_settings)
retval.emplace_back(i.first);
return retval;
}
ModernSettings::Setting ModernSettings::get(const std::wstring_view& name) const
{
auto it = m_settings.find(name);
if (it != m_settings.end())
return { (*it).second };
return {};
}
static std::mutex s_lock;
static std::shared_ptr<ModernSettings> s_settings;
std::wstring GetLocalAppData()
{
WCHAR path[MAX_PATH]{};
wcscpy_s(path, L"%LOCALAPPDATA%\\OpenShell");
DoEnvironmentSubst(path, _countof(path));
// make sure directory exists
SHCreateDirectory(nullptr, path);
return { path };
}
std::shared_ptr<ModernSettings> GetModernSettings()
{
std::unique_lock l(s_lock);
if (!s_settings)
{
auto path = GetLocalAppData();
path += L"\\ModernSettings.dat";
// try to open cached settings
s_settings = std::make_shared<ModernSettings>(path.c_str());
if (s_settings->size() == 0)
{
// file doesn't exist or wrong format
s_settings.reset();
// re-parse settings
auto buffer = ParseModernSettings();
if (!buffer.empty())
{
// store to file
{
File f(path.c_str(), GENERIC_WRITE, 0, CREATE_ALWAYS);
if (f)
{
DWORD written;
::WriteFile(f, buffer.data(), (DWORD)buffer.size(), &written, nullptr);
}
}
// and try again
s_settings = std::make_shared<ModernSettings>(path.c_str());
}
}
}
return s_settings;
}

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,210 @@
// Context menu handler for Open-Shell Modern Settings shell folder
// Based on Explorer Data Provider Sample (https://docs.microsoft.com/en-us/windows/win32/shell/samples-explorerdataprovider)
#include "stdafx.h"
#include "ModernSettings.h"
#include "ModernSettingsContextMenu.h"
#include "ComHelper.h"
#define MENUVERB_OPEN 0
struct ICIVERBTOIDMAP
{
LPCWSTR pszCmd; // verbW
LPCSTR pszCmdA; // verbA
UINT idCmd; // hmenu id
};
static const ICIVERBTOIDMAP g_ContextMenuIDMap[] =
{
{ L"open", "open", MENUVERB_OPEN },
};
HRESULT _MapICIVerbToCmdID(LPCMINVOKECOMMANDINFO pici, UINT* pid)
{
if (IS_INTRESOURCE(pici->lpVerb))
{
*pid = LOWORD((UINT_PTR)pici->lpVerb);
return S_OK;
}
if (pici->fMask & CMIC_MASK_UNICODE)
{
for (const auto& i : g_ContextMenuIDMap)
{
if (StrCmpIC(((LPCMINVOKECOMMANDINFOEX)pici)->lpVerbW, i.pszCmd) == 0)
{
*pid = i.idCmd;
return S_OK;
}
}
}
else
{
for (const auto& i : g_ContextMenuIDMap)
{
if (StrCmpICA(pici->lpVerb, i.pszCmdA) == 0)
{
*pid = i.idCmd;
return S_OK;
}
}
}
return E_FAIL;
}
static bool ActivateModernSettingPage(const WCHAR* page)
{
CComPtr<IApplicationActivationManager> mgr;
mgr.CoCreateInstance(CLSID_ApplicationActivationManager);
if (mgr)
{
DWORD pid = 0;
return SUCCEEDED(mgr->ActivateApplication(L"windows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel", page, AO_NONE, &pid));
}
return false;
}
extern ModernSettings::Setting GetModernSetting(LPCITEMIDLIST pidl);
static HRESULT Execute(const wchar_t* cmd)
{
return (intptr_t)::ShellExecute(nullptr, L"open", cmd, nullptr, nullptr, SW_SHOWNORMAL) > 32 ? S_OK : E_FAIL;
}
static HRESULT OpenItemByPidl(LPCITEMIDLIST pidl)
{
auto child = ILFindLastID(pidl);
auto setting = GetModernSetting(child);
if (!setting)
return E_INVALIDARG;
if (setting.hostId == L"{6E6DDBCB-9C89-434B-A994-D5F22239523B}")
{
if (setting.deepLink.empty())
return E_INVALIDARG;
std::wstring cmd(L"windowsdefender://");
cmd += setting.deepLink;
return Execute(cmd.c_str());
}
if (setting.hostId == L"{7E0522FC-1AC4-41CA-AFD0-3610417A9C41}")
{
if (setting.pageId.empty())
return E_INVALIDARG;
std::wstring cmd(L"shell:::");
cmd += setting.pageId;
return Execute(cmd.c_str());
}
if (setting.hostId == L"{12B1697E-D3A0-4DBC-B568-CCF64A3F934D}")
{
if (setting.deepLink.empty())
return E_INVALIDARG;
std::wstring cmd(setting.deepLink);
if (cmd.compare(0, 8, L"shell:::") == 0)
return Execute(cmd.c_str());
cmd.resize(MAX_PATH);
DoEnvironmentSubst(cmd.data(), (UINT)cmd.size());
STARTUPINFO startupInfo = { sizeof(startupInfo) };
PROCESS_INFORMATION processInfo{};
if (!CreateProcess(nullptr, cmd.data(), nullptr, nullptr, FALSE, 0, nullptr, nullptr, &startupInfo, &processInfo))
return E_FAIL;
CloseHandle(processInfo.hThread);
CloseHandle(processInfo.hProcess);
return S_OK;
}
if (setting.pageId.empty())
return E_INVALIDARG;
std::wstring page;
page += L"page=";
page += setting.pageId;
if (!setting.settingId.empty())
{
page += L"&target=";
page += setting.settingId;
}
else if (!setting.groupId.empty())
{
page += L"&group=";
page += setting.groupId;
}
page += L"&ActivationType=Search";
ActivateModernSettingPage(page.c_str());
return S_OK;
}
// CModernSettingsContextMenu
HRESULT CModernSettingsContextMenu::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT /* idCmdLast */, UINT /* uFlags */)
{
InsertMenu(hmenu, indexMenu++, MF_BYPOSITION, idCmdFirst + MENUVERB_OPEN, L"Open");
// other verbs could go here...
// indicate that we added one verb.
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, (USHORT)(1));
}
HRESULT CModernSettingsContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO pici)
{
HRESULT hr = E_INVALIDARG;
UINT uID;
// Is this command for us?
if (SUCCEEDED(_MapICIVerbToCmdID(pici, &uID)))
{
if (uID == MENUVERB_OPEN && m_pdtobj)
{
CAbsolutePidl pidl;
hr = SHGetIDListFromObject(m_pdtobj, &pidl);
if (SUCCEEDED(hr))
hr = OpenItemByPidl(pidl);
}
}
return hr;
}
HRESULT CModernSettingsContextMenu::GetCommandString(UINT_PTR /* idCmd */, UINT /* uType */, UINT* /* pRes */, LPSTR /* pszName */, UINT /* cchMax */)
{
return E_NOTIMPL;
}
HRESULT CModernSettingsContextMenu::Initialize(PCIDLIST_ABSOLUTE /* pidlFolder */, IDataObject* pdtobj, HKEY /* hkeyProgID */)
{
m_pdtobj = pdtobj;
return S_OK;
}
HRESULT CModernSettingsContextMenu::SetSite(IUnknown* punkSite)
{
m_punkSite = punkSite;
return S_OK;
}
HRESULT CModernSettingsContextMenu::GetSite(REFIID riid, void** ppvSite)
{
return m_punkSite ? m_punkSite->QueryInterface(riid, ppvSite) : E_FAIL;
}

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

Some files were not shown because too many files have changed in this diff Show More