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