如何将 window 恢复到原始状态(与之前相同的高度和宽度)?

How to restore a window to its orginal state(the same heigth and width as it's before)?

此处(示例程序下方)如果调整记事本大小--> 最大化然后最小化。 window 位置(最大化)未保留。

我想保留 window 最小化前的位置。

我已经尝试了下面的代码。请帮助。

public 部分 class Form1 : 表格 { public 表格 1() { 初始化组件(); }

    private readonly IntPtr HWND_TOPMOST = new IntPtr(0);

    private void button1_Click(object sender, EventArgs e)
    {
        Process[] Processes = Process.GetProcessesByName("notepad");
        string processString = string.Format("Untitled - Notepad");
        IntPtr res;
        foreach (Process theprocess in Processes)
        {
            if (theprocess.MainWindowTitle.Contains(processString))
            {
                if (theprocess.MainWindowHandle == IntPtr.Zero)
                {
                    continue;
                }
                WindowsNativeCalls.SetActiveWindow(theprocess.MainWindowHandle);

                if (theprocess.MainWindowHandle != IntPtr.Zero)
                {
                    if (theprocess.MainWindowTitle.Contains(processString))
                    {
                        WindowsNativeCalls.WINDOWPLACEMENT placement = new WindowsNativeCalls.WINDOWPLACEMENT();
                        WindowsNativeCalls.GetWindowPlacement(theprocess.MainWindowHandle, ref placement);
                        switch (placement.showCmd)
                        {
                            case 1:// SW_NORMAL
                            case 3:// SW_MAXIMIZE does the job of bring to front

                                WindowsNativeCalls.SetWindowPos(theprocess.MainWindowHandle, HWND_TOPMOST, 0, 0, 0, 0, WindowsNativeCalls.SWP_NOMOVE | WindowsNativeCalls.SWP_NOSIZE | WindowsNativeCalls.SWP_SHOWWINDOW);
                                break;

                            case 2: // SW_SHOWMINIMIZED 
                                placement.showCmd = 9;
                                WindowsNativeCalls.SetWindowPlacement(theprocess.MainWindowHandle, ref placement);
                                //res = WindowsNativeCalls.SendMessage(theprocess.MainWindowHandle, WindowsNativeCalls.WM_SYSCOMMAND, (IntPtr)WindowsNativeCalls.SW_SHOWNORMAL, IntPtr.Zero);
                                break;
                        }
                    }
                }
            }
        }
    }
}

public class WindowsNativeCalls { #region 字段

    /// <summary>
    /// Hide Window
    /// </summary>
    public const int SW_HIDE = 0;
    /// <summary>
    /// Show Normal
    /// </summary>
    public const int SW_SHOWNORMAL = 1;
    /// <summary>
    /// Minimize Window
    /// </summary>
    public const int SW_SHOWMINIMIZED = 2;
    /// <summary>
    /// Maxiize Window
    /// </summary>
    public const int SW_SHOWMAXIMIZED = 3;
    /// <summary>
    /// Activate Window
    /// </summary>
    public const int SW_SHOWNOACTIVATE = 4;
    /// <summary>
    /// Restore Window
    /// </summary>
    public const int SW_RESTORE = 9;

    /// <summary>
    /// SW_SHOW
    /// </summary>
    public const int SW_SHOW = 5;
    /// <summary>
    /// Default Window
    /// </summary>
    public const int SW_SHOWDEFAULT = 10;
    /// <summary>
    /// Close Windows message
    /// </summary>
    public const uint WM_CLOSE = 0x10;
    /// <summary>
    /// Screen Window Position to No Size Change
    /// </summary>
    public const UInt32 SWP_NOSIZE = 0x0001;
    /// <summary>
    /// Screen Window Position to No Move Change
    /// </summary>
    public const UInt32 SWP_NOMOVE = 0x0002;
    /// <summary>
    /// Screen Window Position to Show Window
    /// </summary>
    public const UInt32 SWP_SHOWWINDOW = 0x0040;
    /// <summary>
    /// Maximize Window in Graphics mode
    /// </summary>
    public const int SC_MAXIMIZE = 0xF030;
    /// <summary>
    /// Resize Windows message
    /// </summary>
    public const uint WM_SYSCOMMAND = 0x0112;


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

    public struct RECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }

    public struct WINDOWPLACEMENT
    {
        public int length;
        public int flags;
        public int showCmd;
        public POINTAPI ptMinPosition;
        public POINTAPI ptMaxPosition;
        public RECT rcNormalPosition;
    }
    #endregion

    #region DllImport Functions

    /// <summary>
    /// Sets the show state of a window created.
    /// </summary>
    /// <param name="hWnd">Window Handle</param>
    /// <param name="nCmdShow">Show state</param>
    /// <returns>Returns True if successful</returns>
    [DllImport("user32.dll")]
    public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);

    /// <summary>
    /// Sets window in Forefront and activates it
    /// </summary>
    /// <param name="hWnd">Window Handle</param>
    /// <returns>Returns True if successfu</returns>
    [DllImport("user32.dll")]
    public static extern bool SetForegroundWindow(IntPtr hWnd);


    /// <summary>
    /// Sets the show state of a window created.
    /// </summary>
    /// <param name="hWnd">Window Handle</param>
    /// <param name="nCmdShow">Show state</param>
    /// <returns>Returns True if successful</returns>
    [DllImport("user32.dll")]
    public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    [DllImport("user32.dll")]
    public static extern bool SetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);

    [DllImport("user32.dll")]
    public static extern IntPtr GetForegroundWindow();

    [DllImport("user32.dll")]
    public static extern int GetWindowText(IntPtr hWnd, System.Text.StringBuilder text, int count);

    [DllImport("user32.dll")]
    public static extern bool IsIconic(IntPtr hWnd);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
    public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool EnumWindows(EnumedWindow lpEnumFunc, ArrayList lParam);

    public delegate bool EnumedWindow(IntPtr handleWindow, ArrayList handles);

    [DllImport("user32")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool EnumChildWindows(IntPtr window, EnumedWindow callback, ArrayList lParam);

    [DllImport("user32.dll")]
    public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr SetActiveWindow(IntPtr hWnd);

    [StructLayout(LayoutKind.Sequential)]
    public struct WINDOWINFO
    {
        public uint cbSize;
        public RECT rcWindow;
        public RECT rcClient;
        public uint dwStyle;
        public uint dwExStyle;
        public uint dwWindowStatus;
        public uint cxWindowBorders;
        public uint cyWindowBorders;
        public ushort atomWindowType;
        public ushort wCreatorVersion;

        public WINDOWINFO(Boolean? filler)
            : this()   
        {
            cbSize = (UInt32)(Marshal.SizeOf(typeof(WINDOWINFO)));
        }

    }
    [DllImport("user32.dll", SetLastError = true)]
    public static extern bool GetWindowInfo(IntPtr hwnd, ref WINDOWINFO pwi);

    #endregion
}

如果您希望 window 使用其之前的位置,请不要通过调用 SetWindowPos().

覆盖 window 的位置信息

相反,只需使用适当的命令(即 SW_MINIMIZE)调用 ShowWindow() 来最小化 window。那么当你恢复它的时候,它之前的位置信息还在。


<旁白>
顺便说一下,您的代码检查 null 的 window 句柄和 两次 的 window 标题有什么特别的原因吗?

 switch (placement.showCmd) 
                {
                    case 2: // Activates and displays the window -- This case only when the window is minimized.
                        WindowsNativeCalls.ShowWindow(theprocess.MainWindowHandle, WindowsNativeCalls.SW_RESTORE);
                        break;
                    default: // Bring to Front - For all other cases
                        WindowsNativeCalls.SetWindowPos(theprocess.MainWindowHandle, HWND_TOPMOST, 0, 0, 0, 0, WindowsNativeCalls.SWP_NOMOVE | WindowsNativeCalls.SWP_NOSIZE | WindowsNativeCalls.SWP_SHOWWINDOW);
                        break;

                }