annotate dep/animone/src/win/win32.cc @ 337:a7d4e5107531

dep/animone: REFACTOR ALL THE THINGS 1: animone now has its own syntax divergent from anisthesia, making different platforms actually have their own sections 2: process names in animone are now called `comm' (this will probably break things). this is what its called in bsd/linux so I'm just going to use it everywhere 3: the X11 code now checks for the existence of a UTF-8 window title and passes it if available 4: ANYTHING THATS NOT LINUX IS 100% UNTESTED AND CAN AND WILL BREAK! I still actually need to test the bsd code. to be honest I'm probably going to move all of the bsds into separate files because they're all essentially different operating systems at this point
author Paper <paper@paper.us.eu.org>
date Wed, 19 Jun 2024 12:51:15 -0400
parents b1f625b0227c
children adb79bdde329
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
301
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
1 /*
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
2 * win/win32.cc: support for Windows
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
3 *
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
4 * Surprisingly, this is the one time where Microsoft actually
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
5 * does it fairly OK. Everything has a pretty simple API, despite
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
6 * the stupid wide string stuff.
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
7 */
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
8 #include "animone/win/win32.h"
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
9 #include "animone.h"
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
10 #include "animone/util/win32.h"
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
11 #include "animone/win.h"
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
12 #include "animone/fd.h"
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
13
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
14 #include <set>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
15 #include <string>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
16
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
17 #include <windows.h>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
18
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
19 namespace animone::internal::win32 {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
20
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
21 static std::wstring GetWindowClassName(HWND hwnd) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
22 static constexpr int kMaxSize = 256;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
23
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
24 std::wstring buffer(kMaxSize, L'\0');
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
25 const auto size = ::GetClassNameW(hwnd, &buffer.front(), buffer.length());
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
26 buffer.resize(size);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
27 return buffer;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
28 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
29
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
30 static std::wstring GetWindowText(HWND hwnd) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
31 const auto estimated_size = ::GetWindowTextLengthW(hwnd);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
32 std::wstring buffer(estimated_size + 1, L'\0');
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
33
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
34 const auto size = ::GetWindowTextW(hwnd, &buffer.front(), buffer.length());
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
35 /* GetWindowTextLength docs:
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
36 * "Under certain conditions, the GetWindowTextLength function may return a value
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
37 * that is larger than the actual length of the text." */
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
38 buffer.resize(size);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
39 return buffer;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
40 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
41
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
42 static DWORD GetWindowProcessId(HWND hwnd) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
43 DWORD process_id = 0;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
44 ::GetWindowThreadProcessId(hwnd, &process_id);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
45 return process_id;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
46 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
47
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
48 ////////////////////////////////////////////////////////////////////////////////
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
49
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
50 static bool VerifyWindowStyle(HWND hwnd) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
51 const auto window_style = ::GetWindowLong(hwnd, GWL_STYLE);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
52 const auto window_ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
53
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
54 auto has_style = [&window_style](DWORD style) { return (window_style & style) != 0; };
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
55 auto has_ex_style = [&window_ex_style](DWORD ex_style) { return (window_ex_style & ex_style) != 0; };
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
56
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
57 // Toolbars, tooltips and similar topmost windows
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
58 if (has_style(WS_POPUP) && has_ex_style(WS_EX_TOOLWINDOW))
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
59 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
60 if (has_ex_style(WS_EX_TOPMOST) && has_ex_style(WS_EX_TOOLWINDOW))
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
61 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
62
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
63 return true;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
64 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
65
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
66 static bool VerifyClassName(const std::wstring& name) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
67 static const std::set<std::wstring> invalid_names = {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
68 // System classes
337
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
69 "#32770", // Dialog box
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
70 "CabinetWClass", // Windows Explorer
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
71 "ComboLBox",
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
72 "DDEMLEvent",
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
73 "DDEMLMom",
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
74 "DirectUIHWND",
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
75 "GDI+ Hook Window Class",
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
76 "IME",
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
77 "Internet Explorer_Hidden",
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
78 "MSCTFIME UI",
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
79 "tooltips_class32",
301
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
80 };
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
81
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
82 return !name.empty() && !invalid_names.count(name);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
83 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
84
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
85 ////////////////////////////////////////////////////////////////////////////////
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
86
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
87 static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM param) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
88 if (!::IsWindowVisible(hwnd))
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
89 return TRUE;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
90
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
91 if (!VerifyWindowStyle(hwnd))
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
92 return TRUE;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
93
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
94 Window window;
337
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
95 window.platform = WindowPlatform::Win32;
301
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
96 window.id = static_cast<unsigned int>(reinterpret_cast<ULONG_PTR>(hwnd));
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
97 window.text = ToUtf8String(GetWindowText(hwnd));
337
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
98 window.class_name = ToUtf8String(GetWindowClassName(hwnd));
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
99 if (!VerifyClassName(window.class_name))
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
100 return TRUE;
301
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
101
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
102 Process process;
337
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
103 process.platform = ExecutablePlatform::Win32;
301
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
104 process.pid = GetWindowProcessId(hwnd);
337
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
105 GetProcessName(process.pid, process.comm);
301
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
106
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
107 auto& window_proc = *reinterpret_cast<window_proc_t*>(param);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
108 if (!window_proc(process, window))
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
109 return FALSE;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
110
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
111 return TRUE;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
112 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
113
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
114 bool EnumerateWindows(window_proc_t window_proc) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
115 if (!window_proc)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
116 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
117
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
118 const auto param = reinterpret_cast<LPARAM>(&window_proc);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
119
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
120 // Note that EnumWindows enumerates only top-level windows of desktop apps
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
121 // (as opposed to UWP apps) on Windows 8 and above.
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
122 return ::EnumWindows(EnumWindowsProc, param) != FALSE;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
123 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
124
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 267
diff changeset
125 } // namespace animone::internal::win32