【问题标题】:Maximize window from the Main function?从主函数最大化窗口?
【发布时间】:2011-08-24 19:26:50
【问题描述】:

我使用互斥锁来运行单个实例程序,现在我希望窗口在用户重新打开应用程序时当前处于最小化状态时最大化。

这是我目前在 Program.cs 文件中的代码:

static class Program
{
    [DllImport("user32.dll")]
    public static extern bool SetForegroundWindow(IntPtr hWnd);

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        bool Ok = true;
        string ProductName = Application.ProductName;
        Mutex m = new Mutex(true, ProductName, out Ok);
        if (!Ok)
        {
            System.Diagnostics.Process[] p = System.Diagnostics.Process.GetProcessesByName(ProductName);
            SetForegroundWindow(p[0].MainWindowHandle);

    }
    else
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());

    }
}

【问题讨论】:

  • 我可以建议恢复窗口(即取消最小化)比最大化它更有意义。
  • @romkyns:绝对同意。 SW_SHOW 是这样做的方法,正如我在答案底部提到的那样。这会将窗口恢复到最小化之前的状态,无论是标准窗口还是最大化窗口。

标签: c# .net windows winapi maximize


【解决方案1】:

我想建议一个纯 .NET 的解决方案(即不依赖操作系统)。

Program.cs

static class Program
{
    private static volatile bool _exitProcess;

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        bool createdNew;
        var showMeEventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, "MyApp.ShowMe", out createdNew);

        if (createdNew)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            var form = new Form1();
            new Thread(() =>
            {
                while (!_exitProcess)
                {
                    showMeEventHandle.WaitOne(-1);
                    if (!_exitProcess)
                    {
                        if (form.InvokeRequired)
                        {
                            form.BeginInvoke((MethodInvoker)form.BringFormToFront);
                        }
                        else
                        {
                            form.BringFormToFront();
                        }
                    }
                }
            }).Start();

            Application.Run(form);
        }

        _exitProcess = true;
        showMeEventHandle.Set();

        showMeEventHandle.Close();
    }
}

ExtMethods.cs

public static class ExtMethods
{
    public static void BringFormToFront(this Form form)
    {
        form.WindowState = FormWindowState.Normal;
        form.ShowInTaskbar = true;
        form.Show();
        form.Activate();
    }
}

Form1.cs

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.BringFormToFront();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            WindowState = FormWindowState.Minimized;
            ShowInTaskbar = false;
            Hide();
        }
    }

【讨论】:

  • 绝对出色,比 DLL 解决方案好得多。
【解决方案2】:

您正在寻找ShowWindow functionSW_MAXIMIZE 标志。

在 C# 中,P/Invoke 声明如下所示:

[DllImport("user32.dll", CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

private const int SW_MAXIMIZE = 3;

在此处将其添加到您的代码中:

if (!Ok)
{
   Process[] p = Process.GetProcessesByName(ProductName);
   SetForegroundWindow(p[0].MainWindowHandle);
   ShowWindow(p[0].MainWindowHandle, SW_MAXIMIZE);
}


如果你真的想在最大化它之前先测试窗口是否被最小化,你可以使用老派的IsIconic function

[DllImport("user32.dll", CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsIconic(IntPtr hWnd);

// [...]

if (!Ok)
{
   Process[] p = Process.GetProcessesByName(ProductName);
   IntPtr hwndMain= p[0].MainWindowHandle;
   SetForegroundWindow(hwndMain);

   if (IsIconic(hwndMain))
   {
      ShowWindow(hwndMain, SW_MAXIMIZE);
   }
}

如果您只想激活窗口(而不是将其最大化),请使用 SW_SHOW 值 (5) 而不是 SW_MAXIMIZE。这会将其恢复到最小化之前的状态。

【讨论】:

  • 太棒了,那就行了。只需在您的答案中修复它 [DllImport("user32.dll", CharSet = CharSet.Auto)]
  • @moslem:好的,完成。每个人都会时不时忘记一个右括号。你能说我习惯在 IDE 中编写代码吗?
  • SW_SHOW 或值 (5) 对我不起作用 - 最小化窗口没有任何反应(在 Win XP SP3 上测试赢 7 SP1)。 SW_RESTORE 或值 (9) 对我有用,在我看来,根据MSDN description,这是正确的选择
  • @bairog 没错。你必须为你想做的事情选择正确的标志。 SW_SHOW 不会恢复或最大化最小化的窗口。为此,您需要 SW_RESTORESW_MAXIMIZE。文档是一个很好的地方,这个答案只是让你开始。它是专门为提出的原始问题编写的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-23
  • 2015-07-21
  • 2010-09-23
  • 2010-10-03
  • 1970-01-01
相关资源
最近更新 更多