57 lines
1.5 KiB
C#
57 lines
1.5 KiB
C#
|
|
using System.Runtime.InteropServices;
|
||
|
|
|
||
|
|
namespace Robovoice.App;
|
||
|
|
|
||
|
|
internal static class IconExtractor
|
||
|
|
{
|
||
|
|
private const string Source = @"%SystemRoot%\System32\mmres.dll";
|
||
|
|
private static readonly int[] CandidateIndices = { 5, 12 };
|
||
|
|
|
||
|
|
public static Icon? TryExtractMicrophone(int size = 32)
|
||
|
|
{
|
||
|
|
string path = Environment.ExpandEnvironmentVariables(Source);
|
||
|
|
if (!File.Exists(path)) return null;
|
||
|
|
|
||
|
|
foreach (int index in CandidateIndices)
|
||
|
|
{
|
||
|
|
if (ExtractIconAt(path, index, size, size) is { } icon)
|
||
|
|
return icon;
|
||
|
|
}
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static Icon? ExtractIconAt(string path, int index, int width, int height)
|
||
|
|
{
|
||
|
|
IntPtr[] hicons = new IntPtr[1];
|
||
|
|
IntPtr[] ids = new IntPtr[1];
|
||
|
|
|
||
|
|
int count = PrivateExtractIcons(path, index, width, height, hicons, ids, 1, 0);
|
||
|
|
if (count <= 0 || hicons[0] == IntPtr.Zero) return null;
|
||
|
|
|
||
|
|
try
|
||
|
|
{
|
||
|
|
return Icon.FromHandle(hicons[0]);
|
||
|
|
}
|
||
|
|
catch
|
||
|
|
{
|
||
|
|
DestroyIcon(hicons[0]);
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||
|
|
private static extern int PrivateExtractIcons(
|
||
|
|
string lpszFile,
|
||
|
|
int nIconIndex,
|
||
|
|
int cxIcon,
|
||
|
|
int cyIcon,
|
||
|
|
IntPtr[] phicon,
|
||
|
|
IntPtr[] phiconId,
|
||
|
|
int nIcons,
|
||
|
|
int flags);
|
||
|
|
|
||
|
|
[DllImport("user32.dll", SetLastError = true)]
|
||
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||
|
|
private static extern bool DestroyIcon(IntPtr hIcon);
|
||
|
|
}
|