// TypeAction.h : Declaration of the cTypeAction #ifndef __TYPEACTION_H_ #define __TYPEACTION_H_ #include "resource.h" // main symbols #include #define MASK_SHIFT 0x0100 #define MASK_CTRL 0x0200 #define MASK_ALT 0x0400 #define SHIFT_MASK 0x0700 #define VKEY_MASK 0x00FF ///////////////////////////////////////////////////////////////////////////// // cTypeAction class ATL_NO_VTABLE cTypeAction : public CComObjectRootEx, public CComCoClass, public IInputActionImpl< cTypeAction > { public: cTypeAction() : i_input( m_pInput ) { ::memset( m_pInput, 0, sizeof( INPUT ) * 16 ); } struct cKey { long m_nShiftState, m_nVK; }; typedef std::deque< cKey > cKeyList; cKeyList m_keys; INPUT m_pInput[ 32 ], *i_input; void nextInput() { ++ i_input; if( i_input == ( m_pInput + 32 ) ) flushInput(); } void flushInput() { if( i_input != m_pInput ) { ::SendInput( ( i_input - m_pInput ), m_pInput, sizeof( INPUT ) ); i_input = m_pInput; ::memset( m_pInput, 0, sizeof( INPUT ) * 32 ); } } void pressKey(long nVK, bool bDown) { switch( nVK ) { case VK_LBUTTON: i_input->type = INPUT_MOUSE; i_input->mi.dwFlags = ( bDown ) ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP; break; case VK_RBUTTON: i_input->type = INPUT_MOUSE; i_input->mi.dwFlags = ( bDown ) ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP; break; default: i_input->type = INPUT_KEYBOARD; i_input->ki.wVk = nVK; i_input->ki.wScan = ::MapVirtualKey( nVK, 0 ); i_input->ki.dwFlags = ( bDown ) ? 0 : KEYEVENTF_KEYUP; break; } nextInput(); } void transitionShift(long nFrom, long nTo) { if( nFrom == nTo ) // Nothing to transition return; // Check for all 6 possible key presses if( ( nFrom & MASK_SHIFT ) && !( nTo & MASK_SHIFT ) ) pressKey( VK_SHIFT, false ); else if( !( nFrom & MASK_SHIFT ) && ( nTo & MASK_SHIFT ) ) pressKey( VK_SHIFT, true ); if( ( nFrom & MASK_CTRL ) && !( nTo & MASK_CTRL ) ) pressKey( VK_CONTROL, false ); else if( !( nFrom & MASK_CTRL ) && ( nTo & MASK_CTRL ) ) pressKey( VK_CONTROL, true ); if( ( nFrom & MASK_ALT ) && !( nTo & MASK_ALT ) ) pressKey( VK_MENU, false ); else if( !( nFrom & MASK_ALT ) && ( nTo & MASK_ALT ) ) pressKey( VK_MENU, true ); } HRESULT extractKey( LPTSTR &szIterator, long nShiftState, IInputService *pService ); HRESULT onLoad( LPTSTR szData ); template< class iterator_t > void doInput( iterator_t begin, iterator_t end, bool bDown ) { for( iterator_t i = begin; i != end; ++ i ) pressKey( i->m_nVK, bDown ); flushInput(); } DECLARE_REGISTRY_RESOURCEID(IDR_TYPEACTION) DECLARE_PROTECT_FINAL_CONSTRUCT() BEGIN_COM_MAP(cTypeAction) COM_INTERFACE_ENTRY(IInputAction) END_COM_MAP() // ITypeAction public: STDMETHOD(get_Stackable)(VARIANT_BOOL *pVal) { *pVal = VARIANT_TRUE; return S_OK; } STDMETHOD(Execute)(); STDMETHOD(Push)(); STDMETHOD(Pop)(); }; #endif //__TYPEACTION_H_