COMとWILを使ってIUIAutomationElementを列挙するコードです。
実行例(ExplorerPatcher起動中)
Source.cpp
#include <format> #include <iostream> #include "string_util.hpp" #define STRICT #define NOMINMAX #include <Windows.h> #include <UIAutomation.h> #include "stl_win.hpp" #include "wil/com.h" int main() { std::wcout.imbue(std::locale("", std::locale::ctype)); auto coinit = wil::CoInitializeEx(COINIT_APARTMENTTHREADED); auto uiAutomation = wil::CoCreateInstance<CUIAutomation, IUIAutomation>(CLSCTX_INPROC_SERVER); auto hwnds = GetWindowHandles(); std::wcout << L"WindowHandle, ClassName, WindowText, UIAutomation ElementName, ClassName" << std::endl; for (auto hwnd : hwnds) { wil::com_ptr<IUIAutomationElement> uiAutoElem; if (FAILED(uiAutomation->ElementFromHandle(hwnd, uiAutoElem.put()))) continue; wil::unique_bstr name, className; uiAutoElem->get_CurrentName(name.put()); uiAutoElem->get_CurrentClassName(className.put()); std::wcout << std::format(L"{}, {}, {}, {}, {}", pad_start(to_wstring_hex_uc(std::bit_cast<size_t>(hwnd)), MAX_SIZE_T_HEX_LENGTH, L'0'), GetClassNameW(hwnd), GetWindowTextW(hwnd), wil::string_get_not_null(name), wil::string_get_not_null(className)) << std::endl; } return 0; }
string_util.hpp
#pragma once #include <string> const size_t MAX_SIZE_T_HEX_LENGTH = sizeof(size_t) * 2; constexpr std::wstring to_wstring_hex_uc(size_t x) { std::wstring s; for (; x != 0; x /= 16) { auto m = x % 16; s.push_back(static_cast<wchar_t>((m < 10 ? L'0' : L'A' - 10) + m)); } return s; } constexpr std::wstring pad_start(std::wstring_view source, size_t length, wchar_t fill) { if (source.size() >= length) return std::wstring(source.cbegin(), source.cend()); std::wstring s; s.reserve(length); s.append(length - source.size(), fill); s.append(source); return s; }
stl_win.hpp
#pragma once #include <bit> #include <string> #include <vector> BOOL CALLBACK GetWindowHandlesWorker(HWND hwnd, LPARAM lParam) { auto& v = *std::bit_cast<std::vector<HWND>*>(lParam); v.emplace_back(hwnd); EnumChildWindows(hwnd, GetWindowHandlesWorker, lParam); return TRUE; } std::vector<HWND> GetWindowHandles() { std::vector<HWND> v; EnumWindows(GetWindowHandlesWorker, std::bit_cast<LPARAM>(std::addressof(v))); return v; } std::wstring GetClassNameW(HWND hwnd) { std::wstring s; for (int size = 0xff; ; size += 0xff) { s.resize(size); auto copied = ::GetClassNameW(hwnd, s.data(), size + 1); if (copied != 0) { s.resize(copied); s.shrink_to_fit(); break; } else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { return {}; } } return s; } std::wstring GetWindowTextW(HWND hwnd) { auto len = GetWindowTextLengthW(hwnd); if (len == 0) return {}; std::wstring s(len, L'\0'); if (GetWindowTextW(hwnd, s.data(), len + 1) == 0) return {}; return s; }