C#操作窗口句柄

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




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值