Skip to content

Commit

Permalink
Refactoring ShellIcons to use CsWin32
Browse files Browse the repository at this point in the history
  • Loading branch information
brondavies committed Nov 1, 2024
1 parent 13e5e53 commit e787acd
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 40 deletions.
53 changes: 14 additions & 39 deletions src/TrayToolbar/Extensions/ShellIcons.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using Windows.Win32;
using Windows.Win32.UI.Controls;
using Windows.Win32.UI.Shell;
using Windows.Win32.UI.WindowsAndMessaging;

namespace TrayToolbar.Extensions
{
public static partial class ShellIcons
public static class ShellIcons
{
public static unsafe Bitmap FetchIconAsBitmap(string path, bool large)
{
Expand All @@ -13,7 +17,7 @@ public static unsafe Bitmap FetchIconAsBitmap(string path, bool large)
gp.Clear(Color.Transparent);
gp.DrawIcon(icon, new Rectangle(0, 0, icon.Width, icon.Height));
}
DestroyIcon(icon.Handle);
PInvoke.DestroyIcon((HICON)icon.Handle);
return bmp;
}

Expand All @@ -23,51 +27,22 @@ public static unsafe Icon FetchIcon(string path, bool large = false)
return icon;
}

static uint SizeOfSHGetFileInfo = (uint)Marshal.SizeOf(new SHFILEINFO());
private static Icon ExtractFromPath(string path, bool large = false)
static uint SizeOfSHGetFileInfo = (uint)Unsafe.SizeOf<SHFILEINFOW>();

Check failure on line 30 in src/TrayToolbar/Extensions/ShellIcons.cs

View workflow job for this annotation

GitHub Actions / build (Debug)

The type or namespace name 'SHFILEINFOW' could not be found (are you missing a using directive or an assembly reference?)
private static unsafe Icon ExtractFromPath(string path, bool large = false)
{
var shinfo = new SHFILEINFO();
var himl = SHGetFileInfo(
var shinfo = new SHFILEINFOW();

Check failure on line 33 in src/TrayToolbar/Extensions/ShellIcons.cs

View workflow job for this annotation

GitHub Actions / build (Debug)

The type or namespace name 'SHFILEINFOW' could not be found (are you missing a using directive or an assembly reference?)
var himl = PInvoke.SHGetFileInfo(

Check failure on line 34 in src/TrayToolbar/Extensions/ShellIcons.cs

View workflow job for this annotation

GitHub Actions / build (Debug)

'PInvoke' does not contain a definition for 'SHGetFileInfo'
path,
0, ref shinfo, SizeOfSHGetFileInfo,
SHGFI_SYSICONINDEX | (large ? SHGFI_LARGEICON : SHGFI_SMALLICON));
0, &shinfo, SizeOfSHGetFileInfo,
SHGFI_FLAGS.SHGFI_SYSICONINDEX | (large ? SHGFI_FLAGS.SHGFI_LARGEICON : SHGFI_FLAGS.SHGFI_SMALLICON));

Icon? icon = null;
var iconHandle = ImageList_GetIcon(himl, shinfo.iIcon, ILD_NORMAL);
var iconHandle = PInvoke.ImageList_GetIcon(new HIMAGELIST((nint)himl), shinfo.iIcon, IMAGE_LIST_DRAW_STYLE.ILD_NORMAL);
if (iconHandle != 0)
{
icon = Icon.FromHandle(iconHandle);
}
return icon ?? SystemIcons.Application;
}

/// <summary>
/// Struct used by SHGetFileInfo function
/// </summary>
[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
};

[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);

[DllImport("Comctl32.dll")]
private static extern IntPtr ImageList_GetIcon(IntPtr himl, int i, int flags);

[DllImport("user32.dll")]
private static extern bool DestroyIcon(IntPtr handle);

private const int ILD_NORMAL = 0x00000000;
private const uint SHGFI_LARGEICON = 0x0;
private const uint SHGFI_SMALLICON = 0x000000001;
private const uint SHGFI_SYSICONINDEX = 0x4000;
}
}
7 changes: 6 additions & 1 deletion src/TrayToolbar/NativeMethods.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
DwmSetWindowAttribute
DestroyIcon
DwmSetWindowAttribute
DWMWINDOWATTRIBUTE
ImageList_GetIcon
IMAGE_LIST_DRAW_STYLE
RegCloseKey
RegNotifyChangeKeyValue
RegOpenKeyEx
SHGetFileInfo

Check warning on line 9 in src/TrayToolbar/NativeMethods.txt

View workflow job for this annotation

GitHub Actions / build (Debug)

This API is only available when targeting a specific CPU architecture. AnyCPU cannot generate this API.
SHGFI_FLAGS
WM_MOUSE*
WM_PAINT
WM_SETTINGCHANGE
Expand Down
1 change: 1 addition & 0 deletions src/TrayToolbar/TrayToolbar.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<PackageIcon>Resources\TrayIcon.png</PackageIcon>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>

<ItemGroup>
Expand Down
6 changes: 6 additions & 0 deletions src/TrayToolbar/TrayToolbar.sln
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,19 @@ EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B5556312-F7AB-4175-B429-DE186E579FAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B5556312-F7AB-4175-B429-DE186E579FAD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B5556312-F7AB-4175-B429-DE186E579FAD}.Debug|x64.ActiveCfg = Debug|x64
{B5556312-F7AB-4175-B429-DE186E579FAD}.Debug|x64.Build.0 = Debug|x64
{B5556312-F7AB-4175-B429-DE186E579FAD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B5556312-F7AB-4175-B429-DE186E579FAD}.Release|Any CPU.Build.0 = Release|Any CPU
{B5556312-F7AB-4175-B429-DE186E579FAD}.Release|x64.ActiveCfg = Release|x64
{B5556312-F7AB-4175-B429-DE186E579FAD}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down

0 comments on commit e787acd

Please sign in to comment.