OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 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/events/event.h" |
| 6 |
| 7 #include <windowsx.h> |
| 8 |
| 9 #include "base/logging.h" |
| 10 #include "ui/base/keycodes/keyboard_code_conversion_win.h" |
| 11 |
| 12 namespace ui { |
| 13 |
| 14 namespace { |
| 15 |
| 16 // Returns a mask corresponding to the set of modifier keys that are currently |
| 17 // pressed. Windows key messages don't come with control key state as parameters |
| 18 // as with mouse messages, so we need to explicitly ask for these states. |
| 19 int GetKeyStateFlags() { |
| 20 int flags = 0; |
| 21 if (GetKeyState(VK_MENU) & 0x80) |
| 22 flags |= Event::EF_ALT_DOWN; |
| 23 if (GetKeyState(VK_SHIFT) & 0x80) |
| 24 flags |= Event::EF_SHIFT_DOWN; |
| 25 if (GetKeyState(VK_CONTROL) & 0x80) |
| 26 flags |= Event::EF_CONTROL_DOWN; |
| 27 return flags; |
| 28 } |
| 29 |
| 30 // Convert windows message identifiers to Event types. |
| 31 Event::EventType EventTypeFromNative(NativeEvent native_event) { |
| 32 switch (native_event.message) { |
| 33 case WM_KEYDOWN: |
| 34 case WM_SYSKEYDOWN: |
| 35 return Event::ET_KEY_PRESSED; |
| 36 case WM_KEYUP: |
| 37 case WM_SYSKEYUP: |
| 38 return Event::ET_KEY_RELEASED; |
| 39 case WM_LBUTTONDOWN: |
| 40 case WM_MBUTTONDOWN: |
| 41 case WM_NCLBUTTONDOWN: |
| 42 case WM_NCMBUTTONDOWN: |
| 43 case WM_NCRBUTTONDOWN: |
| 44 case WM_RBUTTONDOWN: |
| 45 return Event::ET_MOUSE_PRESSED; |
| 46 case WM_LBUTTONDBLCLK: |
| 47 case WM_LBUTTONUP: |
| 48 case WM_MBUTTONDBLCLK: |
| 49 case WM_MBUTTONUP: |
| 50 case WM_NCLBUTTONDBLCLK: |
| 51 case WM_NCLBUTTONUP: |
| 52 case WM_NCMBUTTONDBLCLK: |
| 53 case WM_NCMBUTTONUP: |
| 54 case WM_NCRBUTTONDBLCLK: |
| 55 case WM_NCRBUTTONUP: |
| 56 case WM_RBUTTONDBLCLK: |
| 57 case WM_RBUTTONUP: |
| 58 return Event::ET_MOUSE_RELEASED; |
| 59 case WM_MOUSEMOVE: |
| 60 case WM_NCMOUSEMOVE: |
| 61 return Event::ET_MOUSE_MOVED; |
| 62 case WM_MOUSEWHEEL: |
| 63 return Event::ET_MOUSEWHEEL; |
| 64 case WM_MOUSELEAVE: |
| 65 case WM_NCMOUSELEAVE: |
| 66 return Event::ET_MOUSE_EXITED; |
| 67 default: |
| 68 NOTREACHED(); |
| 69 } |
| 70 return Event::ET_UNKNOWN; |
| 71 } |
| 72 |
| 73 bool IsClientMouseEvent(NativeEvent native_event) { |
| 74 return native_event.message == WM_MOUSELEAVE || |
| 75 (native_event.message >= WM_MOUSEFIRST && |
| 76 native_event.message <= WM_MOUSELAST); |
| 77 } |
| 78 |
| 79 bool IsNonClientMouseEvent(NativeEvent native_event) { |
| 80 return native_event.message == WM_NCMOUSELEAVE || |
| 81 (native_event.message >= WM_NCMOUSEMOVE && |
| 82 native_event.message <= WM_NCMBUTTONDBLCLK); |
| 83 } |
| 84 |
| 85 gfx::Point MousePositionFromNative(NativeEvent native_event) { |
| 86 if (IsClientMouseEvent(native_event)) { |
| 87 // Client message. The position is contained in the LPARAM. |
| 88 return gfx::Point(GET_X_LPARAM(native_event.lParam), |
| 89 GET_Y_LPARAM(native_event.lParam)); |
| 90 } |
| 91 DCHECK(IsNonClientMouseEvent(native_event)); |
| 92 // Non-client message. The position is contained in a POINTS structure in |
| 93 // LPARAM, and is in screen coordinates so we have to convert to client. |
| 94 POINT native_point = { GET_X_LPARAM(native_event.lParam), |
| 95 GET_Y_LPARAM(native_event.lParam) }; |
| 96 ScreenToClient(native_event.hwnd, &native_point); |
| 97 return gfx::Point(native_point); |
| 98 } |
| 99 |
| 100 int MouseEventFlagsFromNative(NativeEvent native_event) { |
| 101 int flags = 0; |
| 102 |
| 103 // Check if the event occurred in the non-client area. |
| 104 if (IsNonClientMouseEvent(native_event)) |
| 105 flags |= MouseEvent::EF_IS_NON_CLIENT; |
| 106 |
| 107 // Check for double click events. |
| 108 switch (native_event.message) { |
| 109 case WM_NCLBUTTONDBLCLK: |
| 110 case WM_NCMBUTTONDBLCLK: |
| 111 case WM_NCRBUTTONDBLCLK: |
| 112 case WM_LBUTTONDBLCLK: |
| 113 case WM_MBUTTONDBLCLK: |
| 114 case WM_RBUTTONDBLCLK: |
| 115 flags |= MouseEvent::EF_IS_DOUBLE_CLICK; |
| 116 break; |
| 117 } |
| 118 |
| 119 // Check for pressed buttons. |
| 120 if (IsClientMouseEvent(native_event)) { |
| 121 if (native_event.wParam & MK_LBUTTON) |
| 122 flags |= Event::EF_LEFT_BUTTON_DOWN; |
| 123 if (native_event.wParam & MK_MBUTTON) |
| 124 flags |= Event::EF_MIDDLE_BUTTON_DOWN; |
| 125 if (native_event.wParam & MK_RBUTTON) |
| 126 flags |= Event::EF_RIGHT_BUTTON_DOWN; |
| 127 } else if (IsNonClientMouseEvent(native_event)) { |
| 128 switch (native_event.message) { |
| 129 case WM_NCLBUTTONDOWN: |
| 130 flags |= Event::EF_LEFT_BUTTON_DOWN; |
| 131 break; |
| 132 case WM_NCMBUTTONDOWN: |
| 133 flags |= Event::EF_MIDDLE_BUTTON_DOWN; |
| 134 break; |
| 135 case WM_NCRBUTTONDOWN: |
| 136 flags |= Event::EF_RIGHT_BUTTON_DOWN; |
| 137 break; |
| 138 } |
| 139 } |
| 140 |
| 141 // Finally make sure the key state flags are included. |
| 142 return flags | GetKeyStateFlags(); |
| 143 } |
| 144 |
| 145 int MouseWheelEventFlagsFromNative(NativeEvent native_event) { |
| 146 int native_flags = GET_KEYSTATE_WPARAM(native_event.wParam); |
| 147 int flags = 0; |
| 148 if (native_flags & MK_CONTROL) |
| 149 flags |= Event::EF_CONTROL_DOWN; |
| 150 if (native_flags & MK_SHIFT) |
| 151 flags |= Event::EF_SHIFT_DOWN; |
| 152 if (GetKeyState(VK_MENU) < 0) |
| 153 flags |= Event::EF_ALT_DOWN; |
| 154 if (native_flags & MK_LBUTTON) |
| 155 flags |= Event::EF_LEFT_BUTTON_DOWN; |
| 156 if (native_flags & MK_MBUTTON) |
| 157 flags |= Event::EF_MIDDLE_BUTTON_DOWN; |
| 158 if (native_flags & MK_RBUTTON) |
| 159 flags |= Event::EF_RIGHT_BUTTON_DOWN; |
| 160 return flags; |
| 161 } |
| 162 |
| 163 } // namespace |
| 164 |
| 165 //////////////////////////////////////////////////////////////////////////////// |
| 166 // KeyEvent, public: |
| 167 |
| 168 KeyEvent::KeyEvent(NativeEvent native_event) |
| 169 : Event(EventTypeFromNative(native_event), GetKeyStateFlags()), |
| 170 key_code_(KeyboardCodeForWindowsKeyCode(native_event.wParam)), |
| 171 repeat_count_(native_event.lParam & 0xFFFF), |
| 172 message_flags_((native_event.lParam & 0xFFFF0000) >> 16) { |
| 173 } |
| 174 |
| 175 //////////////////////////////////////////////////////////////////////////////// |
| 176 // MouseEvent, public: |
| 177 |
| 178 MouseEvent::MouseEvent(NativeEvent native_event) |
| 179 : LocatedEvent(EventTypeFromNative(native_event), |
| 180 MousePositionFromNative(native_event), |
| 181 MouseEventFlagsFromNative(native_event)) { |
| 182 } |
| 183 |
| 184 //////////////////////////////////////////////////////////////////////////////// |
| 185 // MouseWheelEvent, public: |
| 186 |
| 187 MouseWheelEvent::MouseWheelEvent(NativeEvent native_event) |
| 188 : LocatedEvent(ET_MOUSEWHEEL, |
| 189 MousePositionFromNative(native_event), |
| 190 MouseWheelEventFlagsFromNative(native_event)), |
| 191 offset_(GET_WHEEL_DELTA_WPARAM(native_event.wParam)) { |
| 192 } |
| 193 |
| 194 } // namespace ui |
| 195 |
OLD | NEW |