怎样通过正在运行的Process获取窗体的实例?
今天在做程序的单实例运行时发现个问题(Winform),我将程序运行后最小化到托盘,再次双击程序时弹出已运行的程序。
[code=C#]
[DllImport( "User32.dll ")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
[DllImport( "User32.dll ")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
private const int WS_SHOWNORMAL = 1;
/// <summary>
/// 程序入口
/// </summary>
[STAThread]
static void Main()
{
//其他代码省略。。。
Process instance = RunningInstance();
if (instance == null)
{//运行程序}
else//程序已经运行,显示已运行的程序
{
System.IntPtr handler = instance.MainWindowHandle;
frmDefault frm = (frmDefault)Form.FromHandle(handler);//frmDefault程序主窗体,就是这句的问题
frm.FormOpen();//主窗体中点击托盘图标显示窗体的方法
}
}
[/code]
frmDefault frm = (frmDefault)Form.FromHandle(handler);这句获取的frm是Null.
我试了下Form frm = (Form)Form.FromHandle(handler);frm 还是Null
请问怎么能通过运行的Process得到窗体的实例?
[解决办法]
用API:
ShowWindow(SW_SHOWNORMAL);
[解决办法]
帮顶~~~~~~~~~
[解决办法]
搞不懂 是不是可以父子窗体来搞这个东西
[解决办法]
我以前也做过类似的功能,就是当一个.exe程序(winform应用程序)已经打开的时候,再双击图标打开的时候就提示:程序已经启动,具体实现代码如下:
[STAThread]
static void Main()
{
bool canStart;
System.Threading.Mutex mutex = new System.Threading.Mutex(false,"进程名字-不带.exe的(也就是窗体的名字),我这里是GIS_DMC",out canStart);
if (canStart)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new GIS_DMCForm());
}
else
{
MessageBox.Show("程序已启动");
}
}
[解决办法]
[DllImport("User32.dll ", EntryPoint = "FindWindow")] private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)] public static extern int ShowWindow(IntPtr hwnd, int nCmdShow); [DllImport("user32.dll", EntryPoint = "SetForegroundWindow")] public static extern bool SetF(IntPtr hWnd); [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Process current = RunningInstance(); if (current != null) { IntPtr handle = FindWindow(null, "Form1"); ShowWindow(handle, 1); SetF(handle); } else { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } public static Process RunningInstance() { Process current = Process.GetCurrentProcess(); Process[] processes = Process.GetProcessesByName(current.ProcessName); foreach (Process process in processes) { if (process.Id != current.Id) { if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == current.MainModule.FileName) { return process; } } } return null; }
[解决办法]
我是来学习的,路过帮顶
[解决办法]
[System.Runtime.InteropServices.DllImport("user32.dll")] private static extern IntPtr FindWindow(string strclassName, string strWindowName); [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern bool OpenIcon(IntPtr hWnd); [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern bool IsIconic(IntPtr hWnd); [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern int SetForegroundWindow(IntPtr hWnd); void FindAndOpenWindow(string Title) { IntPtr hWnd = (IntPtr ) FindWindow(null, Title); if (hWnd != IntPtr.Zero) { bool isIcon = IsIconic(hWnd); if ( !isIcon ) { SetForegroundWindow(hWnd); } else { OpenIcon(hWnd); } } }
[解决办法]
看了这么多 API,再回过头来看看楼主的需求,最适合的应该是Singleton 模式了,
使用这个,就没有楼主说的那些 api 烦劳