撤消/重置AllowSetForegroundWindow()调用

时间:2012-04-04 14:50:35

标签: c++ winapi

有没有办法撤消对AllowSetForegroundWindow(ASFW_ANY)的调用?

大图:

  • 我想要一次运行一个exe进程。
  • 为实现这一目标,这些流程使用命名管道和流程相互通信。如果一个过程已经存在,它的窗口必须被带到前面。
  • 为了能够执行此操作,最新流程必须使用现有流程ID设置AllowSetForegroundWindow()
    • 我不想获取进程ID(抱歉我的懒惰),所以我打算做的是:1。使用ASFW_ANY调用AllowSetForegroundWindow() 2.以防万一发生错误,撤消致电AllowSetForegroundWindow(),以便其他人无法从我的流程中窃取重点。

简单来说,我想允许其他进程从我这里偷走焦点,只在特定的时间窗口...

之前有人遇到过类似的问题,并找到了解决方法吗?

此外,如果您有任何更好的建议/替代方案,请告诉我......

2 个答案:

答案 0 :(得分:2)

According to the documentation,目标流程(可能包括“任意”)将在您下次致电AllowSetForegroundWindow时失去从您那里窃取焦点的能力。

换句话说,听起来你一次只能激活一个这样的权限。

以下是您应该能够通过调用一些不存在的ID或者您自己的进程ID来取消权限。这是理论,但我还没有测试过。

我个人只是在命名管道上发送目标进程ID。

答案 1 :(得分:0)

如果我了解您的主要要求是一次只运行一个应用程序实例。如果您描述的其他内容仅仅服从于此要求,而不是某些更宏大的方案的一部分,那么有一种更简单的方法可以实现这一点。

您可以在应用程序启动时创建全局命名的互斥锁。所有其他实例都会将此互斥锁视为已设置,并立即退出。这是它的快速和肮脏:

// Multiple instances detection
HANDLE my_mutex = ::CreateMutex(NULL, FALSE, "Global\\MyCuteFluffyMutex" );

int create_mutex_error = ::GetLastError();
bool already_running =
          ( my_mutex && ( create_mutex_error == ERROR_ALREADY_EXISTS ))
       || ( create_mutex_error == ERROR_ACCESS_DENIED );

if ( !already_running ) {
  // Run my application
}

::CloseHandle(my_mutex);

有关CreateMutex及其参数的更详尽信息,请参阅documentation