Windows下获取窗口列表,会过滤一些无效窗口

一、Windows下获取到当前所有窗口的列表

1、获取桌面窗口,因为Windows上所有的窗口都是在桌面上面的,所有其他的窗口都是桌面窗口的子窗口

HWND desktop_window = GetDesktopWindow();

2、获取子窗口

HWND window = GetWindow(desktop_window, GW_CHILD);

3、获取同级下一个窗口,因为所有的窗口都是桌面窗口的子窗口,所有接下来一直获取下一个窗口,一直到获取的窗口为NULL结束

window = GetNextWindow(window, GW_HWNDNEXT);

 4、获取窗口的进程id

DWORD process_id;
GetWindowThreadProcessId(window, &process_id);

5、获取窗口大小

RECT rect;
GetWindowRect(hwnd, &rect);

6、获取窗口的标题title

char windowTitle[128] = "";
GetWindowTextA(window, windowTitle, 128);

 7、获取窗口所对应的进程名

char name[128] = "";
HANDLE hProc = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, process_id);
GetProcessImageFileNameA(hProc, name, 128);
CloseHandle(hProc);
// 这里获取到的exe name会有路径信息,接下来我们把路径截掉
std::string exename = name;
auto pos = exename.rfind("/");
if (pos == std::string::npos) {
    pos = exename.rfind("\\");
}
if (pos == std::string::npos) {
    return "";
}
exename = exename.substr(pos + 1, window_name.length() - pos);

上面的代码已经完成了一个基本的窗口获取,打印输出一下,发现获取到的窗口非常的多,很多窗口都是我们不需要的,接下来对窗口做一些过滤 

1、首先把exename为空的过滤掉

if(exename.empty()){
    continue;
}

2、过滤掉最小化的窗口,这个时候会过滤掉大部分的窗口,当然也可以不使用这个条件

if(!IsWindowVisible(window)) {
    continue;
}

 3、过滤掉window title为空的窗口,也可以根据窗口标题过滤掉一些特殊的窗口,比如:Microsoft Store和Microsoft Edge

if(strlen(windowTitle) == 0) {
    continue;
}

4、 过滤掉窗口大小为0的窗口

RECT rect;
GetClientRect(window, &rect);
if ((rect.bottom == 0 || rect.right == 0)) {
    continue;
}

5、 过滤掉工具窗口,工具窗口不出现在任务条或用户按下ALT+TAB时出现的窗口中,关于Windows下窗口样式也可以参考这一篇文章https://blog.csdn.net/u011555996/article/details/93513347

DWORD ex_styles = (DWORD)GetWindowLongPtr(window, GWL_EXSTYLE);
if (ex_styles & WS_EX_TOOLWINDOW) {
    continue;
}

6、过滤掉一些不能应用于弹出式窗口风格,也就是带有WS_CHILD属性的窗口

DWORD styles = (DWORD)GetWindowLongPtr(window, GWL_STYLE);
if (styles & WS_CHILD) {
    continue;
}

 三、全部代码

#include <Windows.h>
#include <iostream>
#include <vector>
#include <string>
#include <dwmapi.h>
#include <olectl.h>
#include <psapi.h>
#include <wingdi.h>

const uint32_t kBufferSize = 128;

struct WindowInfo {
    HWND windowHwnd;
    std::string windowName;
    std::string windowTitle;
    uint32_t windowWidth;
    uint32_t windowHeight;
};

bool CheckWindowValid(HWND window) {
    RECT rect;
    GetClientRect(window, &rect);
    if ((rect.bottom == 0 || rect.right == 0)) {
        return false;
    }
    DWORD ex_styles = (DWORD)GetWindowLongPtr(window, GWL_EXSTYLE);
    if (ex_styles & WS_EX_TOOLWINDOW) {
        return false;
    }
    DWORD styles = (DWORD)GetWindowLongPtr(window, GWL_STYLE);
    if (styles & WS_CHILD) {
        return false;
    }
    if (!IsWindowVisible(window)) {
        return false;
    }
    return true;
}

bool CheckWindowTitleValid(char* windowName) {
    char storeName[] = "Microsoft Store";
    if (strcmp(windowName, storeName) == 0) {
        return false;
    }

    char edgeName[] = "Microsoft Edge";
    if (strcmp(windowName, edgeName) == 0) {
        return false;
    }

    if (strlen(windowName) == 0) {
        return false;
    }
    return true;
}

std::string GetWindowName(HWND window, DWORD process_id) {
    char exename[kBufferSize] = "";
    HANDLE hProc =
        OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, process_id);
    GetProcessImageFileNameA(hProc, exename, 128);
    CloseHandle(hProc);
    std::string window_name = exename;
    auto pos = window_name.rfind("/");
    if (pos == std::string::npos) {
        pos = window_name.rfind("\\");
    }
    if (pos == std::string::npos) {
        return "";
    }
    return window_name.substr(pos + 1, window_name.length() - pos);
}

void GetWindowList() {
    HWND default_window = GetDesktopWindow();
    char windowTitle[kBufferSize] = "";
    std::string exename = "";
    HWND window = GetWindow(default_window, GW_CHILD);
    while (window) {
        DWORD process_id;
        GetWindowThreadProcessId(window, &process_id);

        RECT rect;
        GetWindowRect(window, &rect);

        GetWindowTextA(window, windowTitle, 128);
        exename = GetWindowName(window, process_id);
        if (exename.empty() || !CheckWindowValid(window)) {
            break;
        }
        break;
    }
    while (window != NULL) {
        window = GetNextWindow(window, GW_HWNDNEXT);
        DWORD process_id;
        GetWindowThreadProcessId(window, &process_id);

        RECT rect;
        GetWindowRect(window, &rect);

        GetWindowTextA(window, windowTitle, 128);
        exename = GetWindowName(window, process_id);
        if (exename.empty() || !CheckWindowValid(window) || !CheckWindowTitleValid(windowTitle)) {
            continue;
        }
        std::cout << "windowTitle:" << windowTitle << std::endl;
        std::cout << "exename:" << exename << std::endl;
    }
}

int main(void) {
    GetWindowList();
    getchar();
    return 0;
}

 

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值