Can raw keyboard input be implemented????

Postby Rossine » Sat Sep 27, 2008 5:02 pm

Olá Antonio,

É possível saber:

1) Qual objeto esta focado na WM_INPUT ?
2) Se estou usando o teclado, qual tecla foi pressionada.
3) Se estou usando o mouse, em qual objeto cliquei.

Obrigado,

Rossine.
Obrigado, Regards, Saludos

Rossine.

Harbour and Harbour++
Rossine
 
Posts: 344
Joined: Tue Oct 11, 2005 11:33 am

Postby Antonio Linares » Sat Sep 27, 2008 5:48 pm

Rossine,

We are doing many tests to find the right way to use the Raw Input API.

We think there is a mistake in Microsoft docs regarding DefRawInputProc():

http://msdn.microsoft.com/en-us/library/ms645594(VS.85).aspx

Microsoft docs says: "DefRawInputProc is called with the same parameters received by the window procedure." But thats not true according to the function prototype:
Code: Select all  Expand view  RUN
LRESULT DefRawInputProc(     
    PRAWINPUT *paRawInput,
    INT nInput,
    UINT cbSizeHeader
);

Those are not the parameters that a window procedure receives. So we need to find the right way to call DefRawInputProc().

This is our most recent code. You will find some answers to your questions in it :-)
Code: Select all  Expand view  RUN
// Windows Raw Input API support demo, (c) FiveTech Software

#include "FiveWin.ch"

#define WM_INPUT  0x00FF

function Main()

   local oWnd1 := TMyWindow():New(), oWnd2 := TMyWindow():New()

   oWnd1:SetText( "Mouse 1" )
   oWnd2:SetText( "Mouse 2" )
   
   oWnd1:hMouse = GetRawMouse( 1 ) // Use mouse 1 only
   oWnd2:hMouse = GetRawMouse( 2 ) // Use mouse 2 only
   
   RegisterRawInputDevices( oWnd1:hWnd )
   RegisterRawInputDevices( oWnd2:hWnd )

   WndTop( oWnd2:hWnd, 350 )
   oWnd2:Show()
   oWnd2:bLClicked = { || MsgInfo( "mouse 2 click" ) }

   ACTIVATE WINDOW oWnd1 ;
      ON CLICK MsgInfo( "mouse 1 click" )

return nil

CLASS TMyWindow FROM TWindow

   CLASSDATA lRegistered
   
   DATA hMouse // handle of the mouse to use
   DATA lProcessMouse INIT .F.

   METHOD HandleEvent( nMsg, nWParam, nLParam )

ENDCLASS

METHOD HandleEvent( nMsg, nWParam, nLParam ) CLASS TMyWindow

   local nButtons

   if nMsg == WM_INPUT
      ::SetText( Str( RawGetHandle( nLParam ) ) )
      ::lProcessMouse = RawIsMouse( nLParam ) .and. RawGetHandle( nLParam ) == ::hMouse
      return DefRawInputProc( nLParam )
   endif   
   
   if nMsg == WM_LBUTTONDOWN .and. ! ::lProcessMouse
      return nil
   endif   

return Super:HandleEvent( nMsg, nWParam, nLParam )

#pragma BEGINDUMP

#include <hbapi.h>
#include <windows.h>

#define RIDEV_NOLEGACY  0x00000030
#define RIDEV_INPUTSINK 0x00000100

#define RID_INPUT       0x10000003
#define RID_HEADER      0x10000005

#define RIDI_DEVICENAME 0x20000007
#define RIDI_DEVICEINFO 0x2000000b

#define RIM_TYPEMOUSE       0
#define RIM_TYPEKEYBOARD    1
#define RIM_TYPEHID         2

#define RI_MOUSE_LEFT_BUTTON_DOWN   0x0001  // Left Button changed to down.
#define RI_MOUSE_LEFT_BUTTON_UP     0x0002  // Left Button changed to up.
#define RI_MOUSE_RIGHT_BUTTON_DOWN  0x0004  // Right Button changed to down.
#define RI_MOUSE_RIGHT_BUTTON_UP    0x0008  // Right Button changed to up.
#define RI_MOUSE_MIDDLE_BUTTON_DOWN 0x0010  // Middle Button changed to down.
#define RI_MOUSE_MIDDLE_BUTTON_UP   0x0020  // Middle Button changed to up.

typedef struct tagRAWINPUTDEVICE
{
   USHORT usUsagePage;
   USHORT usUsage;
   DWORD dwFlags;
   HWND hwndTarget;
} RAWINPUTDEVICE, * PRAWINPUTDEVICE, * LPRAWINPUTDEVICE;

typedef BOOL WINAPI ( * PREGISTERRAWINPUTDEVICES ) (     
   PRAWINPUTDEVICE pRawInputDevices,
   UINT uiNumDevices,
   UINT cbSize
);

typedef struct tagRAWINPUTHEADER {
    DWORD dwType;
    DWORD dwSize;
    HANDLE hDevice;
    WPARAM wParam;
} RAWINPUTHEADER, * PRAWINPUTHEADER;

typedef struct tagRAWMOUSE {
  USHORT    usFlags;
  union {
         ULONG    ulButtons;
             struct {
                       USHORT usButtonFlags;
                       USHORT usButtonData;
                       };
  };
  ULONG ulRawButtons;
  LONG  lLastX;
  LONG  lLastY;
  ULONG ulExtraInformation;
} RAWMOUSE, * PRAWMOUSE, * LPRAWMOUSE;

typedef struct tagRAWKEYBOARD {
    USHORT MakeCode;
    USHORT Flags;
    USHORT Reserved;
    USHORT VKey;
    UINT Message;
    ULONG ExtraInformation;
} RAWKEYBOARD, *PRAWKEYBOARD, *LPRAWKEYBOARD;

typedef struct tagRAWHID {
    DWORD dwSizeHid;
    DWORD dwCount;
    BYTE bRawData;
} RAWHID, **LPRAWHID;

typedef struct tagRAWINPUT {
    RAWINPUTHEADER header;
    union {
       RAWMOUSE    mouse;
       RAWKEYBOARD keyboard;
       RAWHID      hid;
    } data;
} RAWINPUT, * PRAWINPUT, * LPRAWINPUT;

typedef UINT WINAPI ( * PGETRAWINPUTDATA ) (     
    LPRAWINPUT hRawInput,
    UINT uiCommand,
    LPVOID pData,
    PUINT pcbSize,
    UINT cbSizeHeader
);

typedef struct tagRAWINPUTDEVICELIST {
    HANDLE hDevice;
    DWORD dwType;
} RAWINPUTDEVICELIST, * PRAWINPUTDEVICELIST;

typedef UINT WINAPI ( * PGETRAWINPUTDEVICELIST ) (     
    PRAWINPUTDEVICELIST pRawInputDeviceList,
    PUINT puiNumDevices,
    UINT cbSize
);

typedef struct tagRID_DEVICE_INFO_MOUSE {
    DWORD dwId;
    DWORD dwNumberOfButtons;
    DWORD dwSampleRate;
    BOOL fHasHorizontalWheel;
} RID_DEVICE_INFO_MOUSE, * PRID_DEVICE_INFO_MOUSE;

typedef struct tagRID_DEVICE_INFO_KEYBOARD {
    DWORD dwType;
    DWORD dwSubType;
    DWORD dwKeyboardMode;
    DWORD dwNumberOfFunctionKeys;
    DWORD dwNumberOfIndicators;
    DWORD dwNumberOfKeysTotal;
} RID_DEVICE_INFO_KEYBOARD, * PRID_DEVICE_INFO_KEYBOARD;

typedef struct tagRID_DEVICE_INFO_HID {
    DWORD dwVendorId;
    DWORD dwProductId;
    DWORD dwVersionNumber;
    USHORT usUsagePage;
    USHORT usUsage;
} RID_DEVICE_INFO_HID, * PRID_DEVICE_INFO_HID;

typedef struct tagRID_DEVICE_INFO {
  DWORD    cbSize;
  DWORD    dwType;
  union {
      RID_DEVICE_INFO_MOUSE     mouse;
      RID_DEVICE_INFO_KEYBOARD  keyboard;
      RID_DEVICE_INFO_HID       hid;
  };
} RID_DEVICE_INFO, * PRID_DEVICE_INFO, * LPRID_DEVICE_INFO;

typedef UINT WINAPI ( * PGETRAWINPUTDEVICEINFO ) (     
    HANDLE hDevice,
    UINT uiCommand,
    LPVOID pData,
    PUINT pcbSize
);

typedef LRESULT WINAPI ( * PDEFRAWINPUTPROC ) (     
    PRAWINPUT * paRawInput,
    INT nInput,
    UINT cbSizeHeader
);

static PREGISTERRAWINPUTDEVICES pRegisterRawInputDevices;
static PGETRAWINPUTDEVICELIST   pGetRawInputDeviceList;
static PGETRAWINPUTDEVICEINFO   pGetRawInputDeviceInfo;
static PGETRAWINPUTDATA         pGetRawInputData;
static PDEFRAWINPUTPROC         pDefRawInputProc;

static void RawInit( void )
{
   static BOOL bInit = FALSE;
   
   if( ! bInit )
   {
      HINSTANCE hUser32 = LoadLibrary( "user32.dll" );

      pRegisterRawInputDevices = ( PREGISTERRAWINPUTDEVICES ) GetProcAddress( hUser32, "RegisterRawInputDevices" );
      pGetRawInputDeviceList   = ( PGETRAWINPUTDEVICELIST ) GetProcAddress( hUser32, "GetRawInputDeviceList" );
      pGetRawInputDeviceInfo   = ( PGETRAWINPUTDEVICEINFO ) GetProcAddress( hUser32, "GetRawInputDeviceInfoA" );
      pGetRawInputData         = ( PGETRAWINPUTDATA ) GetProcAddress( hUser32, "GetRawInputData" );
      pDefRawInputProc         = ( PDEFRAWINPUTPROC ) GetProcAddress( hUser32, "DefRawInputProc" );
     
      FreeLibrary( hUser32 );
      bInit = TRUE;
   }   
}   

HB_FUNC( REGISTERRAWINPUTDEVICES )
{
   RAWINPUTDEVICE rid[ 2 ];

   RawInit();
   
   rid[ 0 ].usUsagePage = 0x01;
   rid[ 0 ].usUsage     = 0x02; // Mouse
   rid[ 0 ].dwFlags     = RIDEV_INPUTSINK; // RIDEV_NOLEGACY;
   rid[ 0 ].hwndTarget  = ( HWND ) hb_parnl( 1 );

   rid[ 1 ].usUsagePage = 0x01;
   rid[ 1 ].usUsage     = 0x06; // Keyboard
   rid[ 1 ].dwFlags     = RIDEV_INPUTSINK;
   rid[ 1 ].hwndTarget  = ( HWND ) hb_parnl( 1 );
   
   hb_retl( pRegisterRawInputDevices( rid, 2, sizeof( RAWINPUTDEVICE ) ) );
}

HB_FUNC( GETRAWINPUTDATA )
{
   UINT dwSize;
   LPBYTE lpb;

   RawInit();
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, NULL, &dwSize,
                     sizeof( RAWINPUTHEADER ) );
                     
   lpb = ( LPBYTE ) hb_xgrab( dwSize );                 

   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, lpb, &dwSize,
                     sizeof( RAWINPUTHEADER ) );
   hb_retnl( ( unsigned long ) lpb );                 
}                   

HB_FUNC( GETRAWINPUTDEVICELIST )
{
   UINT nDevices;
   PRAWINPUTDEVICELIST pRawInputDeviceList;

   RawInit();
   
   pGetRawInputDeviceList( NULL, &nDevices, sizeof( RAWINPUTDEVICELIST ) );
   
   if( nDevices )
   {
      UINT ui;
     
      pRawInputDeviceList = ( PRAWINPUTDEVICELIST ) hb_xgrab( sizeof( RAWINPUTDEVICELIST ) * nDevices );
     
      pGetRawInputDeviceList( pRawInputDeviceList, &nDevices, sizeof( RAWINPUTDEVICELIST ) );
     
      hb_reta( nDevices );
     
      for( ui = 0; ui < nDevices; ui++ )
      {
         char name[ 512 ];
         UINT uiSize = 511;
         
         pGetRawInputDeviceInfo( pRawInputDeviceList[ ui ].hDevice, RIDI_DEVICENAME, ( void * ) name, &uiSize );
         hb_storclen( name, uiSize, -1, ui + 1 );
      }
     
      hb_xfree( ( void * ) pRawInputDeviceList );
   }   
}

HB_FUNC( GETRAWMOUSE ) // nMouse --> hDevice
{
   UINT nDevices;
   PRAWINPUTDEVICELIST pRawInputDeviceList;

   RawInit();   
   pGetRawInputDeviceList( NULL, &nDevices, sizeof( RAWINPUTDEVICELIST ) );
   
   if( nDevices )
   {
      UINT ui;
      UINT uiMouses = 0;
     
      pRawInputDeviceList = ( PRAWINPUTDEVICELIST ) hb_xgrab( sizeof( RAWINPUTDEVICELIST ) * nDevices );
     
      pGetRawInputDeviceList( pRawInputDeviceList, &nDevices, sizeof( RAWINPUTDEVICELIST ) );
     
      for( ui = 0; ui < nDevices; ui++ )
      {
         RID_DEVICE_INFO rdi;
         UINT uiSize = sizeof( RID_DEVICE_INFO );       
         UINT uiMouse = hb_parnl( 1 );
         
         rdi.cbSize = sizeof( RID_DEVICE_INFO );
         
         pGetRawInputDeviceInfo( pRawInputDeviceList[ ui ].hDevice, RIDI_DEVICEINFO, ( void * ) &rdi, &uiSize );
         
         if( rdi.dwType == RIM_TYPEMOUSE )
         {
            if( ++uiMouses == uiMouse )
            {
               hb_retnl( ( unsigned long ) pRawInputDeviceList[ ui ].hDevice );
               hb_xfree( ( void * ) pRawInputDeviceList );
               return;
            }   
         }   
      }
     
      hb_retnl( 0 );
      hb_xfree( ( void * ) pRawInputDeviceList );
   }   
}

HB_FUNC( GETRAWMOUSES ) // --> nMouses
{
   UINT nDevices, uiMouses = 0;
   PRAWINPUTDEVICELIST pRawInputDeviceList;

   RawInit();   
   pGetRawInputDeviceList( NULL, &nDevices, sizeof( RAWINPUTDEVICELIST ) );
   
   if( nDevices )
   {
      UINT ui;
     
      pRawInputDeviceList = ( PRAWINPUTDEVICELIST ) hb_xgrab( sizeof( RAWINPUTDEVICELIST ) * nDevices );
     
      pGetRawInputDeviceList( pRawInputDeviceList, &nDevices, sizeof( RAWINPUTDEVICELIST ) );
     
      for( ui = 0; ui < nDevices; ui++ )
      {
         RID_DEVICE_INFO rdi;
         UINT uiSize = sizeof( RID_DEVICE_INFO );       
         
         rdi.cbSize = sizeof( RID_DEVICE_INFO );
         
         pGetRawInputDeviceInfo( pRawInputDeviceList[ ui ].hDevice, RIDI_DEVICEINFO, ( void * ) &rdi, &uiSize );
         
         if( rdi.dwType == RIM_TYPEMOUSE )
            uiMouses++;
      }
     
      hb_xfree( ( void * ) pRawInputDeviceList );
   }   

   hb_retnl( --uiMouses ); // Windows reports an extra mouse (?)
}

HB_FUNC( RAWISMOUSE )
{
   LPBYTE lpb;
   UINT dwSize;

   RawInit();
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, NULL, &dwSize,
                     sizeof( RAWINPUTHEADER ) );
   lpb = ( LPBYTE ) hb_xgrab( dwSize );                 
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, lpb, &dwSize,
                     sizeof( RAWINPUTHEADER ) );   
   hb_retl( ( ( PRAWINPUT ) lpb )->header.dwType == RIM_TYPEMOUSE );
   hb_xfree( ( void * ) lpb );
}   

HB_FUNC( RAWGETHANDLE )
{
   LPBYTE lpb;
   UINT dwSize;

   RawInit();
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, NULL, &dwSize,
                     sizeof( RAWINPUTHEADER ) );
   lpb = ( LPBYTE ) hb_xgrab( dwSize );                 
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, lpb, &dwSize,
                     sizeof( RAWINPUTHEADER ) );   
   hb_retnl( ( unsigned long ) ( ( PRAWINPUT ) lpb )->header.hDevice );
   hb_xfree( ( void * ) lpb );
}   

HB_FUNC( RAWBUTTONS )
{
   LPBYTE lpb;
   UINT dwSize;

   RawInit();
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, NULL, &dwSize,
                     sizeof( RAWINPUTHEADER ) );
   lpb = ( LPBYTE ) hb_xgrab( dwSize );                 
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, lpb, &dwSize,
                     sizeof( RAWINPUTHEADER ) );   
   hb_retnl( ( unsigned long ) ( ( PRAWINPUT ) lpb )->data.mouse.usButtonFlags );
   hb_xfree( ( void * ) lpb );
}   

HB_FUNC( DEFRAWINPUTPROC )
{
   LPRAWINPUT pri = ( LPRAWINPUT ) hb_parnl( 1 );

   RawInit();
   hb_retnl( ( unsigned long ) pDefRawInputProc( &pri, 1, sizeof( RAWINPUTHEADER ) ) );
}   

#pragma ENDDUMP
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42118
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Antonio Linares » Sat Sep 27, 2008 5:52 pm

This is the most recent PRG and EXE:
http://rapidshare.com/files/148882254/rawinput.zip.html

We need to properly call DefRawInputProc() or the first window does not receive WM_INPUT messages.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42118
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Antonio Linares » Sat Sep 27, 2008 8:23 pm

This is a better example that lets you select the mouse to use. Please connect several mouses to your computer and select the one to use from the main menu:

PRG and EXE here:
http://rapidshare.com/files/148918411/rawinput.zip.html
Code: Select all  Expand view  RUN
// Windows Raw Input API support demo, (c) FiveTech Software

#include "FiveWin.ch"

#define WM_INPUT  0x00FF

function Main()

   local oWnd := TMyWindow():New()

   oWnd:SetText( "Raw API test" )
   oWnd:SetMenu( BuildMenu( oWnd ) )
   
   oWnd:hMouse = GetRawMouse( 1 )
   
   RegisterRawInputDevices( oWnd:hWnd )

   SET MESSAGE OF oWnd TO "Click on the window to test it" 2007

   ACTIVATE WINDOW oWnd ;
      ON CLICK MsgInfo( "mouse click" )

return nil

function BuildMenu( oWnd )

   local oMenu, oMit1, oMit2, oMit3
   
   MENU oMenu
      MENUITEM "Select Mouse"
      MENU
         MENUITEM oMit1 PROMPT "Mouse 1" CHECKED ACTION ( oWnd:hMouse := GetRawMouse( 1 ), oMit1:SetCheck( .T. ), oMit2:SetCheck( .F. ), oMit3:SetCheck( .F. ) )
         MENUITEM oMit2 PROMPT "Mouse 2" ACTION ( oWnd:hMouse := GetRawMouse( 2 ), oMit1:SetCheck( .F. ), oMit2:SetCheck( .T. ), oMit3:SetCheck( .F. ) ) 
         MENUITEM oMit3 PROMPT "Mouse 3" ACTION ( oWnd:hMouse := GetRawMouse( 3 ), oMit1:SetCheck( .F. ), oMit2:SetCheck( .F. ), oMit3:SetCheck( .T. ) ) 
         SEPARATOR
         MENUITEM "Exit" ACTION oWnd:End()
      ENDMENU
   ENDMENU
   
return oMenu     

CLASS TMyWindow FROM TWindow

   CLASSDATA lRegistered
   
   DATA hMouse // handle of the mouse to use
   DATA lProcessMouse INIT .F.

   METHOD HandleEvent( nMsg, nWParam, nLParam )

ENDCLASS

METHOD HandleEvent( nMsg, nWParam, nLParam ) CLASS TMyWindow

   local nButtons

   if nMsg == WM_INPUT
      ::lProcessMouse = RawIsMouse( nLParam ) .and. RawGetHandle( nLParam ) == ::hMouse
   endif   
   
   if nMsg == WM_LBUTTONDOWN .and. ! ::lProcessMouse
      return nil
   endif   

return Super:HandleEvent( nMsg, nWParam, nLParam )

#pragma BEGINDUMP

#include <hbapi.h>
#include <windows.h>

#define RIDEV_NOLEGACY  0x00000030
#define RIDEV_INPUTSINK 0x00000100

#define RID_INPUT       0x10000003
#define RID_HEADER      0x10000005

#define RIDI_DEVICENAME 0x20000007
#define RIDI_DEVICEINFO 0x2000000b

#define RIM_TYPEMOUSE       0
#define RIM_TYPEKEYBOARD    1
#define RIM_TYPEHID         2

#define RI_MOUSE_LEFT_BUTTON_DOWN   0x0001  // Left Button changed to down.
#define RI_MOUSE_LEFT_BUTTON_UP     0x0002  // Left Button changed to up.
#define RI_MOUSE_RIGHT_BUTTON_DOWN  0x0004  // Right Button changed to down.
#define RI_MOUSE_RIGHT_BUTTON_UP    0x0008  // Right Button changed to up.
#define RI_MOUSE_MIDDLE_BUTTON_DOWN 0x0010  // Middle Button changed to down.
#define RI_MOUSE_MIDDLE_BUTTON_UP   0x0020  // Middle Button changed to up.

typedef struct tagRAWINPUTDEVICE
{
   USHORT usUsagePage;
   USHORT usUsage;
   DWORD dwFlags;
   HWND hwndTarget;
} RAWINPUTDEVICE, * PRAWINPUTDEVICE, * LPRAWINPUTDEVICE;

typedef BOOL WINAPI ( * PREGISTERRAWINPUTDEVICES ) (     
   PRAWINPUTDEVICE pRawInputDevices,
   UINT uiNumDevices,
   UINT cbSize
);

typedef struct tagRAWINPUTHEADER {
    DWORD dwType;
    DWORD dwSize;
    HANDLE hDevice;
    WPARAM wParam;
} RAWINPUTHEADER, * PRAWINPUTHEADER;

typedef struct tagRAWMOUSE {
  USHORT    usFlags;
  union {
         ULONG    ulButtons;
             struct {
                       USHORT usButtonFlags;
                       USHORT usButtonData;
                       };
  };
  ULONG ulRawButtons;
  LONG  lLastX;
  LONG  lLastY;
  ULONG ulExtraInformation;
} RAWMOUSE, * PRAWMOUSE, * LPRAWMOUSE;

typedef struct tagRAWKEYBOARD {
    USHORT MakeCode;
    USHORT Flags;
    USHORT Reserved;
    USHORT VKey;
    UINT Message;
    ULONG ExtraInformation;
} RAWKEYBOARD, *PRAWKEYBOARD, *LPRAWKEYBOARD;

typedef struct tagRAWHID {
    DWORD dwSizeHid;
    DWORD dwCount;
    BYTE bRawData;
} RAWHID, **LPRAWHID;

typedef struct tagRAWINPUT {
    RAWINPUTHEADER header;
    union {
       RAWMOUSE    mouse;
       RAWKEYBOARD keyboard;
       RAWHID      hid;
    } data;
} RAWINPUT, * PRAWINPUT, * LPRAWINPUT;

typedef UINT WINAPI ( * PGETRAWINPUTDATA ) (     
    LPRAWINPUT hRawInput,
    UINT uiCommand,
    LPVOID pData,
    PUINT pcbSize,
    UINT cbSizeHeader
);

typedef struct tagRAWINPUTDEVICELIST {
    HANDLE hDevice;
    DWORD dwType;
} RAWINPUTDEVICELIST, * PRAWINPUTDEVICELIST;

typedef UINT WINAPI ( * PGETRAWINPUTDEVICELIST ) (     
    PRAWINPUTDEVICELIST pRawInputDeviceList,
    PUINT puiNumDevices,
    UINT cbSize
);

typedef struct tagRID_DEVICE_INFO_MOUSE {
    DWORD dwId;
    DWORD dwNumberOfButtons;
    DWORD dwSampleRate;
    BOOL fHasHorizontalWheel;
} RID_DEVICE_INFO_MOUSE, * PRID_DEVICE_INFO_MOUSE;

typedef struct tagRID_DEVICE_INFO_KEYBOARD {
    DWORD dwType;
    DWORD dwSubType;
    DWORD dwKeyboardMode;
    DWORD dwNumberOfFunctionKeys;
    DWORD dwNumberOfIndicators;
    DWORD dwNumberOfKeysTotal;
} RID_DEVICE_INFO_KEYBOARD, * PRID_DEVICE_INFO_KEYBOARD;

typedef struct tagRID_DEVICE_INFO_HID {
    DWORD dwVendorId;
    DWORD dwProductId;
    DWORD dwVersionNumber;
    USHORT usUsagePage;
    USHORT usUsage;
} RID_DEVICE_INFO_HID, * PRID_DEVICE_INFO_HID;

typedef struct tagRID_DEVICE_INFO {
  DWORD    cbSize;
  DWORD    dwType;
  union {
      RID_DEVICE_INFO_MOUSE     mouse;
      RID_DEVICE_INFO_KEYBOARD  keyboard;
      RID_DEVICE_INFO_HID       hid;
  };
} RID_DEVICE_INFO, * PRID_DEVICE_INFO, * LPRID_DEVICE_INFO;

typedef UINT WINAPI ( * PGETRAWINPUTDEVICEINFO ) (     
    HANDLE hDevice,
    UINT uiCommand,
    LPVOID pData,
    PUINT pcbSize
);

typedef LRESULT WINAPI ( * PDEFRAWINPUTPROC ) (     
    PRAWINPUT * paRawInput,
    INT nInput,
    UINT cbSizeHeader
);

static PREGISTERRAWINPUTDEVICES pRegisterRawInputDevices;
static PGETRAWINPUTDEVICELIST   pGetRawInputDeviceList;
static PGETRAWINPUTDEVICEINFO   pGetRawInputDeviceInfo;
static PGETRAWINPUTDATA         pGetRawInputData;
static PDEFRAWINPUTPROC         pDefRawInputProc;

static void RawInit( void )
{
   static BOOL bInit = FALSE;
   
   if( ! bInit )
   {
      HINSTANCE hUser32 = LoadLibrary( "user32.dll" );

      pRegisterRawInputDevices = ( PREGISTERRAWINPUTDEVICES ) GetProcAddress( hUser32, "RegisterRawInputDevices" );
      pGetRawInputDeviceList   = ( PGETRAWINPUTDEVICELIST ) GetProcAddress( hUser32, "GetRawInputDeviceList" );
      pGetRawInputDeviceInfo   = ( PGETRAWINPUTDEVICEINFO ) GetProcAddress( hUser32, "GetRawInputDeviceInfoA" );
      pGetRawInputData         = ( PGETRAWINPUTDATA ) GetProcAddress( hUser32, "GetRawInputData" );
      pDefRawInputProc         = ( PDEFRAWINPUTPROC ) GetProcAddress( hUser32, "DefRawInputProc" );
     
      FreeLibrary( hUser32 );
      bInit = TRUE;
   }   
}   

HB_FUNC( REGISTERRAWINPUTDEVICES )
{
   RAWINPUTDEVICE rid[ 2 ];

   RawInit();
   
   rid[ 0 ].usUsagePage = 0x01;
   rid[ 0 ].usUsage     = 0x02; // Mouse
   rid[ 0 ].dwFlags     = RIDEV_INPUTSINK; // RIDEV_NOLEGACY;
   rid[ 0 ].hwndTarget  = ( HWND ) hb_parnl( 1 );

   rid[ 1 ].usUsagePage = 0x01;
   rid[ 1 ].usUsage     = 0x06; // Keyboard
   rid[ 1 ].dwFlags     = RIDEV_INPUTSINK;
   rid[ 1 ].hwndTarget  = ( HWND ) hb_parnl( 1 );
   
   hb_retl( pRegisterRawInputDevices( rid, 2, sizeof( RAWINPUTDEVICE ) ) );
}

HB_FUNC( GETRAWINPUTDATA )
{
   UINT dwSize;
   LPBYTE lpb;

   RawInit();
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, NULL, &dwSize,
                     sizeof( RAWINPUTHEADER ) );
                     
   lpb = ( LPBYTE ) hb_xgrab( dwSize );                 

   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, lpb, &dwSize,
                     sizeof( RAWINPUTHEADER ) );
   hb_retnl( ( unsigned long ) lpb );                 
}                   

HB_FUNC( GETRAWINPUTDEVICELIST )
{
   UINT nDevices;
   PRAWINPUTDEVICELIST pRawInputDeviceList;

   RawInit();
   
   pGetRawInputDeviceList( NULL, &nDevices, sizeof( RAWINPUTDEVICELIST ) );
   
   if( nDevices )
   {
      UINT ui;
     
      pRawInputDeviceList = ( PRAWINPUTDEVICELIST ) hb_xgrab( sizeof( RAWINPUTDEVICELIST ) * nDevices );
     
      pGetRawInputDeviceList( pRawInputDeviceList, &nDevices, sizeof( RAWINPUTDEVICELIST ) );
     
      hb_reta( nDevices );
     
      for( ui = 0; ui < nDevices; ui++ )
      {
         char name[ 512 ];
         UINT uiSize = 511;
         
         pGetRawInputDeviceInfo( pRawInputDeviceList[ ui ].hDevice, RIDI_DEVICENAME, ( void * ) name, &uiSize );
         hb_storclen( name, uiSize, -1, ui + 1 );
      }
     
      hb_xfree( ( void * ) pRawInputDeviceList );
   }   
}

HB_FUNC( GETRAWMOUSE ) // nMouse --> hDevice
{
   UINT nDevices;
   PRAWINPUTDEVICELIST pRawInputDeviceList;

   RawInit();   
   pGetRawInputDeviceList( NULL, &nDevices, sizeof( RAWINPUTDEVICELIST ) );
   
   if( nDevices )
   {
      UINT ui;
      UINT uiMouses = 0;
     
      pRawInputDeviceList = ( PRAWINPUTDEVICELIST ) hb_xgrab( sizeof( RAWINPUTDEVICELIST ) * nDevices );
     
      pGetRawInputDeviceList( pRawInputDeviceList, &nDevices, sizeof( RAWINPUTDEVICELIST ) );
     
      for( ui = 0; ui < nDevices; ui++ )
      {
         RID_DEVICE_INFO rdi;
         UINT uiSize = sizeof( RID_DEVICE_INFO );       
         UINT uiMouse = hb_parnl( 1 );
         
         rdi.cbSize = sizeof( RID_DEVICE_INFO );
         
         pGetRawInputDeviceInfo( pRawInputDeviceList[ ui ].hDevice, RIDI_DEVICEINFO, ( void * ) &rdi, &uiSize );
         
         if( rdi.dwType == RIM_TYPEMOUSE )
         {
            if( ++uiMouses == uiMouse )
            {
               hb_retnl( ( unsigned long ) pRawInputDeviceList[ ui ].hDevice );
               hb_xfree( ( void * ) pRawInputDeviceList );
               return;
            }   
         }   
      }
     
      hb_retnl( 0 );
      hb_xfree( ( void * ) pRawInputDeviceList );
   }   
}

HB_FUNC( GETRAWMOUSES ) // --> nMouses
{
   UINT nDevices, uiMouses = 0;
   PRAWINPUTDEVICELIST pRawInputDeviceList;

   RawInit();   
   pGetRawInputDeviceList( NULL, &nDevices, sizeof( RAWINPUTDEVICELIST ) );
   
   if( nDevices )
   {
      UINT ui;
     
      pRawInputDeviceList = ( PRAWINPUTDEVICELIST ) hb_xgrab( sizeof( RAWINPUTDEVICELIST ) * nDevices );
     
      pGetRawInputDeviceList( pRawInputDeviceList, &nDevices, sizeof( RAWINPUTDEVICELIST ) );
     
      for( ui = 0; ui < nDevices; ui++ )
      {
         RID_DEVICE_INFO rdi;
         UINT uiSize = sizeof( RID_DEVICE_INFO );       
         
         rdi.cbSize = sizeof( RID_DEVICE_INFO );
         
         pGetRawInputDeviceInfo( pRawInputDeviceList[ ui ].hDevice, RIDI_DEVICEINFO, ( void * ) &rdi, &uiSize );
         
         if( rdi.dwType == RIM_TYPEMOUSE )
            uiMouses++;
      }
     
      hb_xfree( ( void * ) pRawInputDeviceList );
   }   

   hb_retnl( --uiMouses ); // Windows reports an extra mouse (?)
}

HB_FUNC( RAWISMOUSE )
{
   LPBYTE lpb;
   UINT dwSize;

   RawInit();
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, NULL, &dwSize,
                     sizeof( RAWINPUTHEADER ) );
   lpb = ( LPBYTE ) hb_xgrab( dwSize );                 
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, lpb, &dwSize,
                     sizeof( RAWINPUTHEADER ) );   
   hb_retl( ( ( PRAWINPUT ) lpb )->header.dwType == RIM_TYPEMOUSE );
   hb_xfree( ( void * ) lpb );
}   

HB_FUNC( RAWGETHANDLE )
{
   LPBYTE lpb;
   UINT dwSize;

   RawInit();
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, NULL, &dwSize,
                     sizeof( RAWINPUTHEADER ) );
   lpb = ( LPBYTE ) hb_xgrab( dwSize );                 
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, lpb, &dwSize,
                     sizeof( RAWINPUTHEADER ) );   
   hb_retnl( ( unsigned long ) ( ( PRAWINPUT ) lpb )->header.hDevice );
   hb_xfree( ( void * ) lpb );
}   

HB_FUNC( RAWBUTTONS )
{
   LPBYTE lpb;
   UINT dwSize;

   RawInit();
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, NULL, &dwSize,
                     sizeof( RAWINPUTHEADER ) );
   lpb = ( LPBYTE ) hb_xgrab( dwSize );                 
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, lpb, &dwSize,
                     sizeof( RAWINPUTHEADER ) );   
   hb_retnl( ( unsigned long ) ( ( PRAWINPUT ) lpb )->data.mouse.usButtonFlags );
   hb_xfree( ( void * ) lpb );
}   

HB_FUNC( DEFRAWINPUTPROC )
{
   LPBYTE lpb;
   UINT dwSize;

   RawInit();
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, NULL, &dwSize,
                     sizeof( RAWINPUTHEADER ) );
   lpb = ( LPBYTE ) hb_xgrab( dwSize );                 
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, lpb, &dwSize,
                     sizeof( RAWINPUTHEADER ) );   
   pDefRawInputProc( ( LPRAWINPUT * ) &lpb, 1, sizeof( RAWINPUTHEADER ) );
   hb_xfree( ( void * ) lpb );
}   

#pragma ENDDUMP
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42118
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Mike Buckler » Sun Sep 28, 2008 12:40 am

First Off Great Work Antonio
This is what I noticed.

I added to METHOD HandleEvent()
if nMsg == WM_MOUSEMOVE
if RawGetHandle( nLParam ) == ::hMouse
::MouseMove( nHiWord( nLParam ), nLoWord( nLParam ), nWParam )
return nil
else
return nil
endif
endif

And also added to the window-
oWnd:OnMouseMove:= {|SELF,X,Y,FLAGS|(oWnd:SetText( "Raw API test Mouse at"+str(x)+" "+str(y) ) ,oWnd:refresh())}

When you move the mouse that is not active the mouse moves.
I there a way to fake a mouse that is only displayed on a specific monitor?
Thanks Mike
Mike Buckler
 
Posts: 67
Joined: Thu Jan 05, 2006 10:35 pm
Location: Canada

Postby Antonio Linares » Sun Sep 28, 2008 8:31 am

Mike,

Let me explain you what we have discovered so far:

1) When we use RIDEV_INPUTSINK when we call REGISTERRAWINPUTDEVICES() then we receive standard Windows mouse and keyboard messages besides the WM_INPUT messages.

2) If we use RIDEV_NOLEGACY instead of RIDEV_INPUTSINK, then Windows does not send any mouse or keyboard message at all, so it is our responsability to translate WM_INPUT messages into the WM_(mouse)... and WM_(keyb)... equivalents ones.

If using 2) then we can not directly call the FWH methods as there are many processes (i.e. when you drag and move a window) that have to be managed by Windows. So basically we have to do: SendMessage( ::hWnd, WM_(proper message), proper params... )

On our first tests the 2) seems more complex to be implemented, but obviously we will have full control on what it is allowed and what we don't allow.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42118
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Mike Buckler » Mon Sep 29, 2008 11:36 pm

Antonio what are your thoughts on how to move forward?
Mike
Mike Buckler
 
Posts: 67
Joined: Thu Jan 05, 2006 10:35 pm
Location: Canada

Postby Antonio Linares » Mon Sep 29, 2008 11:59 pm

Mike,

I think that we have to go for the option 2) to have full control of the mouse and keyboard
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42118
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Mike Buckler » Tue Sep 30, 2008 12:19 am

Antonio if I knew how to do c programming I would jump right in there and help you. I believe that the hardware dollar savings that an end user could realize, would make our FiveWin applications really shine over our competition.
Thanks Again
Mike
Mike Buckler
 
Posts: 67
Joined: Thu Jan 05, 2006 10:35 pm
Location: Canada

Postby Rossine » Tue Sep 30, 2008 2:10 pm

Hello Antonio,

I find this important and very interesting matter.

Congratulations,

Rossine.
Obrigado, Regards, Saludos

Rossine.

Harbour and Harbour++
Rossine
 
Posts: 344
Joined: Tue Oct 11, 2005 11:33 am

Postby Antonio Linares » Wed Oct 01, 2008 7:53 am

In this example we try to analize all mouse input that we receive. If you run this example you will see that we get all the mouse activity. We need to find a way to select just the messages for the used window:
Code: Select all  Expand view  RUN
// Windows Raw Input API support demo, (c) FiveTech Software

#include "FiveWin.ch"

#define WM_INPUT  0x00FF

#define RI_MOUSE_LEFT_BUTTON_DOWN   0x0001  // Left Button changed to down.
#define RI_MOUSE_LEFT_BUTTON_UP     0x0002  // Left Button changed to up.
#define RI_MOUSE_RIGHT_BUTTON_DOWN  0x0004  // Right Button changed to down.
#define RI_MOUSE_RIGHT_BUTTON_UP    0x0008  // Right Button changed to up.
#define RI_MOUSE_MIDDLE_BUTTON_DOWN 0x0010  // Middle Button changed to down.
#define RI_MOUSE_MIDDLE_BUTTON_UP   0x0020  // Middle Button changed to up.

function Main()

   local oWnd := TMyWindow():New()

   oWnd:SetText( "Raw API test" )
   oWnd:SetMenu( BuildMenu( oWnd ) )
   
   oWnd:hMouse = GetRawMouse( 1 ) // First mouse is not valid
   
   RegisterRawInputDevices( oWnd:hWnd )

   SET MESSAGE OF oWnd TO "Click on the window to test it" 2007

   ACTIVATE WINDOW oWnd ;
      ON CLICK MsgInfo( "mouse click" )

return nil

function BuildMenu( oWnd )

   local oMenu, oMit1, oMit2, oMit3
   
   MENU oMenu
      MENUITEM "Select Mouse"
      MENU
         MENUITEM oMit1 PROMPT "Mouse 1" CHECKED ACTION ( oWnd:hMouse := GetRawMouse( 1 ), oMit1:SetCheck( .T. ), oMit2:SetCheck( .F. ), oMit3:SetCheck( .F. ) )
         MENUITEM oMit2 PROMPT "Mouse 2" ACTION ( oWnd:hMouse := GetRawMouse( 2 ), oMit1:SetCheck( .F. ), oMit2:SetCheck( .T. ), oMit3:SetCheck( .F. ) ) 
         MENUITEM oMit3 PROMPT "Mouse 3" ACTION ( oWnd:hMouse := GetRawMouse( 3 ), oMit1:SetCheck( .F. ), oMit2:SetCheck( .F. ), oMit3:SetCheck( .T. ) ) 
         SEPARATOR
         MENUITEM "Exit" ACTION oWnd:End()
      ENDMENU
   ENDMENU
   
return oMenu     

CLASS TMyWindow FROM TWindow

   CLASSDATA lRegistered
   
   DATA hMouse // handle of the mouse to use
   DATA lProcessMouse INIT .F.

   METHOD HandleEvent( nMsg, nWParam, nLParam )

ENDCLASS

METHOD HandleEvent( nMsg, nWParam, nLParam ) CLASS TMyWindow

   local nButtons

   if nMsg == WM_INPUT
      // ::lProcessMouse = RawIsMouse( nLParam ) .and. RawGetHandle( nLParam ) == ::hMouse
      if RawIsMouse( nLParam ) .and. RawGetHandle( nLParam ) == ::hMouse
         nButtons = RawButtons( nLParam )
         do case
            case nAnd( nButtons, RI_MOUSE_LEFT_BUTTON_DOWN ) == RI_MOUSE_LEFT_BUTTON_DOWN
                 MsgInfo( "Left button down" )

         endcase           
      endif   
   endif   
   
   if nMsg == WM_LBUTTONDOWN .and. ! ::lProcessMouse
      return nil
   endif   

return Super:HandleEvent( nMsg, nWParam, nLParam )

#pragma BEGINDUMP

#include <hbapi.h>
#include <windows.h>

#define RIDEV_NOLEGACY  0x00000030
#define RIDEV_INPUTSINK 0x00000100

#define RID_INPUT       0x10000003
#define RID_HEADER      0x10000005

#define RIDI_DEVICENAME 0x20000007
#define RIDI_DEVICEINFO 0x2000000b

#define RIM_TYPEMOUSE       0
#define RIM_TYPEKEYBOARD    1
#define RIM_TYPEHID         2

#define RI_MOUSE_LEFT_BUTTON_DOWN   0x0001  // Left Button changed to down.
#define RI_MOUSE_LEFT_BUTTON_UP     0x0002  // Left Button changed to up.
#define RI_MOUSE_RIGHT_BUTTON_DOWN  0x0004  // Right Button changed to down.
#define RI_MOUSE_RIGHT_BUTTON_UP    0x0008  // Right Button changed to up.
#define RI_MOUSE_MIDDLE_BUTTON_DOWN 0x0010  // Middle Button changed to down.
#define RI_MOUSE_MIDDLE_BUTTON_UP   0x0020  // Middle Button changed to up.

typedef struct tagRAWINPUTDEVICE
{
   USHORT usUsagePage;
   USHORT usUsage;
   DWORD dwFlags;
   HWND hwndTarget;
} RAWINPUTDEVICE, * PRAWINPUTDEVICE, * LPRAWINPUTDEVICE;

typedef BOOL WINAPI ( * PREGISTERRAWINPUTDEVICES ) (     
   PRAWINPUTDEVICE pRawInputDevices,
   UINT uiNumDevices,
   UINT cbSize
);

typedef struct tagRAWINPUTHEADER {
    DWORD dwType;
    DWORD dwSize;
    HANDLE hDevice;
    WPARAM wParam;
} RAWINPUTHEADER, * PRAWINPUTHEADER;

typedef struct tagRAWMOUSE {
  USHORT    usFlags;
  union {
         ULONG    ulButtons;
             struct {
                       USHORT usButtonFlags;
                       USHORT usButtonData;
                       };
  };
  ULONG ulRawButtons;
  LONG  lLastX;
  LONG  lLastY;
  ULONG ulExtraInformation;
} RAWMOUSE, * PRAWMOUSE, * LPRAWMOUSE;

typedef struct tagRAWKEYBOARD {
    USHORT MakeCode;
    USHORT Flags;
    USHORT Reserved;
    USHORT VKey;
    UINT Message;
    ULONG ExtraInformation;
} RAWKEYBOARD, *PRAWKEYBOARD, *LPRAWKEYBOARD;

typedef struct tagRAWHID {
    DWORD dwSizeHid;
    DWORD dwCount;
    BYTE bRawData;
} RAWHID, **LPRAWHID;

typedef struct tagRAWINPUT {
    RAWINPUTHEADER header;
    union {
       RAWMOUSE    mouse;
       RAWKEYBOARD keyboard;
       RAWHID      hid;
    } data;
} RAWINPUT, * PRAWINPUT, * LPRAWINPUT;

typedef UINT WINAPI ( * PGETRAWINPUTDATA ) (     
    LPRAWINPUT hRawInput,
    UINT uiCommand,
    LPVOID pData,
    PUINT pcbSize,
    UINT cbSizeHeader
);

typedef struct tagRAWINPUTDEVICELIST {
    HANDLE hDevice;
    DWORD dwType;
} RAWINPUTDEVICELIST, * PRAWINPUTDEVICELIST;

typedef UINT WINAPI ( * PGETRAWINPUTDEVICELIST ) (     
    PRAWINPUTDEVICELIST pRawInputDeviceList,
    PUINT puiNumDevices,
    UINT cbSize
);

typedef struct tagRID_DEVICE_INFO_MOUSE {
    DWORD dwId;
    DWORD dwNumberOfButtons;
    DWORD dwSampleRate;
    BOOL fHasHorizontalWheel;
} RID_DEVICE_INFO_MOUSE, * PRID_DEVICE_INFO_MOUSE;

typedef struct tagRID_DEVICE_INFO_KEYBOARD {
    DWORD dwType;
    DWORD dwSubType;
    DWORD dwKeyboardMode;
    DWORD dwNumberOfFunctionKeys;
    DWORD dwNumberOfIndicators;
    DWORD dwNumberOfKeysTotal;
} RID_DEVICE_INFO_KEYBOARD, * PRID_DEVICE_INFO_KEYBOARD;

typedef struct tagRID_DEVICE_INFO_HID {
    DWORD dwVendorId;
    DWORD dwProductId;
    DWORD dwVersionNumber;
    USHORT usUsagePage;
    USHORT usUsage;
} RID_DEVICE_INFO_HID, * PRID_DEVICE_INFO_HID;

typedef struct tagRID_DEVICE_INFO {
  DWORD    cbSize;
  DWORD    dwType;
  union {
      RID_DEVICE_INFO_MOUSE     mouse;
      RID_DEVICE_INFO_KEYBOARD  keyboard;
      RID_DEVICE_INFO_HID       hid;
  };
} RID_DEVICE_INFO, * PRID_DEVICE_INFO, * LPRID_DEVICE_INFO;

typedef UINT WINAPI ( * PGETRAWINPUTDEVICEINFO ) (     
    HANDLE hDevice,
    UINT uiCommand,
    LPVOID pData,
    PUINT pcbSize
);

typedef LRESULT WINAPI ( * PDEFRAWINPUTPROC ) (     
    PRAWINPUT * paRawInput,
    INT nInput,
    UINT cbSizeHeader
);

static PREGISTERRAWINPUTDEVICES pRegisterRawInputDevices;
static PGETRAWINPUTDEVICELIST   pGetRawInputDeviceList;
static PGETRAWINPUTDEVICEINFO   pGetRawInputDeviceInfo;
static PGETRAWINPUTDATA         pGetRawInputData;
static PDEFRAWINPUTPROC         pDefRawInputProc;

static void RawInit( void )
{
   static BOOL bInit = FALSE;
   
   if( ! bInit )
   {
      HINSTANCE hUser32 = LoadLibrary( "user32.dll" );

      pRegisterRawInputDevices = ( PREGISTERRAWINPUTDEVICES ) GetProcAddress( hUser32, "RegisterRawInputDevices" );
      pGetRawInputDeviceList   = ( PGETRAWINPUTDEVICELIST ) GetProcAddress( hUser32, "GetRawInputDeviceList" );
      pGetRawInputDeviceInfo   = ( PGETRAWINPUTDEVICEINFO ) GetProcAddress( hUser32, "GetRawInputDeviceInfoA" );
      pGetRawInputData         = ( PGETRAWINPUTDATA ) GetProcAddress( hUser32, "GetRawInputData" );
      pDefRawInputProc         = ( PDEFRAWINPUTPROC ) GetProcAddress( hUser32, "DefRawInputProc" );
     
      FreeLibrary( hUser32 );
      bInit = TRUE;
   }   
}   

HB_FUNC( REGISTERRAWINPUTDEVICES )
{
   RAWINPUTDEVICE rid[ 2 ];

   RawInit();
   
   rid[ 0 ].usUsagePage = 0x01;
   rid[ 0 ].usUsage     = 0x02; // Mouse
   rid[ 0 ].dwFlags     = RIDEV_INPUTSINK; // RIDEV_NOLEGACY;
   rid[ 0 ].hwndTarget  = ( HWND ) hb_parnl( 1 );

   rid[ 1 ].usUsagePage = 0x01;
   rid[ 1 ].usUsage     = 0x06; // Keyboard
   rid[ 1 ].dwFlags     = RIDEV_INPUTSINK;
   rid[ 1 ].hwndTarget  = ( HWND ) hb_parnl( 1 );
   
   hb_retl( pRegisterRawInputDevices( rid, 2, sizeof( RAWINPUTDEVICE ) ) );
}

HB_FUNC( GETRAWINPUTDATA )
{
   UINT dwSize;
   LPBYTE lpb;

   RawInit();
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, NULL, &dwSize,
                     sizeof( RAWINPUTHEADER ) );
                     
   lpb = ( LPBYTE ) hb_xgrab( dwSize );                 

   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, lpb, &dwSize,
                     sizeof( RAWINPUTHEADER ) );
   hb_retnl( ( unsigned long ) lpb );                 
}                   

HB_FUNC( GETRAWINPUTDEVICELIST )
{
   UINT nDevices;
   PRAWINPUTDEVICELIST pRawInputDeviceList;

   RawInit();
   
   pGetRawInputDeviceList( NULL, &nDevices, sizeof( RAWINPUTDEVICELIST ) );
   
   if( nDevices )
   {
      UINT ui;
     
      pRawInputDeviceList = ( PRAWINPUTDEVICELIST ) hb_xgrab( sizeof( RAWINPUTDEVICELIST ) * nDevices );
     
      pGetRawInputDeviceList( pRawInputDeviceList, &nDevices, sizeof( RAWINPUTDEVICELIST ) );
     
      hb_reta( nDevices );
     
      for( ui = 0; ui < nDevices; ui++ )
      {
         char name[ 512 ];
         UINT uiSize = 511;
         
         pGetRawInputDeviceInfo( pRawInputDeviceList[ ui ].hDevice, RIDI_DEVICENAME, ( void * ) name, &uiSize );
         hb_storclen( name, uiSize, -1, ui + 1 );
      }
     
      hb_xfree( ( void * ) pRawInputDeviceList );
   }   
}

HB_FUNC( GETRAWMOUSE ) // nMouse --> hDevice
{
   UINT nDevices;
   PRAWINPUTDEVICELIST pRawInputDeviceList;

   RawInit();   
   pGetRawInputDeviceList( NULL, &nDevices, sizeof( RAWINPUTDEVICELIST ) );
   
   if( nDevices )
   {
      UINT ui;
      UINT uiMouses = 0;
     
      pRawInputDeviceList = ( PRAWINPUTDEVICELIST ) hb_xgrab( sizeof( RAWINPUTDEVICELIST ) * nDevices );
     
      pGetRawInputDeviceList( pRawInputDeviceList, &nDevices, sizeof( RAWINPUTDEVICELIST ) );
     
      for( ui = 0; ui < nDevices; ui++ )
      {
         RID_DEVICE_INFO rdi;
         UINT uiSize = sizeof( RID_DEVICE_INFO );       
         UINT uiMouse = hb_parnl( 1 );
         
         rdi.cbSize = sizeof( RID_DEVICE_INFO );
         
         pGetRawInputDeviceInfo( pRawInputDeviceList[ ui ].hDevice, RIDI_DEVICEINFO, ( void * ) &rdi, &uiSize );
         
         if( rdi.dwType == RIM_TYPEMOUSE )
         {
            if( ++uiMouses == uiMouse )
            {
               hb_retnl( ( unsigned long ) pRawInputDeviceList[ ui ].hDevice );
               hb_xfree( ( void * ) pRawInputDeviceList );
               return;
            }   
         }   
      }
     
      hb_retnl( 0 );
      hb_xfree( ( void * ) pRawInputDeviceList );
   }   
}

HB_FUNC( GETRAWMOUSES ) // --> nMouses
{
   UINT nDevices, uiMouses = 0;
   PRAWINPUTDEVICELIST pRawInputDeviceList;

   RawInit();   
   pGetRawInputDeviceList( NULL, &nDevices, sizeof( RAWINPUTDEVICELIST ) );
   
   if( nDevices )
   {
      UINT ui;
     
      pRawInputDeviceList = ( PRAWINPUTDEVICELIST ) hb_xgrab( sizeof( RAWINPUTDEVICELIST ) * nDevices );
     
      pGetRawInputDeviceList( pRawInputDeviceList, &nDevices, sizeof( RAWINPUTDEVICELIST ) );
     
      for( ui = 0; ui < nDevices; ui++ )
      {
         RID_DEVICE_INFO rdi;
         UINT uiSize = sizeof( RID_DEVICE_INFO );       
         
         rdi.cbSize = sizeof( RID_DEVICE_INFO );
         
         pGetRawInputDeviceInfo( pRawInputDeviceList[ ui ].hDevice, RIDI_DEVICEINFO, ( void * ) &rdi, &uiSize );
         
         if( rdi.dwType == RIM_TYPEMOUSE )
            uiMouses++;
      }
     
      hb_xfree( ( void * ) pRawInputDeviceList );
   }   

   hb_retnl( --uiMouses ); // Windows reports an extra mouse (?)
}

HB_FUNC( RAWISMOUSE )
{
   LPBYTE lpb;
   UINT dwSize;

   RawInit();
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, NULL, &dwSize,
                     sizeof( RAWINPUTHEADER ) );
   lpb = ( LPBYTE ) hb_xgrab( dwSize );                 
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, lpb, &dwSize,
                     sizeof( RAWINPUTHEADER ) );   
   hb_retl( ( ( PRAWINPUT ) lpb )->header.dwType == RIM_TYPEMOUSE );
   hb_xfree( ( void * ) lpb );
}   

HB_FUNC( RAWGETHANDLE )
{
   LPBYTE lpb;
   UINT dwSize;

   RawInit();
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, NULL, &dwSize,
                     sizeof( RAWINPUTHEADER ) );
   lpb = ( LPBYTE ) hb_xgrab( dwSize );                 
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, lpb, &dwSize,
                     sizeof( RAWINPUTHEADER ) );   
   hb_retnl( ( unsigned long ) ( ( PRAWINPUT ) lpb )->header.hDevice );
   hb_xfree( ( void * ) lpb );
}   

HB_FUNC( RAWBUTTONS )
{
   LPBYTE lpb;
   UINT dwSize;

   RawInit();
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, NULL, &dwSize,
                     sizeof( RAWINPUTHEADER ) );
   lpb = ( LPBYTE ) hb_xgrab( dwSize );                 
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, lpb, &dwSize,
                     sizeof( RAWINPUTHEADER ) );   
   hb_retnl( ( unsigned long ) ( ( PRAWINPUT ) lpb )->data.mouse.usButtonFlags );
   hb_xfree( ( void * ) lpb );
}   

HB_FUNC( DEFRAWINPUTPROC )
{
   LPBYTE lpb;
   UINT dwSize;

   RawInit();
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, NULL, &dwSize,
                     sizeof( RAWINPUTHEADER ) );
   lpb = ( LPBYTE ) hb_xgrab( dwSize );                 
   pGetRawInputData( ( LPRAWINPUT ) hb_parnl( 1 ), RID_INPUT, lpb, &dwSize,
                     sizeof( RAWINPUTHEADER ) );   
   pDefRawInputProc( ( LPRAWINPUT * ) &lpb, 1, sizeof( RAWINPUTHEADER ) );
   hb_xfree( ( void * ) lpb );
}   

#pragma ENDDUMP
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42118
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Mike Buckler » Thu Oct 02, 2008 4:23 am

Thanks For Your Effort Antonio
Mike
Mike Buckler
 
Posts: 67
Joined: Thu Jan 05, 2006 10:35 pm
Location: Canada

Postby Antonio Linares » Thu Oct 02, 2008 7:25 am

I am googling for info about how to proceed. It looks as other programmers have our same questions:

http://www.tech-archive.net/Archive/Dev ... 00021.html

The problem is that WM_INPUT does not provide info about the windows handle where the event hapenned. Meanwhile I am typing this an idea arised: if our windows has the focus and we get a WM_INPUT message then it is for us. If we don't have the focus, it is not for us...

Time for more tests :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42118
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Antonio Linares » Thu Oct 02, 2008 7:41 am

This line may be the missing part that we need:
Code: Select all  Expand view  RUN
      if ::hWnd == GetFocus() .and. RawIsMouse( nLParam ) .and. RawGetHandle( nLParam ) == ::hMouse

More tests... :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42118
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Antonio Linares » Thu Oct 02, 2008 8:35 am

No, not yet.

We need to keep searching how to do the right conversion from WM_INPUT to WM_(mouse) and WM_(keyb) messages.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42118
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

PreviousNext

Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 44 guests