- add sources.
[platform/framework/web/crosswalk.git] / src / ui / views / controls / native / native_view_host_win.cc
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/views/controls/native/native_view_host_win.h"
6
7 #include <oleacc.h>
8
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"
19
20 namespace views {
21
22 ////////////////////////////////////////////////////////////////////////////////
23 // NativeViewHostWin, public:
24
25 NativeViewHostWin::NativeViewHostWin(NativeViewHost* host)
26     : host_(host),
27       installed_clip_(false) {
28 }
29
30 NativeViewHostWin::~NativeViewHostWin() {
31 }
32
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);
39 }
40
41 void NativeViewHostWin::NativeViewDetaching(bool destroyed) {
42   if (!destroyed) {
43     if (installed_clip_)
44       UninstallClip();
45     Widget::ReparentNativeView(host_->native_view(), ui::GetHiddenWindow());
46   }
47   installed_clip_ = false;
48 }
49
50 void NativeViewHostWin::AddedToWidget() {
51   if (!IsWindow(host_->native_view()))
52     return;
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);
57   if (host_->IsDrawn())
58     ShowWindow(host_->native_view(), SW_SHOW);
59   else
60     ShowWindow(host_->native_view(), SW_HIDE);
61   host_->Layout();
62 }
63
64 void NativeViewHostWin::RemovedFromWidget() {
65   if (!IsWindow(host_->native_view()))
66     return;
67   ShowWindow(host_->native_view(), SW_HIDE);
68   SetParent(host_->native_view(), NULL);
69 }
70
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;
77 }
78
79 bool NativeViewHostWin::HasInstalledClip() {
80   return installed_clip_;
81 }
82
83 void NativeViewHostWin::UninstallClip() {
84   SetWindowRgn(host_->native_view(), 0, TRUE);
85   installed_clip_ = false;
86 }
87
88 void NativeViewHostWin::ShowWidget(int x, int y, int w, int h) {
89   UINT swp_flags = SWP_DEFERERASE |
90                    SWP_NOACTIVATE |
91                    SWP_NOCOPYBITS |
92                    SWP_NOOWNERZORDER |
93                    SWP_NOZORDER;
94   gfx::Rect bounds = gfx::win::DIPToScreenRect(gfx::Rect(x,y,w,h));
95
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;
99
100   if (host_->fast_resize()) {
101     // In a fast resize, we move the window and clip it with SetWindowRgn.
102     RECT win_rect;
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(),
107                  swp_flags);
108
109     InstallClip(0, 0, bounds.width(), bounds.height());
110   } else {
111     SetWindowPos(host_->native_view(), 0, bounds.x(), bounds.y(),
112                  bounds.width(), bounds.height(), swp_flags);
113   }
114 }
115
116 void NativeViewHostWin::HideWidget() {
117   if (!IsWindowVisible(host_->native_view()))
118     return;  // Currently not visible, nothing to do.
119
120   // The window is currently visible, but its clipped by another view. Hide
121   // it.
122   SetWindowPos(host_->native_view(), 0, 0, 0, 0, 0,
123                SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER |
124                SWP_NOREDRAW | SWP_NOOWNERZORDER);
125 }
126
127 void NativeViewHostWin::SetFocus() {
128   ::SetFocus(host_->native_view());
129 }
130
131 gfx::NativeViewAccessible NativeViewHostWin::GetNativeViewAccessible() {
132   HWND hwnd = host_->native_view();
133   if (!IsWindow(hwnd))
134     return NULL;
135
136   IAccessible* accessible = NULL;
137   HRESULT success = ::AccessibleObjectFromWindow(
138       hwnd, OBJID_CLIENT, IID_IAccessible,
139       reinterpret_cast<void**>(&accessible));
140
141   if (success == S_OK) {
142     return accessible;
143   } else {
144     return NULL;
145   }
146 }
147
148 ////////////////////////////////////////////////////////////////////////////////
149 // NativeViewHostWrapper, public:
150
151 // static
152 NativeViewHostWrapper* NativeViewHostWrapper::CreateWrapper(
153     NativeViewHost* host) {
154   return new NativeViewHostWin(host);
155 }
156
157 }  // namespace views