Skip to content

Commit

Permalink
Merge pull request #11 from victor-david/feature-one-instance
Browse files Browse the repository at this point in the history
Merge feature-one-instance to main
  • Loading branch information
victor-david authored Jan 30, 2023
2 parents 9b3d7ed + 2ad8cef commit 1a4403f
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 5 deletions.
22 changes: 18 additions & 4 deletions src/Panama/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
* Panama is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License v3.0
* Panama is distributed in the hope that it will be useful, but without warranty of any kind.
*/
using Restless.Panama.ViewModel;
using Restless.Panama.Core;
using Restless.Panama.Database.Core;
using Restless.Panama.Resources;
using Restless.Panama.Database.Tables;
using Restless.Panama.Utility;
using Restless.Panama.ViewModel;
using Restless.Toolkit.Controls;
using System;
using System.Threading;
using System.Windows;
using Restless.Panama.Database.Tables;
using Restless.Toolkit.Controls;

namespace Restless.Panama
{
Expand All @@ -21,6 +21,11 @@ namespace Restless.Panama
/// </summary>
public partial class App : Application
{
#region Private
private const string ApplicationId = "Panama.d9c20b23-f278-4349-a292-17e5a6abb15a";
private static readonly Mutex AppMutex = new(true, ApplicationId);
#endregion

#region Protected methods
/// <summary>
/// Called when the application is starting.
Expand All @@ -32,6 +37,14 @@ public partial class App : Application
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);

/* Prevent app from being run more than once */
if (!AppMutex.WaitOne(TimeSpan.Zero, true))
{
NativeMethods.PostMessage((IntPtr)NativeMethods.HWND_BROADCAST, NativeMethods.WM_SHOW_ACTIVE_WIN, IntPtr.Zero, IntPtr.Zero);
Environment.Exit(0);
}

try
{
RunApplication(e);
Expand All @@ -53,6 +66,7 @@ protected override void OnExit(ExitEventArgs e)
base.OnExit(e);
Config.Instance.SaveFilterObjects();
DatabaseController.Instance.Shutdown(saveTables: true);
AppMutex.ReleaseMutex();
}
#endregion

Expand Down
20 changes: 20 additions & 0 deletions src/Panama/Core/Other/NativeMethods.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.Runtime.InteropServices;

namespace Restless.Panama.Core
{
/// <summary>
/// Provides native methods.
/// </summary>
internal static class NativeMethods
{
public const int HWND_BROADCAST = 0xffff;
public static readonly int WM_SHOW_ACTIVE_WIN = RegisterWindowMessage("911BEAEF-5448-4CB8-A0CF-4A839B7602D1");

[DllImport("user32")]
public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);

[DllImport("user32", CharSet = CharSet.Unicode)]
public static extern int RegisterWindowMessage(string message);
}
}
2 changes: 1 addition & 1 deletion src/Panama/Panama.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<PackageProjectUrl>https://github.com/victor-david/panama</PackageProjectUrl>
<RepositoryUrl>https://github.com/victor-david/panama</RepositoryUrl>
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
<Version>4.0.33</Version>
<Version>4.0.34</Version>
<ApplicationIcon>App.Main.ico</ApplicationIcon>
</PropertyGroup>

Expand Down
64 changes: 64 additions & 0 deletions src/Panama/View/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,79 @@
* Panama is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License v3.0
* Panama is distributed in the hope that it will be useful, but without warranty of any kind.
*/
using Restless.Panama.Core;
using Restless.Toolkit.Controls;
using System;
using System.Windows;
using System.Windows.Interop;

namespace Restless.Panama.View
{
public partial class MainWindow : AppWindow
{
#region Private
private static MainWindow staticMain;
#endregion

/************************************************************************/

#region Constructor
/// <summary>
/// Initializes a new instance of the <see cref="MainWindow"/> class.
/// </summary>
public MainWindow()
{
InitializeComponent();
}
#endregion

/************************************************************************/

#region Protected methods
/// <inheritdoc/>
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
if (PresentationSource.FromVisual(this) is HwndSource hwndSource)
{
staticMain = this;
hwndSource.AddHook(HandleWindowMessage);
}
}
#endregion

/************************************************************************/

#region Private methods
/// <summary>
/// Matches the HwndSourceHook delegate signature so it can be passed to AddHook() as a callback.
/// </summary>
/// <param name="hwnd">The window handle</param>
/// <param name="msg">The message ID</param>
/// <param name="wParam">The message's wParam value, historically used in the win32 api for handles and integers</param>
/// <param name="lParam">The message's lParam value, historically used in the win32 api to pass pointers</param>
/// <param name="handled">A value that indicates whether the message was handled</param>
/// <returns></returns>
private static IntPtr HandleWindowMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == NativeMethods.WM_SHOW_ACTIVE_WIN)
{
staticMain?.ShowMe();
handled = true;
}
return IntPtr.Zero;
}

private void ShowMe()
{
if (WindowState == WindowState.Minimized)
{
WindowState = WindowState.Normal;
}
bool top = Topmost;
Topmost = true;
Topmost = top;
}
#endregion
}
}

0 comments on commit 1a4403f

Please sign in to comment.