mirror of
https://github.com/terrymacdonald/DisplayMagician.git
synced 2024-08-30 18:32:20 +00:00
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:
parent
683bf3d936
commit
e34d59c1f7
@ -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.
|
||||
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
|
||||
if (File.Exists(steamAppInfo[steamGameId].GameSteamIconPath))
|
||||
if (File.Exists(steamAppInfo[steamGameId].GameSteamIconPath) && steamAppInfo[steamGameId].GameSteamIconPath.EndsWith(".ico"))
|
||||
{
|
||||
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
|
||||
steamGameIconPath = steamGameExe;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,6 +62,7 @@
|
||||
<PropertyGroup />
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data" />
|
||||
@ -71,6 +72,7 @@
|
||||
<Reference Include="System.XML" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Xml.Serialization" />
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="GameLibraries\Game.cs" />
|
||||
@ -80,8 +82,10 @@
|
||||
<Compile Include="GameLibraries\SteamAppInfoParser\PackageInfo.cs" />
|
||||
<Compile Include="GameLibraries\SteamAppInfoParser\App.cs" />
|
||||
<Compile Include="GameLibraries\SteamLibrary.cs" />
|
||||
<Compile Include="IconFromFile.cs" />
|
||||
<Compile Include="IconUtils.cs" />
|
||||
<Compile Include="ProgressReporter.cs" />
|
||||
<Compile Include="ShellIcon.cs" />
|
||||
<Compile Include="ShortcutItem.cs" />
|
||||
<Compile Include="ShortcutRepository.cs" />
|
||||
<Compile Include="UIForms\ApplyingProfileForm.cs">
|
||||
@ -199,6 +203,9 @@
|
||||
<PackageReference Include="IconLib.Unofficial">
|
||||
<Version>0.73.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="IconPicker">
|
||||
<Version>2.4.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="ImageListView">
|
||||
<Version>13.8.2</Version>
|
||||
</PackageReference>
|
||||
@ -213,6 +220,9 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MintPlayer.IconUtils">
|
||||
<Version>1.0.4</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json">
|
||||
<Version>12.0.3</Version>
|
||||
</PackageReference>
|
||||
|
606
HeliosPlus/IconFromFile.cs
Normal file
606
HeliosPlus/IconFromFile.cs
Normal 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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -63,6 +63,12 @@ namespace HeliosPlus {
|
||||
Console.WriteLine($"Copyright © Terry MacDonald 2020-{DateTime.Today.Year}");
|
||||
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();
|
||||
|
||||
//app.Name = "HeliosDM+";
|
||||
|
136
HeliosPlus/ShellIcon.cs
Normal file
136
HeliosPlus/ShellIcon.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -25,6 +25,8 @@ using System.Threading;
|
||||
using HeliosPlus.InterProcess;
|
||||
using HeliosPlus.UIForms;
|
||||
using ComponentFactory.Krypton.Toolkit;
|
||||
using MintPlayer.IconUtils;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace HeliosPlus
|
||||
{
|
||||
@ -97,7 +99,7 @@ namespace HeliosPlus
|
||||
private List<StartProgram> _startPrograms;
|
||||
[JsonIgnore]
|
||||
public string _originalIconPath;
|
||||
private Bitmap _shortcutBitmap, _originalBitmap;
|
||||
private Bitmap _shortcutBitmap, _originalLargeBitmap, _originalSmallBitmap;
|
||||
[JsonIgnore]
|
||||
public string _savedShortcutIconCacheFilename;
|
||||
|
||||
@ -155,13 +157,14 @@ namespace HeliosPlus
|
||||
// Now we need to find and populate the profileUuid
|
||||
_profileUuid = profile.UUID;
|
||||
|
||||
// We create the OriginalBitmap from the IconPath
|
||||
_originalBitmap = ToBitmap(_originalIconPath);
|
||||
// We create the OriginalLargeBitmap from the IconPath
|
||||
_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
|
||||
_originalSmallBitmap = ToSmallBitmap(_originalIconPath);
|
||||
|
||||
// We create the ShortcutBitmap from the OriginalBitmap
|
||||
// (We only do it if there is a valid profile)
|
||||
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;
|
||||
|
||||
// We create the OriginalBitmap from the IconPath
|
||||
_originalBitmap = ToBitmap(_originalIconPath);
|
||||
_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
|
||||
|
||||
// We create the ShortcutBitmap from the OriginalBitmap
|
||||
// (We only do it if there is a valid profile)
|
||||
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
|
||||
_originalBitmap = ToBitmap(_originalIconPath);
|
||||
_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
|
||||
|
||||
// We create the ShortcutBitmap from the OriginalBitmap
|
||||
// (We only do it if there is a valid profile)
|
||||
if (_profileToUse is ProfileItem)
|
||||
_shortcutBitmap = ToBitmapOverlay(_originalBitmap, _profileToUse.ProfileTightestBitmap, 256, 256);
|
||||
_shortcutBitmap = ToBitmapOverlay(_originalLargeBitmap, _profileToUse.ProfileTightestBitmap, 256, 256);
|
||||
}
|
||||
|
||||
public ShortcutItem(
|
||||
@ -280,12 +283,12 @@ namespace HeliosPlus
|
||||
_profileUuid = profile.UUID;
|
||||
|
||||
// We create the OriginalBitmap from the IconPath
|
||||
_originalBitmap = ToBitmap(_originalIconPath);
|
||||
_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
|
||||
|
||||
// We create the ShortcutBitmap from the OriginalBitmap
|
||||
// (We only do it if there is a valid profile)
|
||||
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;
|
||||
|
||||
// We create the OriginalBitmap from the IconPath
|
||||
_originalBitmap = ToBitmap(_originalIconPath);
|
||||
_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
|
||||
|
||||
// We create the ShortcutBitmap from the OriginalBitmap
|
||||
// (We only do it if there is a valid profile)
|
||||
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
|
||||
_originalBitmap = ToBitmap(_originalIconPath);
|
||||
_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
|
||||
|
||||
// We create the ShortcutBitmap from the OriginalBitmap
|
||||
// (We only do it if there is a valid profile)
|
||||
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;
|
||||
|
||||
// And we do the same for the OriginalBitmap
|
||||
_originalBitmap = ToBitmap(_originalIconPath);
|
||||
_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
|
||||
}
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(CustomBitmapConverter))]
|
||||
public Bitmap OriginalBitmap
|
||||
/*[JsonConverter(typeof(CustomBitmapConverter))]
|
||||
public Bitmap OriginalSmallBitmap
|
||||
{
|
||||
get
|
||||
{
|
||||
return _originalBitmap;
|
||||
return _originalSmallBitmap;
|
||||
}
|
||||
|
||||
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
|
||||
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.GameArgumentsRequired = GameArgumentsRequired;
|
||||
shortcut.OriginalIconPath = OriginalIconPath;
|
||||
shortcut.OriginalBitmap = OriginalBitmap;
|
||||
shortcut.OriginalLargeBitmap = OriginalLargeBitmap;
|
||||
shortcut.ShortcutBitmap = ShortcutBitmap;
|
||||
shortcut.SavedShortcutIconCacheFilename = SavedShortcutIconCacheFilename;
|
||||
shortcut.IsPossible = IsPossible;
|
||||
@ -780,7 +797,7 @@ namespace HeliosPlus
|
||||
}
|
||||
}
|
||||
|
||||
public static Bitmap ExtractVistaIcon(Icon icoIcon)
|
||||
/* public static Bitmap ExtractVistaIcon(Icon icoIcon)
|
||||
{
|
||||
Bitmap bmpPngExtracted = null;
|
||||
try
|
||||
@ -815,7 +832,7 @@ namespace HeliosPlus
|
||||
return null;
|
||||
}
|
||||
return bmpPngExtracted;
|
||||
}
|
||||
}*/
|
||||
|
||||
/* public Bitmap ToBitmap(int width = 256, int height = 256, PixelFormat format = PixelFormat.Format32bppArgb)
|
||||
{
|
||||
@ -831,26 +848,102 @@ namespace HeliosPlus
|
||||
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 biggestIcon = allIcons.OrderByDescending(item => item.Size).First();
|
||||
//_originalBitmap = ExtractVistaIcon(biggestIcon);
|
||||
Bitmap bitmapToReturn = IconUtil.ToBitmap(biggestIcon);
|
||||
if (bitmapToReturn == null)
|
||||
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))
|
||||
return null;
|
||||
@ -859,24 +952,27 @@ namespace HeliosPlus
|
||||
Bitmap bitmapToReturn = icoIcon.ToBitmap();
|
||||
icoIcon.Dispose();
|
||||
return bitmapToReturn;
|
||||
}
|
||||
}*/
|
||||
|
||||
private Bitmap ToBitmap(string fileNameAndPath)
|
||||
private Bitmap ToLargeBitmap(string fileNameAndPath)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(fileNameAndPath))
|
||||
return null;
|
||||
|
||||
string fileExtension = Path.GetExtension(fileNameAndPath);
|
||||
if (fileExtension.Equals(".ico",StringComparison.OrdinalIgnoreCase))
|
||||
Bitmap bm = IconFromFile.GetLargeBitmapFromFile(fileNameAndPath, true, true);
|
||||
return bm;
|
||||
}
|
||||
|
||||
private Bitmap ToSmallBitmap(string fileNameAndPath)
|
||||
{
|
||||
return ToBitmapFromIcon(fileNameAndPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ToBitmapFromExe(fileNameAndPath);
|
||||
}
|
||||
if (String.IsNullOrWhiteSpace(fileNameAndPath))
|
||||
return null;
|
||||
|
||||
Bitmap bm = IconFromFile.GetSmallBitmapFromFile(fileNameAndPath, false, true, false);
|
||||
return bm;
|
||||
}
|
||||
|
||||
|
||||
public Bitmap ToBitmapOverlay(Bitmap originalBitmap, Bitmap overlayBitmap, int width, int height, PixelFormat format = PixelFormat.Format32bppArgb)
|
||||
{
|
||||
|
||||
@ -919,7 +1015,7 @@ namespace HeliosPlus
|
||||
return combinedBitmap;
|
||||
}
|
||||
|
||||
public MultiIcon ToIcon()
|
||||
/*public MultiIcon ToIcon()
|
||||
{
|
||||
var iconSizes = new[]
|
||||
{
|
||||
@ -942,7 +1038,7 @@ namespace HeliosPlus
|
||||
g.InterpolationMode = InterpolationMode.NearestNeighbor;
|
||||
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||
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);
|
||||
@ -957,7 +1053,7 @@ namespace HeliosPlus
|
||||
multiIcon.SelectedIndex = 0;
|
||||
|
||||
return multiIcon;
|
||||
}
|
||||
}*/
|
||||
|
||||
public MultiIcon ToIconOverlay()
|
||||
{
|
||||
@ -975,7 +1071,7 @@ namespace HeliosPlus
|
||||
|
||||
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);
|
||||
|
||||
if (size.Width >= 256 && size.Height >= 256)
|
||||
@ -991,6 +1087,112 @@ namespace HeliosPlus
|
||||
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()
|
||||
{
|
||||
@ -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
|
||||
internal class CustomBitmapConverter : JsonConverter
|
||||
{
|
||||
|
@ -668,47 +668,34 @@ namespace HeliosPlus.UIForms
|
||||
// Load the Games ListView
|
||||
foreach (var game in SteamLibrary.AllInstalledGames.OrderBy(game => game.Name))
|
||||
{
|
||||
if (File.Exists(game.IconPath))
|
||||
{
|
||||
Bitmap bm = null;
|
||||
try
|
||||
{
|
||||
if (game.IconPath.EndsWith(".ico"))
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
bm = IconFromFile.GetSmallBitmapFromFile(game.IconPath, false, true, false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ShortcutForm exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||
il_games.Images.Add(Image.FromFile("Resources/Steam.ico"));
|
||||
}
|
||||
}
|
||||
else
|
||||
try
|
||||
{
|
||||
//(Icon)global::Calculate.Properties.Resources.ResourceManager.GetObject("Steam.ico");
|
||||
il_games.Images.Add(Image.FromFile("Resources/Steam.ico"));
|
||||
bm = IconFromFile.GetSmallBitmapFromFile(game.ExePath, false, true, false);
|
||||
}
|
||||
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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// ADd the game to the game array
|
||||
lv_games.Items.Add(new ListViewItem
|
||||
{
|
||||
Text = game.Name,
|
||||
|
Loading…
Reference in New Issue
Block a user