window_capturer_win.cc revision 3c089d751ede283e21e186885eaf705c3257ccd2
1b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org/* 2b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 3b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org * 4b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org * Use of this source code is governed by a BSD-style license 5b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org * that can be found in the LICENSE file in the root of the source 6b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org * tree. An additional intellectual property rights grant can be found 7b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org * in the file PATENTS. All contributing project authors may 8b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org * be found in the AUTHORS file in the root of the source tree. 9b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org */ 10b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 11b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org#include "webrtc/modules/desktop_capture/window_capturer.h" 12b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 1312dc1a38ca54a000e4fecfbc6d41138b895c9ca5pbos@webrtc.org#include <assert.h> 14b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 1500b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org#include "webrtc/base/scoped_ptr.h" 16047abc93a24134d59b8feb895bbd7597e1aef4cdjiayl@webrtc.org#include "webrtc/base/win32.h" 17b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org#include "webrtc/modules/desktop_capture/desktop_frame_win.h" 18c8ac17ca04897f8f5fbb5d179e8b7573f66b148ajiayl@webrtc.org#include "webrtc/modules/desktop_capture/win/window_capture_utils.h" 19b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org#include "webrtc/system_wrappers/interface/logging.h" 20b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 21b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.orgnamespace webrtc { 22b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 23b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.orgnamespace { 24b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 25b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.orgBOOL CALLBACK WindowsEnumerationHandler(HWND hwnd, LPARAM param) { 26b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org WindowCapturer::WindowList* list = 27b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org reinterpret_cast<WindowCapturer::WindowList*>(param); 28b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 29b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org // Skip windows that are invisible, minimized, have no title, or are owned, 30b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org // unless they have the app window style set. 31b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org int len = GetWindowTextLength(hwnd); 32b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org HWND owner = GetWindow(hwnd, GW_OWNER); 33b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); 34b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org if (len == 0 || IsIconic(hwnd) || !IsWindowVisible(hwnd) || 35b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org (owner && !(exstyle & WS_EX_APPWINDOW))) { 36b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org return TRUE; 37b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org } 38b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 39b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org // Skip the Program Manager window and the Start button. 40b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org const size_t kClassLength = 256; 41b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org WCHAR class_name[kClassLength]; 42b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org GetClassName(hwnd, class_name, kClassLength); 43b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org // Skip Program Manager window and the Start button. This is the same logic 44b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org // that's used in Win32WindowPicker in libjingle. Consider filtering other 45b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org // windows as well (e.g. toolbars). 46b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org if (wcscmp(class_name, L"Progman") == 0 || wcscmp(class_name, L"Button") == 0) 47b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org return TRUE; 48b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 49b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org WindowCapturer::Window window; 50a590b41c9ae8a41391a0556ae7d2aedbae7d3c38sergeyu@chromium.org window.id = reinterpret_cast<WindowCapturer::WindowId>(hwnd); 51b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 52b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org const size_t kTitleLength = 500; 53b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org WCHAR window_title[kTitleLength]; 54b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org // Truncate the title if it's longer than kTitleLength. 55b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org GetWindowText(hwnd, window_title, kTitleLength); 56047abc93a24134d59b8feb895bbd7597e1aef4cdjiayl@webrtc.org window.title = rtc::ToUtf8(window_title); 57b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 58b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org // Skip windows when we failed to convert the title or it is empty. 59b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org if (window.title.empty()) 60b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org return TRUE; 61b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 62b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org list->push_back(window); 63b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 64b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org return TRUE; 65b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org} 66b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 67b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.orgclass WindowCapturerWin : public WindowCapturer { 68b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org public: 69b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org WindowCapturerWin(); 70b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org virtual ~WindowCapturerWin(); 71b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 72b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org // WindowCapturer interface. 7314665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org bool GetWindowList(WindowList* windows) override; 7414665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org bool SelectWindow(WindowId id) override; 7514665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org bool BringSelectedWindowToFront() override; 76b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 77b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org // DesktopCapturer interface. 7814665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org void Start(Callback* callback) override; 7914665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org void Capture(const DesktopRegion& region) override; 80b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 81b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org private: 82b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org Callback* callback_; 83b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 84b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org // HWND and HDC for the currently selected window or NULL if window is not 85b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org // selected. 86b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org HWND window_; 87b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 88becbefaee6e97f9ca6d478d146b55985fc7b9625sergeyu@chromium.org DesktopSize previous_size_; 89becbefaee6e97f9ca6d478d146b55985fc7b9625sergeyu@chromium.org 90d848d5e74aee56f454311756dc2032fad26d79adJiayang Liu AeroChecker aero_checker_; 91d848d5e74aee56f454311756dc2032fad26d79adJiayang Liu 923c089d751ede283e21e186885eaf705c3257ccd2henrikg RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerWin); 93b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org}; 94b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 95b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.orgWindowCapturerWin::WindowCapturerWin() 96b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org : callback_(NULL), 978d757ac0a21567b177df231b802961b0a2981d07sergeyu@chromium.org window_(NULL) { 98b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org} 99b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 100b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.orgWindowCapturerWin::~WindowCapturerWin() { 101b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org} 102b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 103b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.orgbool WindowCapturerWin::GetWindowList(WindowList* windows) { 104b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org WindowList result; 105b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org LPARAM param = reinterpret_cast<LPARAM>(&result); 106b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org if (!EnumWindows(&WindowsEnumerationHandler, param)) 107b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org return false; 108b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org windows->swap(result); 109b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org return true; 110b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org} 111b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 112b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.orgbool WindowCapturerWin::SelectWindow(WindowId id) { 1138d757ac0a21567b177df231b802961b0a2981d07sergeyu@chromium.org HWND window = reinterpret_cast<HWND>(id); 1148d757ac0a21567b177df231b802961b0a2981d07sergeyu@chromium.org if (!IsWindow(window) || !IsWindowVisible(window) || IsIconic(window)) 115b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org return false; 1168d757ac0a21567b177df231b802961b0a2981d07sergeyu@chromium.org window_ = window; 117becbefaee6e97f9ca6d478d146b55985fc7b9625sergeyu@chromium.org previous_size_.set(0, 0); 118b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org return true; 119b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org} 120b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 121886c94f07cf0a841b81cf9e69783bb1052d9c8a9jiayl@webrtc.orgbool WindowCapturerWin::BringSelectedWindowToFront() { 122886c94f07cf0a841b81cf9e69783bb1052d9c8a9jiayl@webrtc.org if (!window_) 123886c94f07cf0a841b81cf9e69783bb1052d9c8a9jiayl@webrtc.org return false; 124886c94f07cf0a841b81cf9e69783bb1052d9c8a9jiayl@webrtc.org 125886c94f07cf0a841b81cf9e69783bb1052d9c8a9jiayl@webrtc.org if (!IsWindow(window_) || !IsWindowVisible(window_) || IsIconic(window_)) 126886c94f07cf0a841b81cf9e69783bb1052d9c8a9jiayl@webrtc.org return false; 127886c94f07cf0a841b81cf9e69783bb1052d9c8a9jiayl@webrtc.org 128886c94f07cf0a841b81cf9e69783bb1052d9c8a9jiayl@webrtc.org return SetForegroundWindow(window_) != 0; 129886c94f07cf0a841b81cf9e69783bb1052d9c8a9jiayl@webrtc.org} 130886c94f07cf0a841b81cf9e69783bb1052d9c8a9jiayl@webrtc.org 131b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.orgvoid WindowCapturerWin::Start(Callback* callback) { 132b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org assert(!callback_); 133b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org assert(callback); 134b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 135b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org callback_ = callback; 136b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org} 137b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 138b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.orgvoid WindowCapturerWin::Capture(const DesktopRegion& region) { 1398d757ac0a21567b177df231b802961b0a2981d07sergeyu@chromium.org if (!window_) { 140b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org LOG(LS_ERROR) << "Window hasn't been selected: " << GetLastError(); 141b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org callback_->OnCaptureCompleted(NULL); 142b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org return; 143b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org } 144b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 145cc1ba15fe737bfc58ef279d50d7e713cbd8b9310jiayl@webrtc.org // Stop capturing if the window has been closed or hidden. 146cc1ba15fe737bfc58ef279d50d7e713cbd8b9310jiayl@webrtc.org if (!IsWindow(window_) || !IsWindowVisible(window_)) { 147958cdf68f308d5c6e3e10a58cdae40cc0044625bsergeyu@chromium.org callback_->OnCaptureCompleted(NULL); 148958cdf68f308d5c6e3e10a58cdae40cc0044625bsergeyu@chromium.org return; 149958cdf68f308d5c6e3e10a58cdae40cc0044625bsergeyu@chromium.org } 150958cdf68f308d5c6e3e10a58cdae40cc0044625bsergeyu@chromium.org 151d91608dd2ddace8c4c2ce849617228a19e9a082cjiayl@webrtc.org // Return a 1x1 black frame if the window is minimized, to match the behavior 152d91608dd2ddace8c4c2ce849617228a19e9a082cjiayl@webrtc.org // on Mac. 15389959966a9c0eb680da49052e42e3b541da26483jiayl@webrtc.org if (IsIconic(window_)) { 154d91608dd2ddace8c4c2ce849617228a19e9a082cjiayl@webrtc.org BasicDesktopFrame* frame = new BasicDesktopFrame(DesktopSize(1, 1)); 15589959966a9c0eb680da49052e42e3b541da26483jiayl@webrtc.org memset(frame->data(), 0, frame->stride() * frame->size().height()); 15689959966a9c0eb680da49052e42e3b541da26483jiayl@webrtc.org 15789959966a9c0eb680da49052e42e3b541da26483jiayl@webrtc.org previous_size_ = frame->size(); 15889959966a9c0eb680da49052e42e3b541da26483jiayl@webrtc.org callback_->OnCaptureCompleted(frame); 15989959966a9c0eb680da49052e42e3b541da26483jiayl@webrtc.org return; 16089959966a9c0eb680da49052e42e3b541da26483jiayl@webrtc.org } 16189959966a9c0eb680da49052e42e3b541da26483jiayl@webrtc.org 162c8ac17ca04897f8f5fbb5d179e8b7573f66b148ajiayl@webrtc.org DesktopRect original_rect; 163c8ac17ca04897f8f5fbb5d179e8b7573f66b148ajiayl@webrtc.org DesktopRect cropped_rect; 164c8ac17ca04897f8f5fbb5d179e8b7573f66b148ajiayl@webrtc.org if (!GetCroppedWindowRect(window_, &cropped_rect, &original_rect)) { 165c8ac17ca04897f8f5fbb5d179e8b7573f66b148ajiayl@webrtc.org LOG(LS_WARNING) << "Failed to get window info: " << GetLastError(); 166b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org callback_->OnCaptureCompleted(NULL); 167b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org return; 168b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org } 169b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 1708d757ac0a21567b177df231b802961b0a2981d07sergeyu@chromium.org HDC window_dc = GetWindowDC(window_); 1718d757ac0a21567b177df231b802961b0a2981d07sergeyu@chromium.org if (!window_dc) { 1728d757ac0a21567b177df231b802961b0a2981d07sergeyu@chromium.org LOG(LS_WARNING) << "Failed to get window DC: " << GetLastError(); 1738d757ac0a21567b177df231b802961b0a2981d07sergeyu@chromium.org callback_->OnCaptureCompleted(NULL); 1748d757ac0a21567b177df231b802961b0a2981d07sergeyu@chromium.org return; 1758d757ac0a21567b177df231b802961b0a2981d07sergeyu@chromium.org } 1768d757ac0a21567b177df231b802961b0a2981d07sergeyu@chromium.org 17700b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org rtc::scoped_ptr<DesktopFrameWin> frame( 17800b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org DesktopFrameWin::Create(cropped_rect.size(), NULL, window_dc)); 1796a5cc9d8998ec979ea3be1b3378b7b47d6c765e9sergeyu@chromium.org if (!frame.get()) { 1808d757ac0a21567b177df231b802961b0a2981d07sergeyu@chromium.org ReleaseDC(window_, window_dc); 1816a5cc9d8998ec979ea3be1b3378b7b47d6c765e9sergeyu@chromium.org callback_->OnCaptureCompleted(NULL); 1826a5cc9d8998ec979ea3be1b3378b7b47d6c765e9sergeyu@chromium.org return; 1836a5cc9d8998ec979ea3be1b3378b7b47d6c765e9sergeyu@chromium.org } 184b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 1858d757ac0a21567b177df231b802961b0a2981d07sergeyu@chromium.org HDC mem_dc = CreateCompatibleDC(window_dc); 186ad3035fc9e30770392d5f4d955eae08d84562cdesergeyu@chromium.org HGDIOBJ previous_object = SelectObject(mem_dc, frame->bitmap()); 187b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org BOOL result = FALSE; 188b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 189b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org // When desktop composition (Aero) is enabled each window is rendered to a 190b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org // private buffer allowing BitBlt() to get the window content even if the 191b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org // window is occluded. PrintWindow() is slower but lets rendering the window 192b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org // contents to an off-screen device context when Aero is not available. 193b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org // PrintWindow() is not supported by some applications. 194becbefaee6e97f9ca6d478d146b55985fc7b9625sergeyu@chromium.org // 195b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org // If Aero is enabled, we prefer BitBlt() because it's faster and avoids 196b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org // window flickering. Otherwise, we prefer PrintWindow() because BitBlt() may 197b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org // render occluding windows on top of the desired window. 198becbefaee6e97f9ca6d478d146b55985fc7b9625sergeyu@chromium.org // 199becbefaee6e97f9ca6d478d146b55985fc7b9625sergeyu@chromium.org // When composition is enabled the DC returned by GetWindowDC() doesn't always 200becbefaee6e97f9ca6d478d146b55985fc7b9625sergeyu@chromium.org // have window frame rendered correctly. Windows renders it only once and then 201becbefaee6e97f9ca6d478d146b55985fc7b9625sergeyu@chromium.org // caches the result between captures. We hack it around by calling 202f0fc72f70eb9a63565a528aed0c93f9a913cc029jiayl@webrtc.org // PrintWindow() whenever window size changes, including the first time of 203f0fc72f70eb9a63565a528aed0c93f9a913cc029jiayl@webrtc.org // capturing - it somehow affects what we get from BitBlt() on the subsequent 204f0fc72f70eb9a63565a528aed0c93f9a913cc029jiayl@webrtc.org // captures. 205becbefaee6e97f9ca6d478d146b55985fc7b9625sergeyu@chromium.org 206d848d5e74aee56f454311756dc2032fad26d79adJiayang Liu if (!aero_checker_.IsAeroEnabled() || !previous_size_.equals(frame->size())) { 207b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org result = PrintWindow(window_, mem_dc, 0); 208becbefaee6e97f9ca6d478d146b55985fc7b9625sergeyu@chromium.org } 209b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 210b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org // Aero is enabled or PrintWindow() failed, use BitBlt. 211b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org if (!result) { 212b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org result = BitBlt(mem_dc, 0, 0, frame->size().width(), frame->size().height(), 213c8ac17ca04897f8f5fbb5d179e8b7573f66b148ajiayl@webrtc.org window_dc, 214c8ac17ca04897f8f5fbb5d179e8b7573f66b148ajiayl@webrtc.org cropped_rect.left() - original_rect.left(), 215c8ac17ca04897f8f5fbb5d179e8b7573f66b148ajiayl@webrtc.org cropped_rect.top() - original_rect.top(), 216c8ac17ca04897f8f5fbb5d179e8b7573f66b148ajiayl@webrtc.org SRCCOPY); 217b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org } 218b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 219ad3035fc9e30770392d5f4d955eae08d84562cdesergeyu@chromium.org SelectObject(mem_dc, previous_object); 220becbefaee6e97f9ca6d478d146b55985fc7b9625sergeyu@chromium.org DeleteDC(mem_dc); 221becbefaee6e97f9ca6d478d146b55985fc7b9625sergeyu@chromium.org ReleaseDC(window_, window_dc); 222becbefaee6e97f9ca6d478d146b55985fc7b9625sergeyu@chromium.org 223becbefaee6e97f9ca6d478d146b55985fc7b9625sergeyu@chromium.org previous_size_ = frame->size(); 224becbefaee6e97f9ca6d478d146b55985fc7b9625sergeyu@chromium.org 225d402875fa50164c6533ef0f7b2098f73eb94b8a8sergeyu@chromium.org frame->mutable_updated_region()->SetRect( 226d402875fa50164c6533ef0f7b2098f73eb94b8a8sergeyu@chromium.org DesktopRect::MakeSize(frame->size())); 227d402875fa50164c6533ef0f7b2098f73eb94b8a8sergeyu@chromium.org 228b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org if (!result) { 229b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org LOG(LS_ERROR) << "Both PrintWindow() and BitBlt() failed."; 230b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org frame.reset(); 231b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org } 232b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 233b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org callback_->OnCaptureCompleted(frame.release()); 234b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org} 235b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 236b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org} // namespace 237b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 238b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org// static 239894e6fe9ea16a63537ec6d453c81566d02f66059sergeyu@chromium.orgWindowCapturer* WindowCapturer::Create(const DesktopCaptureOptions& options) { 240b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org return new WindowCapturerWin(); 241b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org} 242b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org 243b10ccbec02db00fc17397afb72a115072590d391sergeyu@chromium.org} // namespace webrtc 244