Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(324)

Unified Diff: chrome/browser/ui/panels/taskbar_window_thumbnailer_win.cc

Issue 10408047: Fix bug 105043: Panels [WIN]: For minimize panels, taskbar hover preview show the 4-pixel represent… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix per feedback Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/panels/taskbar_window_thumbnailer_win.cc
diff --git a/chrome/browser/ui/panels/taskbar_window_thumbnailer_win.cc b/chrome/browser/ui/panels/taskbar_window_thumbnailer_win.cc
new file mode 100644
index 0000000000000000000000000000000000000000..9f20f982e96d2c81149ffb156a3e6aa38a70315b
--- /dev/null
+++ b/chrome/browser/ui/panels/taskbar_window_thumbnailer_win.cc
@@ -0,0 +1,129 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/panels/taskbar_window_thumbnailer_win.h"
+
+#include "base/logging.h"
+#include "skia/ext/image_operations.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/gdi_util.h"
+
+namespace {
+
+HBITMAP GetNativeBitmapFromSkBitmap(const SkBitmap& bitmap) {
+ int width = bitmap.width();
+ int height = bitmap.height();
+
+ BITMAPV4HEADER native_bitmap_header;
+ gfx::CreateBitmapV4Header(width, height, &native_bitmap_header);
+
+ HDC dc = ::GetDC(NULL);
+ void* bits;
+ HBITMAP native_bitmap = ::CreateDIBSection(dc,
+ reinterpret_cast<BITMAPINFO*>(&native_bitmap_header),
+ DIB_RGB_COLORS,
+ &bits,
+ NULL,
+ 0);
+ DCHECK(native_bitmap);
+ ::ReleaseDC(NULL, dc);
+ bitmap.copyPixelsTo(bits, width * height * 4, width * 4);
+ return native_bitmap;
+}
+
+void EnableCustomThumbnail(HWND hwnd, bool enable) {
+ BOOL enable_value = enable;
+ ::DwmSetWindowAttribute(hwnd,
+ DWMWA_FORCE_ICONIC_REPRESENTATION,
+ &enable,
+ sizeof(enable_value));
+ ::DwmSetWindowAttribute(hwnd,
+ DWMWA_HAS_ICONIC_BITMAP,
+ &enable,
+ sizeof(enable_value));
+}
+
+} // namespace
+
+
+TaskbarWindowThumbnailerWin::TaskbarWindowThumbnailerWin(HWND hwnd)
+ : hwnd_(hwnd) {
+ capture_bitmap_.reset(CaptureWindowImage());
+ EnableCustomThumbnail(hwnd_, true);
+}
+
+TaskbarWindowThumbnailerWin::~TaskbarWindowThumbnailerWin() {
+ EnableCustomThumbnail(hwnd_, false);
+}
+
+bool TaskbarWindowThumbnailerWin::FilterMessage(HWND hwnd,
+ UINT message,
+ WPARAM w_param,
+ LPARAM l_param,
+ LRESULT* l_result) {
+ DCHECK_EQ(hwnd_, hwnd);
+ switch (message) {
+ case WM_DWMSENDICONICTHUMBNAIL:
+ return OnDwmSendIconicThumbnail(HIWORD(l_param),
+ LOWORD(l_param),
+ l_result);
+ case WM_DWMSENDICONICLIVEPREVIEWBITMAP:
+ return OnDwmSendIconicLivePreviewBitmap(l_result);
+ }
+ return false;
+}
+
+bool TaskbarWindowThumbnailerWin::OnDwmSendIconicThumbnail(
+ int width, int height, LRESULT* l_result) {
+ DCHECK(capture_bitmap_.get());
+
+ SkBitmap* thumbnail_bitmap = capture_bitmap_.get();
+
+ // Scale the image if needed.
+ SkBitmap scaled_bitmap;
+ if (capture_bitmap_->width() != width ||
+ capture_bitmap_->height() != height) {
+ double x_scale = static_cast<double>(width) / capture_bitmap_->width();
+ double y_scale = static_cast<double>(height) / capture_bitmap_->height();
+ double scale = std::min(x_scale, y_scale);
+ width = capture_bitmap_->width() * scale;
+ height = capture_bitmap_->height() * scale;
+ scaled_bitmap = skia::ImageOperations::Resize(
+ *capture_bitmap_, skia::ImageOperations::RESIZE_GOOD, width, height);
+ thumbnail_bitmap = &scaled_bitmap;
+ }
+
+ HBITMAP native_bitmap = GetNativeBitmapFromSkBitmap(*thumbnail_bitmap);
+ ::DwmSetIconicThumbnail(hwnd_, native_bitmap, 0);
+ ::DeleteObject(native_bitmap);
+
+ *l_result = 0;
+ return true;
+}
+
+bool TaskbarWindowThumbnailerWin::OnDwmSendIconicLivePreviewBitmap(
+ LRESULT* l_result) {
+ scoped_ptr<SkBitmap> live_bitmap(CaptureWindowImage());
+ HBITMAP native_bitmap = GetNativeBitmapFromSkBitmap(*live_bitmap);
+ ::DwmSetIconicLivePreviewBitmap(hwnd_, native_bitmap, NULL, 0);
+ ::DeleteObject(native_bitmap);
+
+ *l_result = 0;
+ return true;
+}
+
+SkBitmap* TaskbarWindowThumbnailerWin::CaptureWindowImage() const {
+ RECT bounds;
+ ::GetWindowRect(hwnd_, &bounds);
+ int width = bounds.right - bounds.left;
+ int height = bounds.bottom - bounds.top;
+
+ gfx::Canvas canvas(gfx::Size(width, height), false);
+ HDC target_dc = canvas.BeginPlatformPaint();
+ HDC source_dc = ::GetDC(hwnd_);
+ ::BitBlt(target_dc, 0, 0, width, height, source_dc, 0, 0, SRCCOPY);
+ ::ReleaseDC(hwnd_, source_dc);
+ canvas.EndPlatformPaint();
+ return new SkBitmap(canvas.ExtractBitmap());
+}

Powered by Google App Engine
This is Rietveld 408576698