1 /*
2  *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef MODULES_DESKTOP_CAPTURE_WIN_WINDOW_CAPTURE_UTILS_H_
12 #define MODULES_DESKTOP_CAPTURE_WIN_WINDOW_CAPTURE_UTILS_H_
13 
14 #include <shlobj.h>
15 #include <windows.h>
16 #include <wrl/client.h>
17 
18 #include "modules/desktop_capture/desktop_capturer.h"
19 #include "modules/desktop_capture/desktop_geometry.h"
20 #include "rtc_base/constructor_magic.h"
21 
22 namespace webrtc {
23 
24 // Outputs the window rect. The returned DesktopRect is in system coordinates,
25 // i.e. the primary monitor on the system always starts from (0, 0). This
26 // function returns false if native APIs fail.
27 bool GetWindowRect(HWND window, DesktopRect* result);
28 
29 // Outputs the window rect, with the left/right/bottom frame border cropped if
30 // the window is maximized or has a transparent resize border.
31 // |avoid_cropping_border| may be set to true to avoid cropping the visible
32 // border when cropping any resize border.
33 // |cropped_rect| is the cropped rect relative to the
34 // desktop. |original_rect| is the original rect returned from GetWindowRect.
35 // Returns true if all API calls succeeded. The returned DesktopRect is in
36 // system coordinates, i.e. the primary monitor on the system always starts from
37 // (0, 0). |original_rect| can be nullptr.
38 //
39 // TODO(zijiehe): Move this function to CroppingWindowCapturerWin after it has
40 // been removed from MouseCursorMonitorWin.
41 // This function should only be used by CroppingWindowCapturerWin. Instead a
42 // DesktopRect CropWindowRect(const DesktopRect& rect)
43 // should be added as a utility function to help CroppingWindowCapturerWin and
44 // WindowCapturerWinGdi to crop out the borders or shadow according to their
45 // scenarios. But this function is too generic and easy to be misused.
46 bool GetCroppedWindowRect(HWND window,
47                           bool avoid_cropping_border,
48                           DesktopRect* cropped_rect,
49                           DesktopRect* original_rect);
50 
51 // Retrieves the rectangle of the content area of |window|. Usually it contains
52 // title bar and window client area, but borders or shadow are excluded. The
53 // returned DesktopRect is in system coordinates, i.e. the primary monitor on
54 // the system always starts from (0, 0). This function returns false if native
55 // APIs fail.
56 bool GetWindowContentRect(HWND window, DesktopRect* result);
57 
58 // Returns the region type of the |window| and fill |rect| with the region of
59 // |window| if region type is SIMPLEREGION.
60 int GetWindowRegionTypeWithBoundary(HWND window, DesktopRect* result);
61 
62 // Retrieves the size of the |hdc|. This function returns false if native APIs
63 // fail.
64 bool GetDcSize(HDC hdc, DesktopSize* size);
65 
66 // Retrieves whether the |window| is maximized and stores in |result|. This
67 // function returns false if native APIs fail.
68 bool IsWindowMaximized(HWND window, bool* result);
69 
70 // Checks that the HWND is for a valid window, that window's visibility state is
71 // visible, and that it is not minimized.
72 bool IsWindowValidAndVisible(HWND window);
73 
74 // This function is passed into the EnumWindows API and filters out windows that
75 // we don't want to capture, e.g. minimized or unresponsive windows and the
76 // Start menu.
77 BOOL CALLBACK FilterUncapturableWindows(HWND hwnd, LPARAM param);
78 
79 typedef HRESULT(WINAPI* DwmIsCompositionEnabledFunc)(BOOL* enabled);
80 typedef HRESULT(WINAPI* DwmGetWindowAttributeFunc)(HWND hwnd,
81                                                    DWORD flag,
82                                                    PVOID result_ptr,
83                                                    DWORD result_size);
84 class WindowCaptureHelperWin {
85  public:
86   WindowCaptureHelperWin();
87   ~WindowCaptureHelperWin();
88 
89   bool IsAeroEnabled();
90   bool IsWindowChromeNotification(HWND hwnd);
91   bool AreWindowsOverlapping(HWND hwnd,
92                              HWND selected_hwnd,
93                              const DesktopRect& selected_window_rect);
94   bool IsWindowOnCurrentDesktop(HWND hwnd);
95   bool IsWindowVisibleOnCurrentDesktop(HWND hwnd);
96   bool IsWindowCloaked(HWND hwnd);
97   bool EnumerateCapturableWindows(DesktopCapturer::SourceList* results);
98 
99  private:
100   HMODULE dwmapi_library_ = nullptr;
101   DwmIsCompositionEnabledFunc func_ = nullptr;
102   DwmGetWindowAttributeFunc dwm_get_window_attribute_func_ = nullptr;
103 
104   // Only used on Win10+.
105   Microsoft::WRL::ComPtr<IVirtualDesktopManager> virtual_desktop_manager_;
106 
107   RTC_DISALLOW_COPY_AND_ASSIGN(WindowCaptureHelperWin);
108 };
109 
110 }  // namespace webrtc
111 
112 #endif  // MODULES_DESKTOP_CAPTURE_WIN_WINDOW_CAPTURE_UTILS_H_
113