繁体   English   中英

如何使用 winapi 专注于特定的 window?

[英]How do you focus on a specific window using winapi?

我的目标是制作与此类似的 function 但使用 HWND window object 作为参数。

我的目标解释:

假设我们有 2(两个)应用程序 windows。 Chrome 和 Spotify(只是一个例子)。
目前,我选择了 Chrome window。

I want to focus on the Spotify window with a function that uses the Windows API to focus/select the Spotify Window.

function 有 1 个参数接受 HWND window object。 然后,function重点介绍window。

保持聚焦 window 的初始大小也很好。

我不知道的是 Windows API 要求专注于某些 windows。

我尝试过的事情:

ShowWindow(hwnd, SW_RESTORE);
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
SetActiveWindow(hwnd);
SetForegroundWindow(hwnd)
SetFocus(hwnd);
SendMessage(hwnd, WM_SETFOCUS, 0, 0);
PostMessage(hwnd, WM_SETFOCUS, 0, 0);

可能有点先进,但......基本上为了测试你的问题,我注入了一个创建的 DLL(为简单起见)并将其注入记事本。

首先,您要创建一个控制台 window。 这样我们就有了第二个 window 作为目标,我们还在此过程中创建了一个 window 句柄,以便我们稍后在尝试设置 window 焦点时可以使用它。

接下来获取您的进程 ID 以及进程句柄。 从那里您可以循环访问您电脑上所有活动的 windows 并将 WindowID 与您获得的进程 ID 进行比较。 然后我们将匹配进程 ID 的 windows 与输入的标题参数进行比较,当我们找到匹配项时,我们可以返回 window 句柄。

从这里我们只需创建一个循环并监听按键以针对 window。 您首先要在前台设置目标 window,然后要激活它。 你不能激活 window 除非它在前台。

这是一个完整的示例,其中包含在您可能正在从事的任何可能的项目中自行完成所需的工具

#include <Windows.h>
#include <iostream>

DWORD dwProcessID;
HANDLE dwHandle;
HWND dwHWND;
HANDLE g_Handle;
HWND g_hWnd;
DWORD exitCode = NULL;

void InitConsole()
{
    AllocConsole();
    freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);
    g_Handle = GetStdHandle(STD_OUTPUT_HANDLE);
    g_hWnd = GetConsoleWindow();
    SetConsoleTitleA(("DEBUG CONSOLE"));
    ShowWindow(GetConsoleWindow(), SW_SHOW);
    printf("Console::Initialized\n");
}

HWND GetWindowHandleByName(const char* Title, DWORD ProcID)
{
    HWND tempHWND = NULL;
    do
    {
        tempHWND = FindWindowEx(NULL, tempHWND, NULL, NULL);
        DWORD tempPID = 0;
        GetWindowThreadProcessId(tempHWND, &tempPID);
        if (tempPID == dwProcessID)
        {
            // Retrieve Window Information
            RECT tempRECT;
            LPSTR tempSTRING[MAX_PATH];
            std::string string;
            GetWindowRect(tempHWND, &tempRECT);
            GetWindowTextA(tempHWND, (LPSTR)tempSTRING, MAX_PATH);
            printf("WindowHandle: %p\nWindowName: %s\n\n", tempHWND, tempSTRING);
            string = reinterpret_cast<const char*>(tempSTRING);
            if (string == Title)
                return tempHWND;
        }
    } while (tempHWND != NULL);
    
    return NULL;    // FAILED
}

void SetWindowFocus(HWND WindowHandle)
{
    SetForegroundWindow(WindowHandle);
    HWND prevWindow = SetActiveWindow(WindowHandle);
    printf("currWindowHandle: %p\nprevWindowHandle: %p\n\n", dwHWND, prevWindow);
}

bool CleanExit(bool State)
{
    fclose(stdout);
    DestroyWindow(g_hWnd);
    FreeConsole();
    ExitThread(State);
}

int SetWindowFocus_Initialize()
{
    InitConsole();
    dwProcessID = GetCurrentProcessId();
    dwHandle = OpenProcess(PROCESS_ALL_ACCESS, NULL, dwProcessID);
    dwHWND = GetWindowHandleByName("Untitled - Notepad", dwProcessID);
    if (!dwHWND)
        return CleanExit(EXIT_FAILURE);
    exitCode = NULL;
    while (GetExitCodeProcess(dwHandle, &exitCode) && exitCode == STILL_ACTIVE) {
        if (GetAsyncKeyState(VK_END)) break;

        if (GetAsyncKeyState(VK_NUMPAD1))
            SetWindowFocus(g_hWnd);

        if (GetAsyncKeyState(VK_NUMPAD2))
            SetWindowFocus(dwHWND);
    }
    return CleanExit(EXIT_SUCCESS);
}

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  dwReason, LPVOID lpReserved )
{
    UNREFERENCED_PARAMETER(hModule);
    UNREFERENCED_PARAMETER(lpReserved);
    if (dwReason == DLL_PROCESS_ATTACH)
        CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)SetWindowFocus_Initialize, NULL, NULL, NULL);
    return TRUE;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM