【问题标题】:How to restore a window to its orginal state(the same heigth and width as it's before)?如何将窗口恢复到其原始状态(与以前相同的高度和宽度)?
【发布时间】:2015-07-09 16:55:39
【问题描述】:

如果记事本被调整大小,则在此处(示例程序下方)-> 最大化然后最小化。不保留窗口位置(最大化)。

我想在最小化之前保持窗口位置不变。

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

公共部分类 Form1 : Form { 公共表格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;
                        }
                    }
                }
            }
        }
    }
}

公共类 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
}

【问题讨论】:

    标签: c# .net winapi c#-4.0


    【解决方案1】:

    如果你想让窗口使用它之前的位置,那么不要通过调用SetWindowPos()来覆盖窗口位置信息。

    相反,只需通过使用适当的命令(即SW_MINIMIZE)调用ShowWindow() 来最小化窗口。那么当你恢复它时,它之前的位置信息仍然会存在。



    顺便说一句,您的代码检查null 的窗口句柄和窗口标题两次 的任何特殊原因?

    【讨论】:

    • 嗨彼得,我从 msdn 阅读了以下几行。控制窗口的显示方式。如果启动应用程序的程序提供了 STARTUPINFO 结构,则该参数在应用程序第一次调用 ShowWindow 时将被忽略。否则,第一次调用 ShowWindow 时,该值应该是 WinMain 函数在其 nCmdShow 参数中获取的值。在后续调用中,该参数可以是以下值之一。
    • msdn.microsoft.com/en-us/library/windows/desktop/… 检查此链接。当我们启动 Windows 时,任务栏第一次出现。从下一次开始,它就不会来了。请提供您的意见。
    • @raj:对不起,我不明白你的评论。您最初的问题根本不涉及任务栏。如果您有其他问题,您应该发布一个新问题。 cmets 不是就您的问题的其他方面寻求建议的正确场所。
    • 感谢彼得将作为一个新问题发布
    • 我的问题在这个链接中。 stackoverflow.com/questions/32755118/…
    【解决方案2】:
     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;
    
                    }
    

    【讨论】:

    • 您已经仔细定义了符号常量,只是使用幻数 (2) 代替了SW_SHOWMINIMIZED。您是否希望再也没有人需要阅读此代码?
    • 应该使用枚举。由于是已有代码,我没有修改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-18
    • 2013-09-16
    • 2011-09-09
    • 1970-01-01
    • 2020-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多