annotate src/win/win32.cc @ 0:a76fa32bdc92

*: HUUUGE changes animia has been renamed to animone, so instead of thinking of a health condition, you think of a beautiful flower :) I've also edited some of the code for animone, but I have no idea if it even works or not because I don't have a mac or windows machine lying around. whoops! ... anyway, all of the changes divergent from Anisthesia are now licensed under BSD. it's possible that I could even rewrite most of the code to where I don't even have to keep the MIT license, but that's thinking too far into the future I've been slacking off on implementing the anime seasons page, mostly out of laziness. I think I'd have to create another db file specifically for the seasons anyway, this code is being pushed *primarily* because the hard drive it's on is failing! yay :)
author Paper <paper@paper.us.eu.org>
date Mon, 01 Apr 2024 02:43:44 -0400
parents
children aa55bcfb5b79
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
1 /*
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
2 * win/win32.cc: support for Windows
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
3 *
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
4 * Surprisingly, this is the one time where Microsoft actually
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
5 * does it fairly OK. Everything has a pretty simple API, despite
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
6 * the stupid wide string stuff.
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
7 */
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
8 #include "animone/win/win32.h"
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
9 #include "animone.h"
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
10 #include "animone/util/win32.h"
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
11 #include "animone/win.h"
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
12
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
13 #include <set>
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
14 #include <string>
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
15
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
16 #include <windows.h>
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
17
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
18 namespace animone::internal::win32 {
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
19
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
20 static std::wstring GetWindowClassName(HWND hwnd) {
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
21 static constexpr int kMaxSize = 256;
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
22
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
23 std::wstring buffer(kMaxSize, L'\0');
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
24 const auto size = ::GetClassNameW(hwnd, &buffer.front(), buffer.length());
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
25 buffer.resize(size);
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
26 return buffer;
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
27 }
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
28
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
29 static std::wstring GetWindowText(HWND hwnd) {
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
30 const auto estimated_size = ::GetWindowTextLengthW(hwnd);
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
31 std::wstring buffer(estimated_size + 1, L'\0');
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
32
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
33 const auto size = ::GetWindowTextW(hwnd, &buffer.front(), buffer.length());
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
34 /* GetWindowTextLength docs:
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
35 * "Under certain conditions, the GetWindowTextLength function may return a value
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
36 * that is larger than the actual length of the text." */
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
37 buffer.resize(size);
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
38 return buffer;
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
39 }
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
40
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
41 static DWORD GetWindowProcessId(HWND hwnd) {
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
42 DWORD process_id = 0;
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
43 ::GetWindowThreadProcessId(hwnd, &process_id);
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
44 return process_id;
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
45 }
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
46
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
47 ////////////////////////////////////////////////////////////////////////////////
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
48
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
49 static bool VerifyWindowStyle(HWND hwnd) {
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
50 const auto window_style = ::GetWindowLong(hwnd, GWL_STYLE);
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
51 const auto window_ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
52
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
53 auto has_style = [&window_style](DWORD style) { return (window_style & style) != 0; };
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
54 auto has_ex_style = [&window_ex_style](DWORD ex_style) { return (window_ex_style & ex_style) != 0; };
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
55
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
56 // Toolbars, tooltips and similar topmost windows
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
57 if (has_style(WS_POPUP) && has_ex_style(WS_EX_TOOLWINDOW))
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
58 return false;
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
59 if (has_ex_style(WS_EX_TOPMOST) && has_ex_style(WS_EX_TOOLWINDOW))
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
60 return false;
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
61
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
62 return true;
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
63 }
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
64
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
65 static bool VerifyClassName(const std::wstring& name) {
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
66 static const std::set<std::wstring> invalid_names = {
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
67 // System classes
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
68 L"#32770", // Dialog box
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
69 L"CabinetWClass", // Windows Explorer
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
70 L"ComboLBox",
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
71 L"DDEMLEvent",
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
72 L"DDEMLMom",
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
73 L"DirectUIHWND",
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
74 L"GDI+ Hook Window Class",
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
75 L"IME",
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
76 L"Internet Explorer_Hidden",
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
77 L"MSCTFIME UI",
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
78 L"tooltips_class32",
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
79 };
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
80
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
81 return !name.empty() && !invalid_names.count(name);
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
82 }
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
83
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
84 static bool VerifyProcessPath(const std::wstring& path) {
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
85 return !path.empty() && !IsSystemDirectory(path);
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
86 }
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
87
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
88 static bool VerifyProcessFileName(const std::wstring& name) {
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
89 static const std::set<std::wstring> invalid_names = {
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
90 // System files
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
91 L"explorer", // Windows Explorer
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
92 L"taskeng", // Task Scheduler Engine
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
93 L"taskhost", // Host Process for Windows Tasks
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
94 L"taskhostex", // Host Process for Windows Tasks
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
95 L"Taskmgr", // Task Manager
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
96 };
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
97
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
98 return !name.empty() && !invalid_names.count(name);
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
99 }
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
100
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
101 ////////////////////////////////////////////////////////////////////////////////
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
102
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
103 static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM param) {
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
104 if (!::IsWindowVisible(hwnd))
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
105 return TRUE;
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
106
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
107 if (!VerifyWindowStyle(hwnd))
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
108 return TRUE;
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
109
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
110 Window window;
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
111 window.id = static_cast<unsigned int>(reinterpret_cast<ULONG_PTR>(hwnd));
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
112 window.text = ToUtf8String(GetWindowText(hwnd));
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
113
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
114 {
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
115 std::wstring class_name = GetWindowClassName(hwnd);
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
116 window.class_name = ToUtf8String(class_name);
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
117 if (!VerifyClassName(class_name))
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
118 return TRUE;
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
119 }
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
120
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
121 Process process;
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
122 process.pid = GetWindowProcessId(hwnd);
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
123 process.name = fd::GetProcessName(process.pid)
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
124
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
125 auto& window_proc = *reinterpret_cast<window_proc_t*>(param);
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
126 if (!window_proc(process, window))
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
127 return FALSE;
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
128
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
129 return TRUE;
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
130 }
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
131
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
132 bool EnumerateWindows(window_proc_t window_proc) {
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
133 if (!window_proc)
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
134 return false;
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
135
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
136 const auto param = reinterpret_cast<LPARAM>(&window_proc);
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
137
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
138 // Note that EnumWindows enumerates only top-level windows of desktop apps
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
139 // (as opposed to UWP apps) on Windows 8 and above.
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
140 return ::EnumWindows(EnumWindowsProc, param) != FALSE;
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
141 }
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
142
a76fa32bdc92 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
143 } // namespace animone::internal::win32