WindowsHelper - Ernst Kuschke

   Ernst Kuschke

     Arbitrary thoughts and musings on life, the universe and everything else

Syndication

News

    ernst kuschke (v1.0)

    My Photos

    Microsoft Most Valuable Professional

    Member in good standing

    View Ernst Kuschke's profile on LinkedIn

    Add to Technorati Favorites

Blogs I read

Books I recommend

General Links

WindowsHelper

This class (inspiringly called 'WindowsHelper') finds a specified window, maximizes it, and brings it to the foreground. I used it with my 'Only One Instance' implementation.

using System;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace Win32APIs
{
    /// <summary>
    /// WindowsHelper implements managed wrappers for unmanaged Win32 APIs.
   
/// </summary>
    public sealed class WindowsHelper
    {
        /// <summary>
        /// Point struct used for GetWindowPlacement API.
       
/// </summary>
        [StructLayout(LayoutKind.Sequential)]
        private class ManagedPt 
        {
            public int x = 0;
            public int y = 0;
            
            public ManagedPt() 
            {
            }

            public ManagedPt(int x, int y) 
            {
                this.x = x;
                this.y = y;
            }
        }

        /// <summary>
        /// Rect struct used for GetWindowPlacement API.
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        private class ManagedRect 
        {
            public int x = 0;
            public int y = 0;
            public int right = 0;
            public int bottom = 0;
            
            public ManagedRect() 
            {
            }

            public ManagedRect(int x, int y, int right, int bottom) 
            {
                this.x = x;
                this.y = y;
                this.right = right;
                this.bottom = bottom;
            }
        }

        /// <summary>
        /// WindowPlacement struct used for GetWindowPlacement API.
        /// </summary>

        [StructLayout(LayoutKind.Sequential)]
        private class ManagedWindowPlacement 
        {
            public uint length = 0;
            public uint flags = 0;
            public uint showCmd = 0;
            public ManagedPt minPosition = null;
            public ManagedPt maxPosition = null;
            public ManagedRect normalPosition = null;
            
            public ManagedWindowPlacement() 
            {
                this.length = (uint)Marshal.SizeOf(this);
            }
        }

        // External Win32 APIs that gets called directly
        [DllImport("USER32.DLL", SetLastError=true)]
        private static extern uint ShowWindow (uint hwnd, int showCommand);
        
        [DllImport("USER32.DLL", SetLastError=true)]
        private static extern uint SetForegroundWindow (uint hwnd);
        
        [DllImport("USER32.DLL", SetLastError=true)]
        private static extern uint GetWindowPlacement (uint hwnd, 
            [In, Out]ManagedWindowPlacement lpwndpl);
        
        [DllImport("USER32.DLL", SetLastError=true)]
        private static extern uint FindWindow (string lpClassName, string lpWindowName);

        // Windows defined constants.
        private const int WM_ACTIVATE = 0x0006;
        private const int WA_CLICKACTIVE = 2;
        private const int SW_SHOWNORMAL = 1;
        private const int SW_SHOWMINIMIZED = 2;
        private const int SW_SHOWMAXIMIZED = 3;
        private const int WPF_RESTORETOMAXIMIZED = 2;

        /// <summary>
        /// Finds the specified window by its name (or caption). 
        /// </summary>
        /// <param name="windowName">Name of the window to find and activate.</param>
        /// <returns>Window handle or 0 if window not found by that name.</returns>

        static private uint FindWindow(string windowName)
        {
            // first, try to find the window by its window name or caption.
            uint hwndInstance = FindWindow(null, windowName);
            if (hwndInstance <= 0)
            {
                Debug.Assert(false
                    "Couldn't find window handle for the specified window name.");
            }

            return hwndInstance;
        }

        /// <summary>
        /// Finds the specified window by its name (or caption).  Then brings it to
        /// the foreground.
        /// </summary>
        /// <param name="windowName">Name of the window to find and activate.</param>

        static public void ActivateWindow(string windowName)
        {
            // first, try to find the window by its window name or caption.
            uint hwndInstance = FindWindow(windowName);

            // Then, get the WindowPlacement, so we can decide the best way to 
            // activate the window correctly.

            ManagedWindowPlacement placement = new ManagedWindowPlacement();
            GetWindowPlacement(hwndInstance, placement);

            if (placement.showCmd == SW_SHOWMINIMIZED)
            {
                // if the window is minimized, then we need to restore it to its
                // previous size.  we also take into account whether it was 
                // previously maximized.

                int showCmd = (placement.flags == WPF_RESTORETOMAXIMIZED) ? 
                SW_SHOWMAXIMIZED : SW_SHOWNORMAL;
                ShowWindow(hwndInstance, showCmd);
            }
            else
            {
                // if it's not minimized, then we just call SetForegroundWindow to 
                // bring it to the front.
                SetForegroundWindow(hwndInstance);
            }
        }

        /// <summary>
        /// Finds the specified window by its Process ID.  Then brings it to
        /// the foreground.
        /// </summary>
        /// <param name="hwnd">Process ID of the window to find and activate.</param>

        static public void ActivateWindowByProcID(int processID)
        {
            uint hwndInstance = (uint)Process.GetProcessById(processID).Handle;
            ManagedWindowPlacement placement = new ManagedWindowPlacement();
            GetWindowPlacement(hwndInstance, placement);

            if (placement.showCmd == SW_SHOWMINIMIZED)
            {
                // if the window is minimized, then we need to restore it to its
                // previous size.  we also take into account whether it was 
                // previously maximized.

                int showCmd = (placement.flags == WPF_RESTORETOMAXIMIZED) ? 
                SW_SHOWMAXIMIZED : SW_SHOWNORMAL;
                ShowWindow(hwndInstance, showCmd);
            }
            else
            {
                // if it's not minimized, then we just call SetForegroundWindow to 
                // bring it to the front.

                SetForegroundWindow(hwndInstance);
            }
        }

        /// <summary>
        ///
Finds the specified window by its Process ID.  Then brings it to
        /// the foreground.
        /// </summary>
        /// <param name="hwnd">
Handle to the window to find and activate.</param>
       
        static public void ActivateWindowByHandle(uint hwndInstance)
        {
            ManagedWindowPlacement placement = new ManagedWindowPlacement();
            GetWindowPlacement(hwndInstance, placement);

            if (placement.showCmd == SW_SHOWMINIMIZED)
            {
                // if the window is minimized, then we need to restore it to its
                // previous size.  we also take into account whether it was 
                // previously maximized.

                int showCmd = (placement.flags == WPF_RESTORETOMAXIMIZED) ? 
                SW_SHOWMAXIMIZED : SW_SHOWNORMAL;
                ShowWindow(hwndInstance, showCmd);
            }
            else
            {
                // if it's not minimized, then we just call SetForegroundWindow to 
                // bring it to the front.

                SetForegroundWindow(hwndInstance);
            }
        }
    }
}

Published Sunday, August 22, 2004 8:44 PM by Ernst Kuschke

Comments

# Ensuring only one instance of your app runs@ Sunday, August 22, 2004 8:45 PM

# re: WindowsHelper@ Thursday, October 28, 2004 7:59 PM

Shouldn't this be factored out (a bunch)? How about:

/// <summary>
/// Finds the specified window by its name (or caption). Then brings it to
/// the foreground.
/// </summary>
/// <param name="windowName">Name of the window to find and activate.</param>
static public void ActivateWindow(string windowName)
{
// first, try to find the window by its window name or caption.
uint hwndInstance = FindWindow(windowName);
ActivateWindowByHandle(hwndInstance);
}

/// <summary>
/// Finds the specified window by its Process ID. Then brings it to
/// the foreground.
/// </summary>
/// <param name="hwnd">Process ID of the window to find and activate.</param>
static public void ActivateWindowByProcID(int processID)
{
uint hwndInstance = (uint)Process.GetProcessById(processID).Handle;
ActivateWindowByHandle(hwndInstance);
}

/// <summary>
/// Finds the specified window by its Process ID. Then brings it to
/// the foreground.
/// </summary>
/// <param name="hwnd">Handle to the window to find and activate.</param>
static public void ActivateWindowByHandle(uint hwndInstance)
{
ManagedWindowPlacement placement = new ManagedWindowPlacement();
GetWindowPlacement(hwndInstance, placement);

if (placement.showCmd == SW_SHOWMINIMIZED)
{
// if the window is minimized, then we need to restore it to its
// previous size. we also take into account whether it was
// previously maximized.
int showCmd = (placement.flags == WPF_RESTORETOMAXIMIZED) ?
SW_SHOWMAXIMIZED : SW_SHOWNORMAL;
ShowWindow(hwndInstance, showCmd);
}
else
{
// if it's not minimized, then we just call SetForegroundWindow to
// bring it to the front.
SetForegroundWindow(hwndInstance);
}
}

# re: WindowsHelper@ Sunday, July 03, 2005 7:48 PM

Awesome - that's the longest comment on my blog yet! :P

# re: WindowsHelper@ Friday, August 08, 2008 11:28 PM

Just wanted to let you know that if you call GetWindowPlacement and find out the window was minimized, you should call ShowWindow with SW_RESTORE.  MSDN says that the flags member variable is always 0 in this case, so inspecting it won't do anything.  Instead, SW_RESTORE will do all of the work for you.

by Adam Gross

Leave a Comment

(required) 
(required) 
(optional)
(required) 

Enter the numbers above: