Bounce Metronome Wiki- Bounce helps you keep time

How to disable guestures etc. for multi touch playable on screen keyboards

From Bounce Metronome

Jump to: navigation, search

This is for music keyboards but I imagine you would come across the same issues with e.g. an on-screen touch typing keyboard.

For the background see the video here:


see 9:45 onwards in the movie for background, why you want to do it for an onscreen playable music keyboard - but you have to hunt around to find the code so here it is to save others some time:

If you don't have a multi touch device, you can get started on the programming using Multi Touch Vista to simulate touch by adding extra mice, one for each simulated touch point on the screen, that's how I got started, available here: Multi Touch Vista - I used it on Vista, not yet tried it on Windows 7, was a bit tricky to set up need to read the instructions carefully,.

This is a code snippet - see C-code - it is extracted from a larger working program but can't be compiled and used as is, just a snippet which you can copy / paste, edit, and use in your own program. Public domain, use as you wish, no need to attribute or anything like that.

BOOL (WINAPI *pIsTouchWindow)(
     HWND hwnd,
     PULONG pulFlags);
 
BOOL (WINAPI *pUnregisterTouchWindow)(
   HWND hWnd
);
 
BOOL (WINAPI *pRegisterTouchWindow)(
  HWND hWnd,
  ULONG ulFlags
);
BOOL (WINAPI *pGetTouchInputInfo)(
  HTOUCHINPUT hTouchInput,
  UINT cInputs,
   PTOUCHINPUT pInputs,
  int cbSize
);
BOOL (WINAPI *pCloseTouchInputHandle)(
  HTOUCHINPUT hTouchInput
);
 
 
BOOL (WINAPI *pSetGestureConfig)
(
    HWND hwnd,
    DWORD dwReserved,
    UINT cIDs,
    PGESTURECONFIG pGestureConfig,
    UINT cbSize
);
 
void LoadTouchProcs(void)
{
 // doing it this way for backwards compatibility with earlier versions of
 // windows so you have the same code runs on all versions of Windows
 static char did_this;
 if(did_this)
  return;
 did_this=1;
 if(!hUser32)
 hUser32 = LoadLibraryA("USER32.DLL");
 if(hUser32)
 {
  pIsTouchWindow=(BOOL (WINAPI  *)( HWND,PULONG) ) 
  GetProcAddress( hUser32, "IsTouchWindow" ) ;
  pUnregisterTouchWindow=(BOOL (WINAPI  *)( HWND ) ) 
  GetProcAddress( hUser32, "UnRegisterTouchWindow" ) ;
  pRegisterTouchWindow=(BOOL (WINAPI  *)( HWND, ULONG ) ) 
  GetProcAddress( hUser32, "RegisterTouchWindow" ) ;
  pGetTouchInputInfo=(BOOL (WINAPI  *)( HTOUCHINPUT, UINT,PTOUCHINPUT,int ) ) 
  GetProcAddress( hUser32, "GetTouchInputInfo" ) ;
  pCloseTouchInputHandle=(BOOL (WINAPI  *)( HTOUCHINPUT) ) 
  GetProcAddress( hUser32, "CloseTouchInputHandle" ) ;
  pSetGestureConfig=(BOOL (WINAPI  *)( HWND,DWORD,UINT,PGESTURECONFIG,UINT) ) 
  GetProcAddress( hUser32, "SetGestureConfig" ) ;
 }
}
 
void DoRegisterTouchWindow(HWND hwnd)
{
 //Call this to disable palm rejection and coalescing of touch inputs
  LoadTouchProcs();
  if(pRegisterTouchWindow) 
//   If TWF_WANTPALM is set in calls to RegisterTouchWindow, palm rejection is enabled. This causes a small (100 ms) delay while the software tests whether input is coming from a finger, pen, or the user's palm. Disable palm rejection by calling RegisterTouchWindow with the TWF_WANTPALM flag cleared.
    pRegisterTouchWindow(hwnd,0);//(TWF_FINETOUCH);//(TWF_WANTPALM/*for as quick as possible response*/);
#endif // cl_multitouch
}
 
void DisableAllGuestures(HWND hwnd)
{
 // You can call this to disable all guestures for the window hwnd
 // http://msdn.microsoft.com/en-us/library/ms812373.aspx
 // The atom identifier and Tablet PC atom
 ATOM atomID = 0;
 DWORD dwHwndTabletProperty =  
 TABLET_DISABLE_PRESSANDHOLD | // disables press and hold (right-click) gesture  
 TABLET_DISABLE_PENTAPFEEDBACK | // disables UI feedback on pen up (waves)  
 TABLET_DISABLE_PENBARRELFEEDBACK | // disables UI feedback on pen button down  
 TABLET_DISABLE_FLICKS; // disables pen flicks (back, forward, drag down, drag up)   
 LPCTSTR tabletAtom = "MicrosoftTabletPenServiceProperty";
 
 // Get the Tablet PC atom ID
 atomID = GlobalAddAtom(tabletAtom);
 
 if (atomID)
 {   
  // Try to disable press and hold gesture by 
  // setting the window property, return the result
  SetProp(hwnd, tabletAtom, (HANDLE)dwHwndTabletProperty);
 }
 LoadTouchProcs();
 if(pSetGestureConfig)
 {
  // set the settings in the gesture configuration
  GESTURECONFIG gc[] = {0,0,GC_ALLGESTURES};
 
  UINT uiGcs = 1;
  BOOL bResult = pSetGestureConfig(hwnd, 0, uiGcs, gc, sizeof(GESTURECONFIG));  
 
  if (!bResult)
  {                
   // error handling - never happened though while testing
  }
 }
}
 
 
// http://www.codeproject.com/KB/winsdk/www7.aspx
// http://msdn.microsoft.com/en-us/library/dd317341%28VS.85%29.aspx
 
// This is how I handle the WM_TOUCH - by converting the events to
// WM_TOUCH_UP, WM_TOUCH_DOWN etc
void ProcessMultiTouch(HWND hwnd,WPARAM wParam,LPARAM lParam)
{
 if(!recognise_multitouch)
  return;
 if(!pGetTouchInputInfo)
  return;
 if(!pCloseTouchInputHandle)
  return;
 {
  UINT cInputs=LOWORD(wParam);
  PTOUCHINPUT pInputs=calloc(sizeof(TOUCHINPUT),cInputs);
  if (NULL != pInputs)
  {
    if (pGetTouchInputInfo((HTOUCHINPUT)lParam,
                          cInputs,
                          pInputs,
                          sizeof(TOUCHINPUT))
                          )
    {
     int ii=0;
     for(ii=0;ii<(int)cInputs;ii++)
     {
      // http://209.85.229.132/search?q=cache:ZnIwQW7eDJ8J:ecn.channel9.msdn.com/o9/learn/Windows7/Labs/Multitouch%2520WMTouch%2520-%2520Native/Lab.docx+TWF_FINETOUCH&cd=3&hl=en&ct=clnk&gl=uk&client=firefox-a
      //  Be aware that if the screen is set to High DPI (more than 96 DPI), you may also need to divide the values by 96 and multiply by the current DPI. 
      int x=TOUCH_COORD_TO_PIXEL(pInputs[ii].x);
      int y=TOUCH_COORD_TO_PIXEL(pInputs[ii].y);
	  static int prev_x,prev_y;
	  char did_send_message=0;
      DWORD dwID=pInputs[ii].dwID;
      POINT pt;
      pt.x=x;
      pt.y=y;
      ScreenToClient(hwnd,&pt);
      x=pt.x;
      y=pt.y;
      if((pInputs[ii].dwFlags&TOUCHEVENTF_DOWN)==TOUCHEVENTF_DOWN)
      {
       procCallTouch(hwnd,WM_TOUCH_DOWN,dwID,MAKELONG(x,y));
 	   did_send_message=1;
      }
      if((pInputs[ii].dwFlags&TOUCHEVENTF_MOVE)==TOUCHEVENTF_MOVE)
      {
	   if(x!=prev_x||y!=prev_y)
	   { 
	    // if you don't test for this you will get loads of TOUCHEVENTF_MOVE
	    // even with mouse stationary, so this saves need to
	    // handle all those
        procCallTouch(hwnd,WM_TOUCH_MOVE,dwID,MAKELONG(x,y));
		did_send_message=1;
	   }
      }
      if((pInputs[ii].dwFlags&TOUCHEVENTF_UP)==TOUCHEVENTF_UP)
      {
       procCallTouch(hwnd,WM_TOUCH_UP,dwID,MAKELONG(x,y));
	   did_send_message=1;
      }
	  if(did_send_message)
	  {
       prev_x=x,prev_y=y;
	  }
     }
     if (!pCloseTouchInputHandle((HTOUCHINPUT)lParam))
     {
      // error handling
     }
    }
    else
    {
        // GetLastError() and error handling
    }
    free(pInputs);
 }
 else
 {
     // error handling, presumably out of memory
 }
 }
}
 
 
BOOL recognise_multitouch=1;
 
LRESULT TouchWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 switch (message)
 {
 case WM_CREATE:
  DisableAllGuestures(hwnd); // get rid of right click press and hold animation etc.
    // need to do this also even if you don't do multi-touch processing,
    // for single touch clicks.
  LoadTouchProcs();
  if(!recognise_multitouch)
  if(pUnregisterTouchWindow) 
  {
    pUnregisterTouchWindow(hwnd);
  }
  if(recognise_multitouch)
  if(pRegisterTouchWindow) 
  {
    DoRegisterTouchWindow(hwnd);
    DisableAllGuestures(hwnd);
  }
  break;
 case WM_TOUCH:
  if(recognise_multitouch)
   ProcessMultiTouch(hwnd,wParam,lParam);
   break;
  case WM_TABLET_QUERYSYSTEMGESTURESTATUS:
   // http://msdn.microsoft.com/en-us/library/bb969148(v=vs.85).aspx
   return TABLET_DISABLE_PRESSANDHOLD
    |TABLET_DISABLE_PENTAPFEEDBACK
    |TABLET_DISABLE_PENBARRELFEEDBACK
    |TABLET_DISABLE_TOUCHUIFORCEON
    |TABLET_DISABLE_TOUCHUIFORCEOFF
    |TABLET_DISABLE_TOUCHSWITCH
    |TABLET_DISABLE_FLICKS
    // |TABLET_ENABLE_FLICKSONCONTEXT
    // |TABLET_ENABLE_FLICKLEARNINGMODE
    |TABLET_DISABLE_SMOOTHSCROLLING
    |TABLET_DISABLE_FLICKFALLBACKKEYS 
    |TABLET_ENABLE_MULTITOUCHDATA;
   break;
 }
}
Views
Personal tools
Check out the Astonishing Bounce Metronome Pro

Beginners find the bounce wonderfully easy to work with.

Professional musicians are amazed by its advanced rhythm capabilities

Buy Now

box shot for Bounce Metronome

Or, get your free download
Free 30-day trial
Free taster bounce metronome, yours to keep

Or, find out more:
bouncemetronome.com

(By Robert Walker)