LRESULT GestureHandler::WndProc(HWND hWnd, WPARAM wParam, LPARAM lParam) { bool gestureHandled = 0; GESTUREINFO gi; ZeroMemory(&gi, sizeof(GESTUREINFO)); gi.cbSize = sizeof(GESTUREINFO); BOOL result = GetGestureInfo((HGESTUREINFO)lParam, &gi); if(result) { switch(gi.dwID) { case GID_BEGIN: case GID_END: gestureHandled = 1; break; case GID_ZOOM: handleZoom(hWnd, gi); gestureHandled = 1; break; case GID_PAN: handlePan(hWnd, gi); gestureHandled = 1; break; case GID_ROTATE: handleRotate(hWnd, gi); gestureHandled = 1; break; case GID_TWOFINGERTAP: handle2FingerTap(hWnd, gi); gestureHandled = 1; break; case GID_PRESSANDTAP: handlePNT(hWnd, gi); gestureHandled = 1; break; default: gestureHandled = 0; break; } } else { //failed to get gesture info } if (gestureHandled) { CloseGestureInfoHandle((HGESTUREINFO)lParam); } else { DefWindowProc(hWnd, WM_GESTURE, wParam, lParam); } return (GID_END | GID_ZOOM | GID_PAN | GID_ROTATE | GID_TWOFINGERTAP | GID_PRESSANDTAP) << 1; }
PRBool nsWinGesture::IsPanEvent(LPARAM lParam) { GESTUREINFO gi; ZeroMemory(&gi,sizeof(GESTUREINFO)); gi.cbSize = sizeof(GESTUREINFO); BOOL result = GetGestureInfo((HGESTUREINFO)lParam, &gi); if (!result) return PR_FALSE; if (gi.dwID == GID_PAN) return PR_TRUE; return PR_FALSE; }
PRBool nsWinGesture::ProcessPanMessage(HWND hWnd, WPARAM wParam, LPARAM lParam) { GESTUREINFO gi; ZeroMemory(&gi,sizeof(GESTUREINFO)); gi.cbSize = sizeof(GESTUREINFO); BOOL result = GetGestureInfo((HGESTUREINFO)lParam, &gi); if (!result) return PR_FALSE; // The coordinates of this event nsPointWin coord; coord = mPanRefPoint = gi.ptsLocation; // We want screen coordinates in our local offsets as client coordinates will change // when feedback is taking place. Gui events though require client coordinates. mPanRefPoint.ScreenToClient(hWnd); switch(gi.dwID) { case GID_BEGIN: case GID_END: // These should always fall through to DefWndProc return PR_FALSE; break; // Setup pixel scroll events for both axis case GID_PAN: { if (gi.dwFlags & GF_BEGIN) { mPanIntermediate = coord; mPixelScrollDelta = 0; mPanActive = PR_TRUE; mPanInertiaActive = PR_FALSE; } else { #ifdef DBG_jimm PRInt32 deltaX = mPanIntermediate.x - coord.x; PRInt32 deltaY = mPanIntermediate.y - coord.y; printf("coordX=%d coordY=%d deltaX=%d deltaY=%d x:%d y:%d\n", coord.x, coord.y, deltaX, deltaY, mXAxisFeedback, mYAxisFeedback); #endif mPixelScrollDelta.x = mPanIntermediate.x - coord.x; mPixelScrollDelta.y = mPanIntermediate.y - coord.y; mPanIntermediate = coord; if (gi.dwFlags & GF_INERTIA) mPanInertiaActive = PR_TRUE; if (gi.dwFlags & GF_END) { mPanActive = PR_FALSE; mPanInertiaActive = PR_FALSE; PanFeedbackFinalize(hWnd, PR_TRUE); } } } break; } return PR_TRUE; }
PRBool nsWinGesture::ProcessGestureMessage(HWND hWnd, WPARAM wParam, LPARAM lParam, nsSimpleGestureEvent& evt) { GESTUREINFO gi; ZeroMemory(&gi,sizeof(GESTUREINFO)); gi.cbSize = sizeof(GESTUREINFO); BOOL result = GetGestureInfo((HGESTUREINFO)lParam, &gi); if (!result) return PR_FALSE; // The coordinates of this event nsPointWin coord; coord = gi.ptsLocation; coord.ScreenToClient(hWnd); evt.refPoint.x = coord.x; evt.refPoint.y = coord.y; // Multiple gesture can occur at the same time so gesture state // info can't be shared. switch(gi.dwID) { case GID_BEGIN: case GID_END: // These should always fall through to DefWndProc return PR_FALSE; break; case GID_ZOOM: { if (gi.dwFlags & GF_BEGIN) { // Send a zoom start event // The low 32 bits are the distance in pixels. mZoomIntermediate = (float)gi.ullArguments; evt.message = NS_SIMPLE_GESTURE_MAGNIFY_START; evt.delta = 0.0; } else { // Send a zoom intermediate/end event, the delta is the change // in touch points. evt.message = NS_SIMPLE_GESTURE_MAGNIFY_UPDATE; // (positive for a "zoom in") evt.delta = -1.0 * (mZoomIntermediate - (float)gi.ullArguments); mZoomIntermediate = (float)gi.ullArguments; } } break; case GID_ROTATE: { // Send a rotate start event double radians = 0.0; // On GF_BEGIN, ullArguments contains the absolute rotation at the // start of the gesture. In later events it contains the offset from // the start angle. if (gi.ullArguments != 0) radians = GID_ROTATE_ANGLE_FROM_ARGUMENT(gi.ullArguments); double degrees = -1 * radians * (180/M_PI); if (gi.dwFlags & GF_BEGIN) { // At some point we should pass the initial angle in // along with delta. It's useful. degrees = mRotateIntermediate = 0.0; } evt.direction = 0; evt.delta = degrees - mRotateIntermediate; mRotateIntermediate = degrees; if (evt.delta > 0) evt.direction = nsIDOMSimpleGestureEvent::ROTATION_COUNTERCLOCKWISE; else if (evt.delta < 0) evt.direction = nsIDOMSimpleGestureEvent::ROTATION_CLOCKWISE; if (gi.dwFlags & GF_BEGIN) evt.message = NS_SIMPLE_GESTURE_ROTATE_START; else if (gi.dwFlags & GF_END) evt.message = NS_SIMPLE_GESTURE_ROTATE; else evt.message = NS_SIMPLE_GESTURE_ROTATE_UPDATE; } break; case GID_TWOFINGERTAP: { // Normally maps to "restore" from whatever you may have recently changed. A simple // double click. evt.message = NS_SIMPLE_GESTURE_TAP; } break; case GID_PRESSANDTAP: { // Two finger right click. Defaults to right click if it falls through. evt.message = NS_SIMPLE_GESTURE_PRESSTAP; } break; } return PR_TRUE; }
LRESULT WinWindow::WndProc(UINT message, WPARAM wParam, LPARAM lParam) { SetFocus(mWindowHandle); switch (message) { case WM_PAINT: { PAINTSTRUCT ps; BeginPaint(mWindowHandle, &ps); EndPaint(mWindowHandle, &ps); } break; case WM_DESTROY: //DestroyWindow(hWnd); PostQuitMessage(0); break; case WM_LBUTTONDOWN: if (MK_LBUTTON == wParam) { SetCapture(mWindowHandle); short xi = Math::ClampAboveZero((short)LOWORD(lParam)); short yi = Math::ClampAboveZero((short)HIWORD(lParam)); float x = Math::Clamp((float)xi, 0.f, mSize.Width); float y = mSize.Height - Math::Clamp((float)yi, 0.f, mSize.Height); double timeStamp = Application::Instance().TimeStamp(); Touch touch(TouchPhase::Began, 0, timeStamp, mpp(x, y), Point2F::Zero); TouchEventArg e(TouchPhase::Began, touch); InputManager::Instance().TouchesBegan(e); mPrevMouseTouch = touch; } break; case WM_MOUSEMOVE: if (MK_LBUTTON == wParam) { short xi = Math::ClampAboveZero((short)LOWORD(lParam)); short yi = Math::ClampAboveZero((short)HIWORD(lParam)); float x = Math::Clamp((float)xi, 0.f, mSize.Width); float y = mSize.Height - Math::Clamp((float)yi, 0.f, mSize.Height); double timeStamp = Application::Instance().TimeStamp(); Touch touch(TouchPhase::Moved, 0, timeStamp, mpp(x, y), mPrevMouseTouch.Pos); TouchEventArg e(TouchPhase::Moved, touch); InputManager::Instance().TouchesMoved(e); mPrevMouseTouch = touch; } else { short xi = Math::ClampAboveZero((short)LOWORD(lParam)); short yi = Math::ClampAboveZero((short)HIWORD(lParam)); float x = Math::Clamp((float)xi, 0.f, mSize.Width); float y = mSize.Height - Math::Clamp((float)yi, 0.f, mSize.Height); ApplicationStatics::Instance().SetDebugTouch(mpp(x, y)); } break; case WM_LBUTTONUP: { short xi = Math::ClampAboveZero((short)LOWORD(lParam)); short yi = Math::ClampAboveZero((short)HIWORD(lParam)); float x = Math::Clamp((float)xi, 0.f, mSize.Width); float y = mSize.Height - Math::Clamp((float)yi, 0.f, mSize.Height); double timeStamp = Application::Instance().TimeStamp(); Touch touch(TouchPhase::Ended, 0, timeStamp, mpp(x, y), mPrevMouseTouch.Pos); TouchEventArg e(TouchPhase::Ended, touch); InputManager::Instance().TouchesEnded(e); ReleaseCapture(); mPrevMouseTouch = Touch::Zero; } break; case WM_TOUCH: { unsigned int numInputs = (unsigned int)wParam; TOUCHINPUT* ti = new TOUCHINPUT[numInputs]; if (GetTouchInputInfo((HTOUCHINPUT)lParam, numInputs, ti, sizeof(TOUCHINPUT))) { // Handle each contact point for (unsigned int i = 0; i < numInputs; ++i) { /* handle ti[i] */ } } CloseTouchInputHandle((HTOUCHINPUT)lParam); delete[] ti; } break; case WM_GESTURE: { GESTUREINFO gi; ZeroMemory(&gi, sizeof(GESTUREINFO)); gi.cbSize = sizeof(gi); BOOL bResult = GetGestureInfo((HGESTUREINFO)lParam, &gi); bool isHandled = false; if (bResult) { switch (gi.dwID) { case GID_BEGIN: break; case GID_END: break; case GID_ZOOM: // Code for zooming goes here isHandled = true; break; case GID_PAN: // Code for panning goes here isHandled = true; break; case GID_ROTATE: // Code for rotation goes here isHandled = true; break; case GID_TWOFINGERTAP: // Code for two-finger tap goes here isHandled = true; break; case GID_PRESSANDTAP: // Code for roll over goes here isHandled = true; break; default: // A gesture was not recognized break; } } else { DWORD dwErr = GetLastError(); if (dwErr > 0) { MessageBoxW(mWindowHandle, L"Error!", L"Could not retrieve a GESTUREINFO structure.", MB_OK); } } CloseGestureInfoHandle((HGESTUREINFO)lParam); if (isHandled) { return 0; } else { return DefWindowProc(mWindowHandle, message, wParam, lParam); } } break; case WM_SIZE: switch (wParam) { case SIZE_RESTORED: case SIZE_MAXIMIZED: { Size2F newSize; newSize.Width = (float)LOWORD(lParam); newSize.Height = (float)HIWORD(lParam); OnResize(newSize); Application::Instance().Wakeup(); Application::Instance().Resume(); } break; case SIZE_MINIMIZED: Application::Instance().Pause(); Application::Instance().Sleep(); break; } break; case WM_KEYDOWN: { KeyDownEventArg e((uint)wParam, (uint)lParam); InputManager::Instance().KeyDown(e); } break; case WM_KEYUP: { KeyUpEventArg e((uint)wParam, (uint)lParam); InputManager::Instance().KeyUp(e); } break; case WM_CHAR: { CharInputEventArg e((uint)wParam, (uint)lParam); InputManager::Instance().CharInput(e); } break; case WM_MOUSEWHEEL: { short scrollPos = (short)HIWORD(wParam); short key = (short)LOWORD(wParam); ScrollEventArg e(scrollPos, key); InputManager::Instance().Scroll(e); } break; default: return DefWindowProc(mWindowHandle, message, wParam, lParam); } return 0; }