Skip to content

Commit

Permalink
Modified Icon and Win32Registry to properly support icons with negati…
Browse files Browse the repository at this point in the history
…ve index. The api `ExtractIconExW()` supports negative index.

This effectively reverts changes made for #155.
  • Loading branch information
end2endzone committed Aug 26, 2024
1 parent 094a67f commit 4cbe644
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 7 deletions.
2 changes: 0 additions & 2 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
Changes for 0.10.0

* Deprecated support for icons with negative resource id.
* Fixed issue #6 : (twice) Right-click on a directory with Windows Explorer in the left panel shows the menus twice.
* Fixed issue #31 : (twice) Error in logs for CContextMenu::GetCommandString()
* Fixed issue #109: Implement default and verbose logging.
* Fixed issue #150: ico icon (that do not specifically force index=0) are not working.
* Fixed issue #155: Drop support for loading icons from a resource id (icons with a negative index smaller than -1).
* Fixed issue #157: Compilation fails on Github Action: `fatal error C1083: Cannot open include file: 'atlbase.h': No such file or directory`.
* Fixed issue #158: Compilation fails on Github Action: `CPack error : Problem running WiX.`.
* Fixed issue #159: Unit test fails on Github Actions: TestPlugins.testServices().
Expand Down
17 changes: 14 additions & 3 deletions src/core/Icon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,16 @@ namespace shellanything
{
if (!mFileExtension.empty())
return true;
if (!mPath.empty() && mIndex >= 0) // not a resource id. See Issue #17, #150, #155

//See issue #17, 155, 164.
//An icon with a negative index is valid from the registry.
//Only the special case index = -1 should be considered invalid (Issue #17).
//And ShellAnything accept positive (index) and negative index (resource id). (Issue #155, Issue #164).
if (!mPath.empty() && mIndex != INVALID_ICON_INDEX)
return true;

return false;
}
}

void Icon::ResolveFileExtensionIcon()
{
Expand All @@ -100,7 +106,12 @@ namespace shellanything

//try to find the path to the icon module for the given file extension.
Win32Registry::REGISTRY_ICON resolved_icon = Win32Registry::GetFileTypeIcon(file_extension.c_str());
if (!resolved_icon.path.empty() && resolved_icon.index >= 0) // See Issue #17 #155. Do not accept icons which are resource ids.

//An icon with a negative index is valid from the registry.
//Only the special case index = -1 should be considered invalid (Issue #17).
//And ShellAnything accept positive (index) and negative index (resource id). (Issue #155, Issue #164).
//See issue #17, 155, 164.
if (Win32Registry::IsValid(resolved_icon))
{
//found the icon for the file extension
//replace this menu's icon with the new information
Expand Down
7 changes: 6 additions & 1 deletion src/shared/Win32Registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -684,8 +684,13 @@ namespace Win32Registry
{
if (icon.path.empty())
return false;
if (icon.index == INVALID_ICON_INDEX) //See issue #17

//See issue #17, 155, 164.
//An icon with a negative index is valid from the registry.
//Only the special case index = -1 should be considered invalid (Issue #17).
if (icon.index == INVALID_ICON_INDEX)
return false;

if (IsIconEquals(icon, NULL_ICON))
return false;
return true;
Expand Down
18 changes: 17 additions & 1 deletion src/tests/TestIcon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ namespace shellanything
Icon icon;
icon.SetPath("path/to/a/file.ico");
icon.SetIndex(-99);
ASSERT_FALSE(icon.IsValid());
ASSERT_TRUE(icon.IsValid());
}
}
//--------------------------------------------------------------------------------------------------
Expand All @@ -153,6 +153,22 @@ namespace shellanything
ASSERT_TRUE(icon != Icon::GetDefaultUnknownFileTypeIcon());
}
//--------------------------------------------------------------------------------------------------
TEST_F(TestIcon, testResolveFileExtensionIconHtml)
{
Icon icon;
icon.SetFileExtension("html");

//act
icon.ResolveFileExtensionIcon();

ASSERT_TRUE(icon.GetFileExtension().empty());
ASSERT_FALSE(icon.GetPath().empty());
ASSERT_NE(Icon::INVALID_ICON_INDEX, icon.GetIndex());

// assert we did not resolve to default unknown icon
ASSERT_TRUE(icon != Icon::GetDefaultUnknownFileTypeIcon());
}
//--------------------------------------------------------------------------------------------------
TEST_F(TestIcon, testGetDefaultUnknownFileTypeIcon)
{
Icon icon = Icon::GetDefaultUnknownFileTypeIcon();
Expand Down
63 changes: 63 additions & 0 deletions src/tests/TestWin32Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#pragma warning( pop )

#include "TestWin32Utils.h"
#include "Icon.h"
#include "Win32Utils.h"
#include "ArgumentsHandler.h"

Expand Down Expand Up @@ -652,6 +653,68 @@ namespace shellanything
}
}
//--------------------------------------------------------------------------------------------------
TEST_F(TestWin32Utils, testNegativeIconIndexIssue155) // Issue #155
{
Icon icon;

// On my system, with current implementation,
// Icon::ResolveFileExtensionIcon() resolves HTML file extension to the following:
icon.SetPath("C:\\Program Files\\Internet Explorer\\iexplore.exe");
icon.SetIndex(-17);

// act, load an icon with negative index
HBITMAP hBitmap = Win32Utils::LoadIconFromFileAsBitmap32Bpp(icon.GetPath().c_str(), icon.GetIndex());
ASSERT_NE(hBitmap, Win32Utils::INVALID_BITMAP_HANDLE);

// build output files
std::string test_dir = ra::filesystem::GetTemporaryDirectory();
ASSERT_TRUE(ra::filesystem::CreateDirectory(test_dir.c_str()));
std::string bitmap_filename = ra::testing::GetTestQualifiedName() + ".bmp";
std::string output_path = test_dir + "\\" + bitmap_filename;

// remove data from previous runs
ra::filesystem::DeleteFile(output_path.c_str());

// Save as *.bmp
bool saved = Win32Utils::SaveBitmapFile(output_path.c_str(), hBitmap);
ASSERT_TRUE(saved) << "Failed to save bitmap to file: " << output_path;

// Cleanup
DeleteObject(hBitmap);
}
//--------------------------------------------------------------------------------------------------
TEST_F(TestWin32Utils, testNegativeIconIndexIssue164) // Issue #164
{
Icon icon;

// On my system, Icon::ResolveFileExtensionIcon() resolves 'txt' file extension to a negative icon index
icon.SetFileExtension("txt");
icon.ResolveFileExtensionIcon();

ASSERT_TRUE(icon.IsValid());
ASSERT_TRUE(icon.GetIndex() < 1);

// act, load an icon with negative index
HBITMAP hBitmap = Win32Utils::LoadIconFromFileAsBitmap32Bpp(icon.GetPath().c_str(), icon.GetIndex());
ASSERT_NE(hBitmap, Win32Utils::INVALID_BITMAP_HANDLE);

// build output files
std::string test_dir = ra::filesystem::GetTemporaryDirectory();
ASSERT_TRUE(ra::filesystem::CreateDirectory(test_dir.c_str()));
std::string bitmap_filename = ra::testing::GetTestQualifiedName() + ".bmp";
std::string output_path = test_dir + "\\" + bitmap_filename;

// remove data from previous runs
ra::filesystem::DeleteFile(output_path.c_str());

// Save as *.bmp
bool saved = Win32Utils::SaveBitmapFile(output_path.c_str(), hBitmap);
ASSERT_TRUE(saved) << "Failed to save bitmap to file: " << output_path;

// Cleanup
DeleteObject(hBitmap);
}
//--------------------------------------------------------------------------------------------------

} //namespace test
} //namespace shellanything

0 comments on commit 4cbe644

Please sign in to comment.