让程序只运行一个实例的方法总结

本文介绍了三种确保应用程序仅运行一个实例的技术:使用FindWindow查找主窗口、利用Mutex互斥体和通过SetProp设置特殊属性。每种方法都有其优缺点,并详细展示了相关代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自:http://blog.joycode.com/sam1111/articles/2922.aspx

让程序 只运行一个实例的方法有数种,但原理都是相同的,就是在程序的主窗口创建之前,检查系统中是否已经存在某个与本程序相关的特定标志了。如果存在,则说明已经有一个实例在运行了,当前程序不用创建主窗口,直接退出即可。否则,就说明本程序是第一次运行。各种方法所不同的是,各自检查的标志不同,这也使得各种方法在使用时各有利弊了。

一般来说,使程序 只运行一个实例的最简单的方法当然是使用FindWindow()查找主窗口,如果主窗口已经存在了,当然说明已经有一个实例运行了。代码如下:


  1. // 主窗口创建前
  2. HWND hWnd = FindWindow("ClassName""Caption");
  3. if(IsWindow(hWnd))
  4. {
  5.        ShowWindow(hWnd, SW_NORMAL);     // 显示
  6.        SetForegroundWindow(hWnd);                  // 激活
  7.        return;
  8. }
这个方法的不足之处是,FindWindow()的参数ClassName和Caption比较难取得。比如,凡是使用DialogBoxParam()创建的对话框,他们的ClassName都是“#32770”,没有唯一性;而使用MFC创建的Doc/View结构的窗口的Caption更是会随Doc?Name的不同而有所变化。

另一种方法就是使用Mutex互斥体了。代码如下:


  1. // 声明全局的局柄
  2. HANDLE g_hHandle;
  3. // 主窗口创建前
  4. g_hHandle = CreateMutex(NULL, FALSE, "Mutex Name");
  5. if(GetLastError() == ERROR_ALREADY_EXISTS)
  6. {
  7.       return FALSE;
  8. }
使用Mutex代码比较简洁,但是此时不能取得已经启动的实例窗口局柄,因此无法激活已经启动的实例窗口。

第三种方法是我认为比较完善的方法,就是通过SetProp()为程序主窗口设置一个特殊的Property,然后在启动时遍历所有的窗口,找出包含着个Property的窗口局柄。这个方法的缺点就是代码比较多。如下:


  1. // 声明全局的property名和property value
  2. LPCTSTR g_szPropName = "prop name";
  3. HANDLE g_hValue = (HANDLE)1;
  4. // 定义枚举窗口回调函数
  5. BOOL CALLBACK EnumWndProc(HWND hwnd, LPARAM lParam)
  6. {
  7.     HANDLE h = GetProp(hwnd, g_szPropName);
  8.     if( h == g_hValue)
  9.     {
  10.         *(HWND*)lParam = hwnd;
  11.         return false;
  12.     }
  13.     return true;
  14. }
  15. // 主窗口创建前判断
  16. HWND hWnd = NULL;
  17. EnumWindows(EnumWndProc, (LPARAM)&hWnd);
  18. if(IsWindow(hWnd))
  19. {
  20.       ShowWindow(hWnd, SW_NORMAL);
  21.       SetForegroundWindow(hWnd);
  22.       return FALSE;
  23. }
  24. // 主窗口创建后设置
  25. SetProp(m_hWnd, g_szPropName, g_hValue);
这个方法就是需要遍历系统中所有的窗口,效率可能稍低了些。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值