1.获取当前活动窗口句柄,获取窗口大小及位置
//需在开头引入命名空间
using System.Runtime.InteropServices;
//1.获取当前窗口句柄:GetForegroundWindow()
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr GetForegroundWindow(); //返回值类型是IntPtr,即为当前获得焦点窗口的句柄
使用方法 :
IntPtr myPtr=GetForegroundWindow();
获取到该窗口句柄后,可以对该窗口进行操作.比如,关闭该窗口或在该窗口隐藏后,使其显示
//2.显示窗口
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
其中hwnd为窗口的句柄;nCmdShow指示窗口的显示样式:0关闭窗口,1正常大小显示窗口,2最小化窗口,3 最大化窗口
使用实例:
ShowWindow(myPtr, 0);
//3.获取窗口大小及位置
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left; //最左坐标
public int Top; //最上坐标
public int Right; //最右坐标
public int Bottom; //最下坐标
}
示例:
InPtr awin = GetForegroundWindow(); //获取当前窗口句柄
RECT rect = new RECT();
GetWindowRect(awin, ref rect);
int width = rc.Right - rc.Left; //窗口的宽度
int height = rc.Bottom - rc.Top; //窗口的高度
int x = rc.Left;
int y = rc.Top;
2.C#只允许运行应用程序的一个实例的正确实现方法
static void Main()
{
bool createNew;
try
{
using (System.Threading.Mutex m = new System.Threading.Mutex(true, "Global\\" + Application.ProductName, out createNew))
{
if (createNew)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
else
{
MessageBox.Show("Only one instance of this application is allowed!");
}
}
}
catch
{
MessageBox.Show("Only one instance of this application is allowed!");
}
}
该方法可以保证多用户下的单实例运行,即使把应用程序改名也有效。如果需要在终端机服务器上使用,并且只允许一个实例的话,推荐这种写法。
3.C# 实现程序只启动一次(多次运行激活并显示第一个实例)
using System.Runtime.InteropServices;
//using System.Diagnostics;
using System.Reflection;
static void Main()
{
Process instance = RunningInstance(); //获取正在运行的实例
if (instance != null) //设置程序只能启动一次
{
HandleRunningInstance(instance);
return;
}
else
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
#region 设置程序只能启动一次(多次运行激活第一个实例,使其获得焦点,并在最前端显示)
///
/// 获取正在运行的实例,没有运行的实例返回null;
///
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;
}
///
/// 显示已运行的程序。
///
public static void HandleRunningInstance(Process instance)
{
ShowWindowAsync(instance.MainWindowHandle, 3); //显示窗口。0关闭窗口,1正常大小显示窗口,2最小化窗口,3最大化窗口
SetForegroundWindow(instance.MainWindowHandle); //放到前端
}
///
/// 该函数设置由不同线程产生的窗口的显示状态。
///
/// 窗口句柄
/// 指定窗口如何显示。0关闭窗口,1正常大小显示窗口,2最小化窗口,3最大化窗口。
///
如果函数原来可见,返回值为非零;如果函数原来被隐藏,返回值为零。
[DllImport("User32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
///
/// 该函数将创建指定窗口的线程设置到前台,并且激活该窗口。系统给创建前台窗口的线程分配的权限稍高于其他线程。
///
/// 将被激活并被调入前台的窗口句柄。
///
如果窗口设入了前台,返回值为非零;如果窗口未被设入前台,返回值为零。
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
#endregion