20

I have list of open Applications. To get this list i have used following code

 internal static class NativeMethods
{
    public static readonly Int32 GWL_STYLE = -16;
    public static readonly UInt64 WS_VISIBLE = 0x10000000L;
    public static readonly UInt64 WS_BORDER = 0x00800000L;
    public static readonly UInt64 DESIRED_WS = WS_BORDER | WS_VISIBLE;

    public delegate Boolean EnumWindowsCallback(IntPtr hwnd, Int32 lParam);

    public static List<WindowWrapper> GetAllWindows()
    {
        List<WindowWrapper> windows = new List<WindowWrapper>();
        StringBuilder buffer = new StringBuilder(100);
        EnumWindows(delegate(IntPtr hwnd, Int32 lParam)
        {
            if ((GetWindowLongA(hwnd, GWL_STYLE) & DESIRED_WS) == DESIRED_WS)
            {
                GetWindowText(hwnd, buffer, buffer.Capacity);
                WindowWrapper wnd = new WindowWrapper();
                wnd.handle = hwnd;
                wnd.title = buffer.ToString();
                windows.Add(wnd);
            }
            return true;
        }, 0);

        return windows;
    }

    [DllImport("user32.dll")]
    static extern Int32 EnumWindows(EnumWindowsCallback lpEnumFunc, Int32 lParam);

    [DllImport("user32.dll")]
    public static extern void GetWindowText(IntPtr hWnd, StringBuilder lpString, Int32 nMaxCount);

    [DllImport("user32.dll")]
    static extern UInt64 GetWindowLongA(IntPtr hWnd, Int32 nIndex);
}

public class WindowWrapper : IWin32Window
{
    internal IntPtr handle;
    internal String title;

    public IntPtr Handle
    {
        get { return handle; }
    }

    public String Title
    {
        get { return title; }
    }
}

to call this i used following code

foreach (var wnd in NativeMethods.GetAllWindows())
       {
               string caption = wnd.title;
               string handle = wnd.Handle
               // Add this caption and handle to list
       }

Now, User will select any of the opened window from the list and my task is to read caption of the selected window, get handle of process and maximize/minimize or close window. How can I do this.

1

3 Answers 3

25

You can use findwindowbycaption to get the handle then maximize or minimize with showwindow

private const int SW_MAXIMIZE = 3;
private const int SW_MINIMIZE = 6;
// more here: http://www.pinvoke.net/default.aspx/user32.showwindow

[DllImport("user32.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

Then in your code you use this:

IntPtr hwnd = FindWindowByCaption(IntPtr.Zero, "The window title");
ShowWindow(hwnd, SW_MAXIMIZE);

Although it seems you already have the window handle by using EnumWindows in that case you would only need:

ShowWindow(windows[i].handle, SW_MAXIMIZE);

i is the index of the window.


to close the window you will use:

[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool DestroyWindow(IntPtr hwnd);

in the code:

DestroyWindow(hwnd) //or DestroyWindow(windows[i].handle)

this is the unmanaged version of system.windows.forms.form.close()


or you can use:

Process [] proc Process.GetProcessesByName("process name");
proc[0].Kill();

or you can use:

static uint WM_CLOSE = 0x0010;
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true)]
static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

in code:

PostMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
7
  • DestroyWindow/CloseWindow doesn't closes window, why? Commented Sep 6, 2013 at 9:04
  • it should close the window if the window handle is correct. if the window handle is equal to IntPtr.Zero its an invalid handle. if you destroy a parent window all child windows will also close. Commented Sep 6, 2013 at 9:10
  • No handle is not IntPtr.Zero. Minimize and maximize are working correctly only close is not working, is there any other way? Commented Sep 6, 2013 at 9:20
  • I tried both PostMessage and PostQuitMessage methods, but instead of get closed it gets restore Commented Sep 6, 2013 at 9:34
  • 1
    Nicolas Tyler, I got the answer at the link you provided, thanks a lot Commented Sep 6, 2013 at 9:51
8

You may use native method ShowWindow with SW_MAXIMIZE, SW_MINIMIZE for ncmdShow Take a look at http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx

private const int SW_MAXIMIZE = 3;
private const int SW_MINIMIZE = 6;

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommands nCmdShow);


// in your code
ShowWindow(wnd.Handle, SW_MAXIMIZE);
5
  • can you please tell me how to use that? Commented Sep 6, 2013 at 7:37
  • Your answer is right. can we get handle or window if we only know its caption Commented Sep 6, 2013 at 7:46
  • You got handles in your WindowWrapper, it would be more efficient to store them as window caption can be changed by application itself running in background.
    – Max Markov
    Commented Sep 6, 2013 at 7:50
  • Actually I am creating an application in that user will store caption of window that he/she wants to maximize/minimize/close at specified time, till that window will be open. My code will read caption from database. same thing might happen on another machine which will have same window opened. Now another machine will not have the same handle code as in local machine so i need handle code of process by its caption Commented Sep 6, 2013 at 7:57
  • 1
    I see, there is Windows API function FindWindow that can do it msdn.microsoft.com/en-us/library/windows/desktop/… Just set ClassName to NULL and use your caption for WindowsName
    – Max Markov
    Commented Sep 6, 2013 at 8:06
5

you can use ShowWindowAsync

private const int SW_SHOWNORMAL = 1;
private const int SW_SHOWMINIMIZED = 2;
private const int SW_SHOWMAXIMIZED = 3;

[DllImport("user32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);


ShowWindowAsync(wnd.Handle, SW_SHOWMINIMIZED );

and it's better and to use

    var openWindows = Process.GetProcesses().Where(process=> String.IsNullOrEmpty(process.MainWindowTitle)==false);

to get opened windows

I have test MainWindowTitle in Porcess and it helps to search on window given it's caption.

 var handles = Process.GetProcesses().Where(x => x.MainWindowTitle == "Untitled - Notepad").Select(y=>y.Handle).ToList();
2
  • do you know code to get handle of window if we only know its caption Commented Sep 6, 2013 at 8:06
  • The only way that would work for my WPF application, thanks!
    – Lee
    Commented Aug 13, 2016 at 14:52

Not the answer you're looking for? Browse other questions tagged or ask your own question.