程序已打开,并且在托盘中,重新点击程序时,不用重新运行,仅最大化托盘中的程序!就象金山词霸一样!

xietangz 2008-11-02 11:58:05
我想实现这样一个过程,当一个程序已经有一个实例在运行时,双击图标不会又运行一个新实例,而是将已运行的实例Show给用户看,但是现在的问题是我已经有的实例是被最小化,切隐藏的,怎样才能使这个隐藏了的程序通过API调用Show出来呢,请高手指点。代码如下:
static void Main()
{

//得到正在运行的例程
Process instance = RunningInstance();
if (instance == null)
{
//如果没有其它例程,就新建一个窗体
Application.Run(new Form1());
}
else
{
//处理发现的例程
HandleRunningInstance(instance);
}

}

/// <summary>
/// 得到正在运行的例程
/// </summary>
/// <returns></returns>
public static Process RunningInstance()
{
Process current = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName (current.ProcessName);

//遍历正在有相同名字运行的例程
foreach (Process process in processes)
{
//忽略现有的例程
if (process.Id != current.Id)
{
//确保例程从EXE文件运行
if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") ==
current.MainModule.FileName)
{
//返回另一个例程实例
return process;
}
}
}

//没有其它的例程,返回Null
return null;
}
/// <summary>
/// 处理发现的例程
/// </summary>
/// <param name="instance"></param>
public static void HandleRunningInstance(Process instance)
{
//确保窗口没有被最小化或最大化
ShowWindowAsync (instance.MainWindowHandle , WS_SHOWNORMAL);
/*********************************************************************
* 问题就在这里,如果窗口没有被隐藏,上面那句话会起作用;如果隐藏了,就不起
* 作用,虽然不会新起一个实例,但是已有的实例不会Show出来,真是烦人
********************************************************************/

//设置真实例程为foreground window
SetForegroundWindow (instance.MainWindowHandle);
}

[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;
...全文
181 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
yistudio 2008-11-02
  • 打赏
  • 举报
回复
就是让程序只有一个实例在运行吧,看看孟老大怎么解决的
http://dotnet.aspx.cc/article/e2a17727-765f-4346-8446-5d130622cb54/read.aspx
kent4j 2008-11-02
  • 打赏
  • 举报
回复
他的意思是双击图标 不启动新的程序 那个图标是桌面的图标
  • 打赏
  • 举报
回复
为什么需要去调用api?托盘也是有个主程序的,主程序里只要有你要打开隐藏的窗口的句柄,就可以show和hidden了啊,
xietangz 2008-11-02
  • 打赏
  • 举报
回复
/*********************************************************************
* 问题就在这里,如果窗口没有被隐藏,上面那句话会起作用;如果隐藏了,就不起
* 作用,虽然不会新起一个实例,但是已有的实例不会Show出来,真是烦人
********************************************************************/
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 xietangz 的回复:]

to:tmxk2002


1、我现在的问题是当程序最小化到托盘后,再点击程序时,不用运行新的程序,把最小化到托盘中的程序最大化就可以了,现在是最小化在托盘中的程序无法最大化!
2、所以与你回答的是会事
[/Quote]
我记得几年前开发过这个的,用的是notifyIcon,重新写窗口的Close事件,就是当别人点击关闭的时候,是隐藏自己而不是关闭。双击托盘或者选择托盘的菜单是就显示出来。不知道你是否是要实现这个功能。
gomoku 2008-11-02
  • 打赏
  • 举报
回复
你程序的问题在于,当窗口隐藏时,Process.MainWindowHandle返回的是0。
你可以尝试着用FindWindow() API利用窗口标题来查找窗口句柄,或用命名事件来通知前一进程显示自己。


[DllImport("User32.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
mjjzg 2008-11-02
  • 打赏
  • 举报
回复
我觉得不需要调用API函数吧,只要你各个页面做好处理用notifyIcon1控件就可搞定的,
简单的给你写了一下

private void Form1_SizeChanged(object sender, System.EventArgs e)
{//当窗体的大小改变时
if(WindowState==FormWindowState.Minimized)
{
this.Visible=false;
this.notifyIcon1.Visible=true;
this.Hide();
}
}
private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
{//使用托盘还原窗体
this.Visible=true;
this.WindowState=FormWindowState.Normal;
this.notifyIcon1.Visible=false;
}

简单了写了一下,也不知道是否符合
hyblusea 2008-11-02
  • 打赏
  • 举报
回复
仅运行一个实例


void FirstInstance()
{
HWND pFirstWindow;
if ( pFirstWindow = FindWindow( NULL, L"窗体的名称" ) )
{
if( IsIconic(pFirstWindow) )
ShowWindowAsync(pFirstWindow, 9); // 9:SW_RESTORE标志,表示还原窗体
SetForegroundWindow(pFirstWindow);
PostMessage( pFirstWindow, WM_SHOWWINDOW, true, 0 );
exit(0);
}
else
{
//
}
}
xietangz 2008-11-02
  • 打赏
  • 举报
回复

to:tmxk2002


1、我现在的问题是当程序最小化到托盘后,再点击程序时,不用运行新的程序,把最小化到托盘中的程序最大化就可以了,现在是最小化在托盘中的程序无法最大化!
2、所以与你回答的是会事


xietangz 2008-11-02
  • 打赏
  • 举报
回复


TO:yistudio
你没看我贴子中的内容吗?

就是执行下面代码:
public static void HandleRunningInstance(Process instance)
{
//确保窗口没有被最小化或最大化
ShowWindowAsync (instance.MainWindowHandle , WS_SHOWNORMAL);
/*********************************************************************
* 问题就在这里,如果窗口没有被隐藏,上面那句话会起作用;如果隐藏了,就不起
* 作用,虽然不会新起一个实例,但是已有的实例不会Show出来,真是烦人
********************************************************************/

//设置真实例程为foreground window
SetForegroundWindow (instance.MainWindowHandle);
}

最小化在托盘中的程序没有最大化或显示?


110,567

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧