OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 "ui/snapshot/snapshot_win.h" | |
6 | |
7 #include "base/callback.h" | |
8 #include "base/win/scoped_gdi_object.h" | |
9 #include "base/win/scoped_hdc.h" | |
10 #include "base/win/scoped_select_object.h" | |
11 #include "ui/gfx/codec/png_codec.h" | |
12 #include "ui/gfx/gdi_util.h" | |
13 #include "ui/gfx/rect.h" | |
14 #include "ui/gfx/size.h" | |
15 #include "ui/snapshot/snapshot.h" | |
16 | |
17 namespace { | |
18 | |
19 gfx::Rect GetWindowBounds(HWND window_handle) { | |
20 RECT content_rect = {0, 0, 0, 0}; | |
21 if (window_handle) { | |
22 ::GetWindowRect(window_handle, &content_rect); | |
23 } else { | |
24 MONITORINFO monitor_info = {}; | |
25 monitor_info.cbSize = sizeof(monitor_info); | |
26 if (GetMonitorInfo(MonitorFromWindow(NULL, MONITOR_DEFAULTTOPRIMARY), | |
27 &monitor_info)) { | |
28 content_rect = monitor_info.rcMonitor; | |
29 } | |
30 } | |
31 content_rect.right++; // Match what PrintWindow wants. | |
32 | |
33 return gfx::Rect(content_rect.right - content_rect.left, | |
34 content_rect.bottom - content_rect.top); | |
35 } | |
36 | |
37 } // namespace | |
38 | |
39 namespace ui { | |
40 | |
41 namespace internal { | |
42 | |
43 bool GrabHwndSnapshot(HWND window_handle, | |
44 const gfx::Rect& snapshot_bounds, | |
45 std::vector<unsigned char>* png_representation) { | |
46 DCHECK(snapshot_bounds.right() <= GetWindowBounds(window_handle).right()); | |
47 DCHECK(snapshot_bounds.bottom() <= GetWindowBounds(window_handle).bottom()); | |
48 | |
49 // Create a memory DC that's compatible with the window. | |
50 HDC window_hdc = GetWindowDC(window_handle); | |
51 base::win::ScopedCreateDC mem_hdc(CreateCompatibleDC(window_hdc)); | |
52 | |
53 BITMAPINFOHEADER hdr; | |
54 gfx::CreateBitmapHeader(snapshot_bounds.width(), | |
55 snapshot_bounds.height(), | |
56 &hdr); | |
57 unsigned char *bit_ptr = NULL; | |
58 base::win::ScopedBitmap bitmap( | |
59 CreateDIBSection(mem_hdc.Get(), | |
60 reinterpret_cast<BITMAPINFO*>(&hdr), | |
61 DIB_RGB_COLORS, | |
62 reinterpret_cast<void **>(&bit_ptr), | |
63 NULL, 0)); | |
64 | |
65 base::win::ScopedSelectObject select_bitmap(mem_hdc.Get(), bitmap); | |
66 // Clear the bitmap to white (so that rounded corners on windows | |
67 // show up on a white background, and strangely-shaped windows | |
68 // look reasonable). Not capturing an alpha mask saves a | |
69 // bit of space. | |
70 PatBlt(mem_hdc.Get(), 0, 0, snapshot_bounds.width(), snapshot_bounds.height(), | |
71 WHITENESS); | |
72 // Grab a copy of the window | |
73 // First, see if PrintWindow is defined (it's not in Windows 2000). | |
74 typedef BOOL (WINAPI *PrintWindowPointer)(HWND, HDC, UINT); | |
75 PrintWindowPointer print_window = | |
76 reinterpret_cast<PrintWindowPointer>( | |
77 GetProcAddress(GetModuleHandle(L"User32.dll"), "PrintWindow")); | |
78 | |
79 // If PrintWindow is defined, use it. It will work on partially | |
80 // obscured windows, and works better for out of process sub-windows. | |
81 // Otherwise grab the bits we can get with BitBlt; it's better | |
82 // than nothing and will work fine in the average case (window is | |
83 // completely on screen). Always BitBlt when grabbing the whole screen. | |
84 if (snapshot_bounds.origin() == gfx::Point() && print_window && window_handle) | |
85 (*print_window)(window_handle, mem_hdc.Get(), 0); | |
86 else | |
87 BitBlt(mem_hdc.Get(), 0, 0, snapshot_bounds.width(), | |
88 snapshot_bounds.height(), window_hdc, snapshot_bounds.x(), | |
89 snapshot_bounds.y(), SRCCOPY); | |
90 | |
91 // We now have a copy of the window contents in a DIB, so | |
92 // encode it into a useful format for posting to the bug report | |
93 // server. | |
94 gfx::PNGCodec::Encode(bit_ptr, gfx::PNGCodec::FORMAT_BGRA, | |
95 snapshot_bounds.size(), | |
96 snapshot_bounds.width() * 4, true, | |
97 std::vector<gfx::PNGCodec::Comment>(), | |
98 png_representation); | |
99 | |
100 ReleaseDC(window_handle, window_hdc); | |
101 | |
102 return true; | |
103 } | |
104 | |
105 } // namespace internal | |
106 | |
107 #if !defined(USE_AURA) | |
108 | |
109 bool GrabViewSnapshot(gfx::NativeView view_handle, | |
110 std::vector<unsigned char>* png_representation, | |
111 const gfx::Rect& snapshot_bounds) { | |
112 return GrabWindowSnapshot(view_handle, png_representation, snapshot_bounds); | |
113 } | |
114 | |
115 bool GrabWindowSnapshot(gfx::NativeWindow window_handle, | |
116 std::vector<unsigned char>* png_representation, | |
117 const gfx::Rect& snapshot_bounds) { | |
118 DCHECK(window_handle); | |
119 return internal::GrabHwndSnapshot(window_handle, snapshot_bounds, | |
120 png_representation); | |
121 } | |
122 | |
123 void GrapWindowSnapshotAsync( | |
124 gfx::NativeWindow window, | |
125 const gfx::Rect& snapshot_bounds, | |
126 const gfx::Size& target_size, | |
127 scoped_refptr<base::TaskRunner> background_task_runner, | |
128 GrabWindowSnapshotAsyncCallback callback) { | |
129 callback.Run(gfx::Image()); | |
130 } | |
131 | |
132 void GrabViewSnapshotAsync( | |
133 gfx::NativeView view, | |
134 const gfx::Rect& source_rect, | |
135 scoped_refptr<base::TaskRunner> background_task_runner, | |
136 const GrabWindowSnapshotAsyncPNGCallback& callback) { | |
137 callback.Run(scoped_refptr<base::RefCountedBytes>()); | |
138 } | |
139 | |
140 | |
141 void GrabWindowSnapshotAsync( | |
142 gfx::NativeWindow window, | |
143 const gfx::Rect& source_rect, | |
144 scoped_refptr<base::TaskRunner> background_task_runner, | |
145 const GrabWindowSnapshotAsyncPNGCallback& callback) { | |
146 callback.Run(scoped_refptr<base::RefCountedBytes>()); | |
147 } | |
148 | |
149 #endif // !defined(USE_AURA) | |
150 | |
151 } // namespace ui | |
OLD | NEW |