Cleaned up Icon creation (mostly)

Managed to fix large icon creation thanks to
work from Maurizio. Fied an issue with file
selection for Icon generation. Also found a
new issue with ShortcutList that needs
fixing shortly.

https://tabbles.net/how-to-have-large-file-icons-with-shgetfileinfo-in-c/
This commit is contained in:
Terry MacDonald 2020-10-19 21:50:42 +13:00
parent 683bf3d936
commit e34d59c1f7
7 changed files with 1172 additions and 86 deletions

View File

@ -501,7 +501,7 @@ namespace HeliosPlus.GameLibraries
// Next, we need to get the Icons we want to use, and make sure it's the latest one. // Next, we need to get the Icons we want to use, and make sure it's the latest one.
string steamGameIconPath = ""; string steamGameIconPath = "";
// First of all, we attempt to use the Icon that Steam has cached, if it's available, as that will be updated to the latest // First of all, we attempt to use the Icon that Steam has cached, if it's available, as that will be updated to the latest
if (File.Exists(steamAppInfo[steamGameId].GameSteamIconPath)) if (File.Exists(steamAppInfo[steamGameId].GameSteamIconPath) && steamAppInfo[steamGameId].GameSteamIconPath.EndsWith(".ico"))
{ {
steamGameIconPath = steamAppInfo[steamGameId].GameSteamIconPath; steamGameIconPath = steamAppInfo[steamGameId].GameSteamIconPath;
} }
@ -516,6 +516,7 @@ namespace HeliosPlus.GameLibraries
{ {
// Now we need to get the Icon from the app if possible if it's not in the games folder // Now we need to get the Icon from the app if possible if it's not in the games folder
steamGameIconPath = steamGameExe; steamGameIconPath = steamGameExe;
break;
} }
} }

View File

@ -62,6 +62,7 @@
<PropertyGroup /> <PropertyGroup />
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="PresentationCore" />
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
@ -71,6 +72,7 @@
<Reference Include="System.XML" /> <Reference Include="System.XML" />
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Xml.Serialization" /> <Reference Include="System.Xml.Serialization" />
<Reference Include="WindowsBase" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="GameLibraries\Game.cs" /> <Compile Include="GameLibraries\Game.cs" />
@ -80,8 +82,10 @@
<Compile Include="GameLibraries\SteamAppInfoParser\PackageInfo.cs" /> <Compile Include="GameLibraries\SteamAppInfoParser\PackageInfo.cs" />
<Compile Include="GameLibraries\SteamAppInfoParser\App.cs" /> <Compile Include="GameLibraries\SteamAppInfoParser\App.cs" />
<Compile Include="GameLibraries\SteamLibrary.cs" /> <Compile Include="GameLibraries\SteamLibrary.cs" />
<Compile Include="IconFromFile.cs" />
<Compile Include="IconUtils.cs" /> <Compile Include="IconUtils.cs" />
<Compile Include="ProgressReporter.cs" /> <Compile Include="ProgressReporter.cs" />
<Compile Include="ShellIcon.cs" />
<Compile Include="ShortcutItem.cs" /> <Compile Include="ShortcutItem.cs" />
<Compile Include="ShortcutRepository.cs" /> <Compile Include="ShortcutRepository.cs" />
<Compile Include="UIForms\ApplyingProfileForm.cs"> <Compile Include="UIForms\ApplyingProfileForm.cs">
@ -199,6 +203,9 @@
<PackageReference Include="IconLib.Unofficial"> <PackageReference Include="IconLib.Unofficial">
<Version>0.73.0</Version> <Version>0.73.0</Version>
</PackageReference> </PackageReference>
<PackageReference Include="IconPicker">
<Version>2.4.0</Version>
</PackageReference>
<PackageReference Include="ImageListView"> <PackageReference Include="ImageListView">
<Version>13.8.2</Version> <Version>13.8.2</Version>
</PackageReference> </PackageReference>
@ -213,6 +220,9 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="MintPlayer.IconUtils">
<Version>1.0.4</Version>
</PackageReference>
<PackageReference Include="Newtonsoft.Json"> <PackageReference Include="Newtonsoft.Json">
<Version>12.0.3</Version> <Version>12.0.3</Version>
</PackageReference> </PackageReference>

606
HeliosPlus/IconFromFile.cs Normal file
View File

@ -0,0 +1,606 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
//using System.Windows;
using System.Drawing.Imaging;
//using System.Windows.Media.Imaging;
using System.Diagnostics;
using System.Drawing;
using System.Windows;
namespace HeliosPlus
{
class IconFromFile
{
// Constants that we need in the function call
private const int SHGFI_ICON = 0x100;
private const int SHGFI_SMALLICON = 0x1;
private const int SHGFI_LARGEICON = 0x0;
private const int SHIL_JUMBO = 0x4;
private const int SHIL_EXTRALARGE = 0x2;
// This structure will contain information about the file
public struct SHFILEINFO
{
// Handle to the icon representing the file
public IntPtr hIcon;
// Index of the icon within the image list
public int iIcon;
// Various attributes of the file
public uint dwAttributes;
// Path to the file
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string szDisplayName;
// File type
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
};
[System.Runtime.InteropServices.DllImport("Kernel32.dll")]
public static extern Boolean CloseHandle(IntPtr handle);
private struct IMAGELISTDRAWPARAMS
{
public int cbSize;
public IntPtr himl;
public int i;
public IntPtr hdcDst;
public int x;
public int y;
public int cx;
public int cy;
public int xBitmap; // x offest from the upperleft of bitmap
public int yBitmap; // y offset from the upperleft of bitmap
public int rgbBk;
public int rgbFg;
public int fStyle;
public int dwRop;
public int fState;
public int Frame;
public int crEffect;
}
[StructLayout(LayoutKind.Sequential)]
private struct IMAGEINFO
{
public IntPtr hbmImage;
public IntPtr hbmMask;
public int Unused1;
public int Unused2;
public Rect rcImage;
}
#region Private ImageList COM Interop (XP)
[ComImportAttribute()]
[GuidAttribute("46EB5926-582E-4017-9FDF-E8998DAA0950")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
//helpstring("Image List"),
interface IImageList
{
[PreserveSig]
int Add(
IntPtr hbmImage,
IntPtr hbmMask,
ref int pi);
[PreserveSig]
int ReplaceIcon(
int i,
IntPtr hicon,
ref int pi);
[PreserveSig]
int SetOverlayImage(
int iImage,
int iOverlay);
[PreserveSig]
int Replace(
int i,
IntPtr hbmImage,
IntPtr hbmMask);
[PreserveSig]
int AddMasked(
IntPtr hbmImage,
int crMask,
ref int pi);
[PreserveSig]
int Draw(
ref IMAGELISTDRAWPARAMS pimldp);
[PreserveSig]
int Remove(
int i);
[PreserveSig]
int GetIcon(
int i,
int flags,
ref IntPtr picon);
[PreserveSig]
int GetImageInfo(
int i,
ref IMAGEINFO pImageInfo);
[PreserveSig]
int Copy(
int iDst,
IImageList punkSrc,
int iSrc,
int uFlags);
[PreserveSig]
int Merge(
int i1,
IImageList punk2,
int i2,
int dx,
int dy,
ref Guid riid,
ref IntPtr ppv);
[PreserveSig]
int Clone(
ref Guid riid,
ref IntPtr ppv);
[PreserveSig]
int GetImageRect(
int i,
ref Rect prc);
[PreserveSig]
int GetIconSize(
ref int cx,
ref int cy);
[PreserveSig]
int SetIconSize(
int cx,
int cy);
[PreserveSig]
int GetImageCount(
ref int pi);
[PreserveSig]
int SetImageCount(
int uNewCount);
[PreserveSig]
int SetBkColor(
int clrBk,
ref int pclr);
[PreserveSig]
int GetBkColor(
ref int pclr);
[PreserveSig]
int BeginDrag(
int iTrack,
int dxHotspot,
int dyHotspot);
[PreserveSig]
int EndDrag();
[PreserveSig]
int DragEnter(
IntPtr hwndLock,
int x,
int y);
[PreserveSig]
int DragLeave(
IntPtr hwndLock);
[PreserveSig]
int DragMove(
int x,
int y);
[PreserveSig]
int SetDragCursorImage(
ref IImageList punk,
int iDrag,
int dxHotspot,
int dyHotspot);
[PreserveSig]
int DragShowNolock(
int fShow);
/* [PreserveSig]
int GetDragImage(
ref Point ppt,
ref Point pptHotspot,
ref Guid riid,
ref IntPtr ppv);*/
[PreserveSig]
int GetItemFlags(
int i,
ref int dwFlags);
[PreserveSig]
int GetOverlayImage(
int iOverlay,
ref int piIndex);
};
#endregion
///
/// SHGetImageList is not exported correctly in XP. See KB316931
/// http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q316931
/// Apparently (and hopefully) ordinal 727 isn't going to change.
///
[DllImport("shell32.dll", EntryPoint = "#727")]
private extern static int SHGetImageList(
int iImageList,
ref Guid riid,
out IImageList ppv
);
// The signature of SHGetFileInfo (located in Shell32.dll)
[DllImport("Shell32.dll")]
public static extern int SHGetFileInfo(string pszPath, int dwFileAttributes, ref SHFILEINFO psfi, int cbFileInfo, uint uFlags);
[DllImport("Shell32.dll")]
public static extern int SHGetFileInfo(IntPtr pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, int cbFileInfo, uint uFlags);
[DllImport("shell32.dll", SetLastError = true)]
static extern int SHGetSpecialFolderLocation(IntPtr hwndOwner, Int32 nFolder,
ref IntPtr ppidl);
[DllImport("user32")]
public static extern int DestroyIcon(IntPtr hIcon);
public struct pair
{
public System.Drawing.Icon icon { get; set; }
public IntPtr iconHandleToDestroy { set; get; }
}
public static int DestroyIcon2(IntPtr hIcon)
{
return DestroyIcon(hIcon);
}
/*private static BitmapSource bitmap_source_of_icon(System.Drawing.Icon ic)
{
var ic2 = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(ic.Handle,
System.Windows.Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
ic2.Freeze();
return ((BitmapSource)ic2);
}*/
/*public static BitmapSource SystemIcon(bool small, ShellLib.ShellApi.CSIDL csidl)
{
IntPtr pidlTrash = IntPtr.Zero;
int hr = SHGetSpecialFolderLocation(IntPtr.Zero, (int)csidl, ref pidlTrash);
Debug.Assert(hr == 0);
SHFILEINFO shinfo = new SHFILEINFO();
uint SHGFI_USEFILEATTRIBUTES = 0x000000010;
// Get a handle to the large icon
uint flags;
uint SHGFI_PIDL = 0x000000008;
if (!small)
{
flags = SHGFI_PIDL | SHGFI_ICON | SHGFI_LARGEICON | SHGFI_USEFILEATTRIBUTES;
}
else
{
flags = SHGFI_PIDL | SHGFI_ICON | SHGFI_SMALLICON | SHGFI_USEFILEATTRIBUTES;
}
var res = SHGetFileInfo(pidlTrash, 0, ref shinfo, Marshal.SizeOf(shinfo), flags);
Debug.Assert(res != 0);
var myIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon);
Marshal.FreeCoTaskMem(pidlTrash);
var bs = bitmap_source_of_icon(myIcon);
myIcon.Dispose();
bs.Freeze(); // importantissimo se no fa memory leak
DestroyIcon(shinfo.hIcon);
CloseHandle(shinfo.hIcon);
return bs;
}*/
/* public static BitmapSource GetSmallBitmapFromFile(string FileName, bool small, bool checkDisk, bool addOverlay)
{
SHFILEINFO shinfo = new SHFILEINFO();
uint SHGFI_USEFILEATTRIBUTES = 0x000000010;
uint SHGFI_LINKOVERLAY = 0x000008000;
uint flags;
if (small)
{
flags = SHGFI_ICON | SHGFI_SMALLICON;
}
else
{
flags = SHGFI_ICON | SHGFI_LARGEICON;
}
if (!checkDisk)
flags |= SHGFI_USEFILEATTRIBUTES;
if (addOverlay)
flags |= SHGFI_LINKOVERLAY;
var res = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), flags);
if (res == 0)
{
throw (new System.IO.FileNotFoundException());
}
var myIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon);
var bs = bitmap_source_of_icon(myIcon);
myIcon.Dispose();
bs.Freeze(); // importantissimo se no fa memory leak
DestroyIcon(shinfo.hIcon);
CloseHandle(shinfo.hIcon);
return bs;
}*/
public static Bitmap GetSmallBitmapFromFile(string FileName, bool small, bool checkDisk, bool addOverlay)
{
SHFILEINFO shinfo = new SHFILEINFO();
uint SHGFI_USEFILEATTRIBUTES = 0x000000010;
uint SHGFI_LINKOVERLAY = 0x000008000;
uint flags;
if (small)
{
flags = SHGFI_ICON | SHGFI_SMALLICON;
}
else
{
flags = SHGFI_ICON | SHGFI_LARGEICON;
}
if (!checkDisk)
flags |= SHGFI_USEFILEATTRIBUTES;
if (addOverlay)
flags |= SHGFI_LINKOVERLAY;
var res = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), flags);
if (res == 0)
{
throw (new System.IO.FileNotFoundException());
}
var myIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon);
Bitmap bm = myIcon.ToBitmap();
myIcon.Dispose();
DestroyIcon(shinfo.hIcon);
//CloseHandle(shinfo.hIcon);
return bm;
}
/*public static BitmapSource GetLargeBitmapSourceFromFile(string FileName, bool jumbo, bool checkDisk)
{
SHFILEINFO shinfo = new SHFILEINFO();
uint SHGFI_USEFILEATTRIBUTES = 0x000000010;
uint SHGFI_SYSICONINDEX = 0x4000;
int FILE_ATTRIBUTE_NORMAL = 0x80;
uint flags;
flags = SHGFI_SYSICONINDEX;
if (!checkDisk) // This does not seem to work. If I try it, a folder icon is always returned.
flags |= SHGFI_USEFILEATTRIBUTES;
var res = SHGetFileInfo(FileName, FILE_ATTRIBUTE_NORMAL, ref shinfo, Marshal.SizeOf(shinfo), flags);
if (res == 0)
{
throw (new System.IO.FileNotFoundException());
}
var iconIndex = shinfo.iIcon;
// Get the System IImageList object from the Shell:
Guid iidImageList = new Guid("46EB5926-582E-4017-9FDF-E8998DAA0950");
IImageList iml;
int size = jumbo ? SHIL_JUMBO : SHIL_EXTRALARGE;
var hres = SHGetImageList(size, ref iidImageList, out iml); // writes iml
//if (hres == 0)
//{
// throw (new System.Exception("Error SHGetImageList"));
//}
IntPtr hIcon = IntPtr.Zero;
int ILD_TRANSPARENT = 1;
hres = iml.GetIcon(iconIndex, ILD_TRANSPARENT, ref hIcon);
//if (hres == 0)
//{
// throw (new System.Exception("Error iml.GetIcon"));
//}
var myIcon = System.Drawing.Icon.FromHandle(hIcon);
var bs = bitmap_source_of_icon(myIcon);
myIcon.Dispose();
bs.Freeze(); // very important to avoid memory leak
DestroyIcon(hIcon);
CloseHandle(hIcon);
return bs;
}*/
public static Icon GetSmallIconFromFile(string FileName, bool small, bool checkDisk, bool addOverlay)
{
SHFILEINFO shinfo = new SHFILEINFO();
uint SHGFI_USEFILEATTRIBUTES = 0x000000010;
uint SHGFI_LINKOVERLAY = 0x000008000;
uint flags;
if (small)
{
flags = SHGFI_ICON | SHGFI_SMALLICON;
}
else
{
flags = SHGFI_ICON | SHGFI_LARGEICON;
}
if (!checkDisk)
flags |= SHGFI_USEFILEATTRIBUTES;
if (addOverlay)
flags |= SHGFI_LINKOVERLAY;
var res = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), flags);
if (res == 0)
{
throw (new System.IO.FileNotFoundException());
}
var myIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon);
DestroyIcon(shinfo.hIcon);
//CloseHandle(shinfo.hIcon);
return myIcon;
}
public static Icon GetLargeIconFromFile(string FileName, bool jumbo, bool checkDisk)
{
SHFILEINFO shinfo = new SHFILEINFO();
uint SHGFI_USEFILEATTRIBUTES = 0x000000010;
uint SHGFI_SYSICONINDEX = 0x4000;
int FILE_ATTRIBUTE_NORMAL = 0x80;
uint flags;
flags = SHGFI_SYSICONINDEX;
if (!checkDisk) // This does not seem to work. If I try it, a folder icon is always returned.
flags |= SHGFI_USEFILEATTRIBUTES;
var res = SHGetFileInfo(FileName, FILE_ATTRIBUTE_NORMAL, ref shinfo, Marshal.SizeOf(shinfo), flags);
if (res == 0)
{
throw (new System.IO.FileNotFoundException());
}
var iconIndex = shinfo.iIcon;
// Get the System IImageList object from the Shell:
Guid iidImageList = new Guid("46EB5926-582E-4017-9FDF-E8998DAA0950");
IImageList iml;
int size = jumbo ? SHIL_JUMBO : SHIL_EXTRALARGE;
var hres = SHGetImageList(size, ref iidImageList, out iml); // writes iml
//if (hres == 0)
//{
// throw (new System.Exception("Error SHGetImageList"));
//}
IntPtr hIcon = IntPtr.Zero;
int ILD_TRANSPARENT = 1;
hres = iml.GetIcon(iconIndex, ILD_TRANSPARENT, ref hIcon);
//if (hres == 0)
//{
// throw (new System.Exception("Error iml.GetIcon"));
//}
var myIcon = System.Drawing.Icon.FromHandle(hIcon);
//myIcon.Dispose();
DestroyIcon(hIcon);
//CloseHandle(hIcon);
return myIcon;
}
public static Bitmap GetLargeBitmapFromFile(string FileName, bool jumbo, bool checkDisk)
{
SHFILEINFO shinfo = new SHFILEINFO();
uint SHGFI_USEFILEATTRIBUTES = 0x000000010;
uint SHGFI_SYSICONINDEX = 0x4000;
int FILE_ATTRIBUTE_NORMAL = 0x80;
uint flags;
flags = SHGFI_SYSICONINDEX;
if (!checkDisk) // This does not seem to work. If I try it, a folder icon is always returned.
flags |= SHGFI_USEFILEATTRIBUTES;
var res = SHGetFileInfo(FileName, FILE_ATTRIBUTE_NORMAL, ref shinfo, Marshal.SizeOf(shinfo), flags);
if (res == 0)
{
throw (new System.IO.FileNotFoundException());
}
var iconIndex = shinfo.iIcon;
// Get the System IImageList object from the Shell:
Guid iidImageList = new Guid("46EB5926-582E-4017-9FDF-E8998DAA0950");
IImageList iml;
int size = jumbo ? SHIL_JUMBO : SHIL_EXTRALARGE;
var hres = SHGetImageList(size, ref iidImageList, out iml); // writes iml
//if (hres == 0)
//{
// throw (new System.Exception("Error SHGetImageList"));
//}
IntPtr hIcon = IntPtr.Zero;
int ILD_TRANSPARENT = 1;
hres = iml.GetIcon(iconIndex, ILD_TRANSPARENT, ref hIcon);
//if (hres == 0)
//{
// throw (new System.Exception("Error iml.GetIcon"));
//}
var myIcon = System.Drawing.Icon.FromHandle(hIcon);
Bitmap bm = myIcon.ToBitmap();
myIcon.Dispose();
DestroyIcon(hIcon);
//CloseHandle(hIcon);
return bm;
}
}
}

View File

@ -63,6 +63,12 @@ namespace HeliosPlus {
Console.WriteLine($"Copyright © Terry MacDonald 2020-{DateTime.Today.Year}"); Console.WriteLine($"Copyright © Terry MacDonald 2020-{DateTime.Today.Year}");
Console.WriteLine(@"Based on Helios Display Management - Copyright © Soroush Falahati 2017-2020"); Console.WriteLine(@"Based on Helios Display Management - Copyright © Soroush Falahati 2017-2020");
//Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var app = new CommandLineApplication(); var app = new CommandLineApplication();
//app.Name = "HeliosDM+"; //app.Name = "HeliosDM+";

136
HeliosPlus/ShellIcon.cs Normal file
View File

@ -0,0 +1,136 @@
// -----------------------------------------------------------------------
// <copyright file="ShellIcon.cs" company="Mauricio DIAZ ORLICH (madd0@madd0.com)">
// Distributed under Microsoft Public License (MS-PL).
// http://www.opensource.org/licenses/MS-PL
// </copyright>
// -----------------------------------------------------------------------
using System;
using System.Drawing;
using System.Runtime.InteropServices;
namespace HeliosPlus {
/// <summary>
/// Get a small or large Icon with an easy C# function call
/// that returns a 32x32 or 16x16 System.Drawing.Icon depending on which function you call
/// either GetSmallIcon(string fileName) or GetLargeIcon(string fileName)
/// </summary>
public static class ShellIcon
{
#region Interop constants
private const uint FILE_ATTRIBUTE_NORMAL = 0x80;
private const uint FILE_ATTRIBUTE_DIRECTORY = 0x10;
#endregion
#region Interop data types
[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
public IntPtr hIcon;
public IntPtr iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
}
[Flags]
private enum SHGFI : int
{
/// <summary>get icon</summary>
Icon = 0x000000100,
/// <summary>get display name</summary>
DisplayName = 0x000000200,
/// <summary>get type name</summary>
TypeName = 0x000000400,
/// <summary>get attributes</summary>
Attributes = 0x000000800,
/// <summary>get icon location</summary>
IconLocation = 0x000001000,
/// <summary>return exe type</summary>
ExeType = 0x000002000,
/// <summary>get system icon index</summary>
SysIconIndex = 0x000004000,
/// <summary>put a link overlay on icon</summary>
LinkOverlay = 0x000008000,
/// <summary>show icon in selected state</summary>
Selected = 0x000010000,
/// <summary>get only specified attributes</summary>
Attr_Specified = 0x000020000,
/// <summary>get large icon</summary>
LargeIcon = 0x000000000,
/// <summary>get small icon</summary>
SmallIcon = 0x000000001,
/// <summary>get open icon</summary>
OpenIcon = 0x000000002,
/// <summary>get shell size icon</summary>
ShellIconSize = 0x000000004,
/// <summary>pszPath is a pidl</summary>
PIDL = 0x000000008,
/// <summary>use passed dwFileAttribute</summary>
UseFileAttributes = 0x000000010,
/// <summary>apply the appropriate overlays</summary>
AddOverlays = 0x000000020,
/// <summary>Get the index of the overlay in the upper 8 bits of the iIcon</summary>
OverlayIndex = 0x000000040,
}
#endregion
private class Win32
{
[DllImport("shell32.dll")]
public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
[DllImport("User32.dll")]
public static extern int DestroyIcon(IntPtr hIcon);
}
public static Icon GetSmallFolderIcon()
{
return GetIcon("folder", SHGFI.SmallIcon | SHGFI.UseFileAttributes, true);
}
public static Icon GetLargeFolderIcon()
{
return GetIcon("folder", SHGFI.LargeIcon | SHGFI.UseFileAttributes, true);
}
public static Icon GetSmallIcon(string fileName)
{
return GetIcon(fileName, SHGFI.SmallIcon);
}
public static Icon GetLargeIcon(string fileName)
{
return GetIcon(fileName, SHGFI.LargeIcon);
}
public static Icon GetSmallIconFromExtension(string extension)
{
return GetIcon(extension, SHGFI.SmallIcon | SHGFI.UseFileAttributes);
}
public static Icon GetLargeIconFromExtension(string extension)
{
return GetIcon(extension, SHGFI.LargeIcon | SHGFI.UseFileAttributes);
}
private static Icon GetIcon(string fileName, SHGFI flags, bool isFolder = false)
{
SHFILEINFO shinfo = new SHFILEINFO();
IntPtr hImgSmall = Win32.SHGetFileInfo(fileName, isFolder ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL, ref shinfo, (uint)Marshal.SizeOf(shinfo), (uint)(SHGFI.Icon | flags));
Icon icon = (Icon)System.Drawing.Icon.FromHandle(shinfo.hIcon).Clone();
Win32.DestroyIcon(shinfo.hIcon);
return icon;
}
}
}

View File

@ -25,6 +25,8 @@ using System.Threading;
using HeliosPlus.InterProcess; using HeliosPlus.InterProcess;
using HeliosPlus.UIForms; using HeliosPlus.UIForms;
using ComponentFactory.Krypton.Toolkit; using ComponentFactory.Krypton.Toolkit;
using MintPlayer.IconUtils;
using System.Windows.Media.Imaging;
namespace HeliosPlus namespace HeliosPlus
{ {
@ -97,7 +99,7 @@ namespace HeliosPlus
private List<StartProgram> _startPrograms; private List<StartProgram> _startPrograms;
[JsonIgnore] [JsonIgnore]
public string _originalIconPath; public string _originalIconPath;
private Bitmap _shortcutBitmap, _originalBitmap; private Bitmap _shortcutBitmap, _originalLargeBitmap, _originalSmallBitmap;
[JsonIgnore] [JsonIgnore]
public string _savedShortcutIconCacheFilename; public string _savedShortcutIconCacheFilename;
@ -155,13 +157,14 @@ namespace HeliosPlus
// Now we need to find and populate the profileUuid // Now we need to find and populate the profileUuid
_profileUuid = profile.UUID; _profileUuid = profile.UUID;
// We create the OriginalBitmap from the IconPath // We create the OriginalLargeBitmap from the IconPath
_originalBitmap = ToBitmap(_originalIconPath); _originalLargeBitmap = ToLargeBitmap(_originalIconPath);
_originalSmallBitmap = ToSmallBitmap(_originalIconPath);
// We create the ShortcutBitmap from the OriginalBitmap // We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile) // (We only do it if there is a valid profile)
if (_profileToUse is ProfileItem) if (_profileToUse is ProfileItem)
_shortcutBitmap = ToBitmapOverlay(_originalBitmap, _profileToUse.ProfileTightestBitmap, 256, 256); _shortcutBitmap = ToBitmapOverlay(_originalLargeBitmap, _profileToUse.ProfileTightestBitmap, 256, 256);
} }
@ -189,12 +192,12 @@ namespace HeliosPlus
_profileUuid = profile.UUID; _profileUuid = profile.UUID;
// We create the OriginalBitmap from the IconPath // We create the OriginalBitmap from the IconPath
_originalBitmap = ToBitmap(_originalIconPath); _originalLargeBitmap = ToLargeBitmap(_originalIconPath);
// We create the ShortcutBitmap from the OriginalBitmap // We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile) // (We only do it if there is a valid profile)
if (_profileToUse is ProfileItem) if (_profileToUse is ProfileItem)
_shortcutBitmap = ToBitmapOverlay(_originalBitmap, _profileToUse.ProfileTightestBitmap, 256, 256); _shortcutBitmap = ToBitmapOverlay(_originalLargeBitmap, _profileToUse.ProfileTightestBitmap, 256, 256);
} }
@ -236,12 +239,12 @@ namespace HeliosPlus
} }
// We create the OriginalBitmap from the IconPath // We create the OriginalBitmap from the IconPath
_originalBitmap = ToBitmap(_originalIconPath); _originalLargeBitmap = ToLargeBitmap(_originalIconPath);
// We create the ShortcutBitmap from the OriginalBitmap // We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile) // (We only do it if there is a valid profile)
if (_profileToUse is ProfileItem) if (_profileToUse is ProfileItem)
_shortcutBitmap = ToBitmapOverlay(_originalBitmap, _profileToUse.ProfileTightestBitmap, 256, 256); _shortcutBitmap = ToBitmapOverlay(_originalLargeBitmap, _profileToUse.ProfileTightestBitmap, 256, 256);
} }
public ShortcutItem( public ShortcutItem(
@ -280,12 +283,12 @@ namespace HeliosPlus
_profileUuid = profile.UUID; _profileUuid = profile.UUID;
// We create the OriginalBitmap from the IconPath // We create the OriginalBitmap from the IconPath
_originalBitmap = ToBitmap(_originalIconPath); _originalLargeBitmap = ToLargeBitmap(_originalIconPath);
// We create the ShortcutBitmap from the OriginalBitmap // We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile) // (We only do it if there is a valid profile)
if (_profileToUse is ProfileItem) if (_profileToUse is ProfileItem)
_shortcutBitmap = ToBitmapOverlay(_originalBitmap, _profileToUse.ProfileTightestBitmap, 256, 256); _shortcutBitmap = ToBitmapOverlay(_originalLargeBitmap, _profileToUse.ProfileTightestBitmap, 256, 256);
} }
@ -312,12 +315,12 @@ namespace HeliosPlus
_profileUuid = profile.UUID; _profileUuid = profile.UUID;
// We create the OriginalBitmap from the IconPath // We create the OriginalBitmap from the IconPath
_originalBitmap = ToBitmap(_originalIconPath); _originalLargeBitmap = ToLargeBitmap(_originalIconPath);
// We create the ShortcutBitmap from the OriginalBitmap // We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile) // (We only do it if there is a valid profile)
if (_profileToUse is ProfileItem) if (_profileToUse is ProfileItem)
_shortcutBitmap = ToBitmapOverlay(_originalBitmap, _profileToUse.ProfileTightestBitmap, 256, 256); _shortcutBitmap = ToBitmapOverlay(_originalLargeBitmap, _profileToUse.ProfileTightestBitmap, 256, 256);
} }
@ -357,12 +360,12 @@ namespace HeliosPlus
} }
// We create the OriginalBitmap from the IconPath // We create the OriginalBitmap from the IconPath
_originalBitmap = ToBitmap(_originalIconPath); _originalLargeBitmap = ToLargeBitmap(_originalIconPath);
// We create the ShortcutBitmap from the OriginalBitmap // We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile) // (We only do it if there is a valid profile)
if (_profileToUse is ProfileItem) if (_profileToUse is ProfileItem)
_shortcutBitmap = ToBitmapOverlay(_originalBitmap, _profileToUse.ProfileTightestBitmap, 256, 256); _shortcutBitmap = ToBitmapOverlay(_originalLargeBitmap, _profileToUse.ProfileTightestBitmap, 256, 256);
} }
@ -649,25 +652,39 @@ namespace HeliosPlus
_originalIconPath = value; _originalIconPath = value;
// And we do the same for the OriginalBitmap // And we do the same for the OriginalBitmap
_originalBitmap = ToBitmap(_originalIconPath); _originalLargeBitmap = ToLargeBitmap(_originalIconPath);
} }
} }
[JsonConverter(typeof(CustomBitmapConverter))] /*[JsonConverter(typeof(CustomBitmapConverter))]
public Bitmap OriginalBitmap public Bitmap OriginalSmallBitmap
{ {
get get
{ {
return _originalBitmap; return _originalSmallBitmap;
} }
set set
{ {
_originalBitmap = value; _originalSmallBitmap = value;
}
}*/
[JsonConverter(typeof(CustomBitmapConverter))]
public Bitmap OriginalLargeBitmap
{
get
{
return _originalLargeBitmap;
}
set
{
_originalLargeBitmap = value;
// And we do the same for the Bitmap overlay, but only if the ProfileToUse is set // And we do the same for the Bitmap overlay, but only if the ProfileToUse is set
if (_profileToUse is ProfileItem) if (_profileToUse is ProfileItem)
_shortcutBitmap = ToBitmapOverlay(_originalBitmap, _profileToUse.ProfileTightestBitmap, 256, 256); _shortcutBitmap = ToBitmapOverlay(_originalLargeBitmap, _profileToUse.ProfileTightestBitmap, 256, 256);
} }
} }
@ -737,7 +754,7 @@ namespace HeliosPlus
shortcut.GameArguments = GameArguments; shortcut.GameArguments = GameArguments;
shortcut.GameArgumentsRequired = GameArgumentsRequired; shortcut.GameArgumentsRequired = GameArgumentsRequired;
shortcut.OriginalIconPath = OriginalIconPath; shortcut.OriginalIconPath = OriginalIconPath;
shortcut.OriginalBitmap = OriginalBitmap; shortcut.OriginalLargeBitmap = OriginalLargeBitmap;
shortcut.ShortcutBitmap = ShortcutBitmap; shortcut.ShortcutBitmap = ShortcutBitmap;
shortcut.SavedShortcutIconCacheFilename = SavedShortcutIconCacheFilename; shortcut.SavedShortcutIconCacheFilename = SavedShortcutIconCacheFilename;
shortcut.IsPossible = IsPossible; shortcut.IsPossible = IsPossible;
@ -780,7 +797,7 @@ namespace HeliosPlus
} }
} }
public static Bitmap ExtractVistaIcon(Icon icoIcon) /* public static Bitmap ExtractVistaIcon(Icon icoIcon)
{ {
Bitmap bmpPngExtracted = null; Bitmap bmpPngExtracted = null;
try try
@ -815,7 +832,7 @@ namespace HeliosPlus
return null; return null;
} }
return bmpPngExtracted; return bmpPngExtracted;
} }*/
/* public Bitmap ToBitmap(int width = 256, int height = 256, PixelFormat format = PixelFormat.Format32bppArgb) /* public Bitmap ToBitmap(int width = 256, int height = 256, PixelFormat format = PixelFormat.Format32bppArgb)
{ {
@ -831,26 +848,102 @@ namespace HeliosPlus
return bitmap; return bitmap;
}*/ }*/
private Bitmap ToBitmapFromExe(string fileNameAndPath) private const string Shell32 = "shell32.dll";
/*private Bitmap ToBitmapFromExe(string fileNameAndPath)
{ {
/* IconExtractor ie = new IconExtractor(fileNameAndPath); if (String.IsNullOrWhiteSpace(fileNameAndPath))
return null;
*//*IconActions ia = new IconActions();
int index = 0;
var sb = new StringBuilder(fileNameAndPath, 500);
IconReference iconReference = new IconReference(sb.ToString(), index);
var largeIcons = new IntPtr[1];
var smallIcons = new IntPtr[1];
ia.ExtractIcon(iconReference.FilePath, iconReference.IconIndex, largeIcons, smallIcons, 1);
System.Windows.
BitmapSource bitmapSource;
try
{
bitmapSource = Imaging.CreateBitmapSourceFromHIcon(largeIcons[0], Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}
catch
{
return null;
}
ia.DestroyIconAtHandle(largeIcons[0]);
ia.DestroyIconAtHandle(smallIcons[0]);
return bitmapSource;
*//*
//IconFromFile iconFromFile = new IconFromFile();
Bitmap bm = IconFromFile.GetLargeBitmapFromFile(fileNameAndPath, true, true);
return bm;
//var icons = MintPlayer.IconUtils.IconExtractor.Split(fileNameAndPath);
*//*var folder = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(fileNameAndPath), "Split");
if (!System.IO.Directory.Exists(folder)) System.IO.Directory.CreateDirectory(folder);
var index = 1;
foreach (var icon in icons)
{
var filename = System.IO.Path.Combine(folder, "icon_" + (index++).ToString() + ".ico");
using (var fs = new System.IO.FileStream(filename, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite))
{
icon.Save(fs);
}
}
*//*
Icon ExeIcon = ExtractIcon.ExtractIconFromExecutable(fileNameAndPath);
FileStream fs = new FileStream(fileNameAndPath, FileMode.Open, FileAccess.Read, FileShare.Read);
MultiIcon mi = new MultiIcon();
mi.Load(fs);
int count = mi.Count;
TsudaKageyu.IconExtractor ie = new TsudaKageyu.IconExtractor(fileNameAndPath);
Icon[] allIcons = ie.GetAllIcons(); Icon[] allIcons = ie.GetAllIcons();
Icon biggestIcon = allIcons.OrderByDescending(item => item.Size).First(); Icon biggestIcon = allIcons.OrderByDescending(item => item.Size).First();
//_originalBitmap = ExtractVistaIcon(biggestIcon); //_originalBitmap = ExtractVistaIcon(biggestIcon);
Bitmap bitmapToReturn = IconUtil.ToBitmap(biggestIcon); Bitmap bitmapToReturn = IconUtil.ToBitmap(biggestIcon);
if (bitmapToReturn == null) if (bitmapToReturn == null)
bitmapToReturn = biggestIcon.ToBitmap(); bitmapToReturn = biggestIcon.ToBitmap();
return bitmapToReturn;
*/
if (String.IsNullOrWhiteSpace(fileNameAndPath))
return null;
Icon exeIcon = IconUtils.ExtractIcon.ExtractIconFromExecutable(fileNameAndPath);
Bitmap bitmapToReturn = exeIcon.ToBitmap();
exeIcon.Dispose();
return bitmapToReturn;
}
private Bitmap ToBitmapFromIcon(string fileNameAndPath) // Only gets the 32x32 icon!
//Icon exeIcon = IconUtils.ExtractIcon.ExtractIconFromExecutable(fileNameAndPath);
//Bitmap bitmapToReturn = exeIcon.ToBitmap();
//exeIcon.Dispose();
return bitmapToReturn;
}*/
/* public static BitmapSource ConvertBitmap(Bitmap source)
{
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
source.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
}*/
/*public static Bitmap BitmapFromSource(BitmapSource bitmapsource)
{
Bitmap bitmap;
using (var outStream = new MemoryStream())
{
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmapsource));
enc.Save(outStream);
bitmap = new Bitmap(outStream);
}
return bitmap;
}*/
/*private Bitmap ToBitmapFromIcon(string fileNameAndPath)
{ {
if (String.IsNullOrWhiteSpace(fileNameAndPath)) if (String.IsNullOrWhiteSpace(fileNameAndPath))
return null; return null;
@ -859,24 +952,27 @@ namespace HeliosPlus
Bitmap bitmapToReturn = icoIcon.ToBitmap(); Bitmap bitmapToReturn = icoIcon.ToBitmap();
icoIcon.Dispose(); icoIcon.Dispose();
return bitmapToReturn; return bitmapToReturn;
} }*/
private Bitmap ToBitmap(string fileNameAndPath) private Bitmap ToLargeBitmap(string fileNameAndPath)
{ {
if (String.IsNullOrWhiteSpace(fileNameAndPath)) if (String.IsNullOrWhiteSpace(fileNameAndPath))
return null; return null;
string fileExtension = Path.GetExtension(fileNameAndPath); Bitmap bm = IconFromFile.GetLargeBitmapFromFile(fileNameAndPath, true, true);
if (fileExtension.Equals(".ico",StringComparison.OrdinalIgnoreCase)) return bm;
}
private Bitmap ToSmallBitmap(string fileNameAndPath)
{ {
return ToBitmapFromIcon(fileNameAndPath); if (String.IsNullOrWhiteSpace(fileNameAndPath))
} return null;
else
{ Bitmap bm = IconFromFile.GetSmallBitmapFromFile(fileNameAndPath, false, true, false);
return ToBitmapFromExe(fileNameAndPath); return bm;
}
} }
public Bitmap ToBitmapOverlay(Bitmap originalBitmap, Bitmap overlayBitmap, int width, int height, PixelFormat format = PixelFormat.Format32bppArgb) public Bitmap ToBitmapOverlay(Bitmap originalBitmap, Bitmap overlayBitmap, int width, int height, PixelFormat format = PixelFormat.Format32bppArgb)
{ {
@ -919,7 +1015,7 @@ namespace HeliosPlus
return combinedBitmap; return combinedBitmap;
} }
public MultiIcon ToIcon() /*public MultiIcon ToIcon()
{ {
var iconSizes = new[] var iconSizes = new[]
{ {
@ -942,7 +1038,7 @@ namespace HeliosPlus
g.InterpolationMode = InterpolationMode.NearestNeighbor; g.InterpolationMode = InterpolationMode.NearestNeighbor;
g.PixelOffsetMode = PixelOffsetMode.HighQuality; g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.CompositingQuality = CompositingQuality.AssumeLinear; g.CompositingQuality = CompositingQuality.AssumeLinear;
g.DrawImage(_originalBitmap, new Rectangle(0, 0, size.Width, size.Height)); g.DrawImage(_originalLargeBitmap, new Rectangle(0, 0, size.Width, size.Height));
} }
icon.Add(bitmap); icon.Add(bitmap);
@ -957,7 +1053,7 @@ namespace HeliosPlus
multiIcon.SelectedIndex = 0; multiIcon.SelectedIndex = 0;
return multiIcon; return multiIcon;
} }*/
public MultiIcon ToIconOverlay() public MultiIcon ToIconOverlay()
{ {
@ -975,7 +1071,7 @@ namespace HeliosPlus
foreach (var size in iconSizes) foreach (var size in iconSizes)
{ {
Bitmap bitmapOverlay = ToBitmapOverlay(_originalBitmap, ProfileToUse.ProfileTightestBitmap, size.Width, size.Height); Bitmap bitmapOverlay = ToBitmapOverlay(_originalLargeBitmap, ProfileToUse.ProfileTightestBitmap, size.Width, size.Height);
icon.Add(bitmapOverlay); icon.Add(bitmapOverlay);
if (size.Width >= 256 && size.Height >= 256) if (size.Width >= 256 && size.Height >= 256)
@ -991,6 +1087,112 @@ namespace HeliosPlus
return multiIcon; return multiIcon;
} }
/*internal static class ExtractIcon
{
[UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = true, CharSet = CharSet.Unicode)]
//[SuppressUnmanagedCodeSecurity]
internal delegate bool ENUMRESNAMEPROC(IntPtr hModule, IntPtr lpszType, IntPtr lpszName, IntPtr lParam);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr FindResource(IntPtr hModule, IntPtr lpName, IntPtr lpType);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LockResource(IntPtr hResData);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern uint SizeofResource(IntPtr hModule, IntPtr hResInfo);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
//[SuppressUnmanagedCodeSecurity]
public static extern bool EnumResourceNames(IntPtr hModule, IntPtr lpszType, ENUMRESNAMEPROC lpEnumFunc, IntPtr lParam);
private const uint LOAD_LIBRARY_AS_DATAFILE = 0x00000002;
private readonly static IntPtr RT_ICON = (IntPtr)3;
private readonly static IntPtr RT_GROUP_ICON = (IntPtr)14;
public static Icon ExtractIconFromExecutable(string path)
{
IntPtr hModule = LoadLibraryEx(path, IntPtr.Zero, LOAD_LIBRARY_AS_DATAFILE);
var tmpData = new List<byte[]>();
ENUMRESNAMEPROC callback = (h, t, name, l) =>
{
var dir = GetDataFromResource(hModule, RT_GROUP_ICON, name);
// Calculate the size of an entire .icon file.
int count = BitConverter.ToUInt16(dir, 4); // GRPICONDIR.idCount
int len = 6 + 16 * count; // sizeof(ICONDIR) + sizeof(ICONDIRENTRY) * count
for (int i = 0; i < count; ++i)
len += BitConverter.ToInt32(dir, 6 + 14 * i + 8); // GRPICONDIRENTRY.dwBytesInRes
using (var dst = new BinaryWriter(new MemoryStream(len)))
{
// Copy GRPICONDIR to ICONDIR.
dst.Write(dir, 0, 6);
int picOffset = 6 + 16 * count; // sizeof(ICONDIR) + sizeof(ICONDIRENTRY) * count
for (int i = 0; i < count; ++i)
{
// Load the picture.
ushort id = BitConverter.ToUInt16(dir, 6 + 14 * i + 12); // GRPICONDIRENTRY.nID
var pic = GetDataFromResource(hModule, RT_ICON, (IntPtr)id);
// Copy GRPICONDIRENTRY to ICONDIRENTRY.
dst.Seek(6 + 16 * i, 0);
dst.Write(dir, 6 + 14 * i, 8); // First 8bytes are identical.
dst.Write(pic.Length); // ICONDIRENTRY.dwBytesInRes
dst.Write(picOffset); // ICONDIRENTRY.dwImageOffset
// Copy a picture.
dst.Seek(picOffset, 0);
dst.Write(pic, 0, pic.Length);
picOffset += pic.Length;
}
tmpData.Add(((MemoryStream)dst.BaseStream).ToArray());
}
return true;
};
EnumResourceNames(hModule, RT_GROUP_ICON, callback, IntPtr.Zero);
byte[][] iconData = tmpData.ToArray();
using (var ms = new MemoryStream(iconData[0]))
{
return new Icon(ms);
}
}
private static byte[] GetDataFromResource(IntPtr hModule, IntPtr type, IntPtr name)
{
// Load the binary data from the specified resource.
IntPtr hResInfo = FindResource(hModule, name, type);
IntPtr hResData = LoadResource(hModule, hResInfo);
IntPtr pResData = LockResource(hResData);
uint size = SizeofResource(hModule, hResInfo);
byte[] buf = new byte[size];
Marshal.Copy(pResData, buf, 0, buf.Length);
return buf;
}
}
*/
public (bool,string) IsValid() public (bool,string) IsValid()
{ {
@ -1171,6 +1373,144 @@ namespace HeliosPlus
} }
/*internal class IconActions
{
// Constants
// =========
private const string Shell32 = "shell32.dll";
private const string User32 = "user32.dll";
// External Methods
// ================
[DllImport(Shell32, CharSet = CharSet.Auto)]
private static extern int PickIconDlg(IntPtr hwndOwner, StringBuilder lpstrFile, int nMaxFile, ref int lpdwIconIndex);
[DllImport(Shell32, CharSet = CharSet.Auto)]
private static extern uint ExtractIconEx(string szFileName, int nIconIndex, IntPtr[] phiconLarge, IntPtr[] phiconSmall, uint nIcons);
[DllImport(User32, CharSet = CharSet.Auto)]
private static extern bool DestroyIcon(IntPtr handle);
// Methods
// =======
public int PickIconDialog(IntPtr hwndOwner, StringBuilder lpstrFile, int nMaxFile, ref int lpdwIconIndex)
{
return PickIconDlg(hwndOwner, lpstrFile, nMaxFile, ref lpdwIconIndex);
}
public uint ExtractIcon(string szFileName, int nIconIndex, IntPtr[] phiconLarge, IntPtr[] phiconSmall, uint nIcons)
{
return ExtractIconEx(szFileName, nIconIndex, phiconLarge, phiconSmall, nIcons);
}
public bool DestroyIconAtHandle(IntPtr handle)
{
return DestroyIcon(handle);
}
}
public class IconReference
{
// Constants
// =========
private const string comma = ",";
// Variables
// =========
private static readonly Regex regex = new Regex(@".+\,[0-9]+$");
// Properties
// ==========
/// <summary>
/// File path to the icon.
/// </summary>
public string FilePath { get; private set; }
/// <summary>
/// Index of the icon within the file.
/// </summary>
public int IconIndex { get; private set; }
// Constructors
// ============
/// <summary>
/// Constructor.
/// </summary>
/// <param name="reference">A reference for an icon within either an .ico, .exe, or .dll. Must be a valid file location followed by a comma and then an int.</param>
/// <exception cref="RegexMatchTimeoutException">Ignore.</exception>
public IconReference(string reference)
{
if (!regex.IsMatch(reference))
{
throw new ArgumentException("[reference] must be a valid file location followed by a comma and then an int");
}
string[] split = reference.Split(',');
string index = split[split.Length - 1];
string filePath = reference.Substring(0, reference.Length - index.Length - 1);
Setup(filePath, index);
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="filePath">A valid file location for an .ico, .exe, or .dll.</param>
/// <param name="index">The index of the icon wanted within the file.</param>
public IconReference(string filePath, string index)
{
Setup(filePath, index);
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="filePath">A valid file location for an .ico, .exe, or .dll.</param>
/// <param name="index">The index of the icon wanted within the file.</param>
public IconReference(string filePath, int index)
{
Setup(filePath, index);
}
/// <summary>
/// Returns the FileName and the IconIndex separated by a comma
/// </summary>
/// <returns>Returns the FileName and the IconIndex separated by a comma</returns>
public override string ToString()
{
return (FilePath ?? string.Empty) + comma + (IconIndex.ToString() ?? string.Empty);
}
private void Setup(string filepath, string index)
{
if (!int.TryParse(index, out int iconIndex))
{
throw new ArgumentException("Parameter [index] needs to be castable to an integer");
}
Setup(filepath, iconIndex);
}
private void Setup(string filepath, int index)
{
if (index < 0)
{
throw new ArgumentException("Parameter [index] needs to be greater than or equal to zero");
}
FilePath = filepath;
IconIndex = index;
}
}*/
#region JsonConverterBitmap #region JsonConverterBitmap
internal class CustomBitmapConverter : JsonConverter internal class CustomBitmapConverter : JsonConverter
{ {

View File

@ -668,47 +668,34 @@ namespace HeliosPlus.UIForms
// Load the Games ListView // Load the Games ListView
foreach (var game in SteamLibrary.AllInstalledGames.OrderBy(game => game.Name)) foreach (var game in SteamLibrary.AllInstalledGames.OrderBy(game => game.Name))
{ {
if (File.Exists(game.IconPath)) Bitmap bm = null;
{
try try
{ {
if (game.IconPath.EndsWith(".ico")) bm = IconFromFile.GetSmallBitmapFromFile(game.IconPath, false, true, false);
{
// if it's an icon try to load it as a bitmap
il_games.Images.Add(Image.FromFile(game.IconPath));
}
else if (game.IconPath.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase) || game.IconPath.EndsWith(".dll", StringComparison.InvariantCultureIgnoreCase))
{
// otherwise use IconExtractor
/*IconExtractor IconEx = new IconExtractor(game.GameIconPath);
Icon icoAppIcon = IconEx.GetIcon(0); // Because standard System.Drawing.Icon.ExtractAssociatedIcon() returns ONLY 32x32.*/
Icon icoAppIcon = Icon.ExtractAssociatedIcon(game.IconPath);
// We first try high quality icons
Bitmap extractedBitmap = ShortcutItem.ExtractVistaIcon(icoAppIcon);
if (extractedBitmap == null)
extractedBitmap = icoAppIcon.ToBitmap();
il_games.Images.Add(extractedBitmap);
}
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine($"ShortcutForm exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}"); Console.WriteLine($"ShortcutForm exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
il_games.Images.Add(Image.FromFile("Resources/Steam.ico"));
} }
} try
else
{ {
//(Icon)global::Calculate.Properties.Resources.ResourceManager.GetObject("Steam.ico"); bm = IconFromFile.GetSmallBitmapFromFile(game.ExePath, false, true, false);
il_games.Images.Add(Image.FromFile("Resources/Steam.ico")); }
catch (Exception ex)
{
Console.WriteLine($"ShortcutForm exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
bm = Properties.Resources.Steam.ToBitmap();
} }
// Add the images to the images array
il_games.Images.Add(bm);
if (!Visible) if (!Visible)
{ {
return; return;
} }
// ADd the game to the game array
lv_games.Items.Add(new ListViewItem lv_games.Items.Add(new ListViewItem
{ {
Text = game.Name, Text = game.Name,