您的位置:首页 > 移动开发 > Objective-C

Winform 单例模式 如果有相同的程序在运行 notifyIcon气泡提示 “程序正在运行,我在这儿”

2012-01-18 10:01 513 查看
如题 Winform 单例模式 

如果用相同的程序在运行 notifyIcon系统托盘图标 气泡提示 “程序正在运行,我在这儿”

重点是 如何实现 : 当检测到有程序运行时 如何获取该窗口 并调用notifyIcon的气泡提示

用 windows API实现 或用 反射 只要能实现就行。。。

昵称: surfshark5  时间: 2010-06-20 20:50:01

其实不需要直接调用API,也不需要反射:)
C# code

// Program.cs
//
using System;
using System.Threading;
using System.Windows.Forms;

static class Program
{
public static EventWaitHandle ProgramStarted;

[STAThread]
static void Main()
{
// 尝试创建一个命名事件
bool createNew;
ProgramStarted = new EventWaitHandle(false, EventResetMode.AutoReset, "MyStartEvent", out createNew);

// 如果该命名事件已经存在(存在有前一个运行实例),则发事件通知并退出
if (!createNew)
{
ProgramStarted.Set();
return;
}

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

C# code

// Form1.cs
//
using System;
using System.Windows.Forms;
using System.Threading;

public partial class Form1 : Form
{
NotifyIcon notifyIcon1 = new NotifyIcon();

public Form1()
{
//InitializeComponent();
this.notifyIcon1.Text = "Double click me to show window";
this.notifyIcon1.Icon = System.Drawing.SystemIcons.Information;
this.notifyIcon1.DoubleClick += OnNotifyIconDoubleClicked;
this.SizeChanged += OnSizeChanged;
ThreadPool.RegisterWaitForSingleObject(Program.ProgramStarted, OnProgramStarted, null, -1, false);
}

// 当最小化时,放到系统托盘。
void OnSizeChanged(object sender, EventArgs e)
{
if (this.WindowState == FormWindowState.Minimized)
{
this.notifyIcon1.Visible = true;
this.Visible = false;
}
}

// 当双击托盘图标时,恢复窗口显示
void OnNotifyIconDoubleClicked(object sender, EventArgs e)
{
this.Visible = true;
this.notifyIcon1.Visible = false;
this.WindowState = FormWindowState.Normal;
}

// 当收到第二个进程的通知时,显示气球消息
void OnProgramStarted(object state, bool timeout)
{
this.notifyIcon1.ShowBalloonTip(2000, "Hello", "I am here...", ToolTipIcon.Info);
}
}

讨论见原帖(如何操作我的程序的另一个实例(进程)):
http://topic.csdn.net/u/20081221/01/457bb3b1-2f19-47e2-9621-cf4117ee45ce.html 昵称: gomoku  时间: 2010-06-21 06:22:23

引用 1 楼 gomoku 的回复:

其实不需要直接调用API,也不需要反射:)

C# code

// Program.cs

//

using System;

using System.Threading;

using System.Windows.Forms;

static class Program

{

public static EventWaitHandle ProgramStarted;……


昵称: xiaoqiu1234  时间: 2010-06-21 07:59:41

直接使用VB.NET的部分API也可以实现,
http://www.hanselman.com/blog/TheWeeklySourceCode31SingleInstanceWinFormsAndMicrosoftVisualBasicdll.aspx
昵称: lextm  时间: 2010-06-21 14:16:01

非常感谢 gomoku 写的很好 问题解决了

但其中涉及到 命名事件 和 多线程的 一些类 以前没有接触过 好像不太好懂

查了些资料 都很生涩

能不能简单的用比较通俗的语言讲一下 这个程序中用到的 方法 尤其是各参数的意思

算是为了解更多入个门吧 多谢了
C# code

ThreadPool.RegisterWaitForSingleObject(Program.ProgramStarted, OnProgramStarted, null, -1, false);

C# code

// 尝试创建一个命名事件
bool createNew;
ProgramStarted = new EventWaitHandle(false, EventResetMode.AutoReset, "MyStartEvent", out createNew);

// 如果该命名事件已经存在(存在有前一个运行实例),则发事件通知并退出
if (!createNew)
{
ProgramStarted.Set();
return;
}

昵称: surfshark5  时间: 2010-06-21 16:58:17

引用 1 楼 gomoku 的回复:

其实不需要直接调用API,也不需要反射:)

C# code

// Program.cs

//

using System;

using System.Threading;

using System.Windows.Forms;

static class Program

{

public static EventWaitHandle ProgramStarted;

[STA……

e。。。nb 我的思路还是便利所有的线程 然后通过ProcessName判断呢。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐