如何从另一个应用程序恢复具有不可见的WinForm的应用程序?

时间:2014-01-14 22:16:03

标签: c# winforms visibility message-queue

我有一个实用程序WinForm应用程序,通常运行最小化。它用于制造工厂的PC上。我想让应用程序在最小化时变得不可见,以防止意外关闭表单或使用某些设置。不是万无一失,只是有点谨慎。

但是我无法让应用程序的主要且唯一的形式重新出现从同一应用程序的另一个实例发送WM_SYSCOMMANDSC_RESTORE消息。

我设置了Resize_Event,以便在未最小化时将Visible设置回true

我已尝试SendMessagePostMessage。如果我在不将表单的Visible属性设置为false的情况下允许表单最小化或最大化,则调用将按预期工作,并且目标表单将调整大小。

表单的消息泵是否未在此状态下运行,因此忽略了消息?

我应该创建另一个经常检查消息队列的线程吗?怎么做的?

正在恢复表单的应用中的示例代码:

...
Process current = Process.GetCurrentProcess();
foreach (Process process in Process.GetProcessesByName("MyApp")) { //current.ProcessName)) {
  if (process.Id != current.Id) {
    SendMessage(process.MainWindowHandle, WM_SYSCOMMAND, (IntPtr)SC_RESTORE, (IntPtr)0);
    Interaction.AppActivate(process.Id); //Most reliable way to focus target
    SetForegroundWindow(process.MainWindowHandle);
    break;
  }
}
...

恢复可见性的目标形式的代码。

  // If form is minimized then hide it
  if (WindowState == FormWindowState.Minimized) {
    this.Visible = false;
  }
  else {
    this.Visible = true;
  }

3 个答案:

答案 0 :(得分:2)

我通常做的是覆盖Form.OnClosing方法,然后继续设置e.Cancel = true。然后调用Hide()方法,使其仍然在后台运行。

要恢复应用程序,我使用named events创建单个实例应用程序。您也可以使用互斥锁。看到这个SO anwser:How to run one instance of a c# WinForm application?

修改 命名事件也可以帮助您从其他应用程序打开它。就在您收到某种展示活动时,您只需将表单告诉Show()

答案 1 :(得分:0)

这不是万无一失的,但实施起来很简单。

  • 在程序首次加载时添加一个设置为m_closePrompt的布尔值true
  • FormClosing 事件连接事件处理程序。

screen shot

private void MdiForm_Closing(object sender, FormClosingEventArgs e) {
  if (m_closePrompt) {
    string ask = "Really Close this Application?";
    if (MessageBox.Show(ask, "Confirmation",  MessageBoxButtons.YesNo, MessageBoxIcon.Question, 0) != DialogResult.Yes) {
      e.Cancel = true;
    } else {
      m_closePrompt = false;
    }
  }
}

至少应弹出系统对话框。

如果您希望关闭应用程序的其他方法(如未处理的异常),请在关闭应用程序之前在错误处理例程中设置m_closePrompt = false

答案 2 :(得分:0)

Hans Passant指出了正确的方向,他对我提出的问题的评论question

我的最终代码看起来像这样。

using System;
using System.Windows.Forms;
using Microsoft.VisualBasic.ApplicationServices;   // Add reference to Microsoft.VisualBasic

namespace MyApp
{
  class Program : WindowsFormsApplicationBase 
  {
     /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
      var app = new Program();
      app.Run(args);
    }
    public Program()
    {
      this.IsSingleInstance = true;
      this.EnableVisualStyles = true;
      this.MainForm = new fMain();
    }
    protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
    {
      if (this.MainForm.WindowState == FormWindowState.Minimized) {
        this.MainForm.Show();     // Unhide if hidden
        this.MainForm.WindowState = FormWindowState.Normal; //Restore
      }
      this.MainForm.Activate();
    }
  }

}