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

Unified Diff: chrome/browser/views/tabs/hwnd_photobooth.cc

Issue 115475: Refactors HWNDPhotobooth into NativeViewPhotobooth and... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 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
« no previous file with comments | « chrome/browser/views/tabs/hwnd_photobooth.h ('k') | chrome/browser/views/tabs/native_view_photobooth.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/views/tabs/hwnd_photobooth.cc
===================================================================
--- chrome/browser/views/tabs/hwnd_photobooth.cc (revision 16306)
+++ chrome/browser/views/tabs/hwnd_photobooth.cc (working copy)
@@ -1,159 +0,0 @@
-// Copyright (c) 2006-2008 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 "app/gfx/canvas.h"
-#include "base/gfx/point.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/views/tabs/hwnd_photobooth.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "views/widget/widget_win.h"
-
-namespace {
-
-static BOOL CALLBACK MonitorEnumProc(HMONITOR monitor, HDC monitor_dc,
- RECT* monitor_rect, LPARAM data) {
- gfx::Point* point = reinterpret_cast<gfx::Point*>(data);
- if (monitor_rect->right > point->x() && monitor_rect->bottom > point->y()) {
- point->set_x(monitor_rect->right);
- point->set_y(monitor_rect->bottom);
- }
- return TRUE;
-}
-
-gfx::Point GetCaptureWindowPosition() {
- // Since the capture window must be visible to be painted, it must be opened
- // off screen to avoid flashing. But if it is opened completely off-screen
- // (e.g. at 0xFFFFx0xFFFF) then on Windows Vista it will not paint even if it
- // _is_ visible. So we need to find the right/bottommost monitor, and
- // position it so that 1x1 pixel is on-screen on that monitor which is enough
- // to convince Vista to paint it. Don't ask why this is so - this appears to
- // be a regression over XP.
- gfx::Point point(0, 0);
- EnumDisplayMonitors(NULL, NULL, &MonitorEnumProc,
- reinterpret_cast<LPARAM>(&point));
- return gfx::Point(point.x() - 1, point.y() - 1);
-}
-
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// HWNDPhotobooth, public:
-
-HWNDPhotobooth::HWNDPhotobooth(HWND initial_hwnd)
- : capture_window_(NULL),
- current_hwnd_(initial_hwnd) {
- DCHECK(IsWindow(current_hwnd_));
- CreateCaptureWindow(initial_hwnd);
-}
-
-HWNDPhotobooth::~HWNDPhotobooth() {
- // Detach the attached HWND. The creator of the photo-booth is responsible
- // for destroying it.
- ReplaceHWND(NULL);
- capture_window_->Close();
-}
-
-void HWNDPhotobooth::ReplaceHWND(HWND new_hwnd) {
- if (IsWindow(current_hwnd_) &&
- GetParent(current_hwnd_) == capture_window_->GetNativeView()) {
- // We need to hide the window too, so it doesn't show up in the TaskBar or
- // be parented to the desktop.
- ShowWindow(current_hwnd_, SW_HIDE);
- SetParent(current_hwnd_, NULL);
- }
- current_hwnd_ = new_hwnd;
-
- if (IsWindow(new_hwnd)) {
- // Insert the TabContents into the capture window.
- SetParent(current_hwnd_, capture_window_->GetNativeView());
-
- // Show the window (it may not be visible). This is the only safe way of
- // doing this. ShowWindow does not work.
- SetWindowPos(current_hwnd_, NULL, 0, 0, 0, 0,
- SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOCOPYBITS |
- SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOZORDER |
- SWP_SHOWWINDOW | SWP_NOSIZE);
- }
-}
-
-void HWNDPhotobooth::PaintScreenshotIntoCanvas(
- gfx::Canvas* canvas,
- const gfx::Rect& target_bounds) {
- // Our contained window may have been re-parented. Make sure it belongs to
- // us until someone calls ReplaceHWND(NULL).
- if (IsWindow(current_hwnd_) &&
- GetParent(current_hwnd_) != capture_window_->GetNativeView()) {
- ReplaceHWND(current_hwnd_);
- }
-
- // We compel the contained HWND to paint now, synchronously. We do this to
- // populate the device context with valid and current data.
- RedrawWindow(current_hwnd_, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
-
- // Transfer the contents of the layered capture window to the screen-shot
- // canvas' DIB.
- HDC target_dc = canvas->beginPlatformPaint();
- HDC source_dc = GetDC(current_hwnd_);
- RECT window_rect = {0};
- GetWindowRect(current_hwnd_, &window_rect);
- BitBlt(target_dc, target_bounds.x(), target_bounds.y(),
- target_bounds.width(), target_bounds.height(), source_dc, 0, 0,
- SRCCOPY);
- // Windows screws up the alpha channel on all text it draws, and so we need
- // to call makeOpaque _after_ the blit to correct for this.
- canvas->getTopPlatformDevice().makeOpaque(target_bounds.x(),
- target_bounds.y(),
- target_bounds.width(),
- target_bounds.height());
- ReleaseDC(current_hwnd_, source_dc);
- canvas->endPlatformPaint();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// HWNDPhotobooth, private:
-
-void HWNDPhotobooth::CreateCaptureWindow(HWND initial_hwnd) {
- // Snapshotting a HWND is tricky - if the HWND is clipped (e.g. positioned
- // partially off-screen) then just blitting from the HWND' DC to the capture
- // bitmap would be incorrect, since the capture bitmap would show only the
- // visible area of the HWND.
- //
- // The approach turns out to be to create a second layered window in
- // hyperspace the to act as a "photo booth." The window is created with the
- // size of the unclipped HWND, and we attach the HWND as a child, refresh the
- // HWND' by calling |Paint| on it, and then blitting from the HWND's DC to
- // the capture bitmap. This results in the entire unclipped HWND display
- // bitmap being captured.
- //
- // The capture window must be layered so that Windows generates a backing
- // store for it, so that blitting from a child window's DC produces data. If
- // the window is not layered, because it is off-screen Windows does not
- // retain its contents and blitting results in blank data. The capture window
- // is a "basic" (1 level of alpha) layered window because that is the mode
- // that supports having child windows (variable alpha layered windows do not
- // support child HWNDs).
- //
- // This function sets up the off-screen capture window, and attaches the
- // associated HWND to it. Note that the details are important here, see below
- // for further comments.
- //
- CRect contents_rect;
- GetClientRect(initial_hwnd, &contents_rect);
- gfx::Point window_position = GetCaptureWindowPosition();
- gfx::Rect capture_bounds(window_position.x(), window_position.y(),
- contents_rect.Width(), contents_rect.Height());
- capture_window_ = new views::WidgetWin;
- capture_window_->set_window_style(WS_POPUP);
- // WS_EX_TOOLWINDOW ensures the capture window doesn't produce a Taskbar
- // button.
- capture_window_->set_window_ex_style(WS_EX_LAYERED | WS_EX_TOOLWINDOW);
- capture_window_->Init(NULL, capture_bounds, false);
- // If the capture window isn't visible, blitting from the TabContents'
- // HWND's DC to the capture bitmap produces blankness.
- capture_window_->Show();
- SetLayeredWindowAttributes(
- capture_window_->GetNativeView(), RGB(0xFF, 0xFF, 0xFF), 0xFF, LWA_ALPHA);
-
- ReplaceHWND(initial_hwnd);
-}
« no previous file with comments | « chrome/browser/views/tabs/hwnd_photobooth.h ('k') | chrome/browser/views/tabs/native_view_photobooth.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698