Fix build break
[chromium-blink-merge.git] / ui / views / widget / native_widget_win.cc
blob8abb6aeab43fe31224f5728722397181d6f62d3c
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/widget/native_widget_win.h"
7 #include <dwmapi.h>
8 #include <shellapi.h>
10 #include <algorithm>
12 #include "base/bind.h"
13 #include "base/string_util.h"
14 #include "base/win/scoped_gdi_object.h"
15 #include "base/win/win_util.h"
16 #include "base/win/windows_version.h"
17 #include "ui/base/dragdrop/drag_drop_types.h"
18 #include "ui/base/dragdrop/drag_source_win.h"
19 #include "ui/base/dragdrop/os_exchange_data.h"
20 #include "ui/base/dragdrop/os_exchange_data_provider_win.h"
21 #include "ui/base/events/event.h"
22 #include "ui/base/keycodes/keyboard_code_conversion_win.h"
23 #include "ui/base/l10n/l10n_util_win.h"
24 #include "ui/base/theme_provider.h"
25 #include "ui/base/view_prop.h"
26 #include "ui/base/win/hwnd_util.h"
27 #include "ui/base/win/mouse_wheel_util.h"
28 #include "ui/base/win/shell.h"
29 #include "ui/gfx/canvas.h"
30 #include "ui/gfx/canvas_paint.h"
31 #include "ui/gfx/canvas_skia_paint.h"
32 #include "ui/gfx/path.h"
33 #include "ui/gfx/screen.h"
34 #include "ui/native_theme/native_theme.h"
35 #include "ui/views/controls/native_control_win.h"
36 #include "ui/views/controls/textfield/textfield.h"
37 #include "ui/views/drag_utils.h"
38 #include "ui/views/focus/accelerator_handler.h"
39 #include "ui/views/focus/view_storage.h"
40 #include "ui/views/focus/widget_focus_manager.h"
41 #include "ui/views/ime/input_method_win.h"
42 #include "ui/views/widget/aero_tooltip_manager.h"
43 #include "ui/views/widget/drop_target_win.h"
44 #include "ui/views/widget/monitor_win.h"
45 #include "ui/views/widget/native_widget_delegate.h"
46 #include "ui/views/widget/root_view.h"
47 #include "ui/views/widget/widget_delegate.h"
48 #include "ui/views/widget/widget_hwnd_utils.h"
49 #include "ui/views/win/fullscreen_handler.h"
50 #include "ui/views/win/hwnd_message_handler.h"
51 #include "ui/views/window/native_frame_view.h"
53 #pragma comment(lib, "dwmapi.lib")
55 using ui::ViewProp;
57 namespace views {
59 namespace {
61 // Enumeration callback for NativeWidget::GetAllChildWidgets(). Called for each
62 // child HWND beneath the original HWND.
63 BOOL CALLBACK EnumerateChildWindowsForNativeWidgets(HWND hwnd, LPARAM l_param) {
64 Widget* widget = Widget::GetWidgetForNativeView(hwnd);
65 if (widget) {
66 Widget::Widgets* widgets = reinterpret_cast<Widget::Widgets*>(l_param);
67 widgets->insert(widget);
69 return TRUE;
72 // Links the HWND to its NativeWidget.
73 const char* const kNativeWidgetKey = "__VIEWS_NATIVE_WIDGET__";
75 const int kDragFrameWindowAlpha = 200;
77 } // namespace
79 ////////////////////////////////////////////////////////////////////////////////
80 // NativeWidgetWin, public:
82 NativeWidgetWin::NativeWidgetWin(internal::NativeWidgetDelegate* delegate)
83 : delegate_(delegate),
84 ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET),
85 has_non_client_view_(false),
86 ALLOW_THIS_IN_INITIALIZER_LIST(
87 message_handler_(new HWNDMessageHandler(this))) {
90 NativeWidgetWin::~NativeWidgetWin() {
91 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
92 delete delegate_;
93 else
94 CloseNow();
95 message_handler_.reset();
98 // static
99 gfx::Font NativeWidgetWin::GetWindowTitleFont() {
100 NONCLIENTMETRICS ncm;
101 base::win::GetNonClientMetrics(&ncm);
102 l10n_util::AdjustUIFont(&(ncm.lfCaptionFont));
103 base::win::ScopedHFONT caption_font(CreateFontIndirect(&(ncm.lfCaptionFont)));
104 return gfx::Font(caption_font);
107 void NativeWidgetWin::Show(int show_state) {
108 message_handler_->Show(show_state);
111 ////////////////////////////////////////////////////////////////////////////////
112 // NativeWidgetWin, NativeWidget implementation:
114 void NativeWidgetWin::InitNativeWidget(const Widget::InitParams& params) {
115 SetInitParams(params);
116 message_handler_->Init(params.parent, params.bounds);
119 NonClientFrameView* NativeWidgetWin::CreateNonClientFrameView() {
120 return GetWidget()->ShouldUseNativeFrame() ?
121 new NativeFrameView(GetWidget()) : NULL;
124 bool NativeWidgetWin::ShouldUseNativeFrame() const {
125 return ui::win::IsAeroGlassEnabled();
128 void NativeWidgetWin::FrameTypeChanged() {
129 message_handler_->FrameTypeChanged();
132 Widget* NativeWidgetWin::GetWidget() {
133 return delegate_->AsWidget();
136 const Widget* NativeWidgetWin::GetWidget() const {
137 return delegate_->AsWidget();
140 gfx::NativeView NativeWidgetWin::GetNativeView() const {
141 return message_handler_->hwnd();
144 gfx::NativeWindow NativeWidgetWin::GetNativeWindow() const {
145 return message_handler_->hwnd();
148 Widget* NativeWidgetWin::GetTopLevelWidget() {
149 NativeWidgetPrivate* native_widget = GetTopLevelNativeWidget(GetNativeView());
150 return native_widget ? native_widget->GetWidget() : NULL;
153 const ui::Compositor* NativeWidgetWin::GetCompositor() const {
154 return NULL;
157 ui::Compositor* NativeWidgetWin::GetCompositor() {
158 return NULL;
161 gfx::Vector2d NativeWidgetWin::CalculateOffsetToAncestorWithLayer(
162 ui::Layer** layer_parent) {
163 return gfx::Vector2d();
166 void NativeWidgetWin::ViewRemoved(View* view) {
167 if (drop_target_.get())
168 drop_target_->ResetTargetViewIfEquals(view);
171 void NativeWidgetWin::SetNativeWindowProperty(const char* name, void* value) {
172 // Remove the existing property (if any).
173 for (ViewProps::iterator i = props_.begin(); i != props_.end(); ++i) {
174 if ((*i)->Key() == name) {
175 props_.erase(i);
176 break;
180 if (value)
181 props_.push_back(new ViewProp(GetNativeView(), name, value));
184 void* NativeWidgetWin::GetNativeWindowProperty(const char* name) const {
185 return ViewProp::GetValue(GetNativeView(), name);
188 TooltipManager* NativeWidgetWin::GetTooltipManager() const {
189 return tooltip_manager_.get();
192 void NativeWidgetWin::SetCapture() {
193 message_handler_->SetCapture();
196 void NativeWidgetWin::ReleaseCapture() {
197 message_handler_->ReleaseCapture();
200 bool NativeWidgetWin::HasCapture() const {
201 return message_handler_->HasCapture();
204 InputMethod* NativeWidgetWin::CreateInputMethod() {
205 return new InputMethodWin(GetMessageHandler(), GetNativeWindow(), NULL);
208 internal::InputMethodDelegate* NativeWidgetWin::GetInputMethodDelegate() {
209 return message_handler_.get();
212 void NativeWidgetWin::CenterWindow(const gfx::Size& size) {
213 message_handler_->CenterWindow(size);
216 void NativeWidgetWin::GetWindowPlacement(
217 gfx::Rect* bounds,
218 ui::WindowShowState* show_state) const {
219 message_handler_->GetWindowPlacement(bounds, show_state);
222 void NativeWidgetWin::SetWindowTitle(const string16& title) {
223 message_handler_->SetTitle(title);
226 void NativeWidgetWin::SetWindowIcons(const gfx::ImageSkia& window_icon,
227 const gfx::ImageSkia& app_icon) {
228 message_handler_->SetWindowIcons(window_icon, app_icon);
231 void NativeWidgetWin::InitModalType(ui::ModalType modal_type) {
232 message_handler_->InitModalType(modal_type);
235 gfx::Rect NativeWidgetWin::GetWindowBoundsInScreen() const {
236 return message_handler_->GetWindowBoundsInScreen();
239 gfx::Rect NativeWidgetWin::GetClientAreaBoundsInScreen() const {
240 return message_handler_->GetClientAreaBoundsInScreen();
243 gfx::Rect NativeWidgetWin::GetRestoredBounds() const {
244 return message_handler_->GetRestoredBounds();
247 void NativeWidgetWin::SetBounds(const gfx::Rect& bounds) {
248 message_handler_->SetBounds(bounds);
251 void NativeWidgetWin::SetSize(const gfx::Size& size) {
252 message_handler_->SetSize(size);
255 void NativeWidgetWin::StackAbove(gfx::NativeView native_view) {
256 message_handler_->StackAbove(native_view);
259 void NativeWidgetWin::StackAtTop() {
260 message_handler_->StackAtTop();
263 void NativeWidgetWin::StackBelow(gfx::NativeView native_view) {
264 NOTIMPLEMENTED();
267 void NativeWidgetWin::SetShape(gfx::NativeRegion region) {
268 message_handler_->SetRegion(region);
271 void NativeWidgetWin::Close() {
272 message_handler_->Close();
275 void NativeWidgetWin::CloseNow() {
276 message_handler_->CloseNow();
279 void NativeWidgetWin::Show() {
280 message_handler_->Show();
283 void NativeWidgetWin::Hide() {
284 message_handler_->Hide();
287 void NativeWidgetWin::ShowMaximizedWithBounds(
288 const gfx::Rect& restored_bounds) {
289 message_handler_->ShowMaximizedWithBounds(restored_bounds);
292 void NativeWidgetWin::ShowWithWindowState(ui::WindowShowState show_state) {
293 message_handler_->ShowWindowWithState(show_state);
296 bool NativeWidgetWin::IsVisible() const {
297 return message_handler_->IsVisible();
300 void NativeWidgetWin::Activate() {
301 message_handler_->Activate();
304 void NativeWidgetWin::Deactivate() {
305 message_handler_->Deactivate();
308 bool NativeWidgetWin::IsActive() const {
309 return message_handler_->IsActive();
312 void NativeWidgetWin::SetAlwaysOnTop(bool on_top) {
313 message_handler_->SetAlwaysOnTop(on_top);
316 void NativeWidgetWin::Maximize() {
317 message_handler_->Maximize();
320 void NativeWidgetWin::Minimize() {
321 message_handler_->Minimize();
324 bool NativeWidgetWin::IsMaximized() const {
325 return message_handler_->IsMaximized();
328 bool NativeWidgetWin::IsMinimized() const {
329 return message_handler_->IsMinimized();
332 void NativeWidgetWin::Restore() {
333 message_handler_->Restore();
336 void NativeWidgetWin::SetFullscreen(bool fullscreen) {
337 message_handler_->fullscreen_handler()->SetFullscreen(fullscreen);
340 void NativeWidgetWin::SetMetroSnapFullscreen(bool metro_snap) {
341 message_handler_->fullscreen_handler()->SetMetroSnap(metro_snap);
344 bool NativeWidgetWin::IsFullscreen() const {
345 return message_handler_->fullscreen_handler()->fullscreen();
348 bool NativeWidgetWin::IsInMetroSnapMode() const {
349 return message_handler_->fullscreen_handler()->metro_snap();
352 void NativeWidgetWin::SetCanUpdateLayeredWindow(bool can_update) {
353 message_handler_->set_can_update_layered_window(can_update);
356 void NativeWidgetWin::SetOpacity(unsigned char opacity) {
357 message_handler_->SetOpacity(static_cast<BYTE>(opacity));
358 GetWidget()->GetRootView()->SchedulePaint();
361 void NativeWidgetWin::SetUseDragFrame(bool use_drag_frame) {
362 if (use_drag_frame) {
363 // Make the frame slightly transparent during the drag operation.
364 drag_frame_saved_window_style_ = GetWindowLong(GetNativeView(), GWL_STYLE);
365 drag_frame_saved_window_ex_style_ =
366 GetWindowLong(GetNativeView(), GWL_EXSTYLE);
367 SetWindowLong(GetNativeView(), GWL_EXSTYLE,
368 drag_frame_saved_window_ex_style_ | WS_EX_LAYERED);
369 // Remove the captions tyle so the window doesn't have window controls for a
370 // more "transparent" look.
371 SetWindowLong(GetNativeView(), GWL_STYLE,
372 drag_frame_saved_window_style_ & ~WS_CAPTION);
373 SetLayeredWindowAttributes(GetNativeView(), RGB(0xFF, 0xFF, 0xFF),
374 kDragFrameWindowAlpha, LWA_ALPHA);
375 } else {
376 SetWindowLong(GetNativeView(), GWL_STYLE, drag_frame_saved_window_style_);
377 SetWindowLong(GetNativeView(), GWL_EXSTYLE,
378 drag_frame_saved_window_ex_style_);
382 void NativeWidgetWin::FlashFrame(bool flash) {
383 message_handler_->FlashFrame(flash);
386 void NativeWidgetWin::RunShellDrag(View* view,
387 const ui::OSExchangeData& data,
388 const gfx::Point& location,
389 int operation,
390 ui::DragDropTypes::DragEventSource source) {
391 views::RunShellDrag(NULL, data, location, operation, source);
394 void NativeWidgetWin::SchedulePaintInRect(const gfx::Rect& rect) {
395 message_handler_->SchedulePaintInRect(rect);
398 void NativeWidgetWin::SetCursor(gfx::NativeCursor cursor) {
399 message_handler_->SetCursor(cursor);
402 void NativeWidgetWin::ClearNativeFocus() {
403 message_handler_->ClearNativeFocus();
406 gfx::Rect NativeWidgetWin::GetWorkAreaBoundsInScreen() const {
407 return gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
408 GetNativeView()).work_area();
411 void NativeWidgetWin::SetInactiveRenderingDisabled(bool value) {
414 Widget::MoveLoopResult NativeWidgetWin::RunMoveLoop(
415 const gfx::Vector2d& drag_offset,
416 Widget::MoveLoopSource source) {
417 return message_handler_->RunMoveLoop(drag_offset) ?
418 Widget::MOVE_LOOP_SUCCESSFUL : Widget::MOVE_LOOP_CANCELED;
421 void NativeWidgetWin::EndMoveLoop() {
422 message_handler_->EndMoveLoop();
425 void NativeWidgetWin::SetVisibilityChangedAnimationsEnabled(bool value) {
426 message_handler_->SetVisibilityChangedAnimationsEnabled(value);
429 ui::NativeTheme* NativeWidgetWin::GetNativeTheme() const {
430 return ui::NativeTheme::instance();
433 ////////////////////////////////////////////////////////////////////////////////
434 // NativeWidgetWin, protected:
436 void NativeWidgetWin::OnFinalMessage(HWND window) {
437 // We don't destroy props in WM_DESTROY as we may still get messages after
438 // WM_DESTROY that assume the properties are still valid (such as WM_CLOSE).
439 props_.clear();
440 delegate_->OnNativeWidgetDestroyed();
441 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
442 delete this;
445 ////////////////////////////////////////////////////////////////////////////////
446 // NativeWidgetWin, protected:
448 HWNDMessageHandler* NativeWidgetWin::GetMessageHandler() {
449 return message_handler_.get();
452 ////////////////////////////////////////////////////////////////////////////////
453 // NativeWidgetWin, HWNDMessageHandlerDelegate implementation:
455 bool NativeWidgetWin::IsWidgetWindow() const {
456 // We don't NULL check GetWidget()->non_client_view() here because this
457 // function can be called before the widget is fully constructed.
458 return has_non_client_view_;
461 bool NativeWidgetWin::IsUsingCustomFrame() const {
462 return !GetWidget()->ShouldUseNativeFrame();
465 void NativeWidgetWin::SchedulePaint() {
466 GetWidget()->GetRootView()->SchedulePaint();
469 void NativeWidgetWin::EnableInactiveRendering() {
470 delegate_->EnableInactiveRendering();
473 bool NativeWidgetWin::IsInactiveRenderingDisabled() {
474 return delegate_->IsInactiveRenderingDisabled();
477 bool NativeWidgetWin::CanResize() const {
478 return GetWidget()->widget_delegate()->CanResize();
481 bool NativeWidgetWin::CanMaximize() const {
482 return GetWidget()->widget_delegate()->CanMaximize();
485 bool NativeWidgetWin::CanActivate() const {
486 return delegate_->CanActivate();
489 bool NativeWidgetWin::WidgetSizeIsClientSize() const {
490 const Widget* widget = GetWidget()->GetTopLevelWidget();
491 return IsZoomed(GetNativeView()) ||
492 (widget && widget->ShouldUseNativeFrame());
495 bool NativeWidgetWin::CanSaveFocus() const {
496 return GetWidget()->is_top_level();
499 void NativeWidgetWin::SaveFocusOnDeactivate() {
500 GetWidget()->GetFocusManager()->StoreFocusedView(true);
503 void NativeWidgetWin::RestoreFocusOnActivate() {
504 RestoreFocusOnEnable();
507 void NativeWidgetWin::RestoreFocusOnEnable() {
508 GetWidget()->GetFocusManager()->RestoreFocusedView();
511 bool NativeWidgetWin::IsModal() const {
512 return delegate_->IsModal();
515 int NativeWidgetWin::GetInitialShowState() const {
516 return SW_SHOWNORMAL;
519 bool NativeWidgetWin::WillProcessWorkAreaChange() const {
520 return GetWidget()->widget_delegate()->WillProcessWorkAreaChange();
523 int NativeWidgetWin::GetNonClientComponent(const gfx::Point& point) const {
524 return delegate_->GetNonClientComponent(point);
527 void NativeWidgetWin::GetWindowMask(const gfx::Size& size, gfx::Path* path) {
528 if (GetWidget()->non_client_view())
529 GetWidget()->non_client_view()->GetWindowMask(size, path);
532 bool NativeWidgetWin::GetClientAreaInsets(gfx::Insets* insets) const {
533 return false;
536 void NativeWidgetWin::GetMinMaxSize(gfx::Size* min_size,
537 gfx::Size* max_size) const {
538 *min_size = delegate_->GetMinimumSize();
539 *max_size = delegate_->GetMaximumSize();
542 gfx::Size NativeWidgetWin::GetRootViewSize() const {
543 return GetWidget()->GetRootView()->size();
546 void NativeWidgetWin::ResetWindowControls() {
547 GetWidget()->non_client_view()->ResetWindowControls();
550 void NativeWidgetWin::PaintLayeredWindow(gfx::Canvas* canvas) {
551 GetWidget()->GetRootView()->Paint(canvas);
554 InputMethod* NativeWidgetWin::GetInputMethod() {
555 return GetWidget()->GetInputMethodDirect();
558 gfx::NativeViewAccessible NativeWidgetWin::GetNativeViewAccessible() {
559 return GetWidget()->GetRootView()->GetNativeViewAccessible();
562 bool NativeWidgetWin::ShouldHandleSystemCommands() const {
563 return GetWidget()->widget_delegate()->ShouldHandleSystemCommands();
566 void NativeWidgetWin::HandleAppDeactivated() {
567 if (IsInactiveRenderingDisabled()) {
568 delegate_->EnableInactiveRendering();
569 } else {
570 // TODO(pkotwicz): Remove need for SchedulePaint(). crbug.com/165841
571 View* non_client_view = GetWidget()->non_client_view();
572 if (non_client_view)
573 non_client_view->SchedulePaint();
577 void NativeWidgetWin::HandleActivationChanged(bool active) {
578 delegate_->OnNativeWidgetActivationChanged(active);
581 bool NativeWidgetWin::HandleAppCommand(short command) {
582 // We treat APPCOMMAND ids as an extension of our command namespace, and just
583 // let the delegate figure out what to do...
584 return GetWidget()->widget_delegate() &&
585 GetWidget()->widget_delegate()->ExecuteWindowsCommand(command);
588 void NativeWidgetWin::HandleCancelMode() {
591 void NativeWidgetWin::HandleCaptureLost() {
592 delegate_->OnMouseCaptureLost();
595 void NativeWidgetWin::HandleClose() {
596 GetWidget()->Close();
599 bool NativeWidgetWin::HandleCommand(int command) {
600 return GetWidget()->widget_delegate()->ExecuteWindowsCommand(command);
603 void NativeWidgetWin::HandleAccelerator(const ui::Accelerator& accelerator) {
604 GetWidget()->GetFocusManager()->ProcessAccelerator(accelerator);
607 void NativeWidgetWin::HandleCreate() {
608 // TODO(beng): much of this could/should maybe move to HWNDMessageHandler.
610 SetNativeWindowProperty(kNativeWidgetKey, this);
611 CHECK_EQ(this, GetNativeWidgetForNativeView(GetNativeView()));
613 props_.push_back(ui::SetWindowSupportsRerouteMouseWheel(GetNativeView()));
615 drop_target_ = new DropTargetWin(
616 static_cast<internal::RootView*>(GetWidget()->GetRootView()));
618 // Windows special DWM window frame requires a special tooltip manager so
619 // that window controls in Chrome windows don't flicker when you move your
620 // mouse over them. See comment in aero_tooltip_manager.h.
621 Widget* widget = GetWidget()->GetTopLevelWidget();
622 if (widget && widget->ShouldUseNativeFrame()) {
623 tooltip_manager_.reset(new AeroTooltipManager(GetWidget()));
624 } else {
625 tooltip_manager_.reset(new TooltipManagerWin(GetWidget()));
627 if (!tooltip_manager_->Init()) {
628 // There was a problem creating the TooltipManager. Common error is 127.
629 // See 82193 for details.
630 LOG_GETLASTERROR(WARNING) << "tooltip creation failed, disabling tooltips";
631 tooltip_manager_.reset();
634 delegate_->OnNativeWidgetCreated();
637 void NativeWidgetWin::HandleDestroying() {
638 delegate_->OnNativeWidgetDestroying();
639 if (drop_target_.get()) {
640 RevokeDragDrop(GetNativeView());
641 drop_target_ = NULL;
645 void NativeWidgetWin::HandleDestroyed() {
646 OnFinalMessage(GetNativeView());
649 bool NativeWidgetWin::HandleInitialFocus() {
650 return GetWidget()->SetInitialFocus();
653 void NativeWidgetWin::HandleDisplayChange() {
654 GetWidget()->widget_delegate()->OnDisplayChanged();
657 void NativeWidgetWin::HandleBeginWMSizeMove() {
658 delegate_->OnNativeWidgetBeginUserBoundsChange();
661 void NativeWidgetWin::HandleEndWMSizeMove() {
662 delegate_->OnNativeWidgetEndUserBoundsChange();
665 void NativeWidgetWin::HandleMove() {
666 delegate_->OnNativeWidgetMove();
669 void NativeWidgetWin::HandleWorkAreaChanged() {
670 GetWidget()->widget_delegate()->OnWorkAreaChanged();
673 void NativeWidgetWin::HandleVisibilityChanged(bool visible) {
674 delegate_->OnNativeWidgetVisibilityChanged(visible);
677 void NativeWidgetWin::HandleClientSizeChanged(const gfx::Size& new_size) {
678 delegate_->OnNativeWidgetSizeChanged(new_size);
681 void NativeWidgetWin::HandleFrameChanged() {
682 // Replace the frame and layout the contents.
683 GetWidget()->non_client_view()->UpdateFrame(true);
686 void NativeWidgetWin::HandleNativeFocus(HWND last_focused_window) {
687 delegate_->OnNativeFocus(last_focused_window);
688 InputMethod* input_method = GetInputMethod();
689 if (input_method)
690 input_method->OnFocus();
693 void NativeWidgetWin::HandleNativeBlur(HWND focused_window) {
694 delegate_->OnNativeBlur(focused_window);
695 InputMethod* input_method = GetInputMethod();
696 if (input_method)
697 input_method->OnBlur();
700 bool NativeWidgetWin::HandleMouseEvent(const ui::MouseEvent& event) {
701 delegate_->OnMouseEvent(const_cast<ui::MouseEvent*>(&event));
702 return event.handled();
705 bool NativeWidgetWin::HandleKeyEvent(const ui::KeyEvent& event) {
706 delegate_->OnKeyEvent(const_cast<ui::KeyEvent*>(&event));
707 return event.handled();
710 bool NativeWidgetWin::HandleUntranslatedKeyEvent(const ui::KeyEvent& event) {
711 InputMethod* input_method = GetInputMethod();
712 if (input_method)
713 input_method->DispatchKeyEvent(event);
714 return !!input_method;
717 bool NativeWidgetWin::HandleTouchEvent(const ui::TouchEvent& event) {
718 NOTREACHED() << "Touch events are not supported";
719 return false;
722 bool NativeWidgetWin::HandleIMEMessage(UINT message,
723 WPARAM w_param,
724 LPARAM l_param,
725 LRESULT* result) {
726 InputMethod* input_method = GetInputMethod();
727 if (!input_method || input_method->IsMock()) {
728 *result = 0;
729 return false;
732 InputMethodWin* ime_win = static_cast<InputMethodWin*>(input_method);
733 BOOL handled = FALSE;
734 *result = ime_win->OnImeMessages(message, w_param, l_param, &handled);
735 return !!handled;
738 void NativeWidgetWin::HandleInputLanguageChange(DWORD character_set,
739 HKL input_language_id) {
740 InputMethod* input_method = GetInputMethod();
741 if (input_method && !input_method->IsMock()) {
742 static_cast<InputMethodWin*>(input_method)->OnInputLangChange(
743 character_set, input_language_id);
747 bool NativeWidgetWin::HandlePaintAccelerated(const gfx::Rect& invalid_rect) {
748 return delegate_->OnNativeWidgetPaintAccelerated(gfx::Rect(invalid_rect));
751 void NativeWidgetWin::HandlePaint(gfx::Canvas* canvas) {
752 delegate_->OnNativeWidgetPaint(canvas);
755 bool NativeWidgetWin::HandleTooltipNotify(int w_param,
756 NMHDR* l_param,
757 LRESULT* l_result) {
758 // We can be sent this message before the tooltip manager is created, if a
759 // subclass overrides OnCreate and creates some kind of Windows control there
760 // that sends WM_NOTIFY messages.
761 if (tooltip_manager_.get()) {
762 bool handled;
763 *l_result = tooltip_manager_->OnNotify(w_param, l_param, &handled);
764 return handled;
766 return false;
769 void NativeWidgetWin::HandleTooltipMouseMove(UINT message,
770 WPARAM w_param,
771 LPARAM l_param) {
772 if (tooltip_manager_.get())
773 tooltip_manager_->OnMouse(message, w_param, l_param);
776 bool NativeWidgetWin::PreHandleMSG(UINT message,
777 WPARAM w_param,
778 LPARAM l_param,
779 LRESULT* result) {
780 return false;
783 void NativeWidgetWin::PostHandleMSG(UINT message,
784 WPARAM w_param,
785 LPARAM l_param) {
788 ////////////////////////////////////////////////////////////////////////////////
789 // NativeWidgetWin, private:
791 void NativeWidgetWin::SetInitParams(const Widget::InitParams& params) {
792 // Set non-style attributes.
793 ownership_ = params.ownership;
795 ConfigureWindowStyles(message_handler_.get(), params,
796 GetWidget()->widget_delegate(), delegate_);
798 has_non_client_view_ = Widget::RequiresNonClientView(params.type);
799 message_handler_->set_remove_standard_frame(params.remove_standard_frame);
800 message_handler_->set_use_system_default_icon(params.use_system_default_icon);
803 ////////////////////////////////////////////////////////////////////////////////
804 // Widget, public:
806 // static
807 void Widget::NotifyLocaleChanged() {
808 NOTIMPLEMENTED();
811 namespace {
812 BOOL CALLBACK WindowCallbackProc(HWND hwnd, LPARAM lParam) {
813 Widget* widget = Widget::GetWidgetForNativeView(hwnd);
814 if (widget && widget->is_secondary_widget())
815 widget->Close();
816 return TRUE;
818 } // namespace
820 // static
821 void Widget::CloseAllSecondaryWidgets() {
822 EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, 0);
825 bool Widget::ConvertRect(const Widget* source,
826 const Widget* target,
827 gfx::Rect* rect) {
828 DCHECK(source);
829 DCHECK(target);
830 DCHECK(rect);
832 HWND source_hwnd = source->GetNativeView();
833 HWND target_hwnd = target->GetNativeView();
834 if (source_hwnd == target_hwnd)
835 return true;
837 RECT win_rect = rect->ToRECT();
838 if (::MapWindowPoints(source_hwnd, target_hwnd,
839 reinterpret_cast<LPPOINT>(&win_rect),
840 sizeof(RECT)/sizeof(POINT))) {
841 *rect = gfx::Rect(win_rect);
842 return true;
844 return false;
847 namespace internal {
849 ////////////////////////////////////////////////////////////////////////////////
850 // internal::NativeWidgetPrivate, public:
852 // static
853 NativeWidgetPrivate* NativeWidgetPrivate::CreateNativeWidget(
854 internal::NativeWidgetDelegate* delegate) {
855 return new NativeWidgetWin(delegate);
858 // static
859 NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeView(
860 gfx::NativeView native_view) {
861 return reinterpret_cast<NativeWidgetWin*>(
862 ViewProp::GetValue(native_view, kNativeWidgetKey));
865 // static
866 NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeWindow(
867 gfx::NativeWindow native_window) {
868 return GetNativeWidgetForNativeView(native_window);
871 // static
872 NativeWidgetPrivate* NativeWidgetPrivate::GetTopLevelNativeWidget(
873 gfx::NativeView native_view) {
874 if (!native_view)
875 return NULL;
877 // First, check if the top-level window is a Widget.
878 HWND root = ::GetAncestor(native_view, GA_ROOT);
879 if (!root)
880 return NULL;
882 NativeWidgetPrivate* widget = GetNativeWidgetForNativeView(root);
883 if (widget)
884 return widget;
886 // Second, try to locate the last Widget window in the parent hierarchy.
887 HWND parent_hwnd = native_view;
888 // If we fail to find the native widget pointer for the root then it probably
889 // means that the root belongs to a different process in which case we walk up
890 // the native view chain looking for a parent window which corresponds to a
891 // valid native widget. We only do this if we fail to find the native widget
892 // for the current native view which means it is being destroyed.
893 if (!widget && !GetNativeWidgetForNativeView(native_view)) {
894 parent_hwnd = ::GetAncestor(parent_hwnd, GA_PARENT);
895 if (!parent_hwnd)
896 return NULL;
898 NativeWidgetPrivate* parent_widget;
899 do {
900 parent_widget = GetNativeWidgetForNativeView(parent_hwnd);
901 if (parent_widget) {
902 widget = parent_widget;
903 parent_hwnd = ::GetAncestor(parent_hwnd, GA_PARENT);
905 } while (parent_hwnd != NULL && parent_widget != NULL);
907 return widget;
910 // static
911 void NativeWidgetPrivate::GetAllChildWidgets(gfx::NativeView native_view,
912 Widget::Widgets* children) {
913 if (!native_view)
914 return;
916 Widget* widget = Widget::GetWidgetForNativeView(native_view);
917 if (widget)
918 children->insert(widget);
919 EnumChildWindows(native_view, EnumerateChildWindowsForNativeWidgets,
920 reinterpret_cast<LPARAM>(children));
923 // static
924 void NativeWidgetPrivate::ReparentNativeView(gfx::NativeView native_view,
925 gfx::NativeView new_parent) {
926 if (!native_view)
927 return;
929 HWND previous_parent = ::GetParent(native_view);
930 if (previous_parent == new_parent)
931 return;
933 Widget::Widgets widgets;
934 GetAllChildWidgets(native_view, &widgets);
936 // First notify all the widgets that they are being disassociated
937 // from their previous parent.
938 for (Widget::Widgets::iterator it = widgets.begin();
939 it != widgets.end(); ++it) {
940 // TODO(beng): Rename this notification to NotifyNativeViewChanging()
941 // and eliminate the bool parameter.
942 (*it)->NotifyNativeViewHierarchyChanged(false, previous_parent);
945 ::SetParent(native_view, new_parent);
947 // And now, notify them that they have a brand new parent.
948 for (Widget::Widgets::iterator it = widgets.begin();
949 it != widgets.end(); ++it) {
950 (*it)->NotifyNativeViewHierarchyChanged(true, new_parent);
954 // static
955 bool NativeWidgetPrivate::IsMouseButtonDown() {
956 return (GetKeyState(VK_LBUTTON) & 0x80) ||
957 (GetKeyState(VK_RBUTTON) & 0x80) ||
958 (GetKeyState(VK_MBUTTON) & 0x80) ||
959 (GetKeyState(VK_XBUTTON1) & 0x80) ||
960 (GetKeyState(VK_XBUTTON2) & 0x80);
963 // static
964 bool NativeWidgetPrivate::IsTouchDown() {
965 // This currently isn't necessary because we're not generating touch events on
966 // windows. When we do, this will need to be updated.
967 return false;
970 } // namespace internal
972 } // namespace views