Winforms 从“最小化”恢复Windows状态

Winforms 从“最小化”恢复Windows状态,winforms,Winforms,有没有一种简单的方法可以将最小化的表单恢复到其以前的状态(正常或最大化)?我期待着与单击任务栏(或右键单击并选择还原)相同的功能 到目前为止,我有这个,但如果窗体以前被最大化了,它仍然作为一个正常窗口返回 if (docView.WindowState == FormWindowState.Minimized) docView.WindowState = FormWindowState.Normal; 我必须处理表单中的状态更改才能记住以前的状态吗?您可以模拟如下方式单击任务栏按钮:

有没有一种简单的方法可以将最小化的表单恢复到其以前的状态(正常或最大化)?我期待着与单击任务栏(或右键单击并选择还原)相同的功能

到目前为止,我有这个,但如果窗体以前被最大化了,它仍然作为一个正常窗口返回

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

我必须处理表单中的状态更改才能记住以前的状态吗?

您可以模拟如下方式单击任务栏按钮:

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

对我来说,上面的代码不起作用

但最后我找到了工作代码。这是:

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;

我想,您可以通过简单的谷歌搜索找到所有需要的“导入”函数。

我使用以下扩展方法:

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()

将表单恢复到正常状态的最简单方法是:

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

上述代码并非在所有情况下都适用于我


在检查标志后,我还必须检查showcmd=3,如果是这样,最大化else restore

如果有人想知道如何在其他应用程序窗口中执行此操作,此代码适用于我:

    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's upper-left corner when the window is minimized.
    /// </summary>
    public POINT ptMinPosition;
    /// <summary>
    /// The coordinates of the window's upper-left corner when the window is maximized.
    /// </summary>
    public POINT ptMaxPosition;
    /// <summary>
    /// The window's 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);
        }
    }
}
[StructLayout(LayoutKind.Sequential)]
公共结构矩形
{
公共Int32左;
公共Int32 Top;
公共权利;
公共Int32底部;
}
公共结构点
{
公共int x;
公共智力;
}
公共结构窗口放置
{
[旗帜]
公共枚举标志:uint
{
WPF_ASYNCWINDOWPLACEMENT=0x0004,
WPF_RESTORETOMAXIMIZED=0x0002,
WPF_SETMINPOSITION=0x0001
}
/// 
///结构的长度,以字节为单位。在调用GetWindowPlacement或SetWindowPlacement函数之前,请将此成员设置为sizeof(WINDOWPLACEMENT)。
/// 
公共单位长度;
/// 
///控制最小化窗口位置和窗口还原方法的标志。此成员可以是以下一个或多个值。
/// 
/// 
公共标志标志;//uint标志;
/// 
///窗口的当前显示状态。此成员可以是以下值之一。
/// 
公共uint showCmd;
/// 
///窗口最小化时窗口左上角的坐标。
/// 
公共点位置;
/// 
///窗口最大化时窗口左上角的坐标。
/// 
公共点位置;
/// 
///窗口处于恢复位置时的窗口坐标。
/// 
公共直线位置;
}
公共类未初始化类
{
[DllImport(“user32.dll”)]
公共静态外部bool GetWindowPlacement(IntPtr hWnd,out WINDOWPLACEMENT lpwndpl);
[DllImport(“user32.dll”)]
公共静态外部布尔显示窗口(IntPtr hWnd、int nCmdShow);
常数int SW_=3;
const int SW_RESTORE=9;
公共静态无效未最小化(IntPtr句柄)
{
WINDOWPLACEMENT WinPlacement=新建WINDOWPLACEMENT();
GetWindowPlacement(句柄,输出WinPlacement);
if(WinPlacement.flags.HasFlag(WINDOWPLACEMENT.flags.WPF_RESTORETOMAXIMIZED))
{
显示窗口(手柄、开关);
}
其他的
{
显示窗口(手柄,(内部)开关恢复);
}
}
}
[DllImport(“user32.dll”)][return:MarshalAs(UnmanagedType.Bool)]公共静态外部Bool GetWindowRect(IntPtr hWnd,ref wndRect lpRect);
[DllImport(“user32.dll”)]公共静态外部bool-IsWindowVisible(IntPtr-hWnd);
[DllImport(“user32.dll”)]公共静态外部bool EnumWindows(WNDENUMPROC lpEnumFunc,int lParam)//用来遍历所有窗口 
[DllImport(“user32.dll”)]公共静态外部程序int-GetWindowTextW(IntPtr-hWnd[MarshalAs(UnmanagedType.LPWStr)]StringBuilder-lpString,int-nMaxCount)//获取窗口正文
[DllImport(“user32.dll”)]公共静态外部程序int GetClassNameW(IntPtr hWnd,[MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString,int nMaxCount)//获取窗口类名 
公共静态列表GetAllDesktopWindows(bool?isVisitable_389;)
{
//用来保存窗口对象
List wndList=新列表();
//枚举所有桌面窗口
枚举窗口(委托(IntPtr hWnd、int lParam)
{
wndInfo wnd=新的wndInfo();
StringBuilder sb=新的StringBuilder(256);
//得到hwnd
wnd.hWnd=hWnd;
如果(isVisitable_124;==null | | IsWindowVisible(wnd.hWnd)==isVisitable_124;)
{
//获取窗口名
GetWindowTextW(hWnd、sb、sb容量);
wnd.szWindowName=sb.ToString();
//获取窗口类
GetClassNameW(硬件、sb、sb容量);
wnd.szClassName=sb.ToString();
wndList.Add(wnd);
}
返回true;
}, 0);
返回wndList;
}
私有无效Btn_测试5_单击(对象发送者,路由目标e)
{
var ws=WSys.GetAllDesktopWindows(true);
foreach(在ws中为w变量)
{
如果(w.szWindowName==”计算器")
{
WSys.ShowWindow(w.hWnd,5);
WSys.ShowWindow(w.hWnd,9);
Log.WriteLine(w.szWindowName);
}
}
}

使用
MainWindow.WindowState=WindowState.Normal;
是不够的

下一种方法适用于我的WPF应用程序:

MainWindow.WindowState = WindowState.Normal;
MainWindow.Show();
MainWindow.Activate();

我刚刚又添加了一个部分来泛化@Mesmo给出的解决方案。如果没有创建实例,它将创建实例;如果实例已经在应用程序中的任何位置创建,它将恢复并聚焦表单。我的要求是,我不想为应用程序中的某些功能打开多个表单

实用程序类:

public static class Utilities
{
  [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);
    }
  }

  public static void CreateOrRestoreForm<T>() where T: Form
  {
    Form form = Application.OpenForms.OfType<T>().FirstOrDefault();

    if (form == null)
    {
      form = Activator.CreateInstance<T>();
      form.Show();
    }
    else
    {
      form.Restore();
      form.Focus();
    }
  }
}
Utilities.CreateOrRestoreForm<AboutForm>();
公共静态类实用程序
{
[DllImport(“user32.dll”)]
专用静态外部显示窗口(IntPtr hWnd,uint Msg);
私人建筑开关恢复=
Utilities.CreateOrRestoreForm<AboutForm>();