Windows 将应用程序置于前台

Windows 将应用程序置于前台,windows,c++11,process,foreground,Windows,C++11,Process,Foreground,我必须用它的名字把一个窗口放在前台,例如“图像”。 与 我获得了流程的句柄(HWND)。 然后 SetForegroundWindow(windowHandle); 我想我会自动把它放在前台,但我必须按回车键。我做错了什么事还是有别的办法?我还可以使用进程的PID。 我的最终目的是在将进程放到前台后,向进程发送快捷键,如CTRL+V。谢谢。来自MSDN 系统限制哪些进程可以设置前台窗口。仅当以下条件之一为真时,进程才能设置前景窗口: 这个过程就是前景过程 该进程由前台进程启动 进程接收到最

我必须用它的名字把一个窗口放在前台,例如“图像”。 与

我获得了流程的句柄(
HWND
)。 然后

SetForegroundWindow(windowHandle);
我想我会自动把它放在前台,但我必须按回车键。我做错了什么事还是有别的办法?我还可以使用进程的PID。
我的最终目的是在将进程放到前台后,向进程发送快捷键,如CTRL+V。谢谢。

来自MSDN

系统限制哪些进程可以设置前台窗口。仅当以下条件之一为真时,进程才能设置前景窗口:

  • 这个过程就是前景过程
  • 该进程由前台进程启动
  • 进程接收到最后一个输入事件
  • 没有前台进程
  • 进程正在调试中
  • 前台进程不是现代应用程序或开始屏幕
  • 前景未锁定(请参见LockSetForegroundWindow)
  • 前台锁定超时已过期(请参阅SystemParametersInfo中的SPI_GETFOREGROUNDLOCKTIMEOUT)
  • 没有激活的菜单
因此,如果您的程序不符合上述要求,则无法自动设置前景

我认为您可以使用下面的代码来处理您的案例,这也会有所帮助

void SetForegroundWindowForce(HWND hWnd)
{
   HWND hWndForeground = ::GetForegroundWindow();
   if(hWndForeground == hWnd) return;

   DWORD Strange = ::GetWindowThreadProcessId(hWndForeground, NULL);
   DWORD My = ::GetWindowThreadProcessId(hWnd, NULL);
   if( !::AttachThreadInput(My, Strange, TRUE) )
   {
      ASSERT(0);
   }
   ::SetForegroundWindow(hWnd);
   ::BringWindowToTop(hWnd);
   if( !::AttachThreadInput(My, Strange, FALSE) )
   {
      ASSERT(0);
   }
}
来自MSDN

系统限制哪些进程可以设置前台窗口。仅当以下条件之一为真时,进程才能设置前景窗口:

  • 这个过程就是前景过程
  • 该进程由前台进程启动
  • 进程接收到最后一个输入事件
  • 没有前台进程
  • 进程正在调试中
  • 前台进程不是现代应用程序或开始屏幕
  • 前景未锁定(请参见LockSetForegroundWindow)
  • 前台锁定超时已过期(请参阅SystemParametersInfo中的SPI_GETFOREGROUNDLOCKTIMEOUT)
  • 没有激活的菜单
因此,如果您的程序不符合上述要求,则无法自动设置前景

我认为您可以使用下面的代码来处理您的案例,这也会有所帮助

void SetForegroundWindowForce(HWND hWnd)
{
   HWND hWndForeground = ::GetForegroundWindow();
   if(hWndForeground == hWnd) return;

   DWORD Strange = ::GetWindowThreadProcessId(hWndForeground, NULL);
   DWORD My = ::GetWindowThreadProcessId(hWnd, NULL);
   if( !::AttachThreadInput(My, Strange, TRUE) )
   {
      ASSERT(0);
   }
   ::SetForegroundWindow(hWnd);
   ::BringWindowToTop(hWnd);
   if( !::AttachThreadInput(My, Strange, FALSE) )
   {
      ASSERT(0);
   }
}

非常感谢。我没有试过,但看着MSDN,我想我明白了。我的解释是:首先保持前景窗口和相应窗口的句柄;然后,使用AttachThreadInput(),进程共享输入缓冲区(对此不太确定…),然后将另一个窗口设置在顶部,并“拆分”两个进程<我不太确定,如果有什么地方完全错了,请告诉我,谢谢!!你几乎是对的。通过使用
AttachThreadInput
,两个不同的线程可以共享它们的输入状态,如键盘、鼠标等。您的窗口句柄可以获得正确的条件,即调用
AttachThreadInput
函数并为第二个参数指定TRUE。Ok。我使用窗口句柄运行该方法。AttachThreadInput返回一个大于0的值,因此它执行if中的操作(我不知道assert如何仅与参数一起工作…)。如果我想向第二个窗口发送一组键怎么办?即使不改变焦点,谢谢。我没有试过,但看着MSDN,我想我明白了。我的解释是:首先保持前景窗口和相应窗口的句柄;然后,使用AttachThreadInput(),进程共享输入缓冲区(对此不太确定…),然后将另一个窗口设置在顶部,并“拆分”两个进程<我不太确定,如果有什么地方完全错了,请告诉我,谢谢!!你几乎是对的。通过使用
AttachThreadInput
,两个不同的线程可以共享它们的输入状态,如键盘、鼠标等。您的窗口句柄可以获得正确的条件,即调用
AttachThreadInput
函数并为第二个参数指定TRUE。Ok。我使用窗口句柄运行该方法。AttachThreadInput返回一个大于0的值,因此它执行if中的操作(我不知道assert如何仅与参数一起工作…)。如果我想向第二个窗口发送一组键怎么办?即使不改变焦点。