Mercurial > minori
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 |
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 |