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/widget_hwnd_utils.h"
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"
17 #include "ui/base/win/shell.h"
24 void CalculateWindowStylesFromInitParams(
25 const Widget::InitParams
& params
,
26 WidgetDelegate
* widget_delegate
,
27 internal::NativeWidgetDelegate
* native_widget_delegate
,
31 *style
= WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
;
33 *class_style
= CS_DBLCLKS
;
35 // Set type-independent style attributes.
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
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
;
69 if (params
.shadow_type
== Widget::InitParams::SHADOW_TYPE_DROP
) {
70 *class_style
|= (base::win::GetVersion() < base::win::VERSION_XP
) ?
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
) {
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
);
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;
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;
111 native_widget_delegate
->IsDialogBox() ? WS_EX_DLGMODALFRAME
: 0;
113 // See layered window comment above.
114 if (*ex_style
& WS_EX_COMPOSITED
)
115 *style
&= ~(WS_THICKFRAME
| WS_CAPTION
);
118 case Widget::InitParams::TYPE_CONTROL
:
119 *style
|= WS_VISIBLE
;
121 case Widget::InitParams::TYPE_WINDOW_FRAMELESS
:
124 case Widget::InitParams::TYPE_BUBBLE
:
126 *style
|= WS_CLIPCHILDREN
;
127 if (!params
.force_show_in_taskbar
)
128 *ex_style
|= WS_EX_TOOLWINDOW
;
130 case Widget::InitParams::TYPE_POPUP
:
132 if (!params
.force_show_in_taskbar
)
133 *ex_style
|= WS_EX_TOOLWINDOW
;
135 case Widget::InitParams::TYPE_MENU
:
145 bool DidClientAreaSizeChange(const WINDOWPOS
* window_pos
) {
146 return !(window_pos
->flags
& SWP_NOSIZE
) ||
147 window_pos
->flags
& SWP_FRAMECHANGED
;
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
158 DWORD class_style
= 0;
159 CalculateWindowStylesFromInitParams(params
, widget_delegate
,
160 native_widget_delegate
, &style
, &ex_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
);