OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 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 "chrome/browser/ui/window_snapshot/window_snapshot.h" |
| 6 |
| 7 #include "base/win/scoped_gdi_object.h" |
| 8 #include "base/win/scoped_hdc.h" |
| 9 #include "gfx/codec/png_codec.h" |
| 10 #include "gfx/gdi_util.h" |
| 11 #include "gfx/rect.h" |
| 12 |
| 13 namespace browser { |
| 14 |
| 15 gfx::Rect GrabWindowSnapshot(gfx::NativeWindow window_handle, |
| 16 std::vector<unsigned char>* png_representation) { |
| 17 // Create a memory DC that's compatible with the window. |
| 18 HDC window_hdc = GetWindowDC(window_handle); |
| 19 base::win::ScopedHDC mem_hdc(CreateCompatibleDC(window_hdc)); |
| 20 |
| 21 // Create a DIB that's the same size as the window. |
| 22 RECT content_rect = {0, 0, 0, 0}; |
| 23 ::GetWindowRect(window_handle, &content_rect); |
| 24 content_rect.right++; // Match what PrintWindow wants. |
| 25 int width = content_rect.right - content_rect.left; |
| 26 int height = content_rect.bottom - content_rect.top; |
| 27 BITMAPINFOHEADER hdr; |
| 28 gfx::CreateBitmapHeader(width, height, &hdr); |
| 29 unsigned char *bit_ptr = NULL; |
| 30 base::win::ScopedBitmap bitmap( |
| 31 CreateDIBSection(mem_hdc, |
| 32 reinterpret_cast<BITMAPINFO*>(&hdr), |
| 33 DIB_RGB_COLORS, |
| 34 reinterpret_cast<void **>(&bit_ptr), |
| 35 NULL, 0)); |
| 36 |
| 37 SelectObject(mem_hdc, bitmap); |
| 38 // Clear the bitmap to white (so that rounded corners on windows |
| 39 // show up on a white background, and strangely-shaped windows |
| 40 // look reasonable). Not capturing an alpha mask saves a |
| 41 // bit of space. |
| 42 PatBlt(mem_hdc, 0, 0, width, height, WHITENESS); |
| 43 // Grab a copy of the window |
| 44 // First, see if PrintWindow is defined (it's not in Windows 2000). |
| 45 typedef BOOL (WINAPI *PrintWindowPointer)(HWND, HDC, UINT); |
| 46 PrintWindowPointer print_window = |
| 47 reinterpret_cast<PrintWindowPointer>( |
| 48 GetProcAddress(GetModuleHandle(L"User32.dll"), "PrintWindow")); |
| 49 |
| 50 // If PrintWindow is defined, use it. It will work on partially |
| 51 // obscured windows, and works better for out of process sub-windows. |
| 52 // Otherwise grab the bits we can get with BitBlt; it's better |
| 53 // than nothing and will work fine in the average case (window is |
| 54 // completely on screen). |
| 55 if (print_window) |
| 56 (*print_window)(window_handle, mem_hdc, 0); |
| 57 else |
| 58 BitBlt(mem_hdc, 0, 0, width, height, window_hdc, 0, 0, SRCCOPY); |
| 59 |
| 60 // We now have a copy of the window contents in a DIB, so |
| 61 // encode it into a useful format for posting to the bug report |
| 62 // server. |
| 63 gfx::PNGCodec::Encode(bit_ptr, gfx::PNGCodec::FORMAT_BGRA, |
| 64 width, height, width * 4, true, |
| 65 png_representation); |
| 66 |
| 67 ReleaseDC(window_handle, window_hdc); |
| 68 |
| 69 return gfx::Rect(width, height); |
| 70 } |
| 71 |
| 72 } // namespace browser |
OLD | NEW |