From 036fd48bcf1f4f0588fb1dcec857125df0fb15a5 Mon Sep 17 00:00:00 2001 From: Colin Date: Fri, 23 Aug 2019 19:16:02 +0100 Subject: [PATCH] Another attempt to sort out the dialog appearing behind other windows. --- Meade.net/Meade.net.csproj | 1 + Meade.net/SetupDialogForm.cs | 12 +--- Meade.net/Win32Utilities.cs | 106 +++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 10 deletions(-) create mode 100644 Meade.net/Win32Utilities.cs diff --git a/Meade.net/Meade.net.csproj b/Meade.net/Meade.net.csproj index 6c5a077..d8277ba 100644 --- a/Meade.net/Meade.net.csproj +++ b/Meade.net/Meade.net.csproj @@ -135,6 +135,7 @@ + Designer diff --git a/Meade.net/SetupDialogForm.cs b/Meade.net/SetupDialogForm.cs index a09eb72..cac2def 100644 --- a/Meade.net/SetupDialogForm.cs +++ b/Meade.net/SetupDialogForm.cs @@ -2,6 +2,7 @@ using System; using System.ComponentModel; using System.Diagnostics; using System.Runtime.InteropServices; +using System.Text; using System.Windows.Forms; namespace ASCOM.Meade.net @@ -73,18 +74,9 @@ namespace ASCOM.Meade.net return profileProperties; } - [DllImport("user32.dll")] - private static extern bool SetForegroundWindow(IntPtr hWnd); - - [DllImport("user32.dll")] - - private static extern bool AllowSetForegroundWindow(int dwProcessId); - private void SetupDialogForm_Shown(object sender, EventArgs e) { - Process currentProcess = Process.GetCurrentProcess(); - AllowSetForegroundWindow(currentProcess.Id); - SetForegroundWindow(Handle); + Win32Utilities.BringWindowToFront(Handle); Activate(); } diff --git a/Meade.net/Win32Utilities.cs b/Meade.net/Win32Utilities.cs new file mode 100644 index 0000000..2be80b3 --- /dev/null +++ b/Meade.net/Win32Utilities.cs @@ -0,0 +1,106 @@ +using System; +using System.Runtime.InteropServices; +using System.Text; + +namespace ASCOM.Meade.net +{ + internal static class Win32Utilities + { + //Win32 API calls necesary to raise an unowned processs main window + + [DllImport("user32.dll")] + + private static extern bool SetForegroundWindow(IntPtr hWnd); + + [DllImport("user32.dll")] + private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); + + [DllImport("user32.dll")] + private static extern bool IsIconic(IntPtr hWnd); + + [DllImport("user32.dll", SetLastError = true)] + private static extern bool SystemParametersInfo(uint uiAction, uint uiParam, IntPtr pvParam, uint fWinIni); + + [DllImport("user32.dll", SetLastError = true)] + private static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr lpdwProcessId); + + [DllImport("user32.dll")] + private static extern IntPtr GetForegroundWindow(); + + [DllImport("user32.dll")] + private static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach); + + [DllImport("user32.dll")] + static extern bool BringWindowToTop(IntPtr hWnd); + + [DllImport("user32.dll")] + private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, Int32 nMaxCount); + + [DllImport("user32.dll")] + private static extern int GetWindowThreadProcessId(IntPtr hWnd, ref Int32 lpdwProcessId); + + [DllImport("User32.dll")] + public static extern IntPtr GetParent(IntPtr hWnd); + + private const int SW_HIDE = 0; + private const int SW_SHOWNORMAL = 1; + private const int SW_NORMAL = 1; + private const int SW_SHOWMINIMIZED = 2; + private const int SW_SHOWMAXIMIZED = 3; + private const int SW_MAXIMIZE = 3; + private const int SW_SHOWNOACTIVATE = 4; + private const int SW_SHOW = 5; + private const int SW_MINIMIZE = 6; + private const int SW_SHOWMINNOACTIVE = 7; + private const int SW_SHOWNA = 8; + private const int SW_RESTORE = 9; + private const int SW_SHOWDEFAULT = 10; + private const int SW_MAX = 10; + + private const uint SPI_GETFOREGROUNDLOCKTIMEOUT = 0x2000; + private const uint SPI_SETFOREGROUNDLOCKTIMEOUT = 0x2001; + + private const int SPIF_SENDCHANGE = 0x2; + + + public static void BringWindowToFront(IntPtr hWnd) + { + if (IsIconic(hWnd)) + ShowWindowAsync(hWnd, SW_RESTORE); + + ShowWindowAsync(hWnd, SW_SHOW); + + SetForegroundWindow(hWnd); + + // Code from Karl E. Peterson, www.mvps.org/vb/sample.htm + // Converted to Delphi by Ray Lischner + // Published in The Delphi Magazine 55, page 16 + // Converted to C# by Kevin Gale + IntPtr foregroundWindow = GetForegroundWindow(); + IntPtr Dummy = IntPtr.Zero; + + uint foregroundThreadId = GetWindowThreadProcessId(foregroundWindow, Dummy); + + uint thisThreadId = GetWindowThreadProcessId(hWnd, Dummy); + + if (AttachThreadInput(thisThreadId, foregroundThreadId, true)) + { + BringWindowToTop(hWnd); // IE 5.5 related hack + SetForegroundWindow(hWnd); + AttachThreadInput(thisThreadId, foregroundThreadId, false); + } + + if (GetForegroundWindow() != hWnd) + { + // Code by Daniel P. Stasinski + // Converted to C# by Kevin Gale + IntPtr Timeout = IntPtr.Zero; + SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, Timeout, 0); + SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Dummy, SPIF_SENDCHANGE); + BringWindowToTop(hWnd); // IE 5.5 related hack + SetForegroundWindow(hWnd); + SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Timeout, SPIF_SENDCHANGE); + } + } + } +}