加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

Windows获取窗口列表

(2022-08-21 14:09:58)
分类: 编程之乐

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

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


HWND desktop_window = GetDesktopWindow();

2、获取子窗口


HWND window = GetWindow(desktop_window, GW_CHILD);

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


window = GetNextWindow(window, GW_HWNDNEXT);

 4、获取窗口的进程id


  1. DWORD process_id;
  2. GetWindowThreadProcessId(window, &process_id);

5、获取窗口大小


  1. RECT rect;
  2. GetWindowRect(hwnd, &rect);

6、获取窗口的标题title


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

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


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

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

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


  1. if(exename.empty()){
  2. continue;
  3. }

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


  1. if(!IsWindowVisible(window)) {
  2. continue;
  3. }

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


  1. if(strlen(windowTitle) == 0) {
  2. continue;
  3. }

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


  1. RECT rect;
  2. GetClientRect(window, &rect);
  3. if ((rect.bottom == 0 || rect.right == 0)) {
  4. continue;
  5. }

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


  1. DWORD ex_styles = (DWORD)GetWindowLongPtr(window, GWL_EXSTYLE);
  2. if (ex_styles & WS_EX_TOOLWINDOW) {
  3. continue;
  4. }

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


  1. DWORD styles = (DWORD)GetWindowLongPtr(window, GWL_STYLE);
  2. if (styles & WS_CHILD) {
  3. continue;
  4. }

 三、全部代码


  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include
  7. #include
  8. #include
  9. const uint32_t kBufferSize = 128;
  10. struct WindowInfo {
  11. HWND windowHwnd;
  12. std::string windowName;
  13. std::string windowTitle;
  14. uint32_t windowWidth;
  15. uint32_t windowHeight;
  16. };
  17. bool CheckWindowValid(HWND window) {
  18. RECT rect;
  19. GetClientRect(window, &rect);
  20. if ((rect.bottom == 0 || rect.right == 0)) {
  21. return false;
  22. }
  23. DWORD ex_styles = (DWORD)GetWindowLongPtr(window, GWL_EXSTYLE);
  24. if (ex_styles & WS_EX_TOOLWINDOW) {
  25. return false;
  26. }
  27. DWORD styles = (DWORD)GetWindowLongPtr(window, GWL_STYLE);
  28. if (styles & WS_CHILD) {
  29. return false;
  30. }
  31. if (!IsWindowVisible(window)) {
  32. return false;
  33. }
  34. return true;
  35. }
  36. bool CheckWindowTitleValid(char* windowName) {
  37. char storeName[] = "Microsoft Store";
  38. if (strcmp(windowName, storeName) == 0) {
  39. return false;
  40. }
  41. char edgeName[] = "Microsoft Edge";
  42. if (strcmp(windowName, edgeName) == 0) {
  43. return false;
  44. }
  45. if (strlen(windowName) == 0) {
  46. return false;
  47. }
  48. return true;
  49. }
  50. std::string GetWindowName(HWND window, DWORD process_id) {
  51. char exename[kBufferSize] = "";
  52. HANDLE hProc =
  53. OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, process_id);
  54. GetProcessImageFileNameA(hProc, exename, 128);
  55. CloseHandle(hProc);
  56. std::string window_name = exename;
  57. auto pos = window_name.rfind("/");
  58. if (pos == std::string::npos) {
  59. pos = window_name.rfind("\");
  60. }
  61. if (pos == std::string::npos) {
  62. return "";
  63. }
  64. return window_name.substr(pos + 1, window_name.length() - pos);
  65. }
  66. void GetWindowList() {
  67. HWND default_window = GetDesktopWindow();
  68. char windowTitle[kBufferSize] = "";
  69. std::string exename = "";
  70. HWND window = GetWindow(default_window, GW_CHILD);
  71. while (window) {
  72. DWORD process_id;
  73. GetWindowThreadProcessId(window, &process_id);
  74. RECT rect;
  75. GetWindowRect(window, &rect);
  76. GetWindowTextA(window, windowTitle, 128);
  77. exename = GetWindowName(window, process_id);
  78. if (exename.empty() || !CheckWindowValid(window)) {
  79. break;
  80. }
  81. break;
  82. }
  83. while (window != NULL) {
  84. window = GetNextWindow(window, GW_HWNDNEXT);
  85. DWORD process_id;
  86. GetWindowThreadProcessId(window, &process_id);
  87. RECT rect;
  88. GetWindowRect(window, &rect);
  89. GetWindowTextA(window, windowTitle, 128);
  90. exename = GetWindowName(window, process_id);
  91. if (exename.empty() || !CheckWindowValid(window) || !CheckWindowTitleValid(windowTitle)) {
  92. continue;
  93. }
  94. std::cout << "windowTitle:" << windowTitle << std::endl;
  95. std::cout << "exename:" << exename << std::endl;
  96. }
  97. }
  98. int main(void) {
  99. GetWindowList();
  100. getchar();
  101. return 0;
  102. }



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



0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有