Merge pull request #220 from rickyviking/addPenInputWin32

Added PEN input support to GraphicsWindowWin32 with the WM_POINTER*
This commit is contained in:
OpenSceneGraph git repository 2017-03-18 11:17:03 +00:00 committed by GitHub
commit 2cefcc8bfc

View File

@ -79,6 +79,35 @@ typedef TOUCHINPUT const * PCTOUCHINPUT;
#endif
// provide declaration for WM_POINTER* events
// which handle both touch and pen events
// for Windows 8 and above
#if(WINVER < 0x0602)
#define WM_POINTERUPDATE 0x0245
#define WM_POINTERDOWN 0x0246
#define WM_POINTERUP 0x0247
// PointerInput enumeration
enum tagPOINTER_INPUT_TYPE {
PT_POINTER = 0x00000001, // Generic pointer
PT_TOUCH = 0x00000002, // Touch
PT_PEN = 0x00000003, // Pen
PT_MOUSE = 0x00000004, // Mouse
#if(WINVER >= 0x0603)
PT_TOUCHPAD = 0x00000005, // Touchpad
#endif /* WINVER >= 0x0603 */
};
typedef DWORD POINTER_INPUT_TYPE;
// methods to extract pointer info
#define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam))
#endif
typedef
BOOL
(WINAPI GetTouchInputInfoFunc)(
@ -98,10 +127,24 @@ BOOL
HWND hwnd,
ULONG ulFlags));
// used together with WM_POINTER* events
typedef
BOOL
(WINAPI
GetPointerTypeFunc(
UINT32 pointerId,
POINTER_INPUT_TYPE *pointerType));
// Declared static in order to get Header File clean
static RegisterTouchWindowFunc *registerTouchWindowFunc = NULL;
static CloseTouchInputHandleFunc *closeTouchInputHandleFunc = NULL;
static GetTouchInputInfoFunc *getTouchInputInfoFunc = NULL;
static GetPointerTypeFunc *getPointerTypeFunc = NULL;
using namespace osgViewer;
@ -710,6 +753,9 @@ Win32WindowingSystem::Win32WindowingSystem()
closeTouchInputHandleFunc = (CloseTouchInputHandleFunc *) GetProcAddress( hModule, "CloseTouchInputHandle");
getTouchInputInfoFunc = (GetTouchInputInfoFunc *) GetProcAddress( hModule, "GetTouchInputInfo");
// check if Win8 and later API is available
getPointerTypeFunc = (GetPointerTypeFunc*)GetProcAddress(hModule, "GetPointerType");
if (!(registerTouchWindowFunc && closeTouchInputHandleFunc && getTouchInputInfoFunc))
{
registerTouchWindowFunc = NULL;
@ -2883,6 +2929,117 @@ LRESULT GraphicsWindowWin32::handleNativeWindowingEvent( HWND hwnd, UINT uMsg, W
}
break;
/************************************************************************/
/* TOUCH inputs for Win8 and later */
/************************************************************************/
// Note by Riccardo Corsi, 2017-03-16
// Currently only handle the PEN input which is not handled nicely by the
// WM_TOUCH framework.
// At the moment the PEN is mapped to the mouse, emulating LEFT button click.
// WM_POINTER* messages could entirely replace the WM_TOUCH framework,
// at the moment if the input doesn't come from a PEN, than the DefWindowProc()
// default implementation is invoked, which will generate the WM_TOUCH messages.
/////
case WM_POINTERDOWN:
/////
{
UINT32 pointerId = GET_POINTERID_WPARAM(wParam);
POINTER_INPUT_TYPE pointerType = PT_POINTER;
// check pointer type
if (getPointerTypeFunc)
{
(getPointerTypeFunc)(pointerId, &pointerType);
// handle PEN only
if (pointerType == PT_PEN)
{
POINT pt;
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
ScreenToClient(hwnd, &pt);
getEventQueue()->mouseButtonPress(pt.x, pt.y, osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON);
}
// call default implementation to fallback on WM_TOUCH
else
{
if (_ownsWindow)
return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
}
break;
/////
case WM_POINTERUPDATE:
/////
{
UINT32 pointerId = GET_POINTERID_WPARAM(wParam);
POINTER_INPUT_TYPE pointerType = PT_POINTER;
// check pointer type
if (getPointerTypeFunc)
{
(getPointerTypeFunc)(pointerId, &pointerType);
// handle PEN only
if (pointerType == PT_PEN)
{
POINT pt;
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
ScreenToClient(hwnd, &pt);
getEventQueue()->mouseMotion(pt.x, pt.y);
}
// call default implementation to fallback on WM_TOUCH
else
{
if (_ownsWindow)
return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
}
break;
/////
case WM_POINTERUP:
/////
{
UINT32 pointerId = GET_POINTERID_WPARAM(wParam);
POINTER_INPUT_TYPE pointerType = PT_POINTER;
// check pointer type
if (getPointerTypeFunc)
{
(getPointerTypeFunc)(pointerId, &pointerType);
// handle PEN only
if (pointerType == PT_PEN)
{
POINT pt;
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
ScreenToClient(hwnd, &pt);
getEventQueue()->mouseButtonRelease(pt.x, pt.y, osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON);
}
// call default implementation to fallback on WM_TOUCH
else
{
if (_ownsWindow)
return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
}
break;
/////////////////
default :
/////////////////