If you're using win32 then you can handle mouse and keyboard events using RawInput. Info can be found on MSDN.
You would handle windows messages for raw input devices in the window process.
For example, if handling the input for a keyboard and mouse, register those devices in the WM_CREATE case of your application window process like so:
switch( uMsg ){
case WM_CREATE:
{
// register raw input devices
RAWINPUTDEVICE rID[2];
// Keyboard
rID[0].usUsagePage = 1;
rID[0].usUsage = 6;
rID[0].dwFlags = 0;
rID[0].hwndTarget=NULL;
// Mouse
rID[1].usUsagePage = 1;
rID[1].usUsage = 2;
rID[1].dwFlags = 0;
rID[1].hwndTarget = hWnd;
if ( !RegisterRawInputDevices( rID, 2, sizeof( RAWINPUTDEVICE ) ) )
{
// handle failure
}
...
break;
}
Then in the same process handle the raw input messages with WM_INPUT like so:
switch( uMsg )
{
...
case WM_INPUT:
{
RAWINPUT *pRI = NULL;
// Determine how big the buffer should be
UINT iBuffer;
GetRawInputData( ( HRAWINPUT )lParam, RID_INPUT, NULL, &iBuffer, sizeof( RAWINPUTHEADER ) );
// Allocate a buffer with enough size to hold the raw input data
LPBYTE lpb = new BYTE[ iBuffer ];
if( lpb == NULL )
return 0;
// Get the raw input data
UINT readSize = GetRawInputData( ( HRAWINPUT )lParam, RID_INPUT, lpb, &iBuffer, sizeof( RAWINPUTHEADER ) ) ;
// Validate that read size is as expected
if( readSize != iBuffer )
puts( "ERROR: GetRawInputData didn't return correct size!" ) ;
pRI = ( RAWINPUT* )lpb;
// Process the Mouse Messages
if( pRI->header.dwType== RIM_TYPEMOUSE )
{
raw.riProcessMouseMessage( &pRI->data.mouse );
}
// Process the Keyboard Messages
if( pRI->header.dwType== RIM_TYPEKEYBOARD )
{
raw.riProcessKeyboardMessage( &pRI->data.keyboard );
}
// Destroy the Raw Input Data and Return
SAFE_DELETE( lpb );
return 1;
}
}
The 'raw.riProcessMouseMessage() and raw.riProcessKeyboardMessage() functions come from a class I use to keep track of raw input keyboard and mouse states...I found this on a raw input tutorial( that I can't find right now ). Here are the function definitions:
USHORT keyState[256];
short mouseState[5];
short mzr;
long mxr, myr;
USHORT MASKDOWN[ 5 ] = { RI_MOUSE_LEFT_BUTTON_DOWN,
RI_MOUSE_RIGHT_BUTTON_DOWN,
RI_MOUSE_MIDDLE_BUTTON_DOWN,
RI_MOUSE_BUTTON_4_DOWN,
RI_MOUSE_BUTTON_5_DOWN };
USHORT MASKUP[ 5 ] = { RI_MOUSE_LEFT_BUTTON_UP,
RI_MOUSE_RIGHT_BUTTON_UP,
RI_MOUSE_MIDDLE_BUTTON_UP,
RI_MOUSE_BUTTON_4_UP,
RI_MOUSE_BUTTON_5_UP };
void riManager::riProcessMouseMessage( const RAWMOUSE *rmouse )
{
// Store Mouse Button States
for(int i = 0; i < 5; i++)
{
if( MASKDOWN[ i ] & rmouse->usButtonFlags )
mouseState[ i ] = 1;
else if( MASKUP[ i ] & rmouse->usButtonFlags )
mouseState[ i ] = 0;
}
// Check Mouse Position Relative Motion
if ( MOUSE_MOVE_RELATIVE == rmouse->usFlags )
{
mxr = rmouse->lLastX ;
myr = rmouse->lLastY ;
}
// Check Mouse Wheel Relative Motion
mzr = ( RI_MOUSE_WHEEL & rmouse->usButtonFlags ) ? ( short )( rmouse->usButtonData ) : 0;
}
void riManager::riProcessKeyboardMessage( const RAWKEYBOARD *rkey )
{
// Store New Key State
keyState[ rkey->VKey ] &= 0xfe;
keyState[ rkey->VKey ] |= 1 - ( RI_KEY_BREAK & rkey->Flags );
}
It will be up to you to manage these variables. Build a class to hold the variables, then you can access the key and mouse states at will.