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