以下API都尝试过...都不行;将已经最小化的程序激活弹出其窗口
SetForegroundWindow
SwitchToThisWindow
ShowWindowAsync
ShowWindow以上几个API本人都试过...我的程序是最小化到托盘的
当本程序已经打开时,如果程序已经运行了一个实例,就激活它,让它变成正常窗口显示;
如果程序没有运行的实例,就生成一个新的实例;/// <summary>
/// 该函数设置由不同线程产生的窗口的显示状态。
/// </summary>
/// <param name="hWnd">窗口句柄</param>
/// <param name="cmdShow">指定窗口如何显示。查看允许值列表,请查阅ShowWlndow函数的说明部分。</param>
/// <returns>如果函数原来可见,返回值为非零;如果函数原来被隐藏,返回值为零。</returns>
[DllImport("User32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
/**/
/// <summary>
/// 恢复一个最小化的程序,并将其激活
/// </summary>
/// <param name="hWnd">窗口句柄</param>
/// <returns>非零表示成功,零表示失败</returns>
[System.Runtime.InteropServices.DllImport("User32.dll")]
private static extern bool OpenIcon(IntPtr hWnd); /**/
/// <summary>
/// 窗口是否已最小化
/// </summary>
/// <param name="hWnd">窗口句柄</param>
/// <returns>非零表示成功,零表示失败</returns>
[DllImport("User32.dll")]
private static extern bool IsIconic(IntPtr hWnd);
/// <summary>
/// 该函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号。系统给创建前台窗口的线程分配的权限稍高于其他线程。
/// </summary>
/// <param name="hWnd">将被激活并被调入前台的窗口句柄。</param>
/// <returns>如果窗口设入了前台,返回值为非零;如果窗口未被设入前台,返回值为零。</returns>
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("User32.dll")]
private static extern IntPtr FindWindow(string strclassName, string strWindowName); [DllImport("user32.dll", EntryPoint = "SwitchToThisWindow")]
private static extern void SwitchToThisWindow(IntPtr hWnd, Boolean fAltTab); private const int SW_HIDE = 0; //隐藏窗口,活动状态给令一个窗口
private const int SW_SHOWNORMAL = 1; //用原来的大小和位置显示一个窗口,同时令其进入活动状态
private const int SW_SHOWMINIMIZED = 2; //最小化窗口,并将其激活
private const int SW_SHOWMAXIMIZED = 3; //最大化窗口,并将其激活
private const int SW_SHOWNOACTIVATE = 4; //用最近的大小和位置显示一个窗口,同时不改变活动窗口
private const int SW_RESTORE = 9; //用原来的大小和位置显示一个窗口,同时令其进入活动状态
private const int SW_SHOWDEFAULT = 10; //根据默认 创建窗口时的样式 来显示 /// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Process instance = RunningInstance();
if (instance == null)
{
Application.Run(new frmMain());
}
else
{
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)
{
int nIndex; Process procCurrent = Process.GetCurrentProcess();
Process[] procProgram = Process.GetProcessesByName("PC Smart"); /* check if program is already running */
if (procProgram.Length > 1)
{
for (nIndex = 0; nIndex < procProgram.Length; nIndex++)
{
/* switch to the other instance and let this one die */
if (procProgram[nIndex].Id != procCurrent.Id)
SwitchToThisWindow(procProgram[nIndex].MainWindowHandle, true);
}
}
else
{
/* enable visual style, most commonly associated with the XP operating system */
Application.EnableVisualStyles();
Application.DoEvents();
Application.Run(new frmMain());
} //Process[] prs = Process.GetProcesses();
//Process thisone = Process.GetCurrentProcess();
//foreach (Process pr in prs)
//{
// if (thisone.ProcessName == pr.ProcessName && thisone.Id != pr.Id)
// {
// MessageBox.Show("程序已经运行", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
// SwitchToThisWindow(pr.MainWindowHandle, true);
// thisone.Kill();
// }
//}
//SwitchToThisWindow(instance.MainWindowHandle, true);
//ShowWindowAsync(instance.MainWindowHandle, SW_RESTORE); //显示,可以注释掉
//SetForegroundWindow(instance.MainWindowHandle); //放到前端
}测试过,当程序不是最小化时,再打开该程序时,会置前....但最小化以后,运行没有反应!!!
研究N久了...哪位大侠做过???
SetForegroundWindow
SwitchToThisWindow
ShowWindowAsync
ShowWindow以上几个API本人都试过...我的程序是最小化到托盘的
当本程序已经打开时,如果程序已经运行了一个实例,就激活它,让它变成正常窗口显示;
如果程序没有运行的实例,就生成一个新的实例;/// <summary>
/// 该函数设置由不同线程产生的窗口的显示状态。
/// </summary>
/// <param name="hWnd">窗口句柄</param>
/// <param name="cmdShow">指定窗口如何显示。查看允许值列表,请查阅ShowWlndow函数的说明部分。</param>
/// <returns>如果函数原来可见,返回值为非零;如果函数原来被隐藏,返回值为零。</returns>
[DllImport("User32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
/**/
/// <summary>
/// 恢复一个最小化的程序,并将其激活
/// </summary>
/// <param name="hWnd">窗口句柄</param>
/// <returns>非零表示成功,零表示失败</returns>
[System.Runtime.InteropServices.DllImport("User32.dll")]
private static extern bool OpenIcon(IntPtr hWnd); /**/
/// <summary>
/// 窗口是否已最小化
/// </summary>
/// <param name="hWnd">窗口句柄</param>
/// <returns>非零表示成功,零表示失败</returns>
[DllImport("User32.dll")]
private static extern bool IsIconic(IntPtr hWnd);
/// <summary>
/// 该函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号。系统给创建前台窗口的线程分配的权限稍高于其他线程。
/// </summary>
/// <param name="hWnd">将被激活并被调入前台的窗口句柄。</param>
/// <returns>如果窗口设入了前台,返回值为非零;如果窗口未被设入前台,返回值为零。</returns>
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("User32.dll")]
private static extern IntPtr FindWindow(string strclassName, string strWindowName); [DllImport("user32.dll", EntryPoint = "SwitchToThisWindow")]
private static extern void SwitchToThisWindow(IntPtr hWnd, Boolean fAltTab); private const int SW_HIDE = 0; //隐藏窗口,活动状态给令一个窗口
private const int SW_SHOWNORMAL = 1; //用原来的大小和位置显示一个窗口,同时令其进入活动状态
private const int SW_SHOWMINIMIZED = 2; //最小化窗口,并将其激活
private const int SW_SHOWMAXIMIZED = 3; //最大化窗口,并将其激活
private const int SW_SHOWNOACTIVATE = 4; //用最近的大小和位置显示一个窗口,同时不改变活动窗口
private const int SW_RESTORE = 9; //用原来的大小和位置显示一个窗口,同时令其进入活动状态
private const int SW_SHOWDEFAULT = 10; //根据默认 创建窗口时的样式 来显示 /// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Process instance = RunningInstance();
if (instance == null)
{
Application.Run(new frmMain());
}
else
{
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)
{
int nIndex; Process procCurrent = Process.GetCurrentProcess();
Process[] procProgram = Process.GetProcessesByName("PC Smart"); /* check if program is already running */
if (procProgram.Length > 1)
{
for (nIndex = 0; nIndex < procProgram.Length; nIndex++)
{
/* switch to the other instance and let this one die */
if (procProgram[nIndex].Id != procCurrent.Id)
SwitchToThisWindow(procProgram[nIndex].MainWindowHandle, true);
}
}
else
{
/* enable visual style, most commonly associated with the XP operating system */
Application.EnableVisualStyles();
Application.DoEvents();
Application.Run(new frmMain());
} //Process[] prs = Process.GetProcesses();
//Process thisone = Process.GetCurrentProcess();
//foreach (Process pr in prs)
//{
// if (thisone.ProcessName == pr.ProcessName && thisone.Id != pr.Id)
// {
// MessageBox.Show("程序已经运行", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
// SwitchToThisWindow(pr.MainWindowHandle, true);
// thisone.Kill();
// }
//}
//SwitchToThisWindow(instance.MainWindowHandle, true);
//ShowWindowAsync(instance.MainWindowHandle, SW_RESTORE); //显示,可以注释掉
//SetForegroundWindow(instance.MainWindowHandle); //放到前端
}测试过,当程序不是最小化时,再打开该程序时,会置前....但最小化以后,运行没有反应!!!
研究N久了...哪位大侠做过???
所以此时 instance.MainWindowHandle = 0
这还搞个毛啊~ 所以,乖乖 FindWindow 吧
private const int SW_HIDE = 0;
private const int SW_RESTORE = 9;
private const int SW_SHOWNA = 8;private const int GWL_EXSTYLE = -20;
private const int WS_EX_APPWINDOW = 0x40000;[DllImport("user32.dll", EntryPoint = "GetClassNameA")]
private static extern bool GetClassName(IntPtr hwnd, StringBuilder lpClassName, int nMaxCount);[DllImport("user32.dll", EntryPoint = "GetWindowLongA")]
private static extern int GetWindowLong(IntPtr hwnd, int nIndex);[DllImport("user32.dll", EntryPoint = "FindWindowA")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);[DllImport("user32.dll", EntryPoint = "SetForegroundWindow")]
public static extern bool SetForegroundWindow(IntPtr hWnd);[DllImport("user32.dll", EntryPoint = "SetWindowLongA")]
private static extern int SetWindowLong(IntPtr hwnd, int nIndex, int dwNewLong);[DllImport("user32.dll", EntryPoint = "ShowWindowAsync")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);//===========================
StringBuilder sb = new StringBuilder(255);if (GetClassName(this.Handle, sb, sb.Capacity))
{
// 区别窗口标题
this.Text = Guid.NewGuid().ToString(); // "Form1" 窗口标题要改下
IntPtr hwnd = FindWindow(sb.ToString(), "Form1"); if (this.Handle == hwnd) return; int wlong = GetWindowLong(hwnd, GWL_EXSTYLE); // 依据 ShowInTaskBar 判断是否需要隐藏窗口
if ((wlong & WS_EX_APPWINDOW) == 0)
{
ShowWindowAsync(hwnd, SW_HIDE);
wlong |= WS_EX_APPWINDOW;
SetWindowLong(hwnd, GWL_EXSTYLE, wlong);
}
ShowWindowAsync(hwnd, SW_SHOWNA | SW_RESTORE);
SetForegroundWindow(hwnd);
}// 如果要设置多个窗口可以用
// GetNextWindow + GetDesktopWindow + GetClassName + 判断 hwnd != this.Handle
using System.Collections.Generic;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
using System.Security.Permissions;
namespace WindowsApplication7
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
bool bResult;
System.Threading.Mutex mutex = new System.Threading.Mutex(true, "425D04", out bResult);
if (!bResult)
{
IntPtr hHandle = OpenFileMapping(FILE_MAP_READ, 0, "05A79C");
IntPtr lpAddress = MapViewOfFile(hHandle, FILE_MAP_READ, 0, 0, 0);
IntPtr hWnd = new IntPtr(Marshal.ReadInt32(lpAddress));
ShowWindow(hWnd, SW_SHOWNORMAL);
SetForegroundWindow(hWnd);
}
else
{ Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 frm = new Form1(); SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
sa.nLength = 12;
sa.lpSecurityDescriptor = 0;
sa.bInheritHandle = 1; IntPtr hHandle = CreateFileMapping(-1, ref sa, PAGE_READWRITE, 0, 4, "05A79C");
IntPtr lpAddress = MapViewOfFile(hHandle, FILE_MAP_WRITE, 0, 0, 0);
Marshal.WriteInt32(lpAddress, frm.Handle.ToInt32());
Application.Run(frm);
CloseHandle(hHandle);
}
}
[DllImport("Kernel32.dll", EntryPoint = "CreateFileMapping")]
private extern static IntPtr CreateFileMapping(Int32 hFile,
ref SECURITY_ATTRIBUTES lpFileMappingAttributes,
Int32 flProtect, Int32 dwMaximumSizeHigh,
Int32 dwMaximumSizeLow,
string lpName);
[DllImport("Kernel32.dll", EntryPoint = "OpenFileMapping")]
private extern static IntPtr OpenFileMapping(Int32 dwDesiredAccess, Int32 bInheritHandle, string lpName); [DllImport("Kernel32.dll")]
private extern static IntPtr MapViewOfFile(IntPtr hFileMappingObject, Int32 dwDesiredAccess,
Int32 dwFileOffsetHigh,
Int32 dwFileOffsetLow,
Int32 dwNumberOfBytesToMap);
[DllImport("kernel32.dll")]
private extern static bool CloseHandle(IntPtr hHandle);
[DllImport("User32.dll")]
private extern static bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);
[DllImport("user32.dll")]
public static extern int SetForegroundWindow(IntPtr hwnd);
private const Int32 PAGE_READWRITE = 0x04;
private const Int32 FILE_MAP_WRITE = 0x02;
private const Int32 FILE_MAP_READ = 0x04;
private const Int32 SW_SHOWNORMAL = 0x01; }
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{
public Int32 nLength;
public Int32 lpSecurityDescriptor;
public Int32 bInheritHandle;
}
}
但最小化到托盘以后,就没办法再激活显示了!!!求原码~~~本人写不好!
大侠请发邮箱 :[email protected]