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.
5 #include "ui/views/controls/native/native_view_host_win.h"
9 #include "base/logging.h"
10 #include "ui/base/win/hidden_window.h"
11 #include "ui/gfx/canvas.h"
12 #include "ui/gfx/win/dpi.h"
13 #include "ui/gfx/win/window_impl.h"
14 #include "ui/views/controls/native/native_view_host.h"
15 #include "ui/views/focus/focus_manager.h"
16 #include "ui/views/widget/native_widget.h"
17 #include "ui/views/widget/root_view.h"
18 #include "ui/views/widget/widget.h"
22 ////////////////////////////////////////////////////////////////////////////////
23 // NativeViewHostWin, public:
25 NativeViewHostWin::NativeViewHostWin(NativeViewHost* host)
27 installed_clip_(false) {
30 NativeViewHostWin::~NativeViewHostWin() {
33 ////////////////////////////////////////////////////////////////////////////////
34 // NativeViewHostWin, NativeViewHostWrapper implementation:
35 void NativeViewHostWin::NativeViewWillAttach() {
36 // First hide the new window. We don't want anything to draw (like sub-hwnd
37 // borders), when NativeViewHost changes the parent.
38 ShowWindow(host_->native_view(), SW_HIDE);
41 void NativeViewHostWin::NativeViewDetaching(bool destroyed) {
45 Widget::ReparentNativeView(host_->native_view(), ui::GetHiddenWindow());
47 installed_clip_ = false;
50 void NativeViewHostWin::AddedToWidget() {
51 if (!IsWindow(host_->native_view()))
53 HWND parent_hwnd = GetParent(host_->native_view());
54 HWND widget_hwnd = host_->GetWidget()->GetNativeView();
55 if (parent_hwnd != widget_hwnd)
56 SetParent(host_->native_view(), widget_hwnd);
58 ShowWindow(host_->native_view(), SW_SHOW);
60 ShowWindow(host_->native_view(), SW_HIDE);
64 void NativeViewHostWin::RemovedFromWidget() {
65 if (!IsWindow(host_->native_view()))
67 ShowWindow(host_->native_view(), SW_HIDE);
68 SetParent(host_->native_view(), NULL);
71 void NativeViewHostWin::InstallClip(int x, int y, int w, int h) {
72 HRGN clip_region = CreateRectRgn(x, y, x + w, y + h);
73 // NOTE: SetWindowRgn owns the region (as well as the deleting the
74 // current region), as such we don't delete the old region.
75 SetWindowRgn(host_->native_view(), clip_region, TRUE);
76 installed_clip_ = true;
79 bool NativeViewHostWin::HasInstalledClip() {
80 return installed_clip_;
83 void NativeViewHostWin::UninstallClip() {
84 SetWindowRgn(host_->native_view(), 0, TRUE);
85 installed_clip_ = false;
88 void NativeViewHostWin::ShowWidget(int x, int y, int w, int h) {
89 UINT swp_flags = SWP_DEFERERASE |
94 gfx::Rect bounds = gfx::win::DIPToScreenRect(gfx::Rect(x,y,w,h));
96 // Only send the SHOWWINDOW flag if we're invisible, to avoid flashing.
97 if (!IsWindowVisible(host_->native_view()))
98 swp_flags = (swp_flags | SWP_SHOWWINDOW) & ~SWP_NOREDRAW;
100 if (host_->fast_resize()) {
101 // In a fast resize, we move the window and clip it with SetWindowRgn.
103 GetWindowRect(host_->native_view(), &win_rect);
104 gfx::Rect rect(win_rect);
105 SetWindowPos(host_->native_view(), 0, bounds.x(), bounds.y(),
106 rect.width(), rect.height(),
109 InstallClip(0, 0, bounds.width(), bounds.height());
111 SetWindowPos(host_->native_view(), 0, bounds.x(), bounds.y(),
112 bounds.width(), bounds.height(), swp_flags);
116 void NativeViewHostWin::HideWidget() {
117 if (!IsWindowVisible(host_->native_view()))
118 return; // Currently not visible, nothing to do.
120 // The window is currently visible, but its clipped by another view. Hide
122 SetWindowPos(host_->native_view(), 0, 0, 0, 0, 0,
123 SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER |
124 SWP_NOREDRAW | SWP_NOOWNERZORDER);
127 void NativeViewHostWin::SetFocus() {
128 ::SetFocus(host_->native_view());
131 gfx::NativeViewAccessible NativeViewHostWin::GetNativeViewAccessible() {
132 HWND hwnd = host_->native_view();
136 IAccessible* accessible = NULL;
137 HRESULT success = ::AccessibleObjectFromWindow(
138 hwnd, OBJID_CLIENT, IID_IAccessible,
139 reinterpret_cast<void**>(&accessible));
141 if (success == S_OK) {
148 ////////////////////////////////////////////////////////////////////////////////
149 // NativeViewHostWrapper, public:
152 NativeViewHostWrapper* NativeViewHostWrapper::CreateWrapper(
153 NativeViewHost* host) {
154 return new NativeViewHostWin(host);