Mercurial > minori
diff dep/animone/src/win/win32.cc @ 301:b1f625b0227c
*: convert all files CRLF -> LF
some files were in DOS format, others were in unix. now everything
(that at least is under our control) should all be the same format
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Mon, 13 May 2024 15:04:51 -0400 |
parents | 09c5bd74fe93 |
children | a7d4e5107531 |
line wrap: on
line diff
--- a/dep/animone/src/win/win32.cc Mon May 13 14:56:37 2024 -0400 +++ b/dep/animone/src/win/win32.cc Mon May 13 15:04:51 2024 -0400 @@ -1,144 +1,144 @@ -/* - * win/win32.cc: support for Windows - * - * Surprisingly, this is the one time where Microsoft actually - * does it fairly OK. Everything has a pretty simple API, despite - * the stupid wide string stuff. - */ -#include "animone/win/win32.h" -#include "animone.h" -#include "animone/util/win32.h" -#include "animone/win.h" -#include "animone/fd.h" - -#include <set> -#include <string> - -#include <windows.h> - -namespace animone::internal::win32 { - -static std::wstring GetWindowClassName(HWND hwnd) { - static constexpr int kMaxSize = 256; - - std::wstring buffer(kMaxSize, L'\0'); - const auto size = ::GetClassNameW(hwnd, &buffer.front(), buffer.length()); - buffer.resize(size); - return buffer; -} - -static std::wstring GetWindowText(HWND hwnd) { - const auto estimated_size = ::GetWindowTextLengthW(hwnd); - std::wstring buffer(estimated_size + 1, L'\0'); - - const auto size = ::GetWindowTextW(hwnd, &buffer.front(), buffer.length()); - /* GetWindowTextLength docs: - * "Under certain conditions, the GetWindowTextLength function may return a value - * that is larger than the actual length of the text." */ - buffer.resize(size); - return buffer; -} - -static DWORD GetWindowProcessId(HWND hwnd) { - DWORD process_id = 0; - ::GetWindowThreadProcessId(hwnd, &process_id); - return process_id; -} - -//////////////////////////////////////////////////////////////////////////////// - -static bool VerifyWindowStyle(HWND hwnd) { - const auto window_style = ::GetWindowLong(hwnd, GWL_STYLE); - const auto window_ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE); - - auto has_style = [&window_style](DWORD style) { return (window_style & style) != 0; }; - auto has_ex_style = [&window_ex_style](DWORD ex_style) { return (window_ex_style & ex_style) != 0; }; - - // Toolbars, tooltips and similar topmost windows - if (has_style(WS_POPUP) && has_ex_style(WS_EX_TOOLWINDOW)) - return false; - if (has_ex_style(WS_EX_TOPMOST) && has_ex_style(WS_EX_TOOLWINDOW)) - return false; - - return true; -} - -static bool VerifyClassName(const std::wstring& name) { - static const std::set<std::wstring> invalid_names = { - // System classes - L"#32770", // Dialog box - L"CabinetWClass", // Windows Explorer - L"ComboLBox", - L"DDEMLEvent", - L"DDEMLMom", - L"DirectUIHWND", - L"GDI+ Hook Window Class", - L"IME", - L"Internet Explorer_Hidden", - L"MSCTFIME UI", - L"tooltips_class32", - }; - - return !name.empty() && !invalid_names.count(name); -} - -static bool VerifyProcessPath(const std::wstring& path) { - return !path.empty() && !IsSystemDirectory(path); -} - -static bool VerifyProcessFileName(const std::wstring& name) { - static const std::set<std::wstring> invalid_names = { - // System files - L"explorer", // Windows Explorer - L"taskeng", // Task Scheduler Engine - L"taskhost", // Host Process for Windows Tasks - L"taskhostex", // Host Process for Windows Tasks - L"Taskmgr", // Task Manager - }; - - return !name.empty() && !invalid_names.count(name); -} - -//////////////////////////////////////////////////////////////////////////////// - -static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM param) { - if (!::IsWindowVisible(hwnd)) - return TRUE; - - if (!VerifyWindowStyle(hwnd)) - return TRUE; - - Window window; - window.id = static_cast<unsigned int>(reinterpret_cast<ULONG_PTR>(hwnd)); - window.text = ToUtf8String(GetWindowText(hwnd)); - - { - std::wstring class_name = GetWindowClassName(hwnd); - window.class_name = ToUtf8String(class_name); - if (!VerifyClassName(class_name)) - return TRUE; - } - - Process process; - process.pid = GetWindowProcessId(hwnd); - GetProcessName(process.pid, process.name); - - auto& window_proc = *reinterpret_cast<window_proc_t*>(param); - if (!window_proc(process, window)) - return FALSE; - - return TRUE; -} - -bool EnumerateWindows(window_proc_t window_proc) { - if (!window_proc) - return false; - - const auto param = reinterpret_cast<LPARAM>(&window_proc); - - // Note that EnumWindows enumerates only top-level windows of desktop apps - // (as opposed to UWP apps) on Windows 8 and above. - return ::EnumWindows(EnumWindowsProc, param) != FALSE; -} - -} // namespace animone::internal::win32 +/* + * win/win32.cc: support for Windows + * + * Surprisingly, this is the one time where Microsoft actually + * does it fairly OK. Everything has a pretty simple API, despite + * the stupid wide string stuff. + */ +#include "animone/win/win32.h" +#include "animone.h" +#include "animone/util/win32.h" +#include "animone/win.h" +#include "animone/fd.h" + +#include <set> +#include <string> + +#include <windows.h> + +namespace animone::internal::win32 { + +static std::wstring GetWindowClassName(HWND hwnd) { + static constexpr int kMaxSize = 256; + + std::wstring buffer(kMaxSize, L'\0'); + const auto size = ::GetClassNameW(hwnd, &buffer.front(), buffer.length()); + buffer.resize(size); + return buffer; +} + +static std::wstring GetWindowText(HWND hwnd) { + const auto estimated_size = ::GetWindowTextLengthW(hwnd); + std::wstring buffer(estimated_size + 1, L'\0'); + + const auto size = ::GetWindowTextW(hwnd, &buffer.front(), buffer.length()); + /* GetWindowTextLength docs: + * "Under certain conditions, the GetWindowTextLength function may return a value + * that is larger than the actual length of the text." */ + buffer.resize(size); + return buffer; +} + +static DWORD GetWindowProcessId(HWND hwnd) { + DWORD process_id = 0; + ::GetWindowThreadProcessId(hwnd, &process_id); + return process_id; +} + +//////////////////////////////////////////////////////////////////////////////// + +static bool VerifyWindowStyle(HWND hwnd) { + const auto window_style = ::GetWindowLong(hwnd, GWL_STYLE); + const auto window_ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE); + + auto has_style = [&window_style](DWORD style) { return (window_style & style) != 0; }; + auto has_ex_style = [&window_ex_style](DWORD ex_style) { return (window_ex_style & ex_style) != 0; }; + + // Toolbars, tooltips and similar topmost windows + if (has_style(WS_POPUP) && has_ex_style(WS_EX_TOOLWINDOW)) + return false; + if (has_ex_style(WS_EX_TOPMOST) && has_ex_style(WS_EX_TOOLWINDOW)) + return false; + + return true; +} + +static bool VerifyClassName(const std::wstring& name) { + static const std::set<std::wstring> invalid_names = { + // System classes + L"#32770", // Dialog box + L"CabinetWClass", // Windows Explorer + L"ComboLBox", + L"DDEMLEvent", + L"DDEMLMom", + L"DirectUIHWND", + L"GDI+ Hook Window Class", + L"IME", + L"Internet Explorer_Hidden", + L"MSCTFIME UI", + L"tooltips_class32", + }; + + return !name.empty() && !invalid_names.count(name); +} + +static bool VerifyProcessPath(const std::wstring& path) { + return !path.empty() && !IsSystemDirectory(path); +} + +static bool VerifyProcessFileName(const std::wstring& name) { + static const std::set<std::wstring> invalid_names = { + // System files + L"explorer", // Windows Explorer + L"taskeng", // Task Scheduler Engine + L"taskhost", // Host Process for Windows Tasks + L"taskhostex", // Host Process for Windows Tasks + L"Taskmgr", // Task Manager + }; + + return !name.empty() && !invalid_names.count(name); +} + +//////////////////////////////////////////////////////////////////////////////// + +static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM param) { + if (!::IsWindowVisible(hwnd)) + return TRUE; + + if (!VerifyWindowStyle(hwnd)) + return TRUE; + + Window window; + window.id = static_cast<unsigned int>(reinterpret_cast<ULONG_PTR>(hwnd)); + window.text = ToUtf8String(GetWindowText(hwnd)); + + { + std::wstring class_name = GetWindowClassName(hwnd); + window.class_name = ToUtf8String(class_name); + if (!VerifyClassName(class_name)) + return TRUE; + } + + Process process; + process.pid = GetWindowProcessId(hwnd); + GetProcessName(process.pid, process.name); + + auto& window_proc = *reinterpret_cast<window_proc_t*>(param); + if (!window_proc(process, window)) + return FALSE; + + return TRUE; +} + +bool EnumerateWindows(window_proc_t window_proc) { + if (!window_proc) + return false; + + const auto param = reinterpret_cast<LPARAM>(&window_proc); + + // Note that EnumWindows enumerates only top-level windows of desktop apps + // (as opposed to UWP apps) on Windows 8 and above. + return ::EnumWindows(EnumWindowsProc, param) != FALSE; +} + +} // namespace animone::internal::win32