Skip to content

Commit 4503105

Browse files
committed
feat: Implement single-instance application and optimize window management
Add support for single instance applications to prevent multiple launches. Implement activation of existing instances through mutexes and window messages. Optimize the management of the main window and add window message handling to respond to activation requests.
1 parent 882cecb commit 4503105

2 files changed

Lines changed: 72 additions & 18 deletions

File tree

App.xaml.cs

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,61 @@
1-
using System.Configuration;
2-
using System.Data;
1+
using System;
2+
using System.Diagnostics;
3+
using System.Runtime.InteropServices;
34
using System.Windows;
5+
using System.Windows.Interop;
46
using Application = System.Windows.Application;
57

68
namespace DevTools
79
{
8-
/// <summary>
9-
/// Interaction logic for App.xaml
10-
/// </summary>
1110
public partial class App : Application
1211
{
13-
}
12+
private static readonly string MutexName = "DevTools_SingleInstance_Mutex";
13+
private static System.Threading.Mutex? _mutex;
14+
15+
private const int HWND_BROADCAST = 0xffff;
16+
private static readonly int WM_SHOWME = RegisterWindowMessage("WM_SHOWME_DEVTOOLS");
17+
18+
[DllImport("user32.dll")]
19+
private static extern int RegisterWindowMessage(string message);
20+
21+
[DllImport("user32.dll")]
22+
private static extern bool PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
23+
24+
[DllImport("user32.dll")]
25+
private static extern bool SetForegroundWindow(IntPtr hWnd);
26+
27+
[DllImport("user32.dll")]
28+
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
29+
30+
private const int SW_RESTORE = 9;
1431

32+
public static int ShowMeMessage => WM_SHOWME;
33+
34+
protected override void OnStartup(StartupEventArgs e)
35+
{
36+
bool createdNew;
37+
_mutex = new System.Threading.Mutex(true, MutexName, out createdNew);
38+
39+
if (!createdNew)
40+
{
41+
ActivateExistingInstance();
42+
Shutdown();
43+
return;
44+
}
45+
46+
base.OnStartup(e);
47+
}
48+
49+
private void ActivateExistingInstance()
50+
{
51+
PostMessage((IntPtr)HWND_BROADCAST, WM_SHOWME, IntPtr.Zero, IntPtr.Zero);
52+
}
53+
54+
protected override void OnExit(ExitEventArgs e)
55+
{
56+
_mutex?.ReleaseMutex();
57+
_mutex?.Dispose();
58+
base.OnExit(e);
59+
}
60+
}
1561
}

MainWindow.xaml.cs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,12 @@
33
using System.Drawing;
44
using System.IO;
55
using System.Reflection;
6-
using System.Text;
6+
using System.Runtime.InteropServices;
77
using System.Windows;
8-
using System.Windows.Controls;
9-
using System.Windows.Data;
10-
using System.Windows.Documents;
118
using System.Windows.Forms;
12-
using System.Windows.Input;
13-
using System.Windows.Media;
14-
using System.Windows.Media.Imaging;
15-
using System.Windows.Navigation;
16-
using System.Windows.Shapes;
9+
using System.Windows.Interop;
1710
using DevTools.Resources;
1811
using Application = System.Windows.Application;
19-
using MessageBox = System.Windows.MessageBox;
20-
using Button = System.Windows.Controls.Button;
2112
using ContextMenuStrip = System.Windows.Forms.ContextMenuStrip;
2213
using ToolStripMenuItem = System.Windows.Forms.ToolStripMenuItem;
2314
using ToolTipIcon = System.Windows.Forms.ToolTipIcon;
@@ -219,10 +210,27 @@ private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs
219210

220211
private void MinimizeToTray()
221212
{
222-
_notifyIcon!.ShowBalloonTip(2000, Strings.Toolbox, Strings.MinimizedToTray, ToolTipIcon.Info);
213+
_notifyIcon!.ShowBalloonTip(2000, Strings.Toolbox, Strings.MinimizedToTray, ToolTipIcon.None);
223214
Hide();
224215
}
225216

217+
protected override void OnSourceInitialized(EventArgs e)
218+
{
219+
base.OnSourceInitialized(e);
220+
var source = PresentationSource.FromVisual(this) as HwndSource;
221+
source?.AddHook(WndProc);
222+
}
223+
224+
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
225+
{
226+
if (msg == App.ShowMeMessage)
227+
{
228+
ShowWindow();
229+
handled = true;
230+
}
231+
return IntPtr.Zero;
232+
}
233+
226234
protected override void OnClosed(EventArgs e)
227235
{
228236
_notifyIcon?.Dispose();

0 commit comments

Comments
 (0)