openDecal/Native/DecalInput/TypeAction.h
erik d1442e3747 Initial commit: Complete open-source Decal rebuild
All 5 phases of the open-source Decal rebuild:

Phase 1: 14 decompiled .NET projects (Interop.*, Adapter, FileService, DecalUtil)
Phase 2: 10 native DLLs rewritten as C# COM servers with matching GUIDs
  - DecalDat, DHS, SpellFilter, DecalInput, DecalNet, DecalFilters
  - Decal.Core, DecalControls, DecalRender, D3DService
Phase 3: C++ shims for Inject.DLL (D3D9 hooking) and LauncherHook.DLL
Phase 4: DenAgent WinForms tray application
Phase 5: WiX installer and build script

25 C# projects building with 0 errors.
Native C++ projects require VS 2022 + Windows SDK (x86).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 18:27:56 +01:00

140 lines
3.3 KiB
C++

// TypeAction.h : Declaration of the cTypeAction
#ifndef __TYPEACTION_H_
#define __TYPEACTION_H_
#include "resource.h" // main symbols
#include <DecalInputImpl.h>
#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<CComSingleThreadModel>,
public CComCoClass<cTypeAction, &CLSID_TypeAction>,
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_