OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/views/widget/hwnd_message_handler.h" | 5 #include "ui/views/widget/hwnd_message_handler.h" |
6 | 6 |
7 #include <dwmapi.h> | |
8 | |
9 #include "base/system_monitor/system_monitor.h" | |
10 #include "ui/base/native_theme/native_theme_win.h" | |
11 #include "ui/gfx/path.h" | |
12 #include "ui/views/ime/input_method_win.h" | |
13 #include "ui/views/widget/hwnd_message_handler_delegate.h" | 7 #include "ui/views/widget/hwnd_message_handler_delegate.h" |
14 #include "ui/views/widget/native_widget_win.h" | 8 #include "ui/views/widget/native_widget_win.h" |
15 | 9 |
16 namespace views { | 10 namespace views { |
17 | 11 |
18 //////////////////////////////////////////////////////////////////////////////// | 12 //////////////////////////////////////////////////////////////////////////////// |
19 // HWNDMessageHandler, public: | 13 // HWNDMessageHandler, public: |
20 | 14 |
21 HWNDMessageHandler::HWNDMessageHandler(HWNDMessageHandlerDelegate* delegate) | 15 HWNDMessageHandler::HWNDMessageHandler(HWNDMessageHandlerDelegate* delegate) |
22 : delegate_(delegate), | 16 : delegate_(delegate), |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 | 106 |
113 void HWNDMessageHandler::OnExitMenuLoop(BOOL is_track_popup_menu) { | 107 void HWNDMessageHandler::OnExitMenuLoop(BOOL is_track_popup_menu) { |
114 SetMsgHandled(FALSE); | 108 SetMsgHandled(FALSE); |
115 } | 109 } |
116 | 110 |
117 void HWNDMessageHandler::OnExitSizeMove() { | 111 void HWNDMessageHandler::OnExitSizeMove() { |
118 delegate_->HandleEndWMSizeMove(); | 112 delegate_->HandleEndWMSizeMove(); |
119 SetMsgHandled(FALSE); | 113 SetMsgHandled(FALSE); |
120 } | 114 } |
121 | 115 |
122 LRESULT HWNDMessageHandler::OnImeMessages(UINT message, | |
123 WPARAM w_param, | |
124 LPARAM l_param) { | |
125 InputMethod* input_method = delegate_->GetInputMethod(); | |
126 if (!input_method || input_method->IsMock()) { | |
127 SetMsgHandled(FALSE); | |
128 return 0; | |
129 } | |
130 | |
131 InputMethodWin* ime_win = static_cast<InputMethodWin*>(input_method); | |
132 BOOL handled = FALSE; | |
133 LRESULT result = ime_win->OnImeMessages(message, w_param, l_param, &handled); | |
134 SetMsgHandled(handled); | |
135 return result; | |
136 } | |
137 | |
138 void HWNDMessageHandler::OnInitMenu(HMENU menu) { | |
139 bool is_fullscreen = delegate_->AsNativeWidgetWin()->IsFullscreen(); | |
140 bool is_minimized = delegate_->AsNativeWidgetWin()->IsMinimized(); | |
141 bool is_maximized = delegate_->AsNativeWidgetWin()->IsMaximized(); | |
142 bool is_restored = !is_fullscreen && !is_minimized && !is_maximized; | |
143 | |
144 EnableMenuItem(menu, SC_RESTORE, is_minimized || is_maximized); | |
145 EnableMenuItem(menu, SC_MOVE, is_restored); | |
146 EnableMenuItem(menu, SC_SIZE, delegate_->CanResize() && is_restored); | |
147 EnableMenuItem(menu, SC_MAXIMIZE, delegate_->CanMaximize() && | |
148 !is_fullscreen && !is_maximized); | |
149 EnableMenuItem(menu, SC_MINIMIZE, delegate_->CanMaximize() && !is_minimized); | |
150 } | |
151 | |
152 void HWNDMessageHandler::OnInitMenuPopup() { | |
153 SetMsgHandled(FALSE); | |
154 } | |
155 | |
156 void HWNDMessageHandler::OnInputLangChange(DWORD character_set, | |
157 HKL input_language_id) { | |
158 InputMethod* input_method = delegate_->GetInputMethod(); | |
159 if (input_method && !input_method->IsMock()) { | |
160 static_cast<InputMethodWin*>(input_method)->OnInputLangChange( | |
161 character_set, input_language_id); | |
162 } | |
163 } | |
164 | |
165 LRESULT HWNDMessageHandler::OnKeyEvent(UINT message, | |
166 WPARAM w_param, | |
167 LPARAM l_param) { | |
168 MSG msg = { hwnd(), message, w_param, l_param }; | |
169 ui::KeyEvent key(msg, message == WM_CHAR); | |
170 InputMethod* input_method = delegate_->GetInputMethod(); | |
171 if (input_method) | |
172 input_method->DispatchKeyEvent(key); | |
173 else | |
174 delegate_->AsNativeWidgetWin()->DispatchKeyEventPostIME(key); | |
175 return 0; | |
176 } | |
177 | |
178 void HWNDMessageHandler::OnKillFocus(HWND focused_window) { | |
179 delegate_->HandleNativeBlur(focused_window); | |
180 | |
181 InputMethod* input_method = delegate_->GetInputMethod(); | |
182 if (input_method) | |
183 input_method->OnBlur(); | |
184 SetMsgHandled(FALSE); | |
185 } | |
186 | |
187 LRESULT HWNDMessageHandler::OnMouseActivate(UINT message, | |
188 WPARAM w_param, | |
189 LPARAM l_param) { | |
190 // TODO(beng): resolve this with the GetWindowLong() check on the subsequent | |
191 // line. | |
192 if (delegate_->IsWidgetWindow()) | |
193 return delegate_->CanActivate() ? MA_ACTIVATE : MA_NOACTIVATEANDEAT; | |
194 if (delegate_->AsNativeWidgetWin()->GetWindowLong(GWL_EXSTYLE) & | |
195 WS_EX_NOACTIVATE) { | |
196 return MA_NOACTIVATE; | |
197 } | |
198 SetMsgHandled(FALSE); | |
199 return MA_ACTIVATE; | |
200 } | |
201 | |
202 void HWNDMessageHandler::OnMove(const CPoint& point) { | |
203 delegate_->HandleMove(); | |
204 SetMsgHandled(FALSE); | |
205 } | |
206 | |
207 void HWNDMessageHandler::OnMoving(UINT param, const RECT* new_bounds) { | |
208 delegate_->HandleMove(); | |
209 } | |
210 | |
211 LRESULT HWNDMessageHandler::OnNCHitTest(const CPoint& point) { | |
212 if (!delegate_->IsWidgetWindow()) { | |
213 SetMsgHandled(FALSE); | |
214 return 0; | |
215 } | |
216 | |
217 // If the DWM is rendering the window controls, we need to give the DWM's | |
218 // default window procedure first chance to handle hit testing. | |
219 if (!remove_standard_frame_ && !delegate_->IsUsingCustomFrame()) { | |
220 LRESULT result; | |
221 if (DwmDefWindowProc(hwnd(), WM_NCHITTEST, 0, | |
222 MAKELPARAM(point.x, point.y), &result)) { | |
223 return result; | |
224 } | |
225 } | |
226 | |
227 // First, give the NonClientView a chance to test the point to see if it | |
228 // provides any of the non-client area. | |
229 POINT temp = point; | |
230 MapWindowPoints(HWND_DESKTOP, hwnd(), &temp, 1); | |
231 int component = delegate_->GetNonClientComponent(gfx::Point(temp)); | |
232 if (component != HTNOWHERE) | |
233 return component; | |
234 | |
235 // Otherwise, we let Windows do all the native frame non-client handling for | |
236 // us. | |
237 SetMsgHandled(FALSE); | |
238 return 0; | |
239 } | |
240 | |
241 LRESULT HWNDMessageHandler::OnNCUAHDrawCaption(UINT message, | |
242 WPARAM w_param, | |
243 LPARAM l_param) { | |
244 // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for | |
245 // an explanation about why we need to handle this message. | |
246 SetMsgHandled(delegate_->IsUsingCustomFrame()); | |
247 return 0; | |
248 } | |
249 | |
250 LRESULT HWNDMessageHandler::OnNCUAHDrawFrame(UINT message, | |
251 WPARAM w_param, | |
252 LPARAM l_param) { | |
253 // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for | |
254 // an explanation about why we need to handle this message. | |
255 SetMsgHandled(delegate_->IsUsingCustomFrame()); | |
256 return 0; | |
257 } | |
258 | |
259 LRESULT HWNDMessageHandler::OnPowerBroadcast(DWORD power_event, DWORD data) { | |
260 base::SystemMonitor* monitor = base::SystemMonitor::Get(); | |
261 if (monitor) | |
262 monitor->ProcessWmPowerBroadcastMessage(power_event); | |
263 SetMsgHandled(FALSE); | |
264 return 0; | |
265 } | |
266 | |
267 LRESULT HWNDMessageHandler::OnReflectedMessage(UINT message, | |
268 WPARAM w_param, | |
269 LPARAM l_param) { | |
270 SetMsgHandled(FALSE); | |
271 return 0; | |
272 } | |
273 | |
274 LRESULT HWNDMessageHandler::OnSetCursor(UINT message, | |
275 WPARAM w_param, | |
276 LPARAM l_param) { | |
277 // Using ScopedRedrawLock here frequently allows content behind this window to | |
278 // paint in front of this window, causing glaring rendering artifacts. | |
279 // If omitting ScopedRedrawLock here triggers caption rendering artifacts via | |
280 // DefWindowProc message handling, we'll need to find a better solution. | |
281 SetMsgHandled(FALSE); | |
282 return 0; | |
283 } | |
284 | |
285 void HWNDMessageHandler::OnSetFocus(HWND last_focused_window) { | |
286 delegate_->HandleNativeFocus(last_focused_window); | |
287 InputMethod* input_method = delegate_->GetInputMethod(); | |
288 if (input_method) | |
289 input_method->OnFocus(); | |
290 SetMsgHandled(FALSE); | |
291 } | |
292 | |
293 LRESULT HWNDMessageHandler::OnSetIcon(UINT size_type, HICON new_icon) { | |
294 // Use a ScopedRedrawLock to avoid weird non-client painting. | |
295 return DefWindowProcWithRedrawLock(WM_SETICON, size_type, | |
296 reinterpret_cast<LPARAM>(new_icon)); | |
297 } | |
298 | |
299 LRESULT HWNDMessageHandler::OnSetText(const wchar_t* text) { | |
300 // Use a ScopedRedrawLock to avoid weird non-client painting. | |
301 return DefWindowProcWithRedrawLock(WM_SETTEXT, NULL, | |
302 reinterpret_cast<LPARAM>(text)); | |
303 } | |
304 | |
305 void HWNDMessageHandler::OnSize(UINT param, const CSize& size) { | |
306 RedrawWindow(hwnd(), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); | |
307 // ResetWindowRegion is going to trigger WM_NCPAINT. By doing it after we've | |
308 // invoked OnSize we ensure the RootView has been laid out. | |
309 ResetWindowRegion(false); | |
310 } | |
311 | |
312 void HWNDMessageHandler::OnThemeChanged() { | |
313 ui::NativeThemeWin::instance()->CloseHandles(); | |
314 } | |
315 | |
316 void HWNDMessageHandler::OnVScroll(int scroll_type, | |
317 short position, | |
318 HWND scrollbar) { | |
319 SetMsgHandled(FALSE); | |
320 } | |
321 | |
322 void HWNDMessageHandler::ResetWindowRegion(bool force) { | |
323 // A native frame uses the native window region, and we don't want to mess | |
324 // with it. | |
325 if (!delegate_->IsUsingCustomFrame() || !delegate_->IsWidgetWindow()) { | |
326 if (force) | |
327 SetWindowRgn(hwnd(), NULL, TRUE); | |
328 return; | |
329 } | |
330 | |
331 // Changing the window region is going to force a paint. Only change the | |
332 // window region if the region really differs. | |
333 HRGN current_rgn = CreateRectRgn(0, 0, 0, 0); | |
334 int current_rgn_result = GetWindowRgn(hwnd(), current_rgn); | |
335 | |
336 CRect window_rect; | |
337 GetWindowRect(hwnd(), &window_rect); | |
338 HRGN new_region; | |
339 if (delegate_->AsNativeWidgetWin()->IsMaximized()) { | |
340 HMONITOR monitor = MonitorFromWindow(hwnd(), MONITOR_DEFAULTTONEAREST); | |
341 MONITORINFO mi; | |
342 mi.cbSize = sizeof mi; | |
343 GetMonitorInfo(monitor, &mi); | |
344 CRect work_rect = mi.rcWork; | |
345 work_rect.OffsetRect(-window_rect.left, -window_rect.top); | |
346 new_region = CreateRectRgnIndirect(&work_rect); | |
347 } else { | |
348 gfx::Path window_mask; | |
349 delegate_->GetWindowMask( | |
350 gfx::Size(window_rect.Width(), window_rect.Height()), &window_mask); | |
351 new_region = window_mask.CreateNativeRegion(); | |
352 } | |
353 | |
354 if (current_rgn_result == ERROR || !EqualRgn(current_rgn, new_region)) { | |
355 // SetWindowRgn takes ownership of the HRGN created by CreateNativeRegion. | |
356 SetWindowRgn(hwnd(), new_region, TRUE); | |
357 } else { | |
358 DeleteObject(new_region); | |
359 } | |
360 | |
361 DeleteObject(current_rgn); | |
362 } | |
363 | |
364 //////////////////////////////////////////////////////////////////////////////// | 116 //////////////////////////////////////////////////////////////////////////////// |
365 // HWNDMessageHandler, private: | 117 // HWNDMessageHandler, private: |
366 | 118 |
367 HWND HWNDMessageHandler::hwnd() { | |
368 return delegate_->AsNativeWidgetWin()->hwnd(); | |
369 } | |
370 | |
371 LRESULT HWNDMessageHandler::DefWindowProcWithRedrawLock(UINT message, | |
372 WPARAM w_param, | |
373 LPARAM l_param) { | |
374 return delegate_->AsNativeWidgetWin()->DefWindowProcWithRedrawLock(message, | |
375 w_param, | |
376 l_param); | |
377 } | |
378 | |
379 void HWNDMessageHandler::SetMsgHandled(BOOL handled) { | 119 void HWNDMessageHandler::SetMsgHandled(BOOL handled) { |
380 delegate_->AsNativeWidgetWin()->SetMsgHandled(handled); | 120 delegate_->AsNativeWidgetWin()->SetMsgHandled(handled); |
381 } | 121 } |
382 | 122 |
383 } // namespace views | 123 } // namespace views |
384 | 124 |
OLD | NEW |