我有以下情况: WinForms应用程序,只允许运行此应用程序的一个实例(此处使用Mutex进行检查)。应用程序开始时有一些paramatere是runnig但隐藏。当有人再次点击应用程序时,Mutex将检测到该应用程序已在运行,并通过调用本机方法“取消隐藏”主窗体(请参阅下面的方法 BringWindowToFront )。
以下是查找和显示表单窗口的代码:
public static class NativeMethods
{
public enum ShowWindowOptions
{
FORCEMINIMIZE = 11,
HIDE = 0,
MAXIMIZE = 3,
MINIMIZE = 6,
RESTORE = 9,
SHOW = 5,
SHOWDEFAULT = 10,
SHOWMAXIMIZED = 3,
SHOWMINIMIZED = 2,
SHOWMINNOACTIVE = 7,
SHOWNA = 8,
SHOWNOACTIVATE = 4,
SHOWNORMAL = 1
}
[DllImport("user32.dll")]
public static extern int ShowWindow(int hwnd, int cmdShow);
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(String lpClassName, String lpWindowName);
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
public static void BringWindowToFront(string windowTitle)
{
// Get a handle to the application.
IntPtr handle = FindWindow(null, windowTitle);
// Verify that app is a running process.
if (handle == IntPtr.Zero)
{
return;
}
// With this line you have changed window status from example, minimized to normal
ShowWindow((int)handle, (int)ShowWindowOptions.SHOWDEFAULT);
// Make app the foreground application
SetForegroundWindow(handle);
}
}
一切都很好但我还需要一个功能。 我希望在主表单第一次取消隐藏时显示另一个表单。通常我是通过表单 _Shown 事件来完成的。但是,当我使用PInvoke方法显示窗口时,此事件不会被激活。
所以基本上我想在显示主窗体时显示其他形式(使用ShowWindow PInvoke方法)
这可能吗?任何其他想法如何实现它?
提前谢谢。
答案 0 :(得分:2)
Form.Shown
事件仅在第一次显示表单时触发(即在加载后),稍后执行任何其他操作(例如,隐藏然后重新显示)将不会触发事件。有关详细信息,请参阅:http://msdn.microsoft.com/en-us/library/system.windows.forms.form.shown.aspx
在您的情况下,还有一些其他可能有用的事件:
如果这些都不起作用,并且您必须使用P / Invoke,那么我会使用SetActiveWindow来发送WM_ACTIVATE消息,该消息应强制Form.Activated。
请注意,如果这不起作用(因为SetActiveWindow
发送一个低位为1的WM_ACTIVATE
,表示该窗口未被鼠标激活,那么您可以解决这可以通过使用您自己的WM_ACTIVATE消息直接向窗口发送消息。
答案 1 :(得分:2)
编写单实例应用程序很棘手。您不必,.NET框架已经非常好地支持它们。 Project + Add Reference,选择Microsoft.VisualBasic。打开项目的Program.cs文件,使其如下所示:
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Microsoft.VisualBasic.ApplicationServices;
namespace WindowsFormsApplication1 {
class Program : WindowsFormsApplicationBase {
[STAThread]
static void Main(string[] args) {
var prg = new Program();
prg.EnableVisualStyles = true;
prg.IsSingleInstance = true;
prg.MainForm = new Form1();
prg.Run(args);
}
protected override void OnStartupNextInstance(StartupNextInstanceEventArgs e) {
var main = this.MainForm as Form1;
main.WindowState = FormWindowState.Normal;
main.BringToFront();
// You could do something interesting with the command line arguments:
//foreach (var arg in e.CommandLine) {
// main.OpenFile(arg);
//}
}
}
}