1 // Copyright 2023 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/win/window_enumerator.h"
6
7 #include <windows.h>
8
9 #include <string>
10
11 #include "base/functional/callback.h"
12
13 namespace base::win {
14
15 namespace {
16
OnWindowProc(HWND hwnd,LPARAM lparam)17 BOOL CALLBACK OnWindowProc(HWND hwnd, LPARAM lparam) {
18 return !reinterpret_cast<WindowEnumeratorCallback*>(lparam)->Run(hwnd);
19 }
20
21 } // namespace
22
EnumerateChildWindows(HWND parent,WindowEnumeratorCallback filter)23 void EnumerateChildWindows(HWND parent, WindowEnumeratorCallback filter) {
24 ::EnumChildWindows(parent, &OnWindowProc, reinterpret_cast<LPARAM>(&filter));
25 }
26
IsTopmostWindow(HWND hwnd)27 bool IsTopmostWindow(HWND hwnd) {
28 return ::GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST;
29 }
30
IsSystemDialog(HWND hwnd)31 bool IsSystemDialog(HWND hwnd) {
32 static constexpr wchar_t kSystemDialogClass[] = L"#32770";
33 return GetWindowClass(hwnd) == kSystemDialogClass;
34 }
35
IsShellWindow(HWND hwnd)36 bool IsShellWindow(HWND hwnd) {
37 const std::wstring class_name = GetWindowClass(hwnd);
38
39 // 'Button' is the start button, 'Shell_TrayWnd' the taskbar, and
40 // 'Shell_SecondaryTrayWnd' is the taskbar on non-primary displays.
41 return class_name == L"Button" || class_name == L"Shell_TrayWnd" ||
42 class_name == L"Shell_SecondaryTrayWnd";
43 }
44
GetWindowClass(HWND hwnd)45 std::wstring GetWindowClass(HWND hwnd) {
46 constexpr int kMaxWindowClassNameLength = 256;
47 std::wstring window_class(kMaxWindowClassNameLength, L'\0');
48 const int name_len =
49 ::GetClassName(hwnd, window_class.data(), kMaxWindowClassNameLength);
50 if (name_len <= 0 || name_len > kMaxWindowClassNameLength) {
51 return {};
52 }
53 window_class.resize(static_cast<size_t>(name_len));
54 return window_class;
55 }
56
GetWindowTextString(HWND hwnd)57 std::wstring GetWindowTextString(HWND hwnd) {
58 auto num_chars = ::GetWindowTextLength(hwnd);
59 if (num_chars <= 0) {
60 return {};
61 }
62 std::wstring text(static_cast<size_t>(num_chars), L'\0');
63 // MSDN says that GetWindowText will not write anything other than a string
64 // terminator to the last position in the buffer.
65 auto len = ::GetWindowText(hwnd, text.data(), num_chars + 1);
66 if (len <= 0) {
67 return std::wstring();
68 }
69 // GetWindowText may return a shorter string than reported above.
70 text.resize(static_cast<size_t>(len));
71 return text;
72 }
73
74 } // namespace base::win
75