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.

sandeep.gosavi
  • 610
  • 2
  • 10
  • 27
  • Possible duplicate of [Restore a minimized window of another application](https://stackoverflow.com/questions/9099479/restore-a-minimized-window-of-another-application) – Deniz Jun 20 '18 at 13:14

3 Answers3

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);
Feanaro
  • 922
  • 3
  • 19
  • 35
string.Empty
  • 10,393
  • 4
  • 39
  • 67
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);
Max Markov
  • 924
  • 12
  • 23
  • can you please tell me how to use that? – sandeep.gosavi Sep 06 '13 at 07:37
  • Your answer is right. can we get handle or window if we only know its caption – sandeep.gosavi Sep 06 '13 at 07: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 Sep 06 '13 at 07: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 – sandeep.gosavi Sep 06 '13 at 07:57
  • 1
    I see, there is Windows API function FindWindow that can do it http://msdn.microsoft.com/en-us/library/windows/desktop/ms633499(v=vs.85).aspx Just set ClassName to NULL and use your caption for WindowsName – Max Markov Sep 06 '13 at 08: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();
Alyafey
  • 1,455
  • 3
  • 15
  • 23