激活任意 Windows 窗口

11 篇文章 1 订阅

有时候我们调用 SetForegroundWindow 想将某个窗口带到前台并且激活时,该窗口只是在任务栏上闪动(FlashWindow),并未能带到前台来。
研究了一下,发现是否能够成功,和 SetForegroundWindow 所在线程所附加的输入上下文有关(可以调用 AttachThreadInput 修改)。

目前以下 3 种方法均可以将任意窗口带到前台来。

  1. SwitchToThisWindow API
    第二个参数含义:TRUE:如果窗口被极小化了,则恢复
    微软说该函数将被废弃,见:This function is not intended for general use. It may be altered or unavailable in subsequent versions of Windows。
    但是根据经验可知,微软说废弃的,不知道到猴年马月才会真的从系统 API 中去除。
    该方法使用最简单。

  2. SetForegroundWindow & AttachThreadInput API

  3. BringWindowToTop & AttachThreadInput API

注意
被 AttachThreadInput 的进程,如果是具有管理员权限的进程,则调用 AttachThreadInput 的进程也必须要有管理员权限,否则会失败,GetLastError 返回 5(拒绝访问)。

具体代码(包含以上 3 种方法):

#include <iostream>
#include <windows.h>

// SwitchToThisWindow 方法
void ActiveAnyWindow_SwitchToThisWindow(HWND hWnd)
{
    // 第二个参数需要传 TRUE:这样的话,如果窗口被极小化了,可以恢复。
    SwitchToThisWindow(hWnd, TRUE);
}

// SetForegroundWindow 方法
void ActiveAnyWindow_SetForegroundWindow(HWND hWnd)
{
    const HWND hForeWnd = ::GetForegroundWindow();
    ::AttachThreadInput(::GetWindowThreadProcessId(hForeWnd, nullptr), ::GetCurrentThreadId(), TRUE);
    if (!::SetForegroundWindow(hWnd))
    {
        std::cout << "SetForegroundWindow GLE=%d", ::GetLastError();
    }
    else
    {
        std::cout << "SetForegroundWindow OK";
    }
    AttachThreadInput(::GetWindowThreadProcessId(hForeWnd, nullptr), ::GetCurrentThreadId(), FALSE);
}

// BringWindowToTop 方法
void ActiveAnyWindow_BringWindowToTop(HWND hWnd)
{
    const HWND hForeWnd = ::GetForegroundWindow();
    ::AttachThreadInput(::GetWindowThreadProcessId(hForeWnd, nullptr), ::GetCurrentThreadId(), TRUE);
    if (!::BringWindowToTop(hWnd))
    {
        std::cout << "BringWindowToTop GLE=%d", ::GetLastError();
    }
    else
    {
        std::cout << "BringWindowToTop OK";
    }
    AttachThreadInput(::GetWindowThreadProcessId(hForeWnd, nullptr), ::GetCurrentThreadId(), FALSE);
}

int main()
{
    // 测试前,先要手动打开系统记事本

    ::Sleep(3000);
    ActiveAnyWindow_BringWindowToTop(::FindWindow(L"Notepad", nullptr));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值