mirror of
https://github.com/Hofknecht/SystemTrayMenu.git
synced 2024-05-05 21:12:39 +12:00
[Feature] Show icons of *.ico files and links to *.ico files (#396), version 1.2.9.16
This commit is contained in:
parent
e5e1f848e4
commit
532716ea12
|
@ -470,7 +470,7 @@ namespace SystemTrayMenu.Business
|
|||
RowData rowData = ReadRowData(directory, false, true);
|
||||
rowData.HiddenEntry = hiddenEntry;
|
||||
string resolvedLnkPath = string.Empty;
|
||||
rowData.ReadIcon(true, ref resolvedLnkPath, level);
|
||||
rowData.ReadIconOrResolveLinkAndReadIcon(true, ref resolvedLnkPath, level);
|
||||
rowData.MenuLevel = level;
|
||||
menuData.RowDatas.Add(rowData);
|
||||
}
|
||||
|
@ -528,7 +528,7 @@ namespace SystemTrayMenu.Business
|
|||
}
|
||||
|
||||
string resolvedLnkPath = string.Empty;
|
||||
if (rowData.ReadIcon(false, ref resolvedLnkPath, level))
|
||||
if (rowData.ReadIconOrResolveLinkAndReadIcon(false, ref resolvedLnkPath, level))
|
||||
{
|
||||
rowData = ReadRowData(resolvedLnkPath, true, true, rowData);
|
||||
rowData.HiddenEntry = hiddenEntry;
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace SystemTrayMenu
|
|||
{
|
||||
private static readonly Icon SystemTrayMenu = Properties.Resources.SystemTrayMenu;
|
||||
private static readonly Icon IconFromRootFolder = IconReader.GetIconSTA(
|
||||
Path, false, IconReader.IconSize.Small, IconReader.FolderType.Closed);
|
||||
Path, Path, false, IconReader.IconSize.Small, IconReader.FolderType.Closed);
|
||||
|
||||
private static bool readDarkModeDone;
|
||||
private static bool isDarkMode;
|
||||
|
|
|
@ -81,7 +81,7 @@ namespace SystemTrayMenu.DataClasses
|
|||
row[2] = data;
|
||||
}
|
||||
|
||||
internal bool ReadIcon(bool isDirectory, ref string resolvedLnkPath, int level)
|
||||
internal bool ReadIconOrResolveLinkAndReadIcon(bool isDirectory, ref string resolvedLnkPath, int level)
|
||||
{
|
||||
bool isLnkDirectory = false;
|
||||
|
||||
|
@ -108,7 +108,7 @@ namespace SystemTrayMenu.DataClasses
|
|||
|
||||
if (fileExtension.Equals(".lnk", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
handled = SetLnk(level, ref isLnkDirectory, ref resolvedLnkPath);
|
||||
handled = ResolveLinkAndReadIcon(level, ref isLnkDirectory, ref resolvedLnkPath);
|
||||
showOverlay = Properties.Settings.Default.ShowLinkOverlay;
|
||||
}
|
||||
else if (fileExtension.Equals(".url", StringComparison.InvariantCultureIgnoreCase))
|
||||
|
@ -116,10 +116,6 @@ namespace SystemTrayMenu.DataClasses
|
|||
SetText($"{FileInfo.Name[0..^4]}");
|
||||
showOverlay = Properties.Settings.Default.ShowLinkOverlay;
|
||||
}
|
||||
else if (fileExtension.Equals(".sln", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
handled = SetSln(level);
|
||||
}
|
||||
else if (fileExtension.Equals(".appref-ms", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
showOverlay = Properties.Settings.Default.ShowLinkOverlay;
|
||||
|
@ -127,21 +123,14 @@ namespace SystemTrayMenu.DataClasses
|
|||
|
||||
if (!handled)
|
||||
{
|
||||
try
|
||||
{
|
||||
FilePathIcon = TargetFilePathOrig;
|
||||
icon = IconReader.GetFileIconWithCache(
|
||||
FilePathIcon,
|
||||
showOverlay,
|
||||
true,
|
||||
level == 0,
|
||||
out bool loading);
|
||||
IconLoading = loading;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Warn($"path:'{TargetFilePathOrig}'", ex);
|
||||
}
|
||||
icon = IconReader.GetFileIconWithCache(
|
||||
TargetFilePathOrig,
|
||||
TargetFilePath,
|
||||
showOverlay,
|
||||
true,
|
||||
level == 0,
|
||||
out bool loading);
|
||||
IconLoading = loading;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,20 +239,15 @@ namespace SystemTrayMenu.DataClasses
|
|||
else
|
||||
{
|
||||
bool showOverlay = false;
|
||||
string fileExtension = Path.GetExtension(TargetFilePath);
|
||||
string fileExtension = Path.GetExtension(TargetFilePathOrig);
|
||||
if (fileExtension == ".lnk" || fileExtension == ".url" || fileExtension == ".appref-ms")
|
||||
{
|
||||
showOverlay = Properties.Settings.Default.ShowLinkOverlay;
|
||||
}
|
||||
|
||||
string filePath = FilePathIcon;
|
||||
if (string.IsNullOrEmpty(filePath))
|
||||
{
|
||||
filePath = TargetFilePathOrig;
|
||||
}
|
||||
|
||||
icon = IconReader.GetFileIconWithCache(
|
||||
filePath,
|
||||
TargetFilePathOrig,
|
||||
TargetFilePath,
|
||||
showOverlay,
|
||||
false,
|
||||
MenuLevel == 0,
|
||||
|
@ -299,7 +283,7 @@ namespace SystemTrayMenu.DataClasses
|
|||
}
|
||||
}
|
||||
|
||||
private bool SetLnk(int level, ref bool isLnkDirectory, ref string resolvedLnkPath)
|
||||
private bool ResolveLinkAndReadIcon(int level, ref bool isLnkDirectory, ref string resolvedLnkPath)
|
||||
{
|
||||
bool handled = false;
|
||||
resolvedLnkPath = FileLnk.GetResolvedFileName(TargetFilePath, out bool isFolder);
|
||||
|
@ -334,26 +318,5 @@ namespace SystemTrayMenu.DataClasses
|
|||
|
||||
return handled;
|
||||
}
|
||||
|
||||
private bool SetSln(int level)
|
||||
{
|
||||
bool handled = false;
|
||||
try
|
||||
{
|
||||
icon = IconReader.GetExtractAllIconsLastWithCache(
|
||||
TargetFilePathOrig,
|
||||
true,
|
||||
level == 0,
|
||||
out bool loading);
|
||||
IconLoading = loading;
|
||||
handled = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Warn($"path:'{TargetFilePath}'", ex);
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,5 +39,5 @@ using System.Runtime.InteropServices;
|
|||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.2.9.15")]
|
||||
[assembly: AssemblyFileVersion("1.2.9.15")]
|
||||
[assembly: AssemblyVersion("1.2.9.16")]
|
||||
[assembly: AssemblyFileVersion("1.2.9.16")]
|
||||
|
|
10
Properties/Resources.Designer.cs
generated
10
Properties/Resources.Designer.cs
generated
|
@ -120,6 +120,16 @@ namespace SystemTrayMenu.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
|
||||
/// </summary>
|
||||
public static System.Drawing.Icon LinkArrow {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("LinkArrow", resourceCulture);
|
||||
return ((System.Drawing.Icon)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
|
||||
/// </summary>
|
||||
|
|
|
@ -112,12 +112,12 @@
|
|||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="White50Percentage" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\White50Percentage.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
|
@ -148,4 +148,7 @@
|
|||
<data name="ic_fluent_settings_28_regular" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\ic_fluent_settings_28_regular.svg;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="LinkArrow" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\LinkArrow.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
BIN
Resources/LinkArrow.ico
Normal file
BIN
Resources/LinkArrow.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
|
@ -110,10 +110,6 @@
|
|||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>ThirdParty\Clearcove.Logging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="TAFactory.IconPack, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>ThirdParty\TAFactory.IconPack.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
|
|
|
@ -16,7 +16,6 @@ namespace SystemTrayMenu.Utilities
|
|||
using System.Text;
|
||||
using System.Threading;
|
||||
using SystemTrayMenu.DllImports;
|
||||
using TAFactory.IconPack;
|
||||
|
||||
/// <summary>
|
||||
/// Provides static methods to read system icons for folders and files.
|
||||
|
@ -70,80 +69,9 @@ namespace SystemTrayMenu.Utilities
|
|||
return cleared;
|
||||
}
|
||||
|
||||
public static Icon GetExtractAllIconsLastWithCache(
|
||||
string filePath,
|
||||
bool updateIconInBackground,
|
||||
bool isMainMenu,
|
||||
out bool loading)
|
||||
{
|
||||
bool linkOverlay = false;
|
||||
loading = false;
|
||||
string key = filePath;
|
||||
|
||||
string extension = Path.GetExtension(filePath);
|
||||
|
||||
if (IsExtensionWithSameIcon(extension))
|
||||
{
|
||||
key = extension + linkOverlay;
|
||||
}
|
||||
|
||||
if (!DictIconCache(isMainMenu).TryGetValue(key, out Icon icon) &&
|
||||
!DictIconCache(!isMainMenu).TryGetValue(key, out icon))
|
||||
{
|
||||
icon = Resources.StaticResources.LoadingIcon;
|
||||
loading = true;
|
||||
|
||||
if (updateIconInBackground)
|
||||
{
|
||||
new Thread(UpdateIconInBackground).Start();
|
||||
void UpdateIconInBackground()
|
||||
{
|
||||
DictIconCache(isMainMenu).GetOrAdd(key, GetExtractAllIconsLastSTA(filePath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Icon GetExtractAllIconsLastSTA(string filePath)
|
||||
{
|
||||
Icon icon = null;
|
||||
|
||||
if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)
|
||||
{
|
||||
icon = GetExtractAllIconsLast(filePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread staThread = new(new ParameterizedThreadStart(StaThreadMethod));
|
||||
void StaThreadMethod(object obj)
|
||||
{
|
||||
icon = GetExtractAllIconsLast(filePath);
|
||||
}
|
||||
|
||||
staThread.SetApartmentState(ApartmentState.STA);
|
||||
staThread.Start(icon);
|
||||
staThread.Join();
|
||||
}
|
||||
|
||||
static Icon GetExtractAllIconsLast(string filePath)
|
||||
{
|
||||
StringBuilder executable = new(1024);
|
||||
NativeMethods.Shell32FindExecutable(filePath, string.Empty, executable);
|
||||
|
||||
// icon = IconReader.GetFileIcon(executable, false);
|
||||
// e.g. VS 2019 icon, need another icom in imagelist
|
||||
List<Icon> extractedIcons = IconHelper.ExtractAllIcons(
|
||||
executable.ToString());
|
||||
return extractedIcons.Last();
|
||||
}
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
public static Icon GetFileIconWithCache(
|
||||
string filePath,
|
||||
string pathOrig,
|
||||
string path,
|
||||
bool linkOverlay,
|
||||
bool updateIconInBackground,
|
||||
bool isMainMenu,
|
||||
|
@ -151,10 +79,10 @@ namespace SystemTrayMenu.Utilities
|
|||
string keyPath = "")
|
||||
{
|
||||
loading = false;
|
||||
string extension = Path.GetExtension(filePath);
|
||||
string extension = Path.GetExtension(pathOrig);
|
||||
IconSize size = IconSize.Large;
|
||||
|
||||
string key = filePath;
|
||||
string key = pathOrig;
|
||||
if (!string.IsNullOrEmpty(keyPath))
|
||||
{
|
||||
key = keyPath;
|
||||
|
@ -175,7 +103,7 @@ namespace SystemTrayMenu.Utilities
|
|||
new Thread(UpdateIconInBackground).Start();
|
||||
void UpdateIconInBackground()
|
||||
{
|
||||
DictIconCache(isMainMenu).GetOrAdd(key, GetIconSTA(filePath, linkOverlay, size, null));
|
||||
DictIconCache(isMainMenu).GetOrAdd(key, GetIconSTA(pathOrig, path, linkOverlay, size, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -228,25 +156,25 @@ namespace SystemTrayMenu.Utilities
|
|||
|
||||
Icon GetFolder(string keyExtension)
|
||||
{
|
||||
return GetIconSTA(path, linkOverlay, size, folderType);
|
||||
return GetIconSTA(path, path, linkOverlay, size, folderType);
|
||||
}
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
public static Icon GetIconSTA(string path, bool linkOverlay, IconSize size, FolderType? folderType)
|
||||
public static Icon GetIconSTA(string pathOrig, string path, bool linkOverlay, IconSize size, FolderType? folderType)
|
||||
{
|
||||
Icon icon = null;
|
||||
if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)
|
||||
{
|
||||
icon = GetIcon(path, linkOverlay, size, folderType);
|
||||
icon = GetIcon(pathOrig, path, linkOverlay, size, folderType);
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread staThread = new(new ParameterizedThreadStart(StaThreadMethod));
|
||||
void StaThreadMethod(object obj)
|
||||
{
|
||||
icon = GetIcon(path, linkOverlay, size, folderType);
|
||||
icon = GetIcon(pathOrig, path, linkOverlay, size, folderType);
|
||||
}
|
||||
|
||||
staThread.SetApartmentState(ApartmentState.STA);
|
||||
|
@ -299,15 +227,34 @@ namespace SystemTrayMenu.Utilities
|
|||
return isExtensionWithSameIcon;
|
||||
}
|
||||
|
||||
private static Icon GetIcon(string path, bool linkOverlay, IconSize size, FolderType? type)
|
||||
private static Icon GetIcon(string path, string pathOrig, bool linkOverlay, IconSize size, FolderType? type)
|
||||
{
|
||||
NativeMethods.SHFILEINFO shFileInfo = default;
|
||||
uint flags = GetFlags(linkOverlay, size, type);
|
||||
uint attribute = type == null ? NativeMethods.FileAttributeNormal :
|
||||
NativeMethods.FileAttributeDirectory;
|
||||
IntPtr imageList = NativeMethods.Shell32SHGetFileInfo(
|
||||
path, attribute, ref shFileInfo, (uint)Marshal.SizeOf(shFileInfo), flags);
|
||||
return GetIcon(path, linkOverlay, shFileInfo, imageList);
|
||||
Icon icon;
|
||||
if (Path.GetExtension(path).Equals(".ico", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
icon = Icon.ExtractAssociatedIcon(path);
|
||||
}
|
||||
else if (Path.GetExtension(pathOrig).Equals(".ico", StringComparison.InvariantCultureIgnoreCase) &&
|
||||
File.Exists(pathOrig))
|
||||
{
|
||||
icon = Icon.ExtractAssociatedIcon(pathOrig);
|
||||
if (linkOverlay)
|
||||
{
|
||||
icon = AddIconOverlay(icon, Properties.Resources.LinkArrow);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NativeMethods.SHFILEINFO shFileInfo = default;
|
||||
uint flags = GetFlags(linkOverlay, size, type);
|
||||
uint attribute = type == null ? NativeMethods.FileAttributeNormal :
|
||||
NativeMethods.FileAttributeDirectory;
|
||||
IntPtr imageList = NativeMethods.Shell32SHGetFileInfo(
|
||||
path, attribute, ref shFileInfo, (uint)Marshal.SizeOf(shFileInfo), flags);
|
||||
icon = GetIcon(path, linkOverlay, shFileInfo, imageList);
|
||||
}
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
private static uint GetFlags(bool linkOverlay, IconSize size, FolderType? folderType)
|
||||
|
|
Loading…
Reference in a new issue