You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
5.1 KiB
149 lines
5.1 KiB
#include "sendInput.hpp"
|
|
#include "globals.hpp"
|
|
|
|
using namespace std ;
|
|
|
|
// --- CONSTRUCTORS ----------------------------------------------------
|
|
|
|
CSendInput::CSendInput()
|
|
{
|
|
}
|
|
|
|
// --- DESTRUCTOR ------------------------------------------------------
|
|
|
|
CSendInput::~CSendInput()
|
|
{
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void
|
|
CSendInput::setKeyboardState( const KeyboardState& newKeyboardState , const KeyboardState& currKeyboardState )
|
|
{
|
|
// NOTE: Applications sometimes get confused when we send a key-down message and that key is already down,
|
|
// so we have to check that we only send messages when they are required.
|
|
|
|
// set the new keyboard state
|
|
if ( newKeyboardState.isCtrlDown() && !currKeyboardState.isCtrlDown() )
|
|
sendKeyboardInput( VK_CONTROL , true ) ;
|
|
else if ( !newKeyboardState.isCtrlDown() && currKeyboardState.isCtrlDown() )
|
|
sendKeyboardInput( VK_CONTROL , false ) ;
|
|
|
|
// set the new keyboard state
|
|
if ( newKeyboardState.isAltDown() && !currKeyboardState.isAltDown() )
|
|
sendKeyboardInput( VK_MENU , true ) ;
|
|
else if ( !newKeyboardState.isAltDown() && currKeyboardState.isAltDown() )
|
|
sendKeyboardInput( VK_MENU , false ) ;
|
|
|
|
// set the new keyboard state
|
|
if ( newKeyboardState.isShiftDown() && !currKeyboardState.isShiftDown() )
|
|
sendKeyboardInput( VK_SHIFT , true ) ;
|
|
else if ( !newKeyboardState.isShiftDown() && currKeyboardState.isShiftDown() )
|
|
sendKeyboardInput( VK_SHIFT , false ) ;
|
|
|
|
// set the new keyboard state
|
|
if ( newKeyboardState.isCapsLockDown() && !currKeyboardState.isCapsLockDown() )
|
|
sendKeyboardInput( VK_CAPITAL , true ) ;
|
|
else if ( !newKeyboardState.isCapsLockDown() && currKeyboardState.isCapsLockDown() )
|
|
sendKeyboardInput( VK_CAPITAL , false ) ;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void
|
|
CSendInput::sendKeyboardInput( WORD keyCode , bool keyDown )
|
|
{
|
|
// send the keyboard input
|
|
INPUT inputRec ;
|
|
memset( &inputRec , 0 , sizeof(INPUT) ) ;
|
|
inputRec.type = INPUT_KEYBOARD ;
|
|
inputRec.ki.wVk = keyCode ;
|
|
if ( ! keyDown )
|
|
inputRec.ki.dwFlags |= KEYEVENTF_KEYUP ;
|
|
doSendInput( &inputRec ) ;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void
|
|
CSendInput::sendMouseMoveInput( int dx , int dy , const KeyboardState& keyboardState )
|
|
{
|
|
// send the mouse movement input
|
|
KeyboardStateGuard keyboardStateGuard( *this , keyboardState ) ;
|
|
INPUT inputRec ;
|
|
memset( &inputRec , 0 , sizeof(INPUT) ) ;
|
|
inputRec.type = INPUT_MOUSE ;
|
|
inputRec.mi.dx = dx ;
|
|
inputRec.mi.dy = dy ;
|
|
inputRec.mi.dwFlags = MOUSEEVENTF_MOVE ;
|
|
doSendInput( &inputRec ) ;
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
void
|
|
CSendInput::sendWheelInput( int scrollSize , const KeyboardState& keyboardState )
|
|
{
|
|
// send the mouse-wheel input
|
|
KeyboardStateGuard keyboardStateGuard( *this , keyboardState ) ;
|
|
INPUT inputRec ;
|
|
memset( &inputRec , 0 , sizeof(INPUT) ) ;
|
|
inputRec.type = INPUT_MOUSE ;
|
|
inputRec.mi.dwFlags = MOUSEEVENTF_WHEEL ;
|
|
inputRec.mi.mouseData = scrollSize ; // FIXME! s.b. dwData for vista
|
|
doSendInput( &inputRec ) ;
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
void
|
|
CSendInput::sendHorzWheelInput( int scrollSize , const KeyboardState& keyboardState )
|
|
{
|
|
// send the mouse-wheel input
|
|
KeyboardStateGuard keyboardStateGuard( *this , keyboardState ) ;
|
|
INPUT inputRec ;
|
|
memset( &inputRec , 0 , sizeof(INPUT) ) ;
|
|
inputRec.type = INPUT_MOUSE ;
|
|
inputRec.mi.dwFlags = MOUSEEVENTF_HWHEEL ;
|
|
inputRec.mi.mouseData = scrollSize ; // FIXME! s.b. dwData for vista
|
|
doSendInput( &inputRec ) ;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void
|
|
CSendInput::doSendInput( INPUT* pInputRec )
|
|
{
|
|
// log the input
|
|
if ( isLoggingEnabled( "sendInput" ) )
|
|
{
|
|
if ( pInputRec->type == INPUT_MOUSE )
|
|
{
|
|
LOG_MSG(
|
|
"SEND INPUT (mouse):"
|
|
<< " dx=" << pInputRec->mi.dx << " ; dy=" << pInputRec->mi.dy
|
|
<< " ; mouseData=" << (int)pInputRec->mi.mouseData
|
|
<< " ; flags=0x" << hexString(pInputRec->mi.dwFlags)
|
|
) ;
|
|
}
|
|
else if ( pInputRec->type == INPUT_KEYBOARD )
|
|
{
|
|
LOG_MSG(
|
|
"SEND INPUT (keyboard):"
|
|
<< " vkey=" << pInputRec->ki.wVk << " ; scan=" << pInputRec->ki.wScan
|
|
<< " ; flags=0x" << hexString(pInputRec->ki.dwFlags)
|
|
) ;
|
|
}
|
|
else
|
|
assert( false ) ;
|
|
}
|
|
|
|
// send the input
|
|
// NOTE: The documentation says that we can send multiple events at once, and they will be guaranteed
|
|
// to not have other events interspersed between them, but things don't work :-( and the only way
|
|
// I could get it to work was to send events one at a time, with a (non-zero) sleep between them.
|
|
// Maybe because we're manipulating the Ctrl/Alt/Shift keys...?
|
|
UINT nEventRecs = SendInput( 1 , pInputRec , sizeof(INPUT) ) ;
|
|
assert( nEventRecs == 1 ) ;
|
|
Sleep( 5 ) ; // FIXME! get rid of this
|
|
}
|
|
|