| OLD | NEW |
| (Empty) |
| 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/widget/widget_hwnd_utils.h" | |
| 6 | |
| 7 #include <dwmapi.h> | |
| 8 | |
| 9 #include "base/command_line.h" | |
| 10 #include "base/win/windows_version.h" | |
| 11 #include "ui/base/l10n/l10n_util_win.h" | |
| 12 #include "ui/base/ui_base_switches.h" | |
| 13 #include "ui/views/widget/widget_delegate.h" | |
| 14 #include "ui/views/win/hwnd_message_handler.h" | |
| 15 | |
| 16 #if defined(OS_WIN) | |
| 17 #include "ui/base/win/shell.h" | |
| 18 #endif | |
| 19 | |
| 20 namespace views { | |
| 21 | |
| 22 namespace { | |
| 23 | |
| 24 void CalculateWindowStylesFromInitParams( | |
| 25 const Widget::InitParams& params, | |
| 26 WidgetDelegate* widget_delegate, | |
| 27 internal::NativeWidgetDelegate* native_widget_delegate, | |
| 28 DWORD* style, | |
| 29 DWORD* ex_style, | |
| 30 DWORD* class_style) { | |
| 31 *style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS; | |
| 32 *ex_style = 0; | |
| 33 *class_style = CS_DBLCLKS; | |
| 34 | |
| 35 // Set type-independent style attributes. | |
| 36 if (params.child) | |
| 37 *style |= WS_CHILD; | |
| 38 if (params.show_state == ui::SHOW_STATE_MAXIMIZED) | |
| 39 *style |= WS_MAXIMIZE; | |
| 40 if (params.show_state == ui::SHOW_STATE_MINIMIZED) | |
| 41 *style |= WS_MINIMIZE; | |
| 42 if (!params.accept_events) | |
| 43 *ex_style |= WS_EX_TRANSPARENT; | |
| 44 DCHECK_NE(Widget::InitParams::ACTIVATABLE_DEFAULT, params.activatable); | |
| 45 if (params.activatable == Widget::InitParams::ACTIVATABLE_NO) | |
| 46 *ex_style |= WS_EX_NOACTIVATE; | |
| 47 if (params.keep_on_top) | |
| 48 *ex_style |= WS_EX_TOPMOST; | |
| 49 if (params.mirror_origin_in_rtl) | |
| 50 *ex_style |= l10n_util::GetExtendedTooltipStyles(); | |
| 51 // Layered windows do not work with Aura. They are basically incompatible | |
| 52 // with Direct3D surfaces. Officially, it should be impossible to achieve | |
| 53 // per-pixel alpha compositing with the desktop and 3D acceleration but it | |
| 54 // has been discovered that since Vista There is a secret handshake between | |
| 55 // user32 and the DMW. If things are set up just right DMW gets out of the | |
| 56 // way; it does not create a backbuffer and simply blends our D3D surface | |
| 57 // and the desktop background. The handshake is as follows: | |
| 58 // 1- Use D3D9Ex to create device/swapchain, etc. You need D3DFMT_A8R8G8B8. | |
| 59 // 2- The window must have WS_EX_COMPOSITED in the extended style. | |
| 60 // 3- The window must have WS_POPUP in its style. | |
| 61 // 4- The windows must not have WM_SIZEBOX, WS_THICKFRAME or WS_CAPTION in its | |
| 62 // style. | |
| 63 // 5- When the window is created but before it is presented, call | |
| 64 // DwmExtendFrameIntoClientArea passing -1 as the margins. | |
| 65 if (params.opacity == Widget::InitParams::TRANSLUCENT_WINDOW) { | |
| 66 if (ui::win::IsAeroGlassEnabled()) | |
| 67 *ex_style |= WS_EX_COMPOSITED; | |
| 68 } | |
| 69 if (params.shadow_type == Widget::InitParams::SHADOW_TYPE_DROP) { | |
| 70 *class_style |= (base::win::GetVersion() < base::win::VERSION_XP) ? | |
| 71 0 : CS_DROPSHADOW; | |
| 72 } | |
| 73 | |
| 74 // Set type-dependent style attributes. | |
| 75 switch (params.type) { | |
| 76 case Widget::InitParams::TYPE_PANEL: | |
| 77 *ex_style |= WS_EX_TOPMOST; | |
| 78 if (params.remove_standard_frame) { | |
| 79 *style |= WS_POPUP; | |
| 80 break; | |
| 81 } | |
| 82 // Else, no break. Fall through to TYPE_WINDOW. | |
| 83 case Widget::InitParams::TYPE_WINDOW: { | |
| 84 // WS_OVERLAPPEDWINDOW is equivalent to: | |
| 85 // WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | | |
| 86 // WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | |
| 87 *style |= WS_OVERLAPPEDWINDOW; | |
| 88 if (!widget_delegate->CanMaximize()) | |
| 89 *style &= ~WS_MAXIMIZEBOX; | |
| 90 if (!widget_delegate->CanMinimize()) | |
| 91 *style &= ~WS_MINIMIZEBOX; | |
| 92 if (!widget_delegate->CanResize()) | |
| 93 *style &= ~(WS_THICKFRAME | WS_MAXIMIZEBOX); | |
| 94 if (params.remove_standard_frame) | |
| 95 *style &= ~(WS_MINIMIZEBOX | WS_MAXIMIZEBOX); | |
| 96 | |
| 97 if (native_widget_delegate->IsDialogBox()) { | |
| 98 *style |= DS_MODALFRAME; | |
| 99 // NOTE: Turning this off means we lose the close button, which is bad. | |
| 100 // Turning it on though means the user can maximize or size the window | |
| 101 // from the system menu, which is worse. We may need to provide our own | |
| 102 // menu to get the close button to appear properly. | |
| 103 // style &= ~WS_SYSMENU; | |
| 104 | |
| 105 // Set the WS_POPUP style for modal dialogs. This ensures that the owner | |
| 106 // window is activated on destruction. This style should not be set for | |
| 107 // non-modal non-top-level dialogs like constrained windows. | |
| 108 *style |= native_widget_delegate->IsModal() ? WS_POPUP : 0; | |
| 109 } | |
| 110 *ex_style |= | |
| 111 native_widget_delegate->IsDialogBox() ? WS_EX_DLGMODALFRAME : 0; | |
| 112 | |
| 113 // See layered window comment above. | |
| 114 if (*ex_style & WS_EX_COMPOSITED) | |
| 115 *style &= ~(WS_THICKFRAME | WS_CAPTION); | |
| 116 break; | |
| 117 } | |
| 118 case Widget::InitParams::TYPE_CONTROL: | |
| 119 *style |= WS_VISIBLE; | |
| 120 break; | |
| 121 case Widget::InitParams::TYPE_WINDOW_FRAMELESS: | |
| 122 *style |= WS_POPUP; | |
| 123 break; | |
| 124 case Widget::InitParams::TYPE_BUBBLE: | |
| 125 *style |= WS_POPUP; | |
| 126 *style |= WS_CLIPCHILDREN; | |
| 127 if (!params.force_show_in_taskbar) | |
| 128 *ex_style |= WS_EX_TOOLWINDOW; | |
| 129 break; | |
| 130 case Widget::InitParams::TYPE_POPUP: | |
| 131 *style |= WS_POPUP; | |
| 132 if (!params.force_show_in_taskbar) | |
| 133 *ex_style |= WS_EX_TOOLWINDOW; | |
| 134 break; | |
| 135 case Widget::InitParams::TYPE_MENU: | |
| 136 *style |= WS_POPUP; | |
| 137 break; | |
| 138 default: | |
| 139 NOTREACHED(); | |
| 140 } | |
| 141 } | |
| 142 | |
| 143 } // namespace | |
| 144 | |
| 145 bool DidClientAreaSizeChange(const WINDOWPOS* window_pos) { | |
| 146 return !(window_pos->flags & SWP_NOSIZE) || | |
| 147 window_pos->flags & SWP_FRAMECHANGED; | |
| 148 } | |
| 149 | |
| 150 void ConfigureWindowStyles( | |
| 151 HWNDMessageHandler* handler, | |
| 152 const Widget::InitParams& params, | |
| 153 WidgetDelegate* widget_delegate, | |
| 154 internal::NativeWidgetDelegate* native_widget_delegate) { | |
| 155 // Configure the HWNDMessageHandler with the appropriate | |
| 156 DWORD style = 0; | |
| 157 DWORD ex_style = 0; | |
| 158 DWORD class_style = 0; | |
| 159 CalculateWindowStylesFromInitParams(params, widget_delegate, | |
| 160 native_widget_delegate, &style, &ex_style, | |
| 161 &class_style); | |
| 162 handler->set_initial_class_style(class_style); | |
| 163 handler->set_window_style(handler->window_style() | style); | |
| 164 handler->set_window_ex_style(handler->window_ex_style() | ex_style); | |
| 165 } | |
| 166 | |
| 167 } // namespace views | |
| OLD | NEW |