积极答复者
如何让其他线程隐藏的主窗口显示出来?

问题
-
我要实现的功能如下:
打开程序的时候先检查,如果这个程序已经在运行了,就直接将以前打开的程序窗口正常显示出来就行了。我的代码如下,但隐藏的窗口不能显示出来,请问怎么改?
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Diagnostics; using System.Reflection; namespace 例子01 { static class Program { [DllImport("User32.dll")] private static extern bool ShowWindow(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(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Process instance = RunningInstance(); if (instance == null) { Application.Run(new Form1()); } else { MessageBox.Show("程序已在运行中", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information); HandleRunningInstance(instance); } } /// <summary> /// 获取正在运行的实例,没有运行的实例返回null; /// </summary> 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; } /// <summary> /// 显示已运行的程序。 /// </summary> public static void HandleRunningInstance(Process instance) { ShowWindow(instance.MainWindowHandle, WS_SHOWNORMAL); //显示,可以注释掉 SetForegroundWindow(instance.MainWindowHandle); //放到前端 } } }
Form1.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace 例子01 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { this.Hide(); this.ShowInTaskbar = false; } private void notifyIcon1_MouseClick(object sender, MouseEventArgs e) { this.Show(); this.ShowInTaskbar = true; } } }
答案
-
你这个代码我在博客园看到了,文章中已经明确指出 “只有窗口最小化的时候可以达到此效果,如果隐藏到托盘则无法将打开的程序显示到桌面”,所以你上面的代码根本无法达到你的目的的,要实现你说的需求你需要用到FindWindow 函数,具体实现代码如下:
static class Program { [DllImport("user32.dll")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll ", SetLastError = true)] static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab); [DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)] public static extern int ShowWindow(IntPtr hwnd, int nCmdShow); public const int SW_RESTORE=9; public static IntPtr formhwnd; static Form1 form = null; ///<summary> /// 应用程序的主入口点。 ///</summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); string proc = Process.GetCurrentProcess().ProcessName; Process[] processes = Process.GetProcessesByName(proc); if (processes.Length <= 1) { form = new Form1(); Application.Run(form); } else { for (int i = 0; i < processes.Length; i++) { if (processes[i].Id != Process.GetCurrentProcess().Id) { if (processes[i].MainWindowHandle.ToInt32() == 0) { formhwnd = FindWindow(null, "Form1"); ShowWindow(formhwnd,SW_RESTORE); SwitchToThisWindow(formhwnd, true); } else { SwitchToThisWindow(processes[i].MainWindowHandle, true); } } } } } }
Form1.cs中代码和你原来代码一样的,我在本地测试是完全可以的,你可以自己试试
If my post is helpful,please help to vote as helpful, if my post solve your question, please help to make it as answer. My sample
- 已建议为答案 Learning hard 2013年6月14日 7:25
- 已标记为答案 Jason Dot WangModerator 2013年6月18日 7:46
全部回复
-
因为你在Form_Load事件中调用了this.Hide方法把窗体隐藏了,其实此时已经创建了窗体的实例且已经初始化了窗体中所有控件,只是你没看到而已,你可以把在Form_Load中this.Hide方法去掉就可以达到你想要的效果了。
If my post is helpful,please help to vote as helpful, if my post solve your question, please help to make it as answer. my sample
- 已建议为答案 Jason Dot WangModerator 2013年6月10日 5:19
- 取消建议作为答案 CSHARP_FANS 2013年6月14日 3:03
-
因为你在Form_Load事件中调用了this.Hide方法把窗体隐藏了,其实此时已经创建了窗体的实例且已经初始化了窗体中所有控件,只是你没看到而已,你可以把在Form_Load中this.Hide方法去掉就可以达到你想要的效果了。
If my post is helpful,please help to vote as helpful, if my post solve your question, please help to make it as answer. my sample
我需要窗体在启动时隐藏并在托盘显示图标,那个this.Hide不能去掉。 -
你的程序代码是没有错误的,刚才我在我这边测试过了,点击托盘上的图标是可以显示窗体的,你应该没有为NotifyIcon控件指定一个图片了。具体实现你也可以参考这个文章:
http://www.cnblogs.com/BrightMoon/archive/2013/02/23/2923338.html
If my post is helpful,please help to vote as helpful, if my post solve your question, please help to make it as answer. My sample
-
你的程序代码是没有错误的,刚才我在我这边测试过了,点击托盘上的图标是可以显示窗体的,你应该没有为NotifyIcon控件指定一个图片了。具体实现你也可以参考这个文章:
http://www.cnblogs.com/BrightMoon/archive/2013/02/23/2923338.html
If my post is helpful,please help to vote as helpful, if my post solve your question, please help to make it as answer. My sample
-
你这个代码我在博客园看到了,文章中已经明确指出 “只有窗口最小化的时候可以达到此效果,如果隐藏到托盘则无法将打开的程序显示到桌面”,所以你上面的代码根本无法达到你的目的的,要实现你说的需求你需要用到FindWindow 函数,具体实现代码如下:
static class Program { [DllImport("user32.dll")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll ", SetLastError = true)] static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab); [DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)] public static extern int ShowWindow(IntPtr hwnd, int nCmdShow); public const int SW_RESTORE=9; public static IntPtr formhwnd; static Form1 form = null; ///<summary> /// 应用程序的主入口点。 ///</summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); string proc = Process.GetCurrentProcess().ProcessName; Process[] processes = Process.GetProcessesByName(proc); if (processes.Length <= 1) { form = new Form1(); Application.Run(form); } else { for (int i = 0; i < processes.Length; i++) { if (processes[i].Id != Process.GetCurrentProcess().Id) { if (processes[i].MainWindowHandle.ToInt32() == 0) { formhwnd = FindWindow(null, "Form1"); ShowWindow(formhwnd,SW_RESTORE); SwitchToThisWindow(formhwnd, true); } else { SwitchToThisWindow(processes[i].MainWindowHandle, true); } } } } } }
Form1.cs中代码和你原来代码一样的,我在本地测试是完全可以的,你可以自己试试
If my post is helpful,please help to vote as helpful, if my post solve your question, please help to make it as answer. My sample
- 已建议为答案 Learning hard 2013年6月14日 7:25
- 已标记为答案 Jason Dot WangModerator 2013年6月18日 7:46