Подтвердить что ты не робот

Восстановить WindowState из Minimized

Есть ли простой способ восстановить свернутую форму в ее предыдущее состояние, как нормальное, так и максимизированное? Я ожидаю такую ​​же функциональность, как щелчок на панели задач (или щелчок правой кнопкой мыши и выбор восстановления).

До сих пор у меня это было, но если форма была предварительно увеличена, она все равно возвращается как нормальное окно.

if (docView.WindowState == FormWindowState.Minimized)
    docView.WindowState = FormWindowState.Normal;

Нужно ли обрабатывать изменение состояния в форме для запоминания предыдущего состояния?

4b9b3361

Ответ 1

Я использую следующий метод расширения:

using System.Runtime.InteropServices;

namespace System.Windows.Forms
{
    public static class Extensions
    {
        [DllImport( "user32.dll" )]
        private static extern int ShowWindow( IntPtr hWnd, uint Msg );

        private const uint SW_RESTORE = 0x09;

        public static void Restore( this Form form )
        {
            if (form.WindowState == FormWindowState.Minimized)
            {
                ShowWindow(form.Handle, SW_RESTORE);
            }
        }
    }
}

Затем вызовите form.Restore() в моем коде.

Ответ 2

Самый простой способ восстановить форму до нормального состояния:

if (MyForm.WindowState == FormWindowState.Minimized)
{
    MyForm.WindowState = FormWindowState.Normal;
}

Ответ 3

Вы можете имитировать щелчок на кнопке панели задач следующим образом:

SendMessage(docView.Handle, WM_SYSCOMMAND, SC_RESTORE, 0);

Ответ 4

Для меня приведенный выше код НЕ работает.

Но наконец я нашел рабочий код. Вот оно:

CxImports.ManagedWindowPlacement placement = new CxImports.ManagedWindowPlacement();
CxImports.GetWindowPlacement(Convert.ToUInt32(Handle.ToInt64()), placement);

if (placement.flags == CxImports.WPF_RESTORETOMAXIMIZED)
    WindowState = FormWindowState.Maximized;
else
    WindowState = FormWindowState.Normal;

Я думаю, вы можете найти все необходимые "импортированные" функции простым поиском в Интернете.

Ответ 5

Если кому-то интересно, как это сделать с окнами других приложений, этот код работает для меня:

    public void UnMinimize(IntPtr handle)
    {
        WINDOWPLACEMENT WinPlacement = new WINDOWPLACEMENT();
        GetWindowPlacement(handle, out WinPlacement);
        if(WinPlacement.flags.HasFlag(WINDOWPLACEMENT.Flags.WPF_RESTORETOMAXIMIZED))
        {
            ShowWindow(handle, (int)SW_MAXIMIZE);
        }
        else
        {
            ShowWindow(handle, (int)SW_RESTORE);
        }
    }

Материал здесь:

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    public Int32 Left;
    public Int32 Top;
    public Int32 Right;
    public Int32 Bottom;
}

public struct POINT
{
    public int x;
    public int y;
}

public struct WINDOWPLACEMENT
{

    [Flags]
    public enum Flags : uint
    {
        WPF_ASYNCWINDOWPLACEMENT = 0x0004,
        WPF_RESTORETOMAXIMIZED = 0x0002,
        WPF_SETMINPOSITION = 0x0001
    }


    /// <summary>
    /// The length of the structure, in bytes. Before calling the GetWindowPlacement or SetWindowPlacement functions, set this member to sizeof(WINDOWPLACEMENT).
    /// </summary>
    public uint length;
    /// <summary>
    /// The flags that control the position of the minimized window and the method by which the window is restored. This member can be one or more of the following values.
    /// </summary>
    /// 
    public Flags flags;//uint flags;
                       /// <summary>
                       /// The current show state of the window. This member can be one of the following values.
                       /// </summary>
    public uint showCmd;
    /// <summary>
    /// The coordinates of the window upper-left corner when the window is minimized.
    /// </summary>
    public POINT ptMinPosition;
    /// <summary>
    /// The coordinates of the window upper-left corner when the window is maximized.
    /// </summary>
    public POINT ptMaxPosition;
    /// <summary>
    /// The window coordinates when the window is in the restored position.
    /// </summary>
    public RECT rcNormalPosition;
}

public class UnMinimizeClass
{
    [DllImport("user32.dll")]
    public static extern bool GetWindowPlacement(IntPtr hWnd, out WINDOWPLACEMENT lpwndpl);

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

    const int SW_MAXIMIZE = 3;
    const int SW_RESTORE = 9;

    public static void UnMinimize(IntPtr handle)
    {
        WINDOWPLACEMENT WinPlacement = new WINDOWPLACEMENT();
        GetWindowPlacement(handle, out WinPlacement);
        if (WinPlacement.flags.HasFlag(WINDOWPLACEMENT.Flags.WPF_RESTORETOMAXIMIZED))
        {
            ShowWindow(handle, SW_MAXIMIZE);
        }
        else
        {
            ShowWindow(handle, (int)SW_RESTORE);
        }
    }
}

Ответ 6

    [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetWindowRect(IntPtr hWnd, ref wndRect lpRect);
    [DllImport("user32.dll")] public static extern bool IsWindowVisible(IntPtr hWnd);
    [DllImport("user32.dll")] public static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, int lParam);//用来遍历所有窗口 
    [DllImport("user32.dll")] public static extern int GetWindowTextW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount);//获取窗口Text 
    [DllImport("user32.dll")] public static extern int GetClassNameW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount);//获取窗口类名 

    public static List<wndInfo> GetAllDesktopWindows(bool? isVisitable_)
    {
        //用来保存窗口对象
        List<wndInfo> wndList = new List<wndInfo>();

        //enum all desktop windows 
        EnumWindows(delegate (IntPtr hWnd, int lParam)
        {
            wndInfo wnd = new wndInfo();
            StringBuilder sb = new StringBuilder(256);
            //get hwnd 
            wnd.hWnd = hWnd;
            if (isVisitable_ == null || IsWindowVisible(wnd.hWnd) == isVisitable_)
            {
                //get window name  
                GetWindowTextW(hWnd, sb, sb.Capacity);
                wnd.szWindowName = sb.ToString();

                //get window class 
                GetClassNameW(hWnd, sb, sb.Capacity);
                wnd.szClassName = sb.ToString();

                wndList.Add(wnd);
            }
            return true;

        }, 0);

        return wndList;
    }

    private void Btn_Test5_Click(object sender, RoutedEventArgs e)
    {
        var ws = WSys.GetAllDesktopWindows(true);
        foreach (var w in ws)
        {
            if (w.szWindowName == "计算器")
            {
                WSys.ShowWindow(w.hWnd, 5);
                WSys.ShowWindow(w.hWnd, 9);
                Log.WriteLine(w.szWindowName);
            }
        }
    }

Ответ 7

Приведенный выше код не совсем сработал у меня во всех ситуациях.

После проверки флажков мне также нужно проверить showcmd = 3, и если это так, чтобы максимизировать else restore