v0.4: mic tray icon from mmres.dll, version in form title
This commit is contained in:
@@ -0,0 +1,56 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
@@ -29,6 +29,7 @@ internal sealed partial class MainForm : Form
|
|||||||
_config = AppConfig.Load();
|
_config = AppConfig.Load();
|
||||||
Directory.CreateDirectory(AppConfig.AppDataDir);
|
Directory.CreateDirectory(AppConfig.AppDataDir);
|
||||||
Directory.CreateDirectory(_voicesDir);
|
Directory.CreateDirectory(_voicesDir);
|
||||||
|
Text = $"Robovoice {AppVersion}";
|
||||||
Load += OnLoad;
|
Load += OnLoad;
|
||||||
FormClosing += OnFormClosing;
|
FormClosing += OnFormClosing;
|
||||||
}
|
}
|
||||||
@@ -426,12 +427,26 @@ internal sealed partial class MainForm : Form
|
|||||||
if (_trayInit) return;
|
if (_trayInit) return;
|
||||||
_trayInit = true;
|
_trayInit = true;
|
||||||
|
|
||||||
_trayIcon = new NotifyIcon
|
var micIcon = IconExtractor.TryExtractMicrophone();
|
||||||
|
if (micIcon is not null)
|
||||||
{
|
{
|
||||||
Icon = SystemIcons.Application,
|
_trayIcon = new NotifyIcon
|
||||||
Text = "Robovoice",
|
{
|
||||||
Visible = true,
|
Icon = micIcon,
|
||||||
};
|
Text = $"Robovoice {AppVersion}",
|
||||||
|
Visible = true,
|
||||||
|
};
|
||||||
|
Icon = micIcon;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_trayIcon = new NotifyIcon
|
||||||
|
{
|
||||||
|
Icon = SystemIcons.Application,
|
||||||
|
Text = $"Robovoice {AppVersion}",
|
||||||
|
Visible = true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
var menu = new ContextMenuStrip();
|
var menu = new ContextMenuStrip();
|
||||||
menu.Items.Add("Show", null, (_, _) => ShowWindow());
|
menu.Items.Add("Show", null, (_, _) => ShowWindow());
|
||||||
@@ -444,6 +459,9 @@ internal sealed partial class MainForm : Form
|
|||||||
_trayIcon.DoubleClick += (_, _) => ShowWindow();
|
_trayIcon.DoubleClick += (_, _) => ShowWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string AppVersion =>
|
||||||
|
typeof(MainForm).Assembly.GetName().Version?.ToString() ?? "0.0";
|
||||||
|
|
||||||
private void OnResize(object? sender, EventArgs e)
|
private void OnResize(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (WindowState == FormWindowState.Minimized && chkMinimizeToTray.Checked)
|
if (WindowState == FormWindowState.Minimized && chkMinimizeToTray.Checked)
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<UseWindowsForms>true</UseWindowsForms>
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Version>0.4.0</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
Reference in New Issue
Block a user