@@ -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