Lost in the matrix

C/C++/C#/Java, Multithreading

Il est agréable qu'une application mobile fonctionne de la même
façon sur windows mobile et windows CE. Sous windows mobile,
lorsqu'une application est lancée et que l'on tente de la relancer,
on récupère simplement le "focus" sur l'application existante.
Contrairement à Windows CE qui autorise les instances multiples.
Afin d'homogénéiser le comportement sur ces deux plateformes,
un code très simple permet de résoudre ce problème.

(le code compatible Windows mobile >= 3.0)

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Reflection;
using MobileTools;

namespace MobileTools
{
static class SingleInstanceApplication
{
[DllImport("coredll.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("coredll.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);

[DllImport("coredll.dll", SetLastError = true)]
private static extern IntPtr CreateMutex(IntPtr Attr, bool Own, string Name);

[DllImport("coredll.dll", SetLastError = true)]
private static extern bool ReleaseMutex(IntPtr hMutex);

public static void Run(Form frm)
{
SingleInstanceApplication.Run(frm, frm.Text);
}

public static void Run(Form frm, string caption)
{
// On créer un mutex avec un nom qui nous sert de référence.
IntPtr MtxHandle = CreateMutex(IntPtr.Zero,
true, Assembly.GetExecutingAssembly().GetName().Name);
// Si le mutex existe déjà on récupère le focus sur
// l'application existante par son nom (caption)
if (Marshal.GetLastWin32Error() == SingleInstanceApplication.ALREADY_EXISTS)
SetForegroundWindow(FindWindow(null, caption));
else
Application.Run(frm); // Sinon on lance la forme
// On libère le mutex
ReleaseMutex(MtxHandle);
}

private const int ALREADY_EXISTS = 183;
}
}

1 commentaires:

NB : Le code fonctionne aussi pour les instances multiples sous Windows Mobile.

Enregistrer un commentaire