Skip to content

Commit 183becd

Browse files
committed
Fixed issue #117: Menu entries with icons that uses an icon file (.ico) does not work when scale is greater than 100%.
1 parent 9d589d0 commit 183becd

File tree

2 files changed

+18
-20
lines changed

2 files changed

+18
-20
lines changed

CHANGES

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Changes for 0.8.0
1414
* Fixed issue #101: Deprecate setup.exe installer in favor of the Windows Installer (*.msi).
1515
* Fixed issue #113: Upgrading from v0.7.0 to 0.8.0 installs at the wrong location.
1616
* Fixed issue #114: Implement sa_plugin_terminate() in the C API.
17+
* Fixed issue #117: Menu entries with icons that uses an icon file (.ico) does not work when scale is greater than 100%.
1718
* Fixed issue #118: Registry corruption while registering the extension.
1819
* Fixed issue #119: Disable logs when the shell extension is loaded by registry editor (regedit.exe).
1920

src/shellextension/CContextMenu.cpp

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -158,46 +158,43 @@ void CContextMenu::BuildMenuTree(HMENU hMenu, shellanything::Menu* menu, UINT& i
158158
//if nothing in cache, create a new one
159159
if (hBitmap == shellanything::BitmapCache::INVALID_BITMAP_HANDLE && !icon_filename.empty())
160160
{
161-
HICON hIconLarge = NULL;
161+
// #117 - ExtractIconEx() behavior is different when the monitor is scaled. A small and a large icon
162+
// cannot always be extracted when scaling factor is greater than 1.0. The solution is to only extract a small icon.
163+
// Small icons matches the size of a menu icon (16x16). A "large" (or larger) icon is not necessary.
164+
// The size of a small icon is scaled to match the monitor scaling. For 300% scaling, menu icons are 48x48.
162165
HICON hIconSmall = NULL;
163166

164167
std::wstring icon_filename_wide = ra::unicode::Utf8ToUnicode(icon_filename);
165168

166169
//check how many icons the file contains
167-
UINT numIconInFile = ExtractIconExW(icon_filename_wide.c_str(), -1, NULL, NULL, 1);
168-
if (numIconInFile == 0)
169-
LOG(ERROR) << __FUNCTION__ << "(), File '" << icon_filename << "' does not contains an icon.";
170+
UINT num_icon_in_file = ExtractIconExW(icon_filename_wide.c_str(), -1, NULL, NULL, 1);
171+
if (num_icon_in_file == 0)
172+
LOG(WARNING) << __FUNCTION__ << "(), File '" << icon_filename << "' does not contains an icon.";
170173
else
171174
{
172-
//the file contains 1 or more icons, try to load a small and a large one
173-
UINT numIconLoaded = 0;
174-
if (numIconInFile >= 1)
175-
numIconLoaded = ExtractIconExW(icon_filename_wide.c_str(), icon_index, &hIconLarge, &hIconSmall, 1);
176-
if (numIconInFile >= 1 && numIconLoaded == 0)
177-
LOG(ERROR) << __FUNCTION__ << "(), Failed to load icon index " << icon_index << " from file '" << icon_filename << "'.";
175+
//the file contains 1 or more icons, try to load a small one
176+
UINT num_icon_loaded = 0;
177+
if (num_icon_in_file >= 1)
178+
num_icon_loaded = ExtractIconExW(icon_filename_wide.c_str(), icon_index, NULL, &hIconSmall, 1);
179+
if (num_icon_in_file >= 1 && num_icon_loaded == 0)
180+
LOG(WARNING) << __FUNCTION__ << "(), Failed to load icon index " << icon_index << " from file '" << icon_filename << "'.";
178181
else
179182
{
180-
//Find the best icon
181-
HICON hIcon = Win32Utils::GetBestIconForMenu(hIconLarge, hIconSmall);
183+
SIZE menu_icon_size = Win32Utils::GetIconSize(hIconSmall);
184+
// LOG(INFO) << __FUNCTION__ << "(), Loaded icon " << icon_index << " from file '" << icon_filename << "' is " << menu_icon_size.cx << "x" << menu_icon_size.cy << ".";
182185

183-
SIZE menu_icon_size = Win32Utils::GetIconSize(hIcon);
184-
LOG(INFO) << __FUNCTION__ << "(), Icon " << icon_index << " from file '" << icon_filename << "' is " << menu_icon_size.cx << "x" << menu_icon_size.cy << ".";
185-
186-
//Convert the icon to a bitmap (with invisible background)
187-
hBitmap = Win32Utils::CopyAsBitmap(hIcon);
186+
//Convert the icon to a 32bpp bitmap with alpha channel (invisible background)
187+
hBitmap = Win32Utils::CopyAsBitmap(hIconSmall);
188188
if (hBitmap == shellanything::BitmapCache::INVALID_BITMAP_HANDLE)
189189
LOG(ERROR) << __FUNCTION__ << "(), Icon " << icon_index << " from file '" << icon_filename << "' has failed to convert to bitmap.";
190190

191-
if (hIconLarge != NULL)
192-
DestroyIcon(hIconLarge);
193191
if (hIconSmall != NULL)
194192
DestroyIcon(hIconSmall);
195193

196194
//add the bitmap to the cache for future use
197195
if (hBitmap != shellanything::BitmapCache::INVALID_BITMAP_HANDLE)
198196
m_BitmapCache.AddHandle(icon_filename.c_str(), icon_index, hBitmap);
199197
}
200-
201198
}
202199
}
203200

0 commit comments

Comments
 (0)