hwnd_message_handler.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
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#ifndef UI_VIEWS_WIN_HWND_MESSAGE_HANDLER_H_ 6#define UI_VIEWS_WIN_HWND_MESSAGE_HANDLER_H_ 7 8#include <atlbase.h> 9#include <atlapp.h> 10#include <atlmisc.h> 11#include <windows.h> 12 13#include <set> 14 15#include "base/basictypes.h" 16#include "base/compiler_specific.h" 17#include "base/memory/scoped_ptr.h" 18#include "base/memory/weak_ptr.h" 19#include "base/message_loop.h" 20#include "base/string16.h" 21#include "base/win/win_util.h" 22#include "ui/base/accessibility/accessibility_types.h" 23#include "ui/base/ui_base_types.h" 24#include "ui/base/win/window_impl.h" 25#include "ui/gfx/rect.h" 26#include "ui/views/ime/input_method_delegate.h" 27#include "ui/views/views_export.h" 28 29namespace gfx { 30class Canvas; 31class ImageSkia; 32class Insets; 33} 34 35namespace views { 36 37class FullscreenHandler; 38class HWNDMessageHandlerDelegate; 39class InputMethod; 40 41// These two messages aren't defined in winuser.h, but they are sent to windows 42// with captions. They appear to paint the window caption and frame. 43// Unfortunately if you override the standard non-client rendering as we do 44// with CustomFrameWindow, sometimes Windows (not deterministically 45// reproducibly but definitely frequently) will send these messages to the 46// window and paint the standard caption/title over the top of the custom one. 47// So we need to handle these messages in CustomFrameWindow to prevent this 48// from happening. 49const int WM_NCUAHDRAWCAPTION = 0xAE; 50const int WM_NCUAHDRAWFRAME = 0xAF; 51 52// An object that handles messages for a HWND that implements the views 53// "Custom Frame" look. The purpose of this class is to isolate the windows- 54// specific message handling from the code that wraps it. It is intended to be 55// used by both a views::NativeWidget and an aura::RootWindowHost 56// implementation. 57// TODO(beng): This object should eventually *become* the WindowImpl. 58class VIEWS_EXPORT HWNDMessageHandler : public ui::WindowImpl, 59 public internal::InputMethodDelegate, 60 public MessageLoopForUI::Observer { 61 public: 62 explicit HWNDMessageHandler(HWNDMessageHandlerDelegate* delegate); 63 ~HWNDMessageHandler(); 64 65 void Init(HWND parent, const gfx::Rect& bounds); 66 void InitModalType(ui::ModalType modal_type); 67 68 void Close(); 69 void CloseNow(); 70 71 gfx::Rect GetWindowBoundsInScreen() const; 72 gfx::Rect GetClientAreaBoundsInScreen() const; 73 gfx::Rect GetRestoredBounds() const; 74 void GetWindowPlacement(gfx::Rect* bounds, 75 ui::WindowShowState* show_state) const; 76 77 void SetBounds(const gfx::Rect& bounds); 78 void SetSize(const gfx::Size& size); 79 void CenterWindow(const gfx::Size& size); 80 81 void SetRegion(HRGN rgn); 82 83 void StackAbove(HWND other_hwnd); 84 void StackAtTop(); 85 86 void Show(); 87 void ShowWindowWithState(ui::WindowShowState show_state); 88 // TODO(beng): distinguish from ShowWindowWithState(). 89 void Show(int show_state); 90 void ShowMaximizedWithBounds(const gfx::Rect& bounds); 91 void Hide(); 92 93 void Maximize(); 94 void Minimize(); 95 void Restore(); 96 97 void Activate(); 98 void Deactivate(); 99 100 void SetAlwaysOnTop(bool on_top); 101 102 bool IsVisible() const; 103 bool IsActive() const; 104 bool IsMinimized() const; 105 bool IsMaximized() const; 106 107 bool RunMoveLoop(const gfx::Vector2d& drag_offset); 108 void EndMoveLoop(); 109 110 // Tells the HWND its client area has changed. 111 void SendFrameChanged(); 112 113 void FlashFrame(bool flash); 114 115 void ClearNativeFocus(); 116 117 void SetCapture(); 118 void ReleaseCapture(); 119 bool HasCapture() const; 120 121 FullscreenHandler* fullscreen_handler() { return fullscreen_handler_.get(); } 122 123 void SetVisibilityChangedAnimationsEnabled(bool enabled); 124 125 void SetTitle(const string16& title); 126 127 void SetAccessibleName(const string16& name); 128 void SetAccessibleRole(ui::AccessibilityTypes::Role role); 129 void SetAccessibleState(ui::AccessibilityTypes::State state); 130 void SendNativeAccessibilityEvent(int id, 131 ui::AccessibilityTypes::Event event_type); 132 133 void SetCursor(HCURSOR cursor); 134 135 void FrameTypeChanged(); 136 137 // Disable Layered Window updates by setting to false. 138 void set_can_update_layered_window(bool can_update_layered_window) { 139 can_update_layered_window_ = can_update_layered_window; 140 } 141 void SchedulePaintInRect(const gfx::Rect& rect); 142 void SetOpacity(BYTE opacity); 143 144 void SetWindowIcons(const gfx::ImageSkia& window_icon, 145 const gfx::ImageSkia& app_icon); 146 147 void set_remove_standard_frame(bool remove_standard_frame) { 148 remove_standard_frame_ = remove_standard_frame; 149 } 150 151 void set_use_system_default_icon(bool use_system_default_icon) { 152 use_system_default_icon_ = use_system_default_icon; 153 } 154 155 private: 156 typedef std::set<DWORD> TouchIDs; 157 158 // Overridden from internal::InputMethodDelegate: 159 virtual void DispatchKeyEventPostIME(const ui::KeyEvent& key) OVERRIDE; 160 161 // Overridden from WindowImpl: 162 virtual HICON GetDefaultWindowIcon() const OVERRIDE; 163 virtual LRESULT OnWndProc(UINT message, 164 WPARAM w_param, 165 LPARAM l_param) OVERRIDE; 166 167 // Overridden from MessageLoopForUI::Observer: 168 virtual base::EventStatus WillProcessEvent( 169 const base::NativeEvent& event) OVERRIDE; 170 virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE; 171 172 // Can be called after the delegate has had the opportunity to set focus and 173 // did not do so. 174 void SetInitialFocus(); 175 176 // Called after the WM_ACTIVATE message has been processed by the default 177 // windows procedure. 178 void PostProcessActivateMessage(int activation_state); 179 180 // Enables disabled owner windows that may have been disabled due to this 181 // window's modality. 182 void RestoreEnabledIfNecessary(); 183 184 // Executes the specified SC_command. 185 void ExecuteSystemMenuCommand(int command); 186 187 // Start tracking all mouse events so that this window gets sent mouse leave 188 // messages too. 189 void TrackMouseEvents(DWORD mouse_tracking_flags); 190 191 // Responds to the client area changing size, either at window creation time 192 // or subsequently. 193 void ClientAreaSizeChanged(); 194 195 // Returns the insets of the client area relative to the non-client area of 196 // the window. 197 gfx::Insets GetClientAreaInsets() const; 198 199 // Resets the window region for the current widget bounds if necessary. 200 // If |force| is true, the window region is reset to NULL even for native 201 // frame windows. 202 void ResetWindowRegion(bool force); 203 204 // Calls DefWindowProc, safely wrapping the call in a ScopedRedrawLock to 205 // prevent frame flicker. DefWindowProc handling can otherwise render the 206 // classic-look window title bar directly. 207 LRESULT DefWindowProcWithRedrawLock(UINT message, 208 WPARAM w_param, 209 LPARAM l_param); 210 211 // Notifies any owned windows that we're closing. 212 void NotifyOwnedWindowsParentClosing(); 213 214 // Lock or unlock the window from being able to redraw itself in response to 215 // updates to its invalid region. 216 class ScopedRedrawLock; 217 void LockUpdates(bool force); 218 void UnlockUpdates(bool force); 219 220 // Stops ignoring SetWindowPos() requests (see below). 221 void StopIgnoringPosChanges() { ignore_window_pos_changes_ = false; } 222 223 // Synchronously paints the invalid contents of the Widget. 224 void RedrawInvalidRect(); 225 226 // Synchronously updates the invalid contents of the Widget. Valid for 227 // layered windows only. 228 void RedrawLayeredWindowContents(); 229 230 231 // Message Handlers ---------------------------------------------------------- 232 233 BEGIN_MSG_MAP_EX(HWNDMessageHandler) 234 // Range handlers must go first! 235 MESSAGE_RANGE_HANDLER_EX(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseRange) 236 MESSAGE_RANGE_HANDLER_EX(WM_NCMOUSEMOVE, WM_NCXBUTTONDBLCLK, OnMouseRange) 237 238 // Reflected message handler 239 MESSAGE_HANDLER_EX(base::win::kReflectedMessage, OnReflectedMessage) 240 241 // CustomFrameWindow hacks 242 MESSAGE_HANDLER_EX(WM_NCUAHDRAWCAPTION, OnNCUAHDrawCaption) 243 MESSAGE_HANDLER_EX(WM_NCUAHDRAWFRAME, OnNCUAHDrawFrame) 244 245 // Vista and newer 246 MESSAGE_HANDLER_EX(WM_DWMCOMPOSITIONCHANGED, OnDwmCompositionChanged) 247 248 // Non-atlcrack.h handlers 249 MESSAGE_HANDLER_EX(WM_GETOBJECT, OnGetObject) 250 251 // Mouse events. 252 MESSAGE_HANDLER_EX(WM_MOUSEACTIVATE, OnMouseActivate) 253 MESSAGE_HANDLER_EX(WM_MOUSELEAVE, OnMouseRange) 254 MESSAGE_HANDLER_EX(WM_NCMOUSELEAVE, OnMouseRange) 255 MESSAGE_HANDLER_EX(WM_SETCURSOR, OnSetCursor); 256 257 // Key events. 258 MESSAGE_HANDLER_EX(WM_KEYDOWN, OnKeyEvent) 259 MESSAGE_HANDLER_EX(WM_KEYUP, OnKeyEvent) 260 MESSAGE_HANDLER_EX(WM_SYSKEYDOWN, OnKeyEvent) 261 MESSAGE_HANDLER_EX(WM_SYSKEYUP, OnKeyEvent) 262 263 // IME Events. 264 MESSAGE_HANDLER_EX(WM_IME_SETCONTEXT, OnImeMessages) 265 MESSAGE_HANDLER_EX(WM_IME_STARTCOMPOSITION, OnImeMessages) 266 MESSAGE_HANDLER_EX(WM_IME_COMPOSITION, OnImeMessages) 267 MESSAGE_HANDLER_EX(WM_IME_ENDCOMPOSITION, OnImeMessages) 268 MESSAGE_HANDLER_EX(WM_IME_REQUEST, OnImeMessages) 269 MESSAGE_HANDLER_EX(WM_CHAR, OnImeMessages) 270 MESSAGE_HANDLER_EX(WM_SYSCHAR, OnImeMessages) 271 MESSAGE_HANDLER_EX(WM_DEADCHAR, OnImeMessages) 272 MESSAGE_HANDLER_EX(WM_SYSDEADCHAR, OnImeMessages) 273 274 // Touch Events. 275 MESSAGE_HANDLER_EX(WM_TOUCH, OnTouchEvent) 276 277 // This list is in _ALPHABETICAL_ order! OR I WILL HURT YOU. 278 MSG_WM_ACTIVATEAPP(OnActivateApp) 279 MSG_WM_APPCOMMAND(OnAppCommand) 280 MSG_WM_CAPTURECHANGED(OnCaptureChanged) 281 MSG_WM_CLOSE(OnClose) 282 MSG_WM_COMMAND(OnCommand) 283 MSG_WM_CREATE(OnCreate) 284 MSG_WM_DESTROY(OnDestroy) 285 MSG_WM_DISPLAYCHANGE(OnDisplayChange) 286 MSG_WM_ERASEBKGND(OnEraseBkgnd) 287 MSG_WM_ENTERSIZEMOVE(OnEnterSizeMove) 288 MSG_WM_EXITSIZEMOVE(OnExitSizeMove) 289 MSG_WM_GETMINMAXINFO(OnGetMinMaxInfo) 290 MSG_WM_INITMENU(OnInitMenu) 291 MSG_WM_INPUTLANGCHANGE(OnInputLangChange) 292 MSG_WM_KILLFOCUS(OnKillFocus) 293 MSG_WM_MOVE(OnMove) 294 MSG_WM_MOVING(OnMoving) 295 MSG_WM_NCACTIVATE(OnNCActivate) 296 MSG_WM_NCCALCSIZE(OnNCCalcSize) 297 MSG_WM_NCHITTEST(OnNCHitTest) 298 MSG_WM_NCPAINT(OnNCPaint) 299 MSG_WM_NOTIFY(OnNotify) 300 MSG_WM_PAINT(OnPaint) 301 MSG_WM_POWERBROADCAST(OnPowerBroadcast) 302 MSG_WM_SETFOCUS(OnSetFocus) 303 MSG_WM_SETICON(OnSetIcon) 304 MSG_WM_SETTEXT(OnSetText) 305 MSG_WM_SETTINGCHANGE(OnSettingChange) 306 MSG_WM_SIZE(OnSize) 307 MSG_WM_SYSCOMMAND(OnSysCommand) 308 MSG_WM_THEMECHANGED(OnThemeChanged) 309 MSG_WM_WINDOWPOSCHANGING(OnWindowPosChanging) 310 MSG_WM_WINDOWPOSCHANGED(OnWindowPosChanged) 311 END_MSG_MAP() 312 313 // Message Handlers. 314 // This list is in _ALPHABETICAL_ order! 315 // TODO(beng): Once this object becomes the WindowImpl, these methods can 316 // be made private. 317 void OnActivateApp(BOOL active, DWORD thread_id); 318 // TODO(beng): return BOOL is temporary until this object becomes a 319 // WindowImpl. 320 BOOL OnAppCommand(HWND window, short command, WORD device, int keystate); 321 void OnCaptureChanged(HWND window); 322 void OnClose(); 323 void OnCommand(UINT notification_code, int command, HWND window); 324 LRESULT OnCreate(CREATESTRUCT* create_struct); 325 void OnDestroy(); 326 void OnDisplayChange(UINT bits_per_pixel, const CSize& screen_size); 327 LRESULT OnDwmCompositionChanged(UINT msg, WPARAM w_param, LPARAM l_param); 328 void OnEnterSizeMove(); 329 LRESULT OnEraseBkgnd(HDC dc); 330 void OnExitSizeMove(); 331 void OnGetMinMaxInfo(MINMAXINFO* minmax_info); 332 LRESULT OnGetObject(UINT message, WPARAM w_param, LPARAM l_param); 333 LRESULT OnImeMessages(UINT message, WPARAM w_param, LPARAM l_param); 334 void OnInitMenu(HMENU menu); 335 void OnInputLangChange(DWORD character_set, HKL input_language_id); 336 LRESULT OnKeyEvent(UINT message, WPARAM w_param, LPARAM l_param); 337 void OnKillFocus(HWND focused_window); 338 LRESULT OnMouseActivate(UINT message, WPARAM w_param, LPARAM l_param); 339 LRESULT OnMouseRange(UINT message, WPARAM w_param, LPARAM l_param); 340 void OnMove(const CPoint& point); 341 void OnMoving(UINT param, const RECT* new_bounds); 342 LRESULT OnNCActivate(BOOL active); 343 LRESULT OnNCCalcSize(BOOL mode, LPARAM l_param); 344 LRESULT OnNCHitTest(const CPoint& point); 345 void OnNCPaint(HRGN rgn); 346 LRESULT OnNCUAHDrawCaption(UINT message, WPARAM w_param, LPARAM l_param); 347 LRESULT OnNCUAHDrawFrame(UINT message, WPARAM w_param, LPARAM l_param); 348 LRESULT OnNotify(int w_param, NMHDR* l_param); 349 void OnPaint(HDC dc); 350 LRESULT OnPowerBroadcast(DWORD power_event, DWORD data); 351 LRESULT OnReflectedMessage(UINT message, WPARAM w_param, LPARAM l_param); 352 LRESULT OnSetCursor(UINT message, WPARAM w_param, LPARAM l_param); 353 void OnSetFocus(HWND last_focused_window); 354 LRESULT OnSetIcon(UINT size_type, HICON new_icon); 355 LRESULT OnSetText(const wchar_t* text); 356 void OnSettingChange(UINT flags, const wchar_t* section); 357 void OnSize(UINT param, const CSize& size); 358 void OnSysCommand(UINT notification_code, const CPoint& point); 359 void OnThemeChanged(); 360 LRESULT OnTouchEvent(UINT message, WPARAM w_param, LPARAM l_param); 361 void OnWindowPosChanging(WINDOWPOS* window_pos); 362 void OnWindowPosChanged(WINDOWPOS* window_pos); 363 364 HWNDMessageHandlerDelegate* delegate_; 365 366 scoped_ptr<FullscreenHandler> fullscreen_handler_; 367 368 base::WeakPtrFactory<HWNDMessageHandler> close_widget_factory_; 369 370 bool remove_standard_frame_; 371 372 bool use_system_default_icon_; 373 374 // Whether the focus should be restored next time we get enabled. Needed to 375 // restore focus correctly when Windows modal dialogs are displayed. 376 bool restore_focus_when_enabled_; 377 378 // Whether all ancestors have been enabled. This is only used if is_modal_ is 379 // true. 380 bool restored_enabled_; 381 382 // The last cursor that was active before the current one was selected. Saved 383 // so that we can restore it. 384 HCURSOR previous_cursor_; 385 386 // Event handling ------------------------------------------------------------ 387 388 // The flags currently being used with TrackMouseEvent to track mouse 389 // messages. 0 if there is no active tracking. The value of this member is 390 // used when tracking is canceled. 391 DWORD active_mouse_tracking_flags_; 392 393 // Set to true when the user presses the right mouse button on the caption 394 // area. We need this so we can correctly show the context menu on mouse-up. 395 bool is_right_mouse_pressed_on_caption_; 396 397 // The set of touch devices currently down. 398 TouchIDs touch_ids_; 399 400 // ScopedRedrawLock ---------------------------------------------------------- 401 402 // Represents the number of ScopedRedrawLocks active against this widget. 403 // If this is greater than zero, the widget should be locked against updates. 404 int lock_updates_count_; 405 406 // This flag can be initialized and checked after certain operations (such as 407 // DefWindowProc) to avoid stack-controlled functions (such as unlocking the 408 // Window with a ScopedRedrawLock) after destruction. 409 bool* destroyed_; 410 411 // Window resizing ----------------------------------------------------------- 412 413 // When true, this flag makes us discard incoming SetWindowPos() requests that 414 // only change our position/size. (We still allow changes to Z-order, 415 // activation, etc.) 416 bool ignore_window_pos_changes_; 417 418 // The following factory is used to ignore SetWindowPos() calls for short time 419 // periods. 420 base::WeakPtrFactory<HWNDMessageHandler> ignore_pos_changes_factory_; 421 422 // The last-seen monitor containing us, and its rect and work area. These are 423 // used to catch updates to the rect and work area and react accordingly. 424 HMONITOR last_monitor_; 425 gfx::Rect last_monitor_rect_, last_work_area_; 426 427 // Layered windows ----------------------------------------------------------- 428 429 // Should we keep an off-screen buffer? This is false by default, set to true 430 // when WS_EX_LAYERED is specified before the native window is created. 431 // 432 // NOTE: this is intended to be used with a layered window (a window with an 433 // extended window style of WS_EX_LAYERED). If you are using a layered window 434 // and NOT changing the layered alpha or anything else, then leave this value 435 // alone. OTOH if you are invoking SetLayeredWindowAttributes then you'll 436 // most likely want to set this to false, or after changing the alpha toggle 437 // the extended style bit to false than back to true. See MSDN for more 438 // details. 439 bool use_layered_buffer_; 440 441 // The default alpha to be applied to the layered window. 442 BYTE layered_alpha_; 443 444 // A canvas that contains the window contents in the case of a layered 445 // window. 446 scoped_ptr<gfx::Canvas> layered_window_contents_; 447 448 // We must track the invalid rect ourselves, for two reasons: 449 // For layered windows, Windows will not do this properly with 450 // InvalidateRect()/GetUpdateRect(). (In fact, it'll return misleading 451 // information from GetUpdateRect()). 452 // We also need to keep track of the invalid rectangle for the RootView should 453 // we need to paint the non-client area. The data supplied to WM_NCPAINT seems 454 // to be insufficient. 455 gfx::Rect invalid_rect_; 456 457 // A factory that allows us to schedule a redraw for layered windows. 458 base::WeakPtrFactory<HWNDMessageHandler> paint_layered_window_factory_; 459 460 // True if we are allowed to update the layered window from the DIB backing 461 // store if necessary. 462 bool can_update_layered_window_; 463 464 DISALLOW_COPY_AND_ASSIGN(HWNDMessageHandler); 465}; 466 467} // namespace views 468 469#endif // UI_VIEWS_WIN_HWND_MESSAGE_HANDLER_H_ 470