 Chromium Code Reviews
 Chromium Code Reviews Issue 2648683003:
  Introduce WM_POINTER to Handle pointer events with pen type  (Closed)
    
  
    Issue 2648683003:
  Introduce WM_POINTER to Handle pointer events with pen type  (Closed) 
  | Index: ui/views/win/hwnd_message_handler.cc | 
| diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc | 
| index 1dbcea22c11137511a37a9d744ab15e6b0b1e8ff..f47aa0eee5946a7a02ac4dfe567ffb3abbcf0cde 100644 | 
| --- a/ui/views/win/hwnd_message_handler.cc | 
| +++ b/ui/views/win/hwnd_message_handler.cc | 
| @@ -31,6 +31,7 @@ | 
| #include "ui/display/win/dpi.h" | 
| #include "ui/display/win/screen_win.h" | 
| #include "ui/events/event.h" | 
| +#include "ui/events/event_constants.h" | 
| #include "ui/events/event_utils.h" | 
| #include "ui/events/keycodes/keyboard_code_conversion_win.h" | 
| #include "ui/events/win/system_event_state_lookup.h" | 
| @@ -974,6 +975,16 @@ LRESULT HWNDMessageHandler::HandleTouchMessage(unsigned int message, | 
| return ret; | 
| } | 
| +LRESULT HWNDMessageHandler::HandlePointerMessage(unsigned int message, | 
| + WPARAM w_param, | 
| + LPARAM l_param, | 
| + bool* handled) { | 
| + base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr()); | 
| 
sadrul
2017/03/23 19:59:38
I am not sure what the WeakPtr<> is useful for (I
 
dtapuska
2017/03/23 20:02:51
IsMsgHandled is a macro written by sky here: https
 
ananta
2017/03/23 20:04:38
The instance can be destroyed while processing a m
 | 
| + LRESULT ret = OnPointerEvent(message, w_param, l_param); | 
| + *handled = IsMsgHandled(); | 
| + return ret; | 
| +} | 
| + | 
| LRESULT HWNDMessageHandler::HandleScrollMessage(unsigned int message, | 
| WPARAM w_param, | 
| LPARAM l_param, | 
| @@ -1642,6 +1653,92 @@ LRESULT HWNDMessageHandler::OnPointerActivate(UINT message, | 
| return -1; | 
| } | 
| +LRESULT HWNDMessageHandler::OnPointerEvent(UINT message, | 
| + WPARAM w_param, | 
| + LPARAM l_param) { | 
| + // WM_POINTER is not supported on Windows 7 or lower. | 
| + if (base::win::GetVersion() <= base::win::VERSION_WIN7) { | 
| 
sky
2017/03/27 15:33:58
Should this be a DCHECK? How can we end up here if
 
ananta
2017/03/27 18:32:45
Shouldn't be a DCHECK i think. We may have drivers
 | 
| + SetMsgHandled(FALSE); | 
| + return -1; | 
| + } | 
| + | 
| + UINT32 pointer_id = GET_POINTERID_WPARAM(w_param); | 
| + using GetPointerTypeFn = BOOL(WINAPI*)(UINT32, POINTER_INPUT_TYPE*); | 
| + POINTER_INPUT_TYPE pointer_type; | 
| + static GetPointerTypeFn get_pointer_type = reinterpret_cast<GetPointerTypeFn>( | 
| + GetProcAddress(GetModuleHandleA("user32.dll"), "GetPointerType")); | 
| + CHECK(get_pointer_type); | 
| 
sky
2017/03/27 15:33:58
Generally we don't assume we can get the function.
 
lanwei
2017/03/28 21:24:36
Done.
 | 
| + // If the WM_POINTER messages are not sent from a stylus device, then we do | 
| + // not handle them to make sure we do not change the current behavior of | 
| + // touch and mouse inputs. | 
| + if (!get_pointer_type(pointer_id, &pointer_type) || pointer_type != PT_PEN) { | 
| + SetMsgHandled(FALSE); | 
| + return -1; | 
| + } | 
| + | 
| + using GetPointerPenInfoFn = BOOL(WINAPI*)(UINT32, POINTER_PEN_INFO*); | 
| + POINTER_PEN_INFO pointer_pen_info; | 
| + static GetPointerPenInfoFn get_pointer_pen_info = | 
| + reinterpret_cast<GetPointerPenInfoFn>( | 
| + GetProcAddress(GetModuleHandleA("user32.dll"), "GetPointerPenInfo")); | 
| + CHECK(get_pointer_pen_info); | 
| 
sky
2017/03/27 15:33:58
Similar comment about CHECK.
 
lanwei
2017/03/28 21:24:36
Done.
 | 
| + if (!get_pointer_pen_info(pointer_id, &pointer_pen_info)) { | 
| + SetMsgHandled(FALSE); | 
| + return -1; | 
| + } | 
| + | 
| + // We are now creating a fake mouse event with pointer type of pen from | 
| + // the WM_POINTER message and then setting up an associated pointer | 
| + // details in the MouseEvent which contains the pen's information. | 
| + float pressure = static_cast<float>(pointer_pen_info.pressure) / 1024; | 
| + float rotation = pointer_pen_info.rotation; | 
| + int tiltX = pointer_pen_info.tiltX; | 
| 
sky
2017/03/27 15:33:58
titl_x (and tilt_y below)
 
lanwei
2017/03/28 21:24:36
Done.
 | 
| + int tiltY = pointer_pen_info.tiltY; | 
| 
sadrul
2017/03/23 19:59:39
tilt_x, tilt_y
 
lanwei
2017/03/28 21:24:36
Done.
 | 
| + POINT client_point = pointer_pen_info.pointerInfo.ptPixelLocationRaw; | 
| + ScreenToClient(hwnd(), &client_point); | 
| + gfx::Point point = gfx::Point(client_point.x, client_point.y); | 
| 
sky
2017/03/27 15:33:58
Do you need to convert to dips?
 
lanwei
2017/03/28 21:24:36
https://codesearch.chromium.org/chromium/src/ui/ev
 | 
| + ui::EventType event_type = ui::ET_MOUSE_MOVED; | 
| + int flag = -1; | 
| + int click_count = 0; | 
| + switch (message) { | 
| + case WM_POINTERDOWN: | 
| + event_type = ui::ET_MOUSE_PRESSED; | 
| + flag = ui::EF_LEFT_MOUSE_BUTTON; | 
| + click_count = 1; | 
| + break; | 
| + case WM_POINTERUP: | 
| + event_type = ui::ET_MOUSE_RELEASED; | 
| + flag = ui::EF_LEFT_MOUSE_BUTTON; | 
| + click_count = 1; | 
| + break; | 
| + case WM_POINTERUPDATE: | 
| + event_type = ui::ET_MOUSE_MOVED; | 
| + break; | 
| + case WM_POINTERLEAVE: | 
| + event_type = ui::ET_MOUSE_EXITED; | 
| + break; | 
| + default: | 
| 
sky
2017/03/27 15:33:58
Should WM_POINTERENTER generate ET_MOUSE_ENTERED?
 
lanwei
2017/03/28 21:24:36
Done.
 | 
| + break; | 
| + } | 
| + ui::MouseEvent event(event_type, point, point, base::TimeTicks::Now(), flag, | 
| 
sky
2017/03/27 15:33:58
Doesn't the event have a time? Also, how come you
 
lanwei
2017/03/28 21:24:36
https://codesearch.chromium.org/chromium/src/ui/ev
 | 
| + flag); | 
| + ui::PointerDetails pointer_details( | 
| + ui::EventPointerType::POINTER_TYPE_PEN, pointer_id, | 
| + /* radius_x */ 0.0f, /* radius_y */ 0.0f, pressure, tiltX, tiltY, | 
| + /* tangential_pressure */ 0.0f, rotation); | 
| + event.set_pointer_details(pointer_details); | 
| + event.SetClickCount(click_count); | 
| + | 
| + // There are cases where the code handling the message destroys the | 
| + // window, so use the weak ptr to check if destruction occured or not. | 
| + base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr()); | 
| + bool handled = delegate_->HandleMouseEvent(event); | 
| + | 
| + if (ref.get()) | 
| 
sadrul
2017/03/23 19:59:38
if (ref) should work too
 
lanwei
2017/03/28 21:24:36
Done.
 | 
| + SetMsgHandled(handled); | 
| + return 0; | 
| +} | 
| + | 
| void HWNDMessageHandler::OnMove(const gfx::Point& point) { | 
| delegate_->HandleMove(); | 
| SetMsgHandled(FALSE); |