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>
This commit is contained in:
erik 2026-02-08 18:27:56 +01:00
commit d1442e3747
1382 changed files with 170725 additions and 0 deletions

View file

@ -0,0 +1,282 @@
// DirectDrawHook.cpp : Implementation of CDirectDrawHook
#include "stdafx.h"
#include "Inject.h"
#include "DirectDrawHook.h"
#include "MaterialHook.h"
#include "DirectDrawSurfaceHook.h"
#include "Manager.h"
//#include <fstream>
/////////////////////////////////////////////////////////////////////////////
// CDirectDrawHook
void CDirectDrawHook::setObject( IDirectDraw *pDD )
{
m_pDD = pDD;
m_pDD->QueryInterface( IID_IDirectDraw2, reinterpret_cast< void ** >( &m_pDD2 ) );
m_pDD->QueryInterface( IID_IDirectDraw4, reinterpret_cast< void ** >( &m_pDD4 ) );
m_pDD->QueryInterface( IID_IDirect3D, reinterpret_cast< void ** >( &m_pD3D ) );
m_pDD->QueryInterface( IID_IDirect3D2, reinterpret_cast< void ** >( &m_pD3D2 ) );
m_pDD->QueryInterface( IID_IDirect3D3, reinterpret_cast< void ** >( &m_pD3D3 ) );
cManager::_p->setDirectDraw( m_pDD4, m_pD3D3, NULL);
}
STDMETHODIMP CDirectDrawHook::SetCooperativeLevel(HWND p1, DWORD p2)
{
cManager::_p->setWindow( p1 );
return m_pDD->SetCooperativeLevel( p1, p2 );
}
STDMETHODIMP CDirectDrawHook::SetDisplayMode(DWORD p1, DWORD p2, DWORD p3)
{
return m_pDD->SetDisplayMode( p1, p2, p3 );
}
HRESULT (__stdcall *pfnOldUnlock)(IDirectDrawSurface4 *pDDS, LPRECT rc);
HRESULT __stdcall myUnlock ( IDirectDrawSurface4 *pDDS, LPRECT rc)
{
HRESULT hRes = pfnOldUnlock(pDDS, rc);
if(rc==NULL)
cManager::_p->draw2D();
//MessageBox(0, _bstr_t(" left: ") + _bstr_t((long)rc->left) + _bstr_t(" top: ") + _bstr_t((long)rc->top) + _bstr_t(" right: ") + _bstr_t((long)rc->right) + _bstr_t(" bottom: ") + _bstr_t((long)rc->bottom), "Asd", 0);
return hRes;
}
STDMETHODIMP CDirectDrawHook::CreateSurface(LPDDSURFACEDESC2 p1, LPDIRECTDRAWSURFACE4 FAR *ppDDS, IUnknown FAR *p3)
{
static bool bGotPrimary=false;
static sc=0;
//static std::ofstream ass("c:\\acl.txt", std::ios::binary);
//ass << "Flags: " << p1->dwFlags << " dwCaps: " << p1->ddsCaps.dwCaps << " Width: " << p1->dwWidth << " Height: " << p1->dwHeight << "\r\n";
if((cManager::_p->getSoftwareMode()))// && (!bGotPrimary))
{
/*CComPtr< IDirectDrawSurface4 > pDDS;
HRESULT hRes = m_pDD4->CreateSurface( p1, &pDDS, p3 );
if( FAILED( hRes ) )
return hRes;
if(!(p1->ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE)))// | DDSCAPS_COMPLEX)))
{
pDDS->QueryInterface(IID_IDirectDrawSurface4, reinterpret_cast< void ** >(ppDDS));
return hRes;
}
m_nSurfaceCount++;
if(m_nSurfaceCount==1)//!=4)
cManager::_p->setDirectDraw(m_pDD4, NULL, pDDS);
CComObject< CDirectDrawSurfaceHook > *pHook;
CComObject< CDirectDrawSurfaceHook >::CreateInstance( &pHook );
pHook->setObject( pDDS );
pHook->setSurfaceNum( m_nSurfaceCount );
pHook->QueryInterface( IID_IDirectDrawSurface4, reinterpret_cast< void ** >( ppDDS ) );
*/
CComPtr< IDirectDrawSurface4 > pDDS;
HRESULT hRes = m_pDD4->CreateSurface( p1, &pDDS, p3 );
if( FAILED( hRes ) )
return hRes;
// Get the configured width from the registry
/* DWORD dwConfiguredWidth;
{
RECT rc;
::GetClientRect( cManager::_p->m_hMain, &rc );
dwConfiguredWidth = rc.right - rc.left;
}*/
/*if( p1->dwWidth < ( dwConfiguredWidth - 330 ) )
{
}
else*/
if(p1->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)// && (p1->dwHeight==362) && (p1->dwWidth==300))//(p1->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)
{
//MessageBox(0, _bstr_t("Width: ") + _bstr_t((long)p1->dwWidth) + _bstr_t(" Height: ") + _bstr_t((long)p1->dwHeight), "asd", 0);
sc++;
if((!bGotPrimary) && (sc==2))
{
sc=0;
HRESULT (__stdcall *&pfnUnlock)(IDirectDrawSurface4 *pDDS, LPRECT rc) = reinterpret_cast< HRESULT (__stdcall**)(IDirectDrawSurface4 *pDDS, LPRECT rc) > ( *reinterpret_cast< DWORD * > ( pDDS.p ) )[ 32 ];
pfnOldUnlock = *pfnUnlock;
pfnUnlock = myUnlock;
//if((p1->dwHeight>=362) && (p1->dwWidth>=300))
//{
// cManager::_p->SurfaceList.push_back(pDDS);
//MessageBox(0, _bstr_t(CSC), "asd", 0);
//557 or 333
//}
//if(CSC==1)
//{
/* CComObject< CDirectDrawSurfaceHook > *pHook;
CComObject< CDirectDrawSurfaceHook >::CreateInstance( &pHook );
pHook->setObject( pDDS );*/
bGotPrimary=true;
//if(!bGotPrimary)
//{
cManager::_p->setDirectDraw(m_pDD4, NULL, pDDS);
cManager::_p->setSurface(NULL);
//}
}
}
//pHook->QueryInterface( IID_IDirectDrawSurface4, reinterpret_cast< void ** >( ppDDS ) );
// return hRes;
//}
/* pHook->QueryInterface(IID_IDirectDrawSurface4, reinterpret_cast< void ** >(ppDDS));
}
else*/
pDDS->QueryInterface(IID_IDirectDrawSurface4, reinterpret_cast< void ** >(ppDDS));
m_pPrimary = pDDS.p;
return hRes;
}
else
return m_pDD4->CreateSurface(p1, ppDDS, p3);
}
STDMETHODIMP CDirectDrawHook::SetDisplayMode(DWORD p1, DWORD p2, DWORD p3, DWORD p4, DWORD p5)
{
return m_pDD2->SetDisplayMode( p1, p2, p3, p4, p5 );
}
STDMETHODIMP CDirectDrawHook::CreateMaterial(LPDIRECT3DMATERIAL *p1,IUnknown *p2)
{
CComPtr< IDirect3DMaterial > pMat;
HRESULT hRes = m_pD3D->CreateMaterial( &pMat, p2 );
if( FAILED( hRes ) )
return hRes;
CComObject< CMaterialHook > *pHook;
CComObject< CMaterialHook >::CreateInstance( &pHook );
pHook->setObject( pMat, m_pDevice2, m_pDevice3 );
pHook->QueryInterface( IID_IDirect3DMaterial, reinterpret_cast< void ** >( p1 ) );
return hRes;
}
STDMETHODIMP CDirectDrawHook::CreateMaterial(LPDIRECT3DMATERIAL2*p1,IUnknown*p2)
{
CComPtr< IDirect3DMaterial2 > pMat;
HRESULT hRes = m_pD3D2->CreateMaterial( &pMat, p2 );
if( FAILED( hRes ) )
return hRes;
CComObject< CMaterialHook > *pHook;
CComObject< CMaterialHook >::CreateInstance( &pHook );
pHook->setObject( pMat, m_pDevice2, m_pDevice3 );
pHook->QueryInterface( IID_IDirect3DMaterial2, reinterpret_cast< void ** >( p1 ) );
return hRes;
}
STDMETHODIMP CDirectDrawHook::CreateMaterial(LPDIRECT3DMATERIAL3*p1,LPUNKNOWN p2)
{
CComPtr< IDirect3DMaterial3 > pMat;
HRESULT hRes = m_pD3D3->CreateMaterial( &pMat, p2 );
if( FAILED( hRes ) )
return hRes;
CComObject< CMaterialHook > *pHook;
CComObject< CMaterialHook >::CreateInstance( &pHook );
pHook->setObject( pMat, m_pDevice2, m_pDevice3 );
pHook->QueryInterface( IID_IDirect3DMaterial3, reinterpret_cast< void ** >( p1 ) );
return hRes;
}
STDMETHODIMP CDirectDrawHook::CreateDevice( REFCLSID cls,LPDIRECTDRAWSURFACE pDDS,LPDIRECT3DDEVICE2 *ppD3D )
{
CComPtr< IDirect3DDevice2 > pD3D;
HRESULT hRes = m_pD3D2->CreateDevice( cls, pDDS, &pD3D );
if( FAILED( hRes ) )
{
::MessageBox (NULL, "2COULDN'T CreateDevice IN D3D HOOK", "ERROR", MB_OK);
return hRes;
}
CComObject< CDirect3DHook > *pHook;
CComObject< CDirect3DHook >::CreateInstance( &pHook );
pHook->setObject( pD3D );
pHook->QueryInterface( IID_IDirect3DDevice2, reinterpret_cast< void ** >( ppD3D ) );
m_pDevice2 = *ppD3D;
return hRes;
}
STDMETHODIMP CDirectDrawHook::CreateDevice(REFCLSID cls,LPDIRECTDRAWSURFACE4 pDDS,LPDIRECT3DDEVICE3* ppD3D,LPUNKNOWN pUnk)
{
CComPtr< IDirect3DDevice3 > pD3D;
HRESULT hRes = m_pD3D3->CreateDevice( cls, pDDS, &pD3D, pUnk );
if( FAILED( hRes ) )
{
::MessageBox (NULL, "3COULDN'T CreateDevice IN D3D HOOK", "ERROR", MB_OK);
return hRes;
}
// Ok, figure out if this is the "primary" 3d device
DDSURFACEDESC2 ddsd;
ddsd.dwSize = sizeof( DDSURFACEDESC2 );
pDDS->GetSurfaceDesc( &ddsd );
// Get the configured width from the registry
DWORD dwConfiguredWidth;
{
RECT rc;
::GetClientRect( cManager::_p->m_hMain, &rc );
dwConfiguredWidth = rc.right - rc.left;
}
if( ddsd.dwWidth < ( dwConfiguredWidth - 330 ) )
{
// This is a secondary 3ddevice - do not hook it
return pD3D->QueryInterface( IID_IDirect3DDevice3, reinterpret_cast< void ** >( ppD3D ) );
}
// Ok, we're past the wrong device, get to the right device
cManager::_p->setSurface( pD3D );
CComObject< CDirect3DHook > *pHook;
CComObject< CDirect3DHook >::CreateInstance( &pHook );
pHook->setObject( pD3D );
pHook->QueryInterface( IID_IDirect3DDevice3, reinterpret_cast< void ** >( ppD3D ) );
m_pDevice3 = *ppD3D;
return hRes;
}

View file

@ -0,0 +1,277 @@
// DirectDrawHook.h : Declaration of the CDirectDrawHook
#ifndef __DIRECTDRAWHOOK_H_
#define __DIRECTDRAWHOOK_H_
#include "resource.h" // main symbols
#include "Direct3DHook.h"
/////////////////////////////////////////////////////////////////////////////
// CDirectDrawHook
class ATL_NO_VTABLE CDirectDrawHook :
public CComObjectRootEx<CComMultiThreadModel>,
public IDirectDraw,
public IDirectDraw2,
public IDirectDraw4,
public IDirect3D,
public IDirect3D2,
public IDirect3D3
{
public:
CDirectDrawHook()
: m_pDevice2( NULL ),
m_pDevice3( NULL ), m_nSurfaceCount( 0 )
{
}
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CDirectDrawHook)
COM_INTERFACE_ENTRY_IID(IID_IDirectDraw, IDirectDraw)
COM_INTERFACE_ENTRY_IID(IID_IDirectDraw2, IDirectDraw2)
COM_INTERFACE_ENTRY_IID(IID_IDirectDraw4, IDirectDraw4)
COM_INTERFACE_ENTRY_IID(IID_IDirect3D, IDirect3D)
COM_INTERFACE_ENTRY_IID(IID_IDirect3D2, IDirect3D2)
COM_INTERFACE_ENTRY_IID(IID_IDirect3D3, IDirect3D3)
END_COM_MAP()
void setObject( IDirectDraw *pDD );
CComPtr< IDirectDraw > m_pDD;
CComPtr< IDirectDraw2 > m_pDD2;
CComPtr< IDirectDraw4 > m_pDD4;
CComPtr< IDirect3D > m_pD3D;
CComPtr< IDirect3D2 > m_pD3D2;
CComPtr< IDirect3D3 > m_pD3D3;
IDirect3DDevice2 *m_pDevice2;
IDirect3DDevice3 *m_pDevice3;
IDirectDrawSurface4 *m_pPrimary;
long m_nSurfaceCount;
public:
// IDirectDraw Methods
STDMETHOD(Compact)()
{
return m_pDD->Compact();
}
STDMETHOD(CreateClipper)(DWORD p1, LPDIRECTDRAWCLIPPER FAR *p2, IUnknown FAR *p3 )
{
return m_pDD->CreateClipper( p1, p2, p3 );
}
STDMETHOD(CreatePalette)(DWORD p1, LPPALETTEENTRY p2, LPDIRECTDRAWPALETTE FAR*p3, IUnknown FAR *p4 )
{
return m_pDD->CreatePalette( p1, p2, p3, p4 );
}
STDMETHOD(CreateSurface)(LPDDSURFACEDESC p1, LPDIRECTDRAWSURFACE FAR *p2, IUnknown FAR *p3 )
{
return m_pDD->CreateSurface( p1, p2, p3 );
}
STDMETHOD(DuplicateSurface)( LPDIRECTDRAWSURFACE p1, LPDIRECTDRAWSURFACE FAR *p2 )
{
return m_pDD->DuplicateSurface( p1, p2 );
}
STDMETHOD(EnumDisplayModes)( DWORD p1, LPDDSURFACEDESC p2, LPVOID p3, LPDDENUMMODESCALLBACK p4 )
{
return m_pDD->EnumDisplayModes( p1, p2, p3, p4 );
}
STDMETHOD(EnumSurfaces)(DWORD p1, LPDDSURFACEDESC p2, LPVOID p3, LPDDENUMSURFACESCALLBACK p4 )
{
return m_pDD->EnumSurfaces( p1, p2, p3, p4 );
}
STDMETHOD(FlipToGDISurface)()
{
return m_pDD4->FlipToGDISurface();
}
STDMETHOD(GetCaps)( LPDDCAPS p1, LPDDCAPS p2 )
{
return m_pDD4->GetCaps( p1, p2 );
}
STDMETHOD(GetDisplayMode)( LPDDSURFACEDESC p1 )
{
return m_pDD->GetDisplayMode( p1 );
}
STDMETHOD(GetFourCCCodes)(LPDWORD p1, LPDWORD p2 )
{
return m_pDD->GetFourCCCodes( p1, p2 );
}
STDMETHOD(GetGDISurface)(LPDIRECTDRAWSURFACE FAR *p1)
{
return m_pDD->GetGDISurface( p1 );
}
STDMETHOD(GetMonitorFrequency)(LPDWORD p1)
{
return m_pDD->GetMonitorFrequency( p1 );
}
STDMETHOD(GetScanLine)(LPDWORD p1)
{
return m_pDD->GetScanLine( p1 );
}
STDMETHOD(GetVerticalBlankStatus)(LPBOOL p1 )
{
return m_pDD->GetVerticalBlankStatus( p1 );
}
STDMETHOD(Initialize)(GUID FAR *p1)
{
return m_pDD->Initialize( p1 );
}
STDMETHOD(RestoreDisplayMode)()
{
return m_pDD->RestoreDisplayMode();
}
STDMETHOD(SetCooperativeLevel)(HWND p1, DWORD p2);
STDMETHOD(SetDisplayMode)(DWORD p1, DWORD p2, DWORD p3);
STDMETHOD(WaitForVerticalBlank)(DWORD p1, HANDLE p2 )
{
return m_pDD->WaitForVerticalBlank( p1, p2 );
}
/*** Added in the v2 interface ***/
STDMETHOD(GetAvailableVidMem)(LPDDSCAPS p1, LPDWORD p2, LPDWORD p3)
{
return m_pDD2->GetAvailableVidMem( p1, p2, p3 );
}
/*** Added in the V4 Interface ***/
STDMETHOD(GetAvailableVidMem)(LPDDSCAPS2 p1, LPDWORD p2, LPDWORD p3)
{
return m_pDD4->GetAvailableVidMem( p1, p2, p3 );
}
STDMETHOD(CreateSurface)(LPDDSURFACEDESC2 p1, LPDIRECTDRAWSURFACE4 FAR *p2, IUnknown FAR *p3);
STDMETHOD(DuplicateSurface)( LPDIRECTDRAWSURFACE4 p1, LPDIRECTDRAWSURFACE4 FAR *p2 )
{
return m_pDD4->DuplicateSurface( p1, p2 );
}
STDMETHOD(EnumDisplayModes)( DWORD p1, LPDDSURFACEDESC2 p2, LPVOID p3, LPDDENUMMODESCALLBACK2 p4 )
{
return m_pDD4->EnumDisplayModes( p1, p2, p3, p4 );
}
STDMETHOD(EnumSurfaces)(DWORD p1, LPDDSURFACEDESC2 p2, LPVOID p3, LPDDENUMSURFACESCALLBACK2 p4 )
{
return m_pDD4->EnumSurfaces( p1, p2, p3, p4 );
}
STDMETHOD(GetDisplayMode)( LPDDSURFACEDESC2 p1 )
{
return m_pDD4->GetDisplayMode( p1 );
}
STDMETHOD(GetGDISurface)(LPDIRECTDRAWSURFACE4 FAR *p1)
{
return m_pDD4->GetGDISurface( p1 );
}
STDMETHOD(GetSurfaceFromDC) (HDC p1, LPDIRECTDRAWSURFACE4 *p2)
{
return m_pDD4->GetSurfaceFromDC( p1, p2 );
}
STDMETHOD(RestoreAllSurfaces)()
{
return m_pDD4->RestoreAllSurfaces();
}
STDMETHOD(TestCooperativeLevel)()
{
return m_pDD4->TestCooperativeLevel();
}
STDMETHOD(GetDeviceIdentifier)(LPDDDEVICEIDENTIFIER p1, DWORD p2 )
{
return m_pDD4->GetDeviceIdentifier( p1, p2 );
}
// Methods for the IDirect3D Interface
STDMETHOD(Initialize)(REFCLSID p1)
{
return m_pD3D->Initialize( p1 );
}
STDMETHOD(EnumDevices)(LPD3DENUMDEVICESCALLBACK p1,LPVOID p2)
{
return m_pD3D->EnumDevices( p1, p2 );
}
STDMETHOD(CreateLight)(LPDIRECT3DLIGHT*p1,IUnknown*p2)
{
return m_pD3D->CreateLight( p1, p2 );
}
STDMETHOD(CreateMaterial)(LPDIRECT3DMATERIAL *p1,IUnknown *p2);
STDMETHOD(CreateViewport)(LPDIRECT3DVIEWPORT*p1,IUnknown*p2)
{
return m_pD3D->CreateViewport( p1, p2 );
}
STDMETHOD(FindDevice)(LPD3DFINDDEVICESEARCH p1,LPD3DFINDDEVICERESULT p2)
{
return m_pD3D->FindDevice( p1, p2 );
}
// Methods for the IDirect3D2 Interface
STDMETHOD(SetDisplayMode)(DWORD p1, DWORD p2, DWORD p3, DWORD p4, DWORD p5);
STDMETHOD(CreateMaterial)(LPDIRECT3DMATERIAL2*p1,IUnknown*p2);
STDMETHOD(CreateViewport)(LPDIRECT3DVIEWPORT2*p1,IUnknown*p2)
{
return m_pD3D2->CreateViewport( p1, p2 );
}
STDMETHOD(CreateDevice)(REFCLSID cls,LPDIRECTDRAWSURFACE pDDS,LPDIRECT3DDEVICE2 *ppD3D);
// Methods for the IDirect3D3 Interface
STDMETHOD(CreateMaterial)(LPDIRECT3DMATERIAL3*p1,LPUNKNOWN p2);
STDMETHOD(CreateViewport)(LPDIRECT3DVIEWPORT3*p1,LPUNKNOWN p2)
{
return m_pD3D3->CreateViewport( p1, p2 );
}
STDMETHOD(CreateDevice)(REFCLSID cls,LPDIRECTDRAWSURFACE4 pDDS,LPDIRECT3DDEVICE3* ppD3D,LPUNKNOWN pUnk);
STDMETHOD(CreateVertexBuffer)(LPD3DVERTEXBUFFERDESC p1,LPDIRECT3DVERTEXBUFFER*p2,DWORD p3,LPUNKNOWN p4)
{
return m_pD3D3->CreateVertexBuffer( p1, p2, p3, p4 );
}
STDMETHOD(EnumZBufferFormats)(REFCLSID p1,LPD3DENUMPIXELFORMATSCALLBACK p2,LPVOID p3)
{
return m_pD3D3->EnumZBufferFormats( p1, p2, p3 );
}
STDMETHOD(EvictManagedTextures)()
{
return m_pD3D3->EvictManagedTextures();
}
};
#endif //__DIRECTDRAWHOOK_H_

View file

@ -0,0 +1,313 @@
// Panel.cpp : Implementation of cPanel
#include "stdafx.h"
#include "Inject.h"
#include "Panel.h"
/////////////////////////////////////////////////////////////////////////////
// cPanel
enum ePanelChildren
{
eViewFirst = 1000
};
cPanel::cPanel()
: m_nIcon( 0 ),
m_nIconModule( 0 ),
m_nActiveView( -1 ),
m_bDragging( false )
{
}
void cPanel::hideView()
{
m_pSite->Invalidate();
if( m_nActiveView == -1 )
// No active view currently
return;
CComPtr< ILayerSite > pActive;
m_pSite->get_Child( m_nActiveView, ePositionByID, &pActive );
static RECT rcHide = { 0, 0, 0, 0 };
pActive->put_Position( &rcHide );
if( m_pSink.p != NULL )
m_pSink->PanelDeactivate( m_nActiveView );
m_nActiveView = -1;
}
void cPanel::onCreate()
{
CComPtr< IPluginSite > pPlugin;
m_pSite->get_PluginSite( &pPlugin );
pPlugin->LoadBitmapPortal( 0x0600126F, &m_pBackground );
pPlugin->LoadBitmapPortal( 0x06001277, &m_pBorder );
pPlugin->CreateFont( _bstr_t( _T( "Times New Roman" ) ), 15, eFontBold, &m_pTitle );
CComPtr< IButton > pRollup;
HRESULT hRes = ::CoCreateInstance( CLSID_Button, NULL, CLSCTX_INPROC_SERVER, IID_IButton,
reinterpret_cast< void ** >( &pRollup ) );
_ASSERTE( SUCCEEDED( hRes ) );
CComPtr< ILayer > pBtnLayer;
pRollup->QueryInterface( &pBtnLayer );
LayerParams lp = { 1, { 180 - 16, 0, 180, 16 }, eRenderClipped };
m_pSite->CreateChild( &lp, pBtnLayer );
pRollup->put_Matte( RGB( 0, 0, 0 ) );
pRollup->SetImages( 0, 0x0600113C, 0x0600113B );
ICommandEventsImpl< BUTTON_CLOSE, cPanel >::advise( pRollup );
m_pSite->put_Transparent( VARIANT_FALSE );
}
void cPanel::onDestroy()
{
m_pBorder.Release();
m_pBackground.Release();
m_pTitle.Release();
}
STDMETHODIMP cPanel::Render( ICanvas *pCanvas )
{
RECT rc;
m_pSite->get_Position( &rc );
SIZE szBorder;
m_pBorder->get_Size( &szBorder );
// Draw the background
RECT rc_pat = { 0, 0, rc.right - rc.left, rc.bottom - rc.top };
static POINT pt_pat = { 0, 0 };
m_pBackground->PatBlt( pCanvas, &rc_pat, &pt_pat );
// Draw the borders
RECT rc_border_top = { 0, 0, rc.right - rc.left, szBorder.cy },
rc_border_bottom = { 0, rc.bottom - rc.top - szBorder.cy,
rc.right - rc.left, rc.bottom - rc.top };
pCanvas->Fill( &rc_border_top, RGB( 0, 0, 0 ) );
m_pBorder->PatBlt( pCanvas, &rc_border_top, &pt_pat );
pCanvas->Fill( &rc_border_bottom, RGB( 0, 0, 0 ) );
m_pBorder->PatBlt( pCanvas, &rc_border_bottom, &pt_pat );
// Draw the title text
if( m_strTitle.length() > 0 )
{
POINT ptText = { 24, szBorder.cy + 5 };
m_pTitle->DrawText( &ptText, m_strTitle, 0, pCanvas );
}
if( m_nIcon != 0 )
{
CComPtr< IPluginSite > pPlugin;
m_pSite->get_PluginSite( &pPlugin );
CComPtr< IIconCache > pIconCache;
static SIZE szIcon = { 16, 16 };
pPlugin->GetIconCache( &szIcon, &pIconCache );
static POINT pt = { 4, szBorder.cy + 4 };
pIconCache->DrawIcon( &pt, m_nIcon, m_nIconModule, pCanvas );
}
_ASSERTE( _CrtCheckMemory( ) );
return S_OK;
}
STDMETHODIMP cPanel::Reformat()
{
// Reset the size
CComPtr< IPluginSite > pPlugin;
m_pSite->get_PluginSite( &pPlugin );
SIZE szScreen;
pPlugin->GetScreenSize( &szScreen );
RECT rc = { m_nLeft, m_nTop, m_nWidth+m_nLeft, m_nHeight+m_nTop };
m_pSite->put_Position( &rc );
RECT rcCloseBtn = { m_nWidth - 16, 0, m_nWidth, 16 };
CComPtr< ILayerSite > pCloseBtnLS;
m_pSite->get_Child(1, ePositionByID, &pCloseBtnLS);
pCloseBtnLS->put_Position(&rcCloseBtn);
if( m_nActiveView != -1 )
{
// Position the active view
SIZE szBorder;
m_pBorder->get_Size( &szBorder );
CComPtr< ILayerSite > pActive;
m_pSite->get_Child( m_nActiveView, ePositionByID, &pActive );
RECT rcChild = { 0, 24 + szBorder.cy, m_nWidth, m_nHeight - szBorder.cy };
pActive->put_Position( &rcChild );
}
return S_OK;
}
STDMETHODIMP cPanel::AddView(long nViewID, ILayer *pLayer)
{
_ASSERTE( pLayer != NULL );
LayerParams p = { nViewID, { 0, 0, 0, 0 }, eRenderClipped };
// Set up the layer - note that it is not visible
return m_pSite->CreateChild( &p, pLayer );
}
STDMETHODIMP cPanel::ActivateView(long nViewID, ViewParams *pParams)
{
// Hide the current view by resizing to 0,0
hideView();
m_strTitle = pParams->label;
m_nIcon = pParams->icon;
m_nIconModule = pParams->iconLibrary;
m_nWidth = pParams->width;
m_nTop = pParams->top;
m_nHeight = pParams->height;
m_nLeft = pParams->left;
#ifdef _DEBUG
// Make sure the child exists
CComPtr< ILayerSite > pChildSite;
_ASSERTE( SUCCEEDED( m_pSite->get_Child( nViewID, ePositionByID, &pChildSite ) ) );
#endif
// Locate the child
m_nActiveView = nViewID;
// Trick it into reformatting next frame
static RECT rcBig = { 0, 0, 1, 1 };
m_pSite->put_Position( &rcBig );
return S_OK;
}
STDMETHODIMP cPanel::RemoveView(long nViewID)
{
if( nViewID == m_nActiveView )
// If this is the current view, run and hide
Deactivate();
CComPtr< ILayerSite > pChildSite;
HRESULT hRes = m_pSite->get_Child( nViewID, ePositionByID, &pChildSite );
_ASSERTE( SUCCEEDED( hRes ) );
pChildSite->Destroy();
return S_OK;
}
void cPanel::onCloseAccepted(long nID)
{
// We should only be getting commands from the button
_ASSERTE( nID == 1 );
Deactivate();
}
STDMETHODIMP cPanel::get_ActiveView(long *pVal)
{
_ASSERTE( pVal != NULL );
*pVal = m_nActiveView;
return S_OK;
}
STDMETHODIMP cPanel::LoadView(long nViewID, IView *pView, IUnknown *pSchema)
{
_ASSERTE( pView != NULL );
_ASSERTE( pSchema != NULL );
long nAssigned;
// Set up the layer - note that it is not visible
return pView->LoadControl( m_pSite, nViewID, pSchema, &nAssigned );
}
STDMETHODIMP cPanel::Deactivate()
{
if( m_nActiveView == -1 )
// No active view currently
return S_OK;
// Hide the current view by resizing to 0,0
hideView();
// Hide the entire panel
static RECT rcHide = { 0, 0, 0, 0 };
m_pSite->put_Position( &rcHide );
m_nActiveView = -1;
return S_OK;
}
STDMETHODIMP cPanel::putref_Sink(IPanelSink *newVal)
{
m_pSink = newVal;
return S_OK;
}
STDMETHODIMP cPanel::MouseEnter(MouseState *)
{
return S_OK;
}
STDMETHODIMP cPanel::MouseExit(MouseState *)
{
return S_OK;
}
STDMETHODIMP cPanel::MouseDown(MouseState *pMS)
{
if((pMS->screen.x>=m_nLeft) && (pMS->screen.x<=m_nLeft+m_nWidth-16) && (pMS->screen.y-28>=m_nTop) && (pMS->screen.y-28<=m_nTop+28))
{
m_DeltaX = pMS->screen.x-m_nLeft;
m_DeltaY = pMS->screen.y-m_nTop-28;
m_bDragging = true;
}
return S_OK;
}
STDMETHODIMP cPanel::MouseUp(MouseState *)
{
m_bDragging = false;
return S_OK;
}
STDMETHODIMP cPanel::MouseMove(MouseState *pMS)
{
if(m_bDragging)
{
m_nLeft = pMS->screen.x-m_DeltaX;
m_nTop = pMS->screen.y-m_DeltaY-28;
static RECT rcBig = { 0, 0, 1, 1 };
m_pSite->put_Position( &rcBig );
}
return S_OK;
}
STDMETHODIMP cPanel::MouseEvent(long nMsg, long wParam, long lParam)
{
return S_OK;
}

View file

@ -0,0 +1,88 @@
// Panel.h : Declaration of the cPanel
#ifndef __PANEL_H_
#define __PANEL_H_
#include "resource.h" // main symbols
#include "SinkImpl.h"
#define BUTTON_CLOSE 1
/////////////////////////////////////////////////////////////////////////////
// cPanel
class ATL_NO_VTABLE cPanel :
public CComObjectRootEx<CComMultiThreadModel>,
public ILayerRenderImpl,
public ILayerImpl< cPanel >,
public ILayerMouseImpl,
public ICommandEventsImpl< BUTTON_CLOSE, cPanel >,
public cNoEventsImpl,
public IPanel
{
public:
cPanel();
_bstr_t m_strTitle;
long m_nIcon, m_nIconModule;
long m_nActiveView;
CComPtr< IImageCache > m_pBorder;
CComPtr< IImageCache > m_pBackground;
CComPtr< IFontCache > m_pTitle;
CComPtr< IPanelSink > m_pSink;
long m_nTop;
long m_nLeft;
long m_nHeight;
long m_nWidth;
long m_DeltaX;
long m_DeltaY;
bool m_bDragging;
void hideView();
void onCreate();
void onDestroy();
BEGIN_COM_MAP(cPanel)
COM_INTERFACE_ENTRY(ILayer)
COM_INTERFACE_ENTRY(ILayerRender)
COM_INTERFACE_ENTRY(IPanel)
COM_INTERFACE_ENTRY(ILayerMouse)
END_COM_MAP()
BEGIN_SINK_MAP( cPanel )
SINK_ENTRY_EX( BUTTON_CLOSE, DIID_ICommandEvents, DISPID_ACCEPTED, onCloseAccepted )
END_SINK_MAP()
// IPanel
public:
STDMETHOD(LoadView)(long nPlugin, IView *pView, IUnknown *pSchema);
STDMETHOD(get_ActiveView)(/*[out, retval]*/ long *pVal);
STDMETHOD(AddView)(long nPluginID, ILayer *pLayer);
STDMETHOD(RemoveView)(long nID);
STDMETHOD(ActivateView)(long nViewID, ViewParams *pParams);
STDMETHOD(Deactivate)();
STDMETHOD(putref_Sink)(/*[in]*/ IPanelSink* newVal);
// ILayerRender Methods
STDMETHOD(Render)(ICanvas *);
STDMETHOD(Reformat)();
// ICommandEvents Methods
void __stdcall onCloseAccepted(long nID);
// ILayerMouse Methods
STDMETHOD(MouseEnter)(struct MouseState *);
STDMETHOD(MouseExit)(struct MouseState *);
STDMETHOD(MouseDown)(struct MouseState *pMS);
STDMETHOD(MouseUp)(struct MouseState *);
STDMETHOD(MouseMove)(struct MouseState *pMS);
STDMETHOD(MouseEvent)(long nMsg, long wParam, long lParam);
};
#endif //__PANEL_H_

View file

@ -0,0 +1,191 @@
// RootLayer.cpp : Implementation of cRootLayer
#include "stdafx.h"
#include "Inject.h"
#include "RootLayer.h"
#include "BarLayer.h"
#include "Panel.h"
#include "View.h"
enum eChildIDs
{
eChildBars,
eChildPanel
};
/////////////////////////////////////////////////////////////////////////////
// cRootLayer
void cRootLayer::addView( cView *pView, ILayer *pRoot )
{
m_views.push_back( pView );
ViewParams vp = { pView->m_nIcon, pView->m_nIconModule, pView->m_strTitle, pView->m_nLeft, pView->m_nTop, pView->m_nWidth, pView->m_nHeight };
// Next, make the bar entry
m_pBars->AddBar( pView->m_nViewID, &vp );
// Last, make the view entry
m_pPanel->AddView( pView->m_nViewID, pRoot );
}
void cRootLayer::removeView( cView *pView )
{
for( cViewList::iterator i = m_views.begin(); i != m_views.end(); ++ i )
{
if( *i == pView )
{
m_views.erase( i );
break;
}
}
}
void cRootLayer::onCreate()
{
LayerParams lpBars = { eChildBars, { 0, 0, 1, 1 }, 0 };
CComObject< cBarLayer > *pBars;
CComObject< cBarLayer >::CreateInstance( &pBars );
m_pBars = pBars;
m_pSite->CreateChild( &lpBars, pBars );
LayerParams lpPanel = { eChildPanel, { 0, 0, 0, 0 }, 0 };
CComObject< cPanel > *pPanel;
CComObject< cPanel >::CreateInstance( &pPanel );
m_pPanel = pPanel;
m_pSite->CreateChild( &lpPanel, pPanel );
m_pPanel->putref_Sink( this );
}
void cRootLayer::onDestroy()
{
m_pBars.Release();
m_pPanel.Release();
}
STDMETHODIMP cRootLayer::CreateView(ViewParams *pParams, ILayer *pLayer, IView **ppView)
{
// First create the view object
CComObject< cView > *pView;
CComObject< cView >::CreateInstance( &pView );
pView->m_pRoot = this;
pView->m_nViewID = m_nNextViewID ++;
pView->m_strTitle = pParams->label;
pView->m_nIcon = pParams->icon;
pView->m_nIconModule = pParams->iconLibrary;
pView->m_nLeft = pParams->left;
pView->m_nTop = pParams->top;
pView->m_nWidth = pParams->width;
pView->m_nHeight = pParams->height;
addView( pView, pLayer );
*ppView = pView;
pView->AddRef();
return S_OK;
}
STDMETHODIMP cRootLayer::SelectBar(long nID)
{
// We are given the Bar ID, find the matching view
for( cViewList::iterator i = m_views.begin(); i != m_views.end(); ++ i )
{
if( ( *i )->m_nViewID == nID )
{
long nPrevActive;
m_pPanel->get_ActiveView( &nPrevActive );
if( nPrevActive != nID )
{
ViewParams p = { ( *i )->m_nIcon, ( *i )->m_nIconModule, ( *i )->m_strTitle, ( *i )->m_nLeft, ( *i )->m_nTop, ( *i )->m_nWidth, ( *i )->m_nHeight };
m_pPanel->ActivateView( ( *i )->m_nViewID, &p );
( *i )->Fire_Activate();
}
else
{
( *i )->Deactivate();
}
return S_OK;
}
}
// Invalid return value
return E_INVALIDARG;
}
STDMETHODIMP cRootLayer::LoadView(BSTR strXML, IView **ppView)
{
CComObject< cView > *pView;
CComObject< cView >::CreateInstance( &pView );
CComPtr< IUnknown > pRootControl;
pView->m_pRoot = this;
pView->m_nViewID = m_nNextViewID ++;
pView->loadSchema( strXML, &pRootControl );
ViewParams vp = { pView->m_nIcon, pView->m_nIconModule, pView->m_strTitle, pView->m_nLeft, pView->m_nTop, pView->m_nWidth, pView->m_nHeight };
m_views.push_back( pView );
*ppView = pView;
pView->AddRef();
// Next, make the bar entry
m_pBars->AddBar( pView->m_nViewID, &vp );
// Last, create all the controls
m_pPanel->LoadView( pView->m_nViewID, pView, pRootControl );
return S_OK;
}
STDMETHODIMP cRootLayer::PanelDeactivate(long nViewID)
{
// Find the view of our desires and fire it's hide message
for( cViewList::iterator i = m_views.begin(); i != m_views.end(); ++ i )
{
if( ( *i )->m_nViewID == nViewID )
( *i )->Fire_Deactivate();
}
return S_OK;
}
STDMETHODIMP cRootLayer::LoadViewObject(IUnknown *pSchema, IView **ppView)
{
CComObject< cView > *pView;
CComObject< cView >::CreateInstance( &pView );
CComPtr< IUnknown > pRootControl;
pView->m_pRoot = this;
pView->m_nViewID = m_nNextViewID ++;
pView->loadSchemaObject( pSchema, &pRootControl );
ViewParams vp = { pView->m_nIcon, pView->m_nIconModule, pView->m_strTitle, pView->m_nLeft, pView->m_nTop, pView->m_nWidth, pView->m_nHeight };
m_views.push_back( pView );
*ppView = pView;
pView->AddRef();
// Next, make the bar entry
m_pBars->AddBar( pView->m_nViewID, &vp );
// Last, create all the controls
m_pPanel->LoadView( pView->m_nViewID, pView, pRootControl );
return S_OK;
}

View file

@ -0,0 +1,61 @@
// RootLayer.h : Declaration of the cRootLayer
#ifndef __ROOTLAYER_H_
#define __ROOTLAYER_H_
#include "resource.h" // main symbols
// This special layer implements no sinks, it is merely a container
// layer for the bar manager and the window manager - it server no other purpose
// than to forward event on and avoid redundant looping in the manager object.
#include "SinkImpl.h"
class cView;
/////////////////////////////////////////////////////////////////////////////
// cRootLayer
class ATL_NO_VTABLE cRootLayer :
public CComObjectRootEx<CComMultiThreadModel>,
public ILayerImpl< cRootLayer >,
public IPanelSink,
public cNoEventsImpl,
public IRootLayer
{
public:
cRootLayer()
: m_nNextViewID( 1000 )
{
}
CComPtr< IBarManager > m_pBars;
CComPtr< IPanel > m_pPanel;
typedef std::list< cView * > cViewList;
cViewList m_views;
long m_nNextViewID;
void addView( cView *pView, ILayer *pRootLayer );
void removeView( cView *pView );
void onCreate();
void onDestroy();
BEGIN_COM_MAP(cRootLayer)
COM_INTERFACE_ENTRY(IPanelSink)
COM_INTERFACE_ENTRY(IRootLayer)
COM_INTERFACE_ENTRY(ILayer)
END_COM_MAP()
public:
// IRootLayer Methods
STDMETHOD(CreateView)(ViewParams *pParams, ILayer *pLayer, /*[out, retval]*/ IView **ppView);
STDMETHOD(SelectBar)(long nID);
STDMETHOD(LoadView)(BSTR strXML, /*[out, retval]*/ IView **ppView);
STDMETHOD(LoadViewObject)(IUnknown *pSchema, /*[out, retval]*/ IView **ppView);
// IPanelSink Methods
STDMETHOD(PanelDeactivate)( long nViewID );
};
#endif //__ROOTLAYER_H_

View file

@ -0,0 +1,410 @@
// View.cpp : Implementation of cView
#include "stdafx.h"
#include "Inject.h"
#include "View.h"
#include "RootLayer.h"
#include "Manager.h"
#include "InjectApi.h"
/////////////////////////////////////////////////////////////////////////////
// cView
cView::~cView()
{
m_pRoot->m_pBars->RemoveBar( m_nViewID );
m_pRoot->m_pPanel->RemoveView( m_nViewID );
m_pRoot->removeView( this );
}
void cView::loadSchema( BSTR strSchema, IUnknown **ppRootControl )
{
USES_CONVERSION;
_ASSERTE( strSchema != NULL );
// Create a new XML document and load this up
MSXML::IXMLDOMDocumentPtr pDoc;
pDoc.CreateInstance( __uuidof( MSXML::DOMDocument ), NULL, CLSCTX_INPROC_SERVER );
VARIANT_BOOL bSuccess;
if( strSchema[ 0 ] == OLESTR( '<' ) )
bSuccess = pDoc->loadXML( strSchema );
else
{
// Load from a file source
pDoc->async = VARIANT_FALSE;
TCHAR szPath[ MAX_PATH ];
bSuccess = pDoc->load( ::InjectMapPath( eInjectPathAgent, OLE2T( strSchema ), szPath ) );
}
if( !bSuccess )
{
USES_CONVERSION;
// The document failed to load, get the error info for posterity
MSXML::IXMLDOMParseErrorPtr pErr = pDoc->parseError;
long nCode = pErr->errorCode;
long nFilePos = pErr->filepos;
long nLine = pErr->line;
long nLinePos = pErr->linepos;
_bstr_t strReason = pErr->reason;
_bstr_t strText = pErr->srcText;
TCHAR szError[ 1024 ];
::_stprintf( szError, _T( "0x%08X (%i, %i): %s" ),
nCode, nLine, nLinePos, OLE2T( strReason ) );
::MessageBox( cManager::_p->m_hMain, szError, _T( "XML Parse Error" ), MB_ICONERROR | MB_OK );
// Give the user a chance to break and look at this lovely info
_ASSERTE( FALSE );
return;
}
// Get the root element and check it out
loadSchemaObject( pDoc->documentElement, ppRootControl );
}
void cView::loadSchemaObject( IUnknown *pObject, IUnknown **ppRootControl )
{
MSXML::IXMLDOMElementPtr pRoot = pObject;
_ASSERTE( pRoot->tagName == _bstr_t( _T( "view" ) ) );
// Get the view parameters
_variant_t vIconModule = pRoot->getAttribute( _T( "iconlibrary" ) ),
vIcon = pRoot->getAttribute( _T( "icon" ) ),
vTitle = pRoot->getAttribute( _T( "title" ) ),
vLeft = pRoot->getAttribute( _T( "left" ) ),
vTop = pRoot->getAttribute( _T( "top" ) ),
vWidth = pRoot->getAttribute( _T( "width" ) ),
vHeight = pRoot->getAttribute( _T( "height" ) );
// We *must* have a title
_ASSERTE( vTitle.vt == VT_BSTR );
// Fill this into a view param
_ASSERTE( vIcon.vt != VT_NULL );
m_nIcon = ( vIcon.vt != VT_NULL ) ? static_cast< long >( vIcon ) + 0x06000000 : 0;
if( vIconModule.vt == VT_BSTR )
cManager::_p->LoadResourceModule( vIconModule.bstrVal, &m_nIconModule );
else
m_nIconModule = 0;
if(vLeft.vt == VT_NULL)
m_nLeft = 0;
else
m_nLeft = static_cast< long >(vLeft);
if(vTop.vt == VT_NULL)
m_nTop = 70;
else
m_nTop = static_cast< long >(vTop);
if(vWidth.vt == VT_NULL)
m_nWidth = 180;
else
m_nWidth = static_cast< long >(vWidth);
if(vHeight.vt == VT_NULL)
{
SIZE szScreen;
cManager::_p->GetScreenSize( &szScreen );
m_nHeight = szScreen.cy/2;
}
else
m_nHeight = static_cast< long >(vHeight);
m_strTitle = vTitle.bstrVal;
// The properly made schema should have a single control child
MSXML::IXMLDOMElementPtr pControl = pRoot->selectSingleNode( _T( "control" ) );
_ASSERTE( pControl.GetInterfacePtr() != NULL );
pControl->QueryInterface( ppRootControl );
}
STDMETHODIMP cView::get_Control(BSTR strName, IControl **pVal)
{
_ASSERTE( strName != NULL );
_ASSERTE( pVal != NULL );
// Search for a matching control name
for( cNamedControlList::iterator i = m_controls.begin(); i != m_controls.end(); ++ i )
{
if( i->m_strName == _bstr_t( strName ) )
{
*pVal = i->m_pControl;
( *pVal )->AddRef();
return S_OK;
}
}
// The name was not found
return E_INVALIDARG;
}
STDMETHODIMP cView::putref_Control(BSTR strName, IControl *newVal)
{
_ASSERTE( strName != NULL );
// First look for a matching name
for( cNamedControlList::iterator i = m_controls.begin(); i != m_controls.end(); ++ i )
{
if( i->m_strName == _bstr_t( strName ) )
{
if( newVal == NULL )
m_controls.erase( i );
else
i->m_pControl = newVal;
return S_OK;
}
}
if( newVal == NULL )
// No value to set
return S_OK;
// Add in a new record
cNamedControl nc;
nc.m_strName = strName;
nc.m_pControl = newVal;
m_controls.push_back( nc );
return S_OK;
}
STDMETHODIMP cView::LoadControl(ILayerSite *pParent, long nID, IUnknown *pSource, long *pAssignedID)
{
// Usual parameter validation
_ASSERTE( pParent != NULL );
_ASSERTE( pSource != NULL );
_ASSERTE( pAssignedID != NULL );
MSXML::IXMLDOMElementPtr pElement = pSource;
// Make sure we're starting from the correct tag name
_ASSERTE( pElement->tagName == _bstr_t( _T( "control" ) ) );
// Get the progid and make an instance
_variant_t strProgID = pElement->getAttribute( _T( "progid" ) );
_ASSERTE( strProgID.vt == VT_BSTR );
CLSID clsid;
HRESULT hRes = ::CLSIDFromProgID( strProgID.bstrVal, &clsid );
_ASSERTE( SUCCEEDED( hRes ) );
CComPtr< ILayer > pChildLayer;
hRes = ::CoCreateInstance( clsid, NULL, CLSCTX_INPROC_SERVER, IID_ILayer,
reinterpret_cast< void ** >( &pChildLayer ) );
_ASSERTE( SUCCEEDED( hRes ) );
// Get some position metrics - note, these are optional and will be
// loaded with 0s - this is for cases when the control is formatted
// entirely by the parent
_variant_t vLeft = pElement->getAttribute( _T( "left" ) ),
vTop = pElement->getAttribute( _T( "top" ) ),
vWidth = pElement->getAttribute( _T( "width" ) ),
vHeight = pElement->getAttribute( _T( "height" ) ),
vUnclipped = pElement->getAttribute( _T( "unclipped" ) ),
vID = pElement->getAttribute( _T( "ID" ) );
long nRealID = ( vID.vt == VT_NULL ) ? nID : static_cast< long >( vID );
*pAssignedID = nRealID;
POINT pt = { ( vLeft.vt != VT_NULL ) ? static_cast< long >( vLeft ) : 0,
( vTop.vt != VT_NULL ) ? static_cast< long >( vTop ) : 0 };
LayerParams lp = { nRealID, { pt.x, pt.y, pt.x + ( ( vWidth.vt != VT_NULL ) ? static_cast< long >( vWidth ) : 0 ),
pt.y + ( ( vHeight.vt != VT_NULL ) ? static_cast< long >( vHeight ) : 0 ) },
( vUnclipped.vt != VT_NULL ) ? 0 : eRenderClipped };
pParent->CreateChild( &lp, pChildLayer );
// Check if this child is named
_variant_t vName = pElement->getAttribute( _T( "name" ) );
if( vName.vt == VT_BSTR )
{
// Add the named control
CComPtr< IControl > pControl;
pChildLayer->QueryInterface( &pControl );
putref_Control( vName.bstrVal, pControl );
}
// Ok, the child is made - trick it into loading it's own parameters
CComPtr< ILayerSchema > pSchema;
if( SUCCEEDED( pChildLayer->QueryInterface( &pSchema ) ) )
pSchema->SchemaLoad( this, pSource );
return S_OK;
}
STDMETHODIMP cView::LoadSchema(BSTR strXMLSchema)
{
long nPreviousView;
m_pRoot->m_pPanel->get_ActiveView( &nPreviousView );
m_pRoot->m_pPanel->RemoveView( m_nViewID );
CComPtr< IUnknown > pRootControl;
loadSchema( strXMLSchema, &pRootControl );
// Set the bar params
ViewParams vp = { m_nIcon, m_nIconModule, m_strTitle, m_nLeft, m_nTop, m_nWidth, m_nHeight };
m_pRoot->m_pBars->put_Bar( m_nViewID, &vp );
// Last, create all the controls
m_pRoot->m_pPanel->LoadView( m_nViewID, this, pRootControl );
if( nPreviousView == m_nViewID )
// Reactivate the view
m_pRoot->SelectBar( m_nViewID );
return S_OK;
}
STDMETHODIMP cView::get_Title(BSTR *pVal)
{
USES_CONVERSION;
*pVal = OLE2BSTR( m_strTitle );
return S_OK;
}
STDMETHODIMP cView::put_Title(BSTR newVal)
{
_ASSERTE( newVal != NULL );
m_strTitle = newVal;
long nActiveView;
m_pRoot->m_pPanel->get_ActiveView( &nActiveView );
ViewParams vp = { m_nIcon, m_nIconModule, m_strTitle, m_nLeft, m_nTop, m_nWidth, m_nHeight };
m_pRoot->m_pBars->put_Bar( m_nViewID, &vp );
// if( nActiveView == m_nViewID )
// Reload the view
// m_pRoot->SelectBar( m_nViewID );
return S_OK;
}
STDMETHODIMP cView::Alert()
{
return S_OK;
}
STDMETHODIMP cView::SetIcon(long icon, VARIANT iconlibrary)
{
USES_CONVERSION;
m_nIcon = icon;
switch( iconlibrary.vt )
{
case VT_ERROR:
case VT_EMPTY:
case VT_NULL:
m_nIconModule = 0;
break;
case VT_BSTR:
m_nIconModule = reinterpret_cast< long >( ::GetModuleHandle( OLE2T( iconlibrary.bstrVal ) ) );
break;
default:
// Try and convert everything else to a number
try
{
_variant_t v = iconlibrary;
m_nIconModule = v;
}
catch( ... )
{
m_nIconModule = 0;
return E_INVALIDARG;
}
break;
}
long nActiveView;
m_pRoot->m_pPanel->get_ActiveView( &nActiveView );
ViewParams vp = { m_nIcon, m_nIconModule, m_strTitle, m_nLeft, m_nTop, m_nWidth, m_nHeight};
m_pRoot->m_pBars->put_Bar( m_nViewID, &vp );
if( nActiveView == m_nViewID )
// Reload the view
m_pRoot->SelectBar( m_nViewID );
return S_OK;
}
STDMETHODIMP cView::Activate()
{
long nActiveView;
m_pRoot->m_pPanel->get_ActiveView( &nActiveView );
if (nActiveView != m_nViewID)
{
m_pRoot->SelectBar( m_nViewID );
}
return S_OK;
}
STDMETHODIMP cView::Deactivate()
{
m_pRoot->m_pPanel->Deactivate();
if(cManager::_p->m_pKeyboard!=NULL)
{
cManager::_p->m_pKeyboard->sendKeyboardEndCapture( VARIANT_TRUE );
cManager::_p->m_pKeyboard=NULL;
}
return S_OK;
}
STDMETHODIMP cView::put_Position(LPRECT pVal)
{
long nActiveView;
m_pRoot->m_pPanel->get_ActiveView( &nActiveView );
if( nActiveView == m_nViewID )
{
m_nLeft = pVal->left;
m_nTop = pVal->top;
m_nWidth = pVal->right;
m_nHeight = pVal->bottom;
ViewParams vp = {m_nIcon, m_nIconModule, m_strTitle, m_nLeft, m_nTop, m_nWidth, m_nHeight};
m_pRoot->m_pPanel->ActivateView(m_nViewID, &vp );
Fire_Activate();
}
return S_OK;
}
STDMETHODIMP cView::get_Position(LPRECT pVal)
{
pVal->left = m_nLeft;
pVal->top = m_nTop;
pVal->right = m_nWidth;
pVal->bottom = m_nHeight;
return S_OK;
}

View file

@ -0,0 +1,81 @@
// View.h : Declaration of the cView
#ifndef __VIEW_H_
#define __VIEW_H_
#include "resource.h" // main symbols
#include "InjectCP.h"
#include "SinkImpl.h"
class cRootLayer;
/////////////////////////////////////////////////////////////////////////////
// cView
class ATL_NO_VTABLE cView :
public CComObjectRootEx<CComMultiThreadModel>,
public IConnectionPointContainerImpl<cView>,
public IProvideClassInfo2Impl< &CLSID_View, &IID_IViewDisp, &LIBID_DecalPlugins >,
public IDispatchImpl< IView, &IID_IViewDisp, &LIBID_DecalPlugins >,
public CProxyIViewEvents< cView >
{
public:
cView()
{
}
~cView();
cRootLayer *m_pRoot;
_bstr_t m_strTitle;
long m_nIcon;
long m_nIconModule;
long m_nViewID;
long m_nWidth;
long m_nHeight;
long m_nTop;
long m_nLeft;
// Named controls
struct cNamedControl
{
_bstr_t m_strName;
CComPtr< IControl > m_pControl;
};
typedef std::list< cNamedControl > cNamedControlList;
cNamedControlList m_controls;
void loadSchema( BSTR strText, IUnknown **ppRootControl );
void loadSchemaObject( IUnknown *pObject, IUnknown **ppRootControl );
BEGIN_COM_MAP(cView)
COM_INTERFACE_ENTRY(IView)
COM_INTERFACE_ENTRY(IViewDisp)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IProvideClassInfo)
COM_INTERFACE_ENTRY(IProvideClassInfo2)
COM_INTERFACE_ENTRY(IConnectionPointContainer)
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
END_COM_MAP()
BEGIN_CONNECTION_POINT_MAP(cView)
CONNECTION_POINT_ENTRY(DIID_IViewEvents)
END_CONNECTION_POINT_MAP()
public:
// IView Methods
STDMETHOD(SetIcon)(long icon, /*[optional]*/ VARIANT iconlibrary);
STDMETHOD(Activate)();
STDMETHOD(Alert)();
STDMETHOD(get_Title)(/*[out, retval]*/ BSTR *pVal);
STDMETHOD(put_Title)(/*[in]*/ BSTR newVal);
STDMETHOD(LoadSchema)(BSTR strXMLSchema);
STDMETHOD(LoadControl)(ILayerSite *pParent, long nID, IUnknown *pSource, long *pAssignedID);
STDMETHOD(get_Control)(BSTR strName, /*[out, retval]*/ IControl * *pVal);
STDMETHOD(putref_Control)(BSTR strName, /*[in]*/ IControl * newVal);
STDMETHOD(Deactivate)();
STDMETHOD(put_Position)(/*[in]*/ LPRECT pVal);
STDMETHOD(get_Position)(/*[out, retval]*/ LPRECT pVal);
};
#endif //__VIEW_H_

View file

@ -0,0 +1,91 @@
// EventsImpl.h
// Declaration of helper class for implementing plugins
#ifndef _EVENTSIMPL_H_
#define _EVENTSIMPL_H_
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
template< UINT nID, class cImpl, const IID *pIID, const GUID *pLIBID >
class IControlEventsImpl
: public IDispEventImpl< nID, cImpl, pIID, pLIBID, 1, 0 >
{
protected:
void advise( IUnknown *pUnk )
{
HRESULT hRes = DispEventAdvise( pUnk );
_ASSERTE( SUCCEEDED( hRes ) );
}
void unadvise( IUnknown *pUnk )
{
HRESULT hRes = DispEventUnadvise( pUnk );
_ASSERTE( SUCCEEDED( hRes ) );
}
};
#define DISPID_DESTROY 1
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
template< UINT nID, class cImpl >
class ICommandEventsImpl
: public IControlEventsImpl< nID, cImpl, &DIID_ICommandEvents, &LIBID_DecalPlugins >
{
};
#define DISPID_HIT 2
#define DISPID_UNHIT 3
#define DISPID_ACCEPTED 4
#define DISPID_CANCELED 5
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
template< UINT nID, class cImpl >
class IPagerEventsImpl
: public IControlEventsImpl< nID, cImpl, &DIID_IPagerEvents, &LIBID_DecalPlugins >
{
};
#define DISPID_CHANGE 6
#define DISPID_GETNEXTPOSITION 7
#define DISPID_UPDATE_POSITION 6
#define DISPID_GET_NEXT_POSITION 7
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
template< UINT nID, class cImpl >
class IViewEventsImpl
: public IControlEventsImpl< nID, cImpl, &DIID_IViewEvents, &LIBID_DecalPlugins >
{
};
#define DISPID_ACTIVATE 8
#define DISPID_DEACTIVATE 9
#define DISPID_SIZE 13
#define DISPID_SIZING 14
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
template< UINT nID, class cImpl >
class IInputEventsImpl
: public IControlEventsImpl< nID, cImpl, &DIID_IInputEvents, &LIBID_DecalPlugins >
{
};
#define DISPID_BEGIN 10
#define DISPID_END 11
#define DISPID_PAUSE 12
#endif // _EVENTSIMPL_H_

Binary file not shown.

8563
Native/Inject/Attic/Inject.h Normal file

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -0,0 +1,71 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: Inject - Win32 Release MinDependency--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\AARONP~1\LOCALS~1\Temp\RSP5AC.tmp" with contents
[
/nologo /MD /W3 /GX /Zd /O1 /D "INJECT_IMPL" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Fp"ReleaseMinDependency/Inject.pch" /Yu"stdafx.h" /Fo"ReleaseMinDependency/" /Fd"ReleaseMinDependency/" /FD /c
"E:\Decal\Source\Inject\Canvas.cpp"
]
Creating command line "cl.exe @C:\DOCUME~1\AARONP~1\LOCALS~1\Temp\RSP5AC.tmp"
Creating temporary file "C:\DOCUME~1\AARONP~1\LOCALS~1\Temp\RSP5AD.tmp" with contents
[
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ddraw.lib winmm.lib ws2_32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"..\Release/Inject.pdb" /debug /machine:I386 /def:".\Inject.def" /out:"..\Release/Inject.dll" /implib:"..\Release/Inject.lib" /pdbtype:sept
.\ReleaseMinDependency\BarLayer.obj
.\ReleaseMinDependency\Button.obj
.\ReleaseMinDependency\Canvas.obj
.\ReleaseMinDependency\DatFile.obj
.\ReleaseMinDependency\Direct3DHook.obj
.\ReleaseMinDependency\DirectDrawHook.obj
.\ReleaseMinDependency\DirectDrawSurfaceHook.obj
.\ReleaseMinDependency\FontCache.obj
.\ReleaseMinDependency\Guids.obj
.\ReleaseMinDependency\IconCache.obj
.\ReleaseMinDependency\Image.obj
.\ReleaseMinDependency\Inject.obj
.\ReleaseMinDependency\InputBuffer.obj
.\ReleaseMinDependency\LayerSite.obj
.\ReleaseMinDependency\Manager.obj
.\ReleaseMinDependency\MaterialHook.obj
.\ReleaseMinDependency\Message.obj
.\ReleaseMinDependency\MessageLoaders.obj
.\ReleaseMinDependency\MessageParsers.obj
.\ReleaseMinDependency\MessageStruct.obj
.\ReleaseMinDependency\MessageVector.obj
.\ReleaseMinDependency\Pager.obj
.\ReleaseMinDependency\Panel.obj
.\ReleaseMinDependency\ProtocolStack.obj
.\ReleaseMinDependency\RootLayer.obj
.\ReleaseMinDependency\SimpleBar.obj
.\ReleaseMinDependency\SinkImpl.obj
.\ReleaseMinDependency\SolidImage.obj
.\ReleaseMinDependency\StdAfx.obj
.\ReleaseMinDependency\View.obj
.\ReleaseMinDependency\Inject.res
]
Creating command line "link.exe @C:\DOCUME~1\AARONP~1\LOCALS~1\Temp\RSP5AD.tmp"
Creating temporary file "C:\DOCUME~1\AARONP~1\LOCALS~1\Temp\RSP5AE.bat" with contents
[
@echo off
regsvr32 /s /c "\Decal\Source\Release\Inject.dll"
echo regsvr32 exec. time > ".\..\Release\regsvr32.trg"
]
Creating command line "C:\DOCUME~1\AARONP~1\LOCALS~1\Temp\RSP5AE.bat"
Compiling...
Canvas.cpp
Linking...
Creating library ..\Release/Inject.lib and object ..\Release/Inject.exp
<h3>Output Window</h3>
Performing registration
<h3>Results</h3>
Inject.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

Binary file not shown.

View file

@ -0,0 +1,448 @@
#pragma warning( disable: 4049 ) /* more than 64k source lines */
/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */
/* link this file in with the server and any clients */
/* File created by MIDL compiler version 5.03.0280 */
/* at Sat Aug 18 01:06:36 2001
*/
/* Compiler settings for E:\Decal\Source\Inject\Inject.idl:
Oicf (OptLev=i2), W1, Zp8, env=Win32 (32b run), ms_ext, c_ext
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
DECLSPEC_UUID(), MIDL_INTERFACE()
*/
//@@MIDL_FILE_HEADING( )
#if !defined(_M_IA64) && !defined(_M_AXP64)
#ifdef __cplusplus
extern "C"{
#endif
#include <rpc.h>
#include <rpcndr.h>
#ifdef _MIDL_USE_GUIDDEF_
#ifndef INITGUID
#define INITGUID
#include <guiddef.h>
#undef INITGUID
#else
#include <guiddef.h>
#endif
#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8)
#else // !_MIDL_USE_GUIDDEF_
#ifndef __IID_DEFINED__
#define __IID_DEFINED__
typedef struct _IID
{
unsigned long x;
unsigned short s1;
unsigned short s2;
unsigned char c[8];
} IID;
#endif // __IID_DEFINED__
#ifndef CLSID_DEFINED
#define CLSID_DEFINED
typedef IID CLSID;
#endif // CLSID_DEFINED
#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
#endif !_MIDL_USE_GUIDDEF_
MIDL_DEFINE_GUID(IID, IID_IManager,0xBC63C4A7,0xBE01,0x400D,0x90,0x8D,0x07,0x47,0xB0,0x6C,0x80,0x62);
MIDL_DEFINE_GUID(IID, IID_IPluginSite,0x702D3901,0xC13A,0x448e,0x88,0x71,0xEC,0xDC,0x8B,0xC8,0xD0,0x79);
MIDL_DEFINE_GUID(IID, IID_IPluginSink,0xD216BA6C,0xD328,0x4765,0xB4,0x0A,0x9B,0xC5,0x7C,0x96,0xF7,0x5E);
MIDL_DEFINE_GUID(IID, IID_IPlugin,0xBA3E677F,0x8E44,0x4829,0x98,0x2E,0x58,0xBB,0xBC,0x5C,0x5F,0x9B);
MIDL_DEFINE_GUID(IID, IID_IControl,0x996B377C,0x1953,0x4db1,0xAA,0xC1,0x15,0x7F,0x72,0x59,0x2D,0x3E);
MIDL_DEFINE_GUID(IID, DIID_IControlEvents,0x2FEBCBC3,0x488C,0x444f,0xAD,0x08,0x5D,0x30,0x97,0xD2,0xD1,0xED);
MIDL_DEFINE_GUID(IID, IID_ILayer,0x0D63504F,0xDEEF,0x4a2d,0x97,0x42,0x28,0xDD,0x1B,0xAD,0xDA,0x7C);
MIDL_DEFINE_GUID(IID, IID_ILayerRender,0xD1C71B85,0x62C2,0x42a3,0xAE,0x2E,0x4B,0xF5,0xA6,0xBE,0x17,0x84);
MIDL_DEFINE_GUID(IID, IID_ILayerSite,0x5B7E9D99,0xBB3A,0x475D,0x84,0x2D,0x43,0xEB,0xEA,0x82,0x84,0xEA);
MIDL_DEFINE_GUID(IID, IID_IBarManager,0xE4CCDC92,0x8658,0x4caa,0x89,0x55,0xFB,0x89,0x1D,0x5B,0xDC,0xF7);
MIDL_DEFINE_GUID(IID, IID_IIconCache,0xDEDCD5AA,0xF6CA,0x4DA5,0xA6,0x57,0xE8,0x2F,0x12,0x6A,0xBB,0xCD);
MIDL_DEFINE_GUID(IID, IID_IImageCacheDisp,0xF88548BC,0xD11E,0x4ac2,0x9A,0x27,0x36,0x07,0x00,0x4D,0x35,0x9F);
MIDL_DEFINE_GUID(IID, IID_IImageCache,0xBE566CEC,0x6881,0x481C,0xA1,0x46,0x9F,0x5A,0x32,0x57,0x6B,0xE6);
MIDL_DEFINE_GUID(IID, IID_IFontCacheDisp,0x9394E96D,0x2B29,0x4c29,0xAF,0x3E,0xDB,0x5C,0x47,0x61,0x22,0xDB);
MIDL_DEFINE_GUID(IID, IID_IFontCache,0x12ECCB0F,0x36A6,0x451C,0xB0,0x86,0x13,0x06,0xB7,0x4A,0xAE,0xC2);
MIDL_DEFINE_GUID(IID, IID_ISimpleBar,0x4A2D87CD,0xBFB4,0x4723,0xB9,0x59,0xFF,0xF3,0xFD,0xD4,0x92,0x78);
MIDL_DEFINE_GUID(IID, IID_ILayerMouse,0x5014E0B2,0x9156,0x412c,0x94,0x6D,0x9D,0x4B,0xAA,0x9F,0x4C,0x51);
MIDL_DEFINE_GUID(IID, IID_ILayerSchema,0x829E0FB2,0xD0B5,0x4814,0xBC,0xF9,0x6E,0xCF,0xA0,0x6C,0x9A,0xED);
MIDL_DEFINE_GUID(IID, IID_IButton,0x0F5765A4,0x9F83,0x4077,0x88,0x84,0x6C,0xBD,0xDC,0xE3,0x48,0xF7);
MIDL_DEFINE_GUID(IID, DIID_ICommandEvents,0xF029D3A1,0x29AF,0x45ef,0x92,0x7E,0x72,0x9F,0xED,0xD8,0x74,0x03);
MIDL_DEFINE_GUID(IID, IID_IPager,0xBD9FC464,0xC0D8,0x4823,0x82,0x55,0xE8,0x18,0xF8,0x83,0x6B,0x08);
MIDL_DEFINE_GUID(IID, DIID_IPagerEvents,0x7499EB61,0x6992,0x4e21,0x8A,0x55,0xCF,0x44,0xD4,0x4C,0x0A,0x07);
MIDL_DEFINE_GUID(IID, IID_IPanel,0x2B52B5CB,0x9E10,0x4238,0x8F,0x62,0xA5,0x01,0x40,0x6E,0x3E,0xAB);
MIDL_DEFINE_GUID(IID, IID_IPanelSink,0x85D70924,0x917D,0x41bb,0x99,0x5D,0xC4,0x0E,0x6A,0xB2,0x1C,0x71);
MIDL_DEFINE_GUID(IID, IID_ICanvas,0x9241862D,0xBA71,0x4317,0x81,0x66,0x3A,0x3E,0x61,0xCE,0x3E,0x5F);
MIDL_DEFINE_GUID(IID, IID_IViewDisp,0xF3B54A0C,0x61B9,0x4B7A,0x9F,0xD8,0x82,0xB0,0x47,0x7F,0xB7,0xD9);
MIDL_DEFINE_GUID(IID, IID_IView,0xA2AE18B7,0x85C9,0x451c,0x8C,0xC3,0xD0,0xFF,0xE6,0xB8,0x6E,0xEB);
MIDL_DEFINE_GUID(IID, DIID_IViewEvents,0x4B7B19D5,0x61A2,0x4ab0,0x8B,0x1B,0x38,0x1A,0x30,0x3A,0x93,0x7F);
MIDL_DEFINE_GUID(IID, IID_IRootLayer,0xD3006096,0xB293,0x47f5,0x93,0x77,0xC1,0x2D,0xEF,0x5C,0x1D,0x34);
MIDL_DEFINE_GUID(IID, IID_IMessageMember,0x05D14E34,0x0A23,0x4A9F,0x95,0xCF,0x9D,0xB2,0x4B,0x3C,0xFB,0x9F);
MIDL_DEFINE_GUID(IID, IID_IMessage,0x23EE0804,0xEAC7,0x493B,0xBB,0x9D,0x22,0x98,0xFD,0x44,0xFF,0xA1);
MIDL_DEFINE_GUID(IID, IID_INetworkFilter,0xEEB0BE9E,0x46BD,0x493F,0x97,0xE2,0x33,0x06,0x70,0xC0,0x9F,0x59);
MIDL_DEFINE_GUID(IID, IID_ILayerKeyboard,0x7500929F,0x4251,0x4373,0xB9,0x78,0x28,0x6A,0x8A,0x8B,0xEC,0xED);
MIDL_DEFINE_GUID(IID, IID_ILayerPopup,0x22072A97,0xE5E6,0x4d91,0xA3,0x44,0x80,0x72,0x35,0xBF,0xA5,0xD8);
MIDL_DEFINE_GUID(IID, IID_ILayerTimer,0x5D6B8A1B,0x321A,0x479f,0x93,0x47,0x55,0x72,0x5B,0xDA,0x3D,0xA9);
MIDL_DEFINE_GUID(IID, IID_IWindowsMessageSink,0xA68BE455,0xC241,0x49c5,0x9F,0x8A,0x07,0x0E,0x4C,0xBE,0x43,0x0F);
MIDL_DEFINE_GUID(IID, IID_IBrushImage,0x50CDFD25,0x4F3B,0x4412,0x96,0xBE,0x94,0x7A,0x6C,0x7B,0x93,0xA2);
MIDL_DEFINE_GUID(IID, IID_IInputBuffer,0x634D74B8,0xAFED,0x4710,0x82,0xC9,0xB5,0x30,0x32,0x6E,0x1A,0xFA);
MIDL_DEFINE_GUID(IID, DIID_IInputEvents,0xBD33BADC,0xF909,0x4eb6,0xAD,0x15,0xB1,0x56,0x9B,0x58,0x89,0x8B);
MIDL_DEFINE_GUID(IID, IID_IInputNotify,0xE288C465,0x2DD6,0x4fcd,0x95,0xE2,0x5B,0xBC,0x1A,0x1D,0x2D,0x32);
MIDL_DEFINE_GUID(IID, LIBID_DecalPlugins,0x3559E08B,0x827E,0x4DFE,0x9D,0x33,0x35,0x67,0x24,0x68,0x49,0xCC);
MIDL_DEFINE_GUID(CLSID, CLSID_Canvas,0x91892F16,0x31A3,0x4E23,0x9C,0xFD,0x89,0xA5,0xA5,0x17,0x4A,0x59);
MIDL_DEFINE_GUID(CLSID, CLSID_PluginSite,0xB2FBD583,0xB64C,0x4dfc,0xBA,0xAA,0x34,0xB8,0xC2,0x14,0x82,0xF8);
MIDL_DEFINE_GUID(CLSID, CLSID_Layer,0x6FEA2219,0x7438,0x4f76,0x81,0x65,0xC4,0x7A,0xA0,0x60,0xD8,0x11);
MIDL_DEFINE_GUID(CLSID, CLSID_View,0x19BF46E4,0x5CB8,0x4CFC,0xA1,0x7A,0x8E,0x66,0x73,0xE6,0x0A,0xBF);
MIDL_DEFINE_GUID(CLSID, CLSID_Button,0xC22BF2FC,0xF144,0x4d17,0x9C,0x12,0xA3,0x44,0xF9,0x80,0xBB,0x17);
MIDL_DEFINE_GUID(CLSID, CLSID_Pager,0xC79E2F76,0x06F8,0x4cd0,0xA6,0x13,0x48,0x29,0x23,0x7D,0x29,0x7D);
MIDL_DEFINE_GUID(CLSID, CLSID_BrushImage,0x918C0333,0x5714,0x4C8D,0xA9,0x5C,0x2C,0x13,0x7B,0x76,0xD3,0x64);
MIDL_DEFINE_GUID(CLSID, CLSID_InputBuffer,0x2F91FC21,0x4D89,0x4B64,0x94,0xAE,0xA1,0x24,0xD5,0x45,0x63,0xAE);
#undef MIDL_DEFINE_GUID
#ifdef __cplusplus
}
#endif
#endif /* !defined(_M_IA64) && !defined(_M_AXP64)*/
#pragma warning( disable: 4049 ) /* more than 64k source lines */
/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */
/* link this file in with the server and any clients */
/* File created by MIDL compiler version 5.03.0280 */
/* at Sat Aug 18 01:06:36 2001
*/
/* Compiler settings for E:\Decal\Source\Inject\Inject.idl:
Oicf (OptLev=i2), W1, Zp8, env=Win64 (32b run,appending), ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
DECLSPEC_UUID(), MIDL_INTERFACE()
*/
//@@MIDL_FILE_HEADING( )
#if defined(_M_IA64) || defined(_M_AXP64)
#ifdef __cplusplus
extern "C"{
#endif
#include <rpc.h>
#include <rpcndr.h>
#ifdef _MIDL_USE_GUIDDEF_
#ifndef INITGUID
#define INITGUID
#include <guiddef.h>
#undef INITGUID
#else
#include <guiddef.h>
#endif
#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8)
#else // !_MIDL_USE_GUIDDEF_
#ifndef __IID_DEFINED__
#define __IID_DEFINED__
typedef struct _IID
{
unsigned long x;
unsigned short s1;
unsigned short s2;
unsigned char c[8];
} IID;
#endif // __IID_DEFINED__
#ifndef CLSID_DEFINED
#define CLSID_DEFINED
typedef IID CLSID;
#endif // CLSID_DEFINED
#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
#endif !_MIDL_USE_GUIDDEF_
MIDL_DEFINE_GUID(IID, IID_IManager,0xBC63C4A7,0xBE01,0x400D,0x90,0x8D,0x07,0x47,0xB0,0x6C,0x80,0x62);
MIDL_DEFINE_GUID(IID, IID_IPluginSite,0x702D3901,0xC13A,0x448e,0x88,0x71,0xEC,0xDC,0x8B,0xC8,0xD0,0x79);
MIDL_DEFINE_GUID(IID, IID_IPluginSink,0xD216BA6C,0xD328,0x4765,0xB4,0x0A,0x9B,0xC5,0x7C,0x96,0xF7,0x5E);
MIDL_DEFINE_GUID(IID, IID_IPlugin,0xBA3E677F,0x8E44,0x4829,0x98,0x2E,0x58,0xBB,0xBC,0x5C,0x5F,0x9B);
MIDL_DEFINE_GUID(IID, IID_IControl,0x996B377C,0x1953,0x4db1,0xAA,0xC1,0x15,0x7F,0x72,0x59,0x2D,0x3E);
MIDL_DEFINE_GUID(IID, DIID_IControlEvents,0x2FEBCBC3,0x488C,0x444f,0xAD,0x08,0x5D,0x30,0x97,0xD2,0xD1,0xED);
MIDL_DEFINE_GUID(IID, IID_ILayer,0x0D63504F,0xDEEF,0x4a2d,0x97,0x42,0x28,0xDD,0x1B,0xAD,0xDA,0x7C);
MIDL_DEFINE_GUID(IID, IID_ILayerRender,0xD1C71B85,0x62C2,0x42a3,0xAE,0x2E,0x4B,0xF5,0xA6,0xBE,0x17,0x84);
MIDL_DEFINE_GUID(IID, IID_ILayerSite,0x5B7E9D99,0xBB3A,0x475D,0x84,0x2D,0x43,0xEB,0xEA,0x82,0x84,0xEA);
MIDL_DEFINE_GUID(IID, IID_IBarManager,0xE4CCDC92,0x8658,0x4caa,0x89,0x55,0xFB,0x89,0x1D,0x5B,0xDC,0xF7);
MIDL_DEFINE_GUID(IID, IID_IIconCache,0xDEDCD5AA,0xF6CA,0x4DA5,0xA6,0x57,0xE8,0x2F,0x12,0x6A,0xBB,0xCD);
MIDL_DEFINE_GUID(IID, IID_IImageCacheDisp,0xF88548BC,0xD11E,0x4ac2,0x9A,0x27,0x36,0x07,0x00,0x4D,0x35,0x9F);
MIDL_DEFINE_GUID(IID, IID_IImageCache,0xBE566CEC,0x6881,0x481C,0xA1,0x46,0x9F,0x5A,0x32,0x57,0x6B,0xE6);
MIDL_DEFINE_GUID(IID, IID_IFontCacheDisp,0x9394E96D,0x2B29,0x4c29,0xAF,0x3E,0xDB,0x5C,0x47,0x61,0x22,0xDB);
MIDL_DEFINE_GUID(IID, IID_IFontCache,0x12ECCB0F,0x36A6,0x451C,0xB0,0x86,0x13,0x06,0xB7,0x4A,0xAE,0xC2);
MIDL_DEFINE_GUID(IID, IID_ISimpleBar,0x4A2D87CD,0xBFB4,0x4723,0xB9,0x59,0xFF,0xF3,0xFD,0xD4,0x92,0x78);
MIDL_DEFINE_GUID(IID, IID_ILayerMouse,0x5014E0B2,0x9156,0x412c,0x94,0x6D,0x9D,0x4B,0xAA,0x9F,0x4C,0x51);
MIDL_DEFINE_GUID(IID, IID_ILayerSchema,0x829E0FB2,0xD0B5,0x4814,0xBC,0xF9,0x6E,0xCF,0xA0,0x6C,0x9A,0xED);
MIDL_DEFINE_GUID(IID, IID_IButton,0x0F5765A4,0x9F83,0x4077,0x88,0x84,0x6C,0xBD,0xDC,0xE3,0x48,0xF7);
MIDL_DEFINE_GUID(IID, DIID_ICommandEvents,0xF029D3A1,0x29AF,0x45ef,0x92,0x7E,0x72,0x9F,0xED,0xD8,0x74,0x03);
MIDL_DEFINE_GUID(IID, IID_IPager,0xBD9FC464,0xC0D8,0x4823,0x82,0x55,0xE8,0x18,0xF8,0x83,0x6B,0x08);
MIDL_DEFINE_GUID(IID, DIID_IPagerEvents,0x7499EB61,0x6992,0x4e21,0x8A,0x55,0xCF,0x44,0xD4,0x4C,0x0A,0x07);
MIDL_DEFINE_GUID(IID, IID_IPanel,0x2B52B5CB,0x9E10,0x4238,0x8F,0x62,0xA5,0x01,0x40,0x6E,0x3E,0xAB);
MIDL_DEFINE_GUID(IID, IID_IPanelSink,0x85D70924,0x917D,0x41bb,0x99,0x5D,0xC4,0x0E,0x6A,0xB2,0x1C,0x71);
MIDL_DEFINE_GUID(IID, IID_ICanvas,0x9241862D,0xBA71,0x4317,0x81,0x66,0x3A,0x3E,0x61,0xCE,0x3E,0x5F);
MIDL_DEFINE_GUID(IID, IID_IViewDisp,0xF3B54A0C,0x61B9,0x4B7A,0x9F,0xD8,0x82,0xB0,0x47,0x7F,0xB7,0xD9);
MIDL_DEFINE_GUID(IID, IID_IView,0xA2AE18B7,0x85C9,0x451c,0x8C,0xC3,0xD0,0xFF,0xE6,0xB8,0x6E,0xEB);
MIDL_DEFINE_GUID(IID, DIID_IViewEvents,0x4B7B19D5,0x61A2,0x4ab0,0x8B,0x1B,0x38,0x1A,0x30,0x3A,0x93,0x7F);
MIDL_DEFINE_GUID(IID, IID_IRootLayer,0xD3006096,0xB293,0x47f5,0x93,0x77,0xC1,0x2D,0xEF,0x5C,0x1D,0x34);
MIDL_DEFINE_GUID(IID, IID_IMessageMember,0x05D14E34,0x0A23,0x4A9F,0x95,0xCF,0x9D,0xB2,0x4B,0x3C,0xFB,0x9F);
MIDL_DEFINE_GUID(IID, IID_IMessage,0x23EE0804,0xEAC7,0x493B,0xBB,0x9D,0x22,0x98,0xFD,0x44,0xFF,0xA1);
MIDL_DEFINE_GUID(IID, IID_INetworkFilter,0xEEB0BE9E,0x46BD,0x493F,0x97,0xE2,0x33,0x06,0x70,0xC0,0x9F,0x59);
MIDL_DEFINE_GUID(IID, IID_ILayerKeyboard,0x7500929F,0x4251,0x4373,0xB9,0x78,0x28,0x6A,0x8A,0x8B,0xEC,0xED);
MIDL_DEFINE_GUID(IID, IID_ILayerPopup,0x22072A97,0xE5E6,0x4d91,0xA3,0x44,0x80,0x72,0x35,0xBF,0xA5,0xD8);
MIDL_DEFINE_GUID(IID, IID_ILayerTimer,0x5D6B8A1B,0x321A,0x479f,0x93,0x47,0x55,0x72,0x5B,0xDA,0x3D,0xA9);
MIDL_DEFINE_GUID(IID, IID_IWindowsMessageSink,0xA68BE455,0xC241,0x49c5,0x9F,0x8A,0x07,0x0E,0x4C,0xBE,0x43,0x0F);
MIDL_DEFINE_GUID(IID, IID_IBrushImage,0x50CDFD25,0x4F3B,0x4412,0x96,0xBE,0x94,0x7A,0x6C,0x7B,0x93,0xA2);
MIDL_DEFINE_GUID(IID, IID_IInputBuffer,0x634D74B8,0xAFED,0x4710,0x82,0xC9,0xB5,0x30,0x32,0x6E,0x1A,0xFA);
MIDL_DEFINE_GUID(IID, DIID_IInputEvents,0xBD33BADC,0xF909,0x4eb6,0xAD,0x15,0xB1,0x56,0x9B,0x58,0x89,0x8B);
MIDL_DEFINE_GUID(IID, IID_IInputNotify,0xE288C465,0x2DD6,0x4fcd,0x95,0xE2,0x5B,0xBC,0x1A,0x1D,0x2D,0x32);
MIDL_DEFINE_GUID(IID, LIBID_DecalPlugins,0x3559E08B,0x827E,0x4DFE,0x9D,0x33,0x35,0x67,0x24,0x68,0x49,0xCC);
MIDL_DEFINE_GUID(CLSID, CLSID_Canvas,0x91892F16,0x31A3,0x4E23,0x9C,0xFD,0x89,0xA5,0xA5,0x17,0x4A,0x59);
MIDL_DEFINE_GUID(CLSID, CLSID_PluginSite,0xB2FBD583,0xB64C,0x4dfc,0xBA,0xAA,0x34,0xB8,0xC2,0x14,0x82,0xF8);
MIDL_DEFINE_GUID(CLSID, CLSID_Layer,0x6FEA2219,0x7438,0x4f76,0x81,0x65,0xC4,0x7A,0xA0,0x60,0xD8,0x11);
MIDL_DEFINE_GUID(CLSID, CLSID_View,0x19BF46E4,0x5CB8,0x4CFC,0xA1,0x7A,0x8E,0x66,0x73,0xE6,0x0A,0xBF);
MIDL_DEFINE_GUID(CLSID, CLSID_Button,0xC22BF2FC,0xF144,0x4d17,0x9C,0x12,0xA3,0x44,0xF9,0x80,0xBB,0x17);
MIDL_DEFINE_GUID(CLSID, CLSID_Pager,0xC79E2F76,0x06F8,0x4cd0,0xA6,0x13,0x48,0x29,0x23,0x7D,0x29,0x7D);
MIDL_DEFINE_GUID(CLSID, CLSID_BrushImage,0x918C0333,0x5714,0x4C8D,0xA9,0x5C,0x2C,0x13,0x7B,0x76,0xD3,0x64);
MIDL_DEFINE_GUID(CLSID, CLSID_InputBuffer,0x2F91FC21,0x4D89,0x4B64,0x94,0xAE,0xA1,0x24,0xD5,0x45,0x63,0xAE);
#undef MIDL_DEFINE_GUID
#ifdef __cplusplus
}
#endif
#endif /* defined(_M_IA64) || defined(_M_AXP64)*/

21230
Native/Inject/Attic/Inject_p.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,345 @@
// Message.cpp : Implementation of cMessage
#include "stdafx.h"
#include "Inject.h"
#include "Message.h"
#include "InjectApi.h"
#include "MessageLoaders.h"
#include "MessageParsers.h"
// m_pParent noahb
cMessage::cFieldList::iterator cMessage::cLoadContext::lookupField( cMessage::cMessageElement *pElement )
{
for( cLoadContext *pContext = this; pContext != NULL; pContext = pContext->m_pParent )
{
for( cFieldList::iterator i = m_pMessage->m_fields.begin() + m_dwOffset; i != m_pMessage->m_fields.end(); i += i->m_nOwns )
{
if( i->m_pSchema == pElement )
return i;
}
}
return m_pMessage->m_fields.end();
}
void cMessage::cMessageSchema::loadSchema( DWORD dwSchema )
{
TCHAR szQuery[ 255 ];
::_stprintf( szQuery, _T( "/schema/messages/message[@type='%04X']" ), dwSchema );
MSXML::IXMLDOMElementPtr pMessage = (*g_pXML)->selectSingleNode( szQuery );
if( pMessage.GetInterfacePtr() == NULL )
// Nothing here, so we create a valid but empty message
return;
cElementParser::cContext c( &m_members );
c.parseChildren( pMessage );
}
MSXML::IXMLDOMDocumentPtr * cMessage::g_pXML;
cMessage::cMessageSchemaMap cMessage::g_schema;
void cMessage::init()
{
// Load the schema
TCHAR szPath[ MAX_PATH ];
::InjectMapPath( eInjectPathAgent, _T( "messages.xml" ), szPath );
g_pXML = new MSXML::IXMLDOMDocumentPtr;
(*g_pXML).CreateInstance( __uuidof( MSXML::DOMDocument ) );
(*g_pXML)->load( szPath );
// Initialize our schema helper objects
cFieldLoader::init();
cElementParser::init();
#ifdef _DEBUG
// Load all of the message type
USES_CONVERSION;
MSXML::IXMLDOMNodeListPtr pAllMessages = (*g_pXML)->selectNodes( _T( "/schema/messages/message" ) );
for( MSXML::IXMLDOMElementPtr pMessage = pAllMessages->nextNode(); pMessage.GetInterfacePtr() != NULL; pMessage = pAllMessages->nextNode() )
{
_variant_t vType = pMessage->getAttribute( _T( "type" ) );
if( vType.vt != VT_BSTR )
{
_ASSERTE( FALSE );
continue;
}
// Get the ID from the message
long nID;
if( ::_stscanf( OLE2T( vType.bstrVal ), _T( "%X" ), &nID ) != 1 )
{
_ASSERTE( FALSE );
continue;
}
cMessageSchema ms;
ms.loadSchema( nID );
}
#endif
}
void cMessage::term()
{
g_schema.clear();
cElementParser::term();
cFieldLoader::term();
if( (*g_pXML).GetInterfacePtr() != NULL )
{
(*g_pXML).Release();
delete g_pXML;
}
}
/////////////////////////////////////////////////////////////////////////////
// cMessage
cMessage::cMessage()
: m_nType( 0 ),
m_pStartCrack( NULL ),
m_pEndCrack( NULL ),
m_pEndData( NULL ),
m_pSchema( NULL )
{
}
cMessage::cFieldList::iterator cMessage::getFieldFromElement( cMessageElement *pElement )
{
for( cFieldList::iterator i = m_fields.begin(); i != m_fields.end(); i += i->m_nOwns )
{
cMessageElement *pSchema = i->m_pSchema;
if( pSchema == pElement )
break;
}
return i;
}
void cMessage::crackMessage( BYTE *pBody, DWORD dwSize )
{
m_pStartCrack = pBody;
m_pEndData = pBody + dwSize + sizeof( DWORD );
m_nType = *reinterpret_cast< long * >( pBody );
m_fields.clear();
m_pEndCrack = m_pStartCrack + sizeof( long );
// First look up the message to see if it's already decoded
cMessageSchemaMap::iterator i_schema = g_schema.find( m_nType );
if( i_schema == g_schema.end() )
{
// Make a new one
m_pSchema = new cMessageSchema;
m_pSchema->loadSchema( m_nType );
g_schema.insert( cMessageSchemaMap::value_type( m_nType, std::auto_ptr< cMessageSchema >( m_pSchema ) ) );
}
else
m_pSchema = i_schema->second.get();
// At this point we have "a" schema of some quality
// set up the cursors
// Crack all fields right awway - testing mostly
cLoadContext context( this );
m_icracked = m_pSchema->m_members.begin();
while( m_icracked != m_pSchema->m_members.end() )
{
if( !m_icracked->get()->load( context ) )
{
// Failure to load the data, abort
m_icracked = m_pSchema->m_members.end();
break;
}
// Carry on to the next field
++ m_icracked;
}
}
void cMessage::crackAll()
{
cLoadContext context( this );
while( m_icracked != m_pSchema->m_members.end() )
{
if( !m_icracked->get()->load( context ) )
{
// Failure to load the data, abort
m_icracked = m_pSchema->m_members.end();
break;
}
// Carry on to the next field
++ m_icracked;
}
}
bool cMessage::crackMember( cFieldList::iterator i )
{
if( i != m_fields.end() )
// We aren't at the end yet
return true;
if( m_icracked == m_pSchema->m_members.end() )
// At the end now
return false;
// Attempt to crack the next field
cLoadContext context( this );
while( m_icracked != m_pSchema->m_members.end() )
{
if( !m_icracked->get()->load( context ) )
{
// Failure to load the data, abort
m_icracked = m_pSchema->m_members.end();
break;
}
// Carry on to the next field
++ m_icracked;
if( i != m_fields.end() )
return true;
}
return false;
}
STDMETHODIMP cMessage::get_Type(long *pVal)
{
_ASSERTE( pVal != NULL );
*pVal = *reinterpret_cast< long * >( m_pStartCrack );
return S_OK;
}
STDMETHODIMP cMessage::get_Data(VARIANT *pVal)
{
long nSize = m_pEndData - m_pStartCrack;
if( nSize == 0 )
{
// Special case, this message is entirely cracked - return NULL
pVal->vt = VT_NULL;
pVal->intVal = 0;
return S_OK;
}
// We've got some data to share
SAFEARRAYBOUND sab = { nSize, 0 };
SAFEARRAY *pArray = ::SafeArrayCreate( VT_UI1, 1, &sab );
::SafeArrayAllocData( pArray );
LPVOID pvData;
::SafeArrayAccessData( pArray, &pvData );
::memcpy( pvData, m_pStartCrack, nSize );
::SafeArrayUnaccessData( pArray );
pVal->vt = VT_ARRAY | VT_UI1;
pVal->parray = pArray;
return S_OK;
}
STDMETHODIMP cMessage::get_Member(VARIANT vName, VARIANT *pVal)
{
::VariantInit (pVal);
if( vName.vt == VT_BSTR )
{
_bstr_t bstrName = vName;
// Iterate over the fields and return our match - in this loop we'll do incremental
// cracking, so it's a little messy. When we hit the end, we look to see if there are
// more uncracked fields
int nFieldCount = m_fields.size();
for( int nField = 0; nField != nFieldCount; nField += m_fields[ nField ].m_nOwns )
{
if( m_fields[ nField ].m_pSchema->m_strName == bstrName )
{
m_fields[ nField ].m_pSchema->getValue( this, m_fields.begin() + nField, pVal );
return S_OK;
}
}
pVal->vt = VT_EMPTY;
return S_OK;
}
// Attempt to convert it into an index
HRESULT hRes = ::VariantChangeType( &vName, &vName, 0, VT_I4 );
if( FAILED( hRes ) )
{
_ASSERTE( FALSE );
return hRes;
}
// Check if the value is in range
long nIndex = vName.lVal;
if( nIndex < 0 )
{
_ASSERTE( nIndex >= 0 );
return E_INVALIDARG;
}
// Now, one problem is we aren't exactly sure how big the array is, so we have to walk
// through the fields, skipping appropriately
for( cFieldList::iterator i = m_fields.begin(); crackMember( i ); i += i->m_nOwns, -- nIndex )
{
if( nIndex == 0 )
{
// We've found the index - extract the value
i->m_pSchema->getValue( this, i, pVal );
return S_OK;
}
}
// The index was too high
_ASSERTE( FALSE );
return E_INVALIDARG;
}
STDMETHODIMP cMessage::get_MemberName(long nIndex, BSTR *pVal)
{
_ASSERTE( nIndex >= 0 );
_ASSERTE( pVal != NULL );
USES_CONVERSION;
for( cFieldList::iterator i = m_fields.begin(); crackMember( i ); i += i->m_nOwns, -- nIndex )
{
if( nIndex == 0 )
{
// We've found the index - extract the value
*pVal = OLE2BSTR( i->m_pSchema->m_strName );
return S_OK;
}
}
// The index was too high
return E_INVALIDARG;
}
STDMETHODIMP cMessage::get_Count(long *pVal)
{
_ASSERTE( pVal != NULL );
// We must crack them all to get a count
crackAll();
*pVal = 0;
for( cFieldList::iterator i = m_fields.begin(); i != m_fields.end(); i += i->m_nOwns, ++ ( *pVal ) );
return S_OK;
}

View file

@ -0,0 +1,148 @@
// Message.h : Declaration of the cMessage
#ifndef __MESSAGE_H_
#define __MESSAGE_H_
#include <map>
#include "resource.h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// cMessage
class ATL_NO_VTABLE cMessage :
public CComObjectRootEx<CComMultiThreadModel>,
public IDispatchImpl< IMessage, &IID_IMessage, &LIBID_DecalPlugins >
{
public:
class cMessageElement;
class cField
{
public:
cMessageElement *m_pSchema;
void *m_pvData;
int m_nOwns;
CComPtr< IDispatch > m_pDisp;
};
typedef std::deque< cField > cFieldList;
class cLoadContext
{
cMessage *m_pMessage;
DWORD m_dwOffset;
cLoadContext *m_pParent;
public:
cLoadContext( cMessage *pMessage )
: m_pMessage( pMessage ),
m_dwOffset( 0 ),
m_pParent( NULL )
{
}
cLoadContext( cLoadContext *pParent )
: m_pMessage( pParent->m_pMessage ),
m_dwOffset( m_pMessage->m_fields.size() ),
m_pParent( pParent )
{
}
cFieldList::iterator lookupField( cMessageElement *pElement );
DWORD addField( cMessageElement *pElement, void *pvData )
{
cField f;
f.m_pSchema = pElement;
f.m_pvData = pvData;
f.m_nOwns = 1;
m_pMessage->m_fields.push_back( f );
return m_pMessage->m_fields.size();
}
void groupField( DWORD dwIndex )
{
m_pMessage->m_fields[ dwIndex - 1 ].m_nOwns += m_pMessage->m_fields.size() - dwIndex;
}
cMessage *getMessage()
{
return m_pMessage;
}
};
class cMessageElement
{
public:
_bstr_t m_strName;
virtual ~cMessageElement()
{
}
// Decodes from the current point and returns
// the pointer advanced by a certain number of offsets
virtual bool load( cLoadContext &context ) = 0;
virtual void getValue( cMessage *pMsg, cFieldList::iterator i, LPVARIANT pDest ) = 0;
virtual long getNumber( cFieldList::iterator i )
{
// Default implementation fails
_ASSERTE( FALSE );
return 0;
}
};
typedef std::vector< std::auto_ptr< cMessageElement > > cElementList;
class cMessageSchema
{
public:
cElementList m_members;
void loadSchema( DWORD dwSchema );
bool parseChildren( cElementList &list, MSXML::IXMLDOMElementPtr &pElement );
};
typedef std::map< DWORD, std::auto_ptr< cMessageSchema > > cMessageSchemaMap;
static MSXML::IXMLDOMDocumentPtr * g_pXML;
static cMessageSchemaMap g_schema;
static void init();
static void term();
cMessage();
cFieldList m_fields;
long m_nType;
cMessageSchema *m_pSchema;
cElementList::iterator m_icracked;
cFieldList::iterator getFieldFromElement( cMessageElement *pElement );
BYTE *m_pStartCrack,
*m_pEndCrack,
*m_pEndData;
void crackMessage( BYTE *pBody, DWORD dwSize );
void crackAll();
bool crackMember( cFieldList::iterator i );
BEGIN_COM_MAP(cMessage)
COM_INTERFACE_ENTRY(IMessage)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
// IMessage
public:
STDMETHOD(get_Count)(/*[out, retval]*/ long *pVal);
STDMETHOD(get_MemberName)(long nIndex, /*[out, retval]*/ BSTR *pVal);
STDMETHOD(get_Member)(VARIANT vIndex, /*[out, retval]*/ VARIANT *pVal);
STDMETHOD(get_Data)(/*[out, retval]*/ VARIANT *pVal);
STDMETHOD(get_Type)(/*[out, retval]*/ long *pVal);
};
#endif //__MESSAGE_H_

View file

@ -0,0 +1,196 @@
// MessageLoaders.cpp
// Implementation of message loaders for various data types
#include "StdAfx.h"
#include "MessageLoaders.h"
// The boatload of decoding classes
template< class ValueT >
class cVariantLoader
: public cFieldLoader
{
public:
virtual void *skip( void *pData )
{
return reinterpret_cast< BYTE * >( pData ) + sizeof( ValueT );
}
virtual void *align( void *pData, void *pStart )
{
size_t nOffset = reinterpret_cast< BYTE * >( pData ) - reinterpret_cast< BYTE * >( pStart );
if( ( nOffset % sizeof( ValueT ) ) == 0 )
return pData;
return ( reinterpret_cast< BYTE * >( pStart ) + nOffset + sizeof( ValueT ) - ( nOffset % sizeof( ValueT ) ) );
}
virtual bool testValue( void *pData, void *pEnd )
{
return ( ( reinterpret_cast< BYTE * >( pData ) + sizeof( ValueT ) ) <= reinterpret_cast< BYTE * >( pEnd ) );
}
ValueT &valueOf( void *pvData )
{
return *reinterpret_cast< ValueT * >( pvData );
}
};
class cByteLoader
: public cVariantLoader< BYTE >
{
public:
virtual void getValue( void *pvData, LPVARIANT pDest )
{
pDest->vt = VT_UI1;
pDest->bVal = valueOf( pvData );
}
virtual long getNumber( void *pvData )
{
return valueOf( pvData );
}
};
class cShortLoader
: public cVariantLoader< short >
{
public:
virtual void getValue( void *pvData, LPVARIANT pDest )
{
pDest->vt = VT_I2;
pDest->iVal = valueOf( pvData );
}
virtual long getNumber( void *pvData )
{
return valueOf( pvData );
}
};
class cLongLoader
: public cVariantLoader< long >
{
public:
virtual void getValue( void *pvData, LPVARIANT pDest )
{
pDest->vt = VT_I4;
pDest->lVal = valueOf( pvData );
}
virtual long getNumber( void *pvData )
{
return valueOf( pvData );
}
};
class cFloatLoader
: public cVariantLoader< float >
{
public:
virtual void getValue( void *pvData, LPVARIANT pDest )
{
pDest->vt = VT_R4;
pDest->fltVal = valueOf( pvData );
}
};
class cDoubleLoader
: public cVariantLoader< double >
{
public:
virtual void getValue( void *pvData, LPVARIANT pDest )
{
pDest->vt = VT_R8;
pDest->dblVal = valueOf( pvData );
}
};
class cStringLoader
: public cFieldLoader
{
public:
virtual void *skip( void *pvData )
{
WORD wLength = *reinterpret_cast< WORD * >( pvData ) + sizeof( WORD );
if( ( wLength % sizeof( DWORD ) ) != 0 )
wLength += sizeof( DWORD ) - ( wLength % sizeof( DWORD ) );
return reinterpret_cast< BYTE * >( pvData ) + wLength;
}
virtual void *align( void *pvData, void * )
{
// Error, this is not a valid alignment type
_ASSERTE( FALSE );
return pvData;
}
virtual bool testValue( void *pvData, void *pvEnd )
{
WORD wLength = *reinterpret_cast< WORD * >( pvData ) + sizeof( WORD ),
wField = wLength;
if( ( wField % sizeof( DWORD ) ) != 0 )
wField += sizeof( DWORD ) - ( wField % sizeof( DWORD ) );
// It fits inside the packet, so our field isn't too big
if( ( reinterpret_cast< BYTE * >( pvData ) + wField ) > reinterpret_cast< BYTE * >( pvEnd ) )
return false;
if( *( reinterpret_cast< char * >( pvData ) + wLength - 1 ) != '\0' )
// This string is not NULL terminated
return false;
// Anything else just makes the string ugly, but won't lead to a memory
// overrun, so let them play
return true;
}
virtual void getValue( void *pvData, LPVARIANT pDest )
{
USES_CONVERSION;
pDest->vt = VT_BSTR;
pDest->bstrVal = A2BSTR( reinterpret_cast< char * >( reinterpret_cast< BYTE * >( pvData ) + sizeof( WORD ) ) );
}
};
long cFieldLoader::getNumber( void *pvData )
{
// This default implementation does not support this conversion
_ASSERTE( FALSE );
return 0;
}
cFieldLoader *cFieldLoader::lookup( const _bstr_t &strName )
{
cFieldLoaderMap::iterator i = g_primitives.find( strName );
if( i == g_primitives.end() )
return NULL;
return i->second.get();
}
void cFieldLoader::init()
{
addLoader( _T( "BYTE" ), new cByteLoader );
addLoader( _T( "WORD" ), new cShortLoader );
addLoader( _T( "DWORD" ), new cLongLoader );
addLoader( _T( "float" ), new cFloatLoader );
addLoader( _T( "double" ), new cDoubleLoader );
addLoader( _T( "String" ), new cStringLoader );
}
void cFieldLoader::term()
{
g_primitives.clear();
}
void cFieldLoader::addLoader( LPCTSTR szName, cFieldLoader *pLoader )
{
g_primitives.insert( cFieldLoaderMap::value_type( szName, std::auto_ptr< cFieldLoader >( pLoader ) ) );
}
cFieldLoader::cFieldLoaderMap cFieldLoader::g_primitives;

View file

@ -0,0 +1,30 @@
// MessageLoaders.h
// Declaration of Primitive Data Type loaders for encoded message data
#ifndef __MESSAGELOADERS_H
#define __MESSAGELOADERS_H
#include <map>
class cFieldLoader
{
public:
virtual void *skip(void *) = 0;
virtual void *align(void *pData, void *pStart) = 0;
virtual bool testValue(void *pData, void *pEnd) = 0;
virtual void getValue( void *, LPVARIANT pDest ) = 0;
virtual long getNumber( void *pvData );
static cFieldLoader *lookup( const _bstr_t &strName );
static void init();
static void term();
private:
static void addLoader( LPCTSTR szName, cFieldLoader *pLoader );
typedef std::map< _bstr_t, std::auto_ptr< cFieldLoader > > cFieldLoaderMap;
static cFieldLoaderMap g_primitives;
};
#endif

View file

@ -0,0 +1,701 @@
// MessageParsers.cpp
// Implementation of parsers and runtime objects for parsing message data
#include "StdAfx.h"
#include "Inject.h"
#include "MessageParsers.h"
#include "MessageLoaders.h"
#include "MessageStruct.h"
#include "MessageVector.h"
class cStructElement
: public cMessage::cMessageElement
{
public:
cMessage::cElementList m_members;
virtual bool load( cMessage::cLoadContext &context )
{
// Walk through the list of members and have them load
int nIndex = context.addField( this, NULL );
for( cMessage::cElementList::iterator i = m_members.begin(); i != m_members.end(); ++ i )
{
if( !i->get()->load( cMessage::cLoadContext( &context ) ) )
return false;
}
// Update the field count
context.groupField( nIndex );
return true;
}
virtual void getValue( cMessage *pMessage, cMessage::cFieldList::iterator i, LPVARIANT pDest )
{
if( i->m_pDisp.p == NULL )
{
// Create the vector object
CComObject< cMessageStruct > *pVecDisp;
CComObject< cMessageStruct >::CreateInstance( &pVecDisp );
pVecDisp->init( pMessage, ( i - pMessage->m_fields.begin() ) );
i->m_pDisp = pVecDisp;
}
else
i->m_pDisp->Reset();
pDest->vt = VT_DISPATCH;
pDest->pdispVal = i->m_pDisp;
pDest->pdispVal->AddRef();
}
};
class cFieldParser
: public cElementParser
{
public:
class cFieldElement
: public cMessage::cMessageElement
{
public:
cFieldLoader *m_pLoader;
virtual bool load( cMessage::cLoadContext &context )
{
if( !m_pLoader->testValue( context.getMessage()->m_pEndCrack, context.getMessage()->m_pEndData ) )
{
// The element failed, this will usually indicate bad schema
_ASSERTE( FALSE );
return false;
}
context.addField( this, context.getMessage()->m_pEndCrack );
context.getMessage()->m_pEndCrack = reinterpret_cast< BYTE * >( m_pLoader->skip( context.getMessage()->m_pEndCrack ) );
return true;
}
virtual void getValue( cMessage *, cMessage::cFieldList::iterator i, LPVARIANT pDest )
{
m_pLoader->getValue( i->m_pvData, pDest );
}
virtual long getNumber( cMessage::cFieldList::iterator i )
{
return m_pLoader->getNumber( i->m_pvData );
}
};
// Strings
static _bstr_t g_strType;
static _bstr_t g_strName;
virtual cMessage::cMessageElement *parse( cContext &context, MSXML::IXMLDOMElementPtr &pElement )
{
// Locate the data type in the list
_variant_t strDataType = pElement->getAttribute( g_strType );
if( strDataType.vt != VT_BSTR )
{
// Schema error
_ASSERTE( strDataType.vt == VT_BSTR );
return NULL;
}
_bstr_t bstrDataType = strDataType;
cFieldLoader *pField = cFieldLoader::lookup( bstrDataType );
if( pField == NULL )
return parseStruct( context, pElement, bstrDataType );
_variant_t strName = pElement->getAttribute( g_strName );
if( strName.vt != VT_BSTR )
{
_ASSERTE( strName.vt == VT_BSTR );
return NULL;
}
cFieldElement *pFieldElement = new cFieldElement;
pFieldElement->m_strName = strName;
pFieldElement->m_pLoader = pField;
return pFieldElement;
}
cMessage::cMessageElement *parseStruct( cContext &context, MSXML::IXMLDOMElementPtr &pElement, const _bstr_t &strType )
{
// Locate the data type in the list
_variant_t strName = pElement->getAttribute( cFieldParser::g_strName );
if( strName.vt != VT_BSTR )
{
// Schema error
_ASSERTE( strName.vt == VT_BSTR );
return NULL;
}
// We have the field name, now look up data type schema
USES_CONVERSION;
TCHAR szQuery[ 255 ];
::_stprintf( szQuery, _T( "/schema/datatypes/type[@name='%s']" ),
OLE2T( strType ) );
MSXML::IXMLDOMElementPtr pStruct = pElement->ownerDocument->selectSingleNode( szQuery );
if( pStruct.GetInterfacePtr() == NULL )
{
// Could not cross reference the structure
_ASSERTE( pStruct.GetInterfacePtr() != NULL );
return NULL;
}
std::auto_ptr< cStructElement > pStructElement( new cStructElement() );
pStructElement->m_strName = strName;
if( context.parseChildren( pStructElement->m_members, pStruct ) )
return pStructElement.release();
return NULL;
}
};
_bstr_t cFieldParser::g_strType( _T( "type" ) );
_bstr_t cFieldParser::g_strName( _T( "name" ) );
class cMaskParser
: public cElementParser
{
public:
class cMaskElement
: public cMessage::cMessageElement
{
public:
cMessage::cMessageElement *m_pValue;
class cMask
{
public:
DWORD m_dwValue;
DWORD m_dwFirstChild,
m_dwLastChild;
};
typedef std::vector< cMask > cMaskMap;
cMaskMap m_masks;
cMessage::cElementList m_members;
virtual bool load( cMessage::cLoadContext &context )
{
// First, look for our value element in the message
cMessage::cFieldList::iterator iField = context.lookupField( m_pValue );
if( iField == context.getMessage()->m_fields.end() )
{
// Could not find a mask source - most likely a bad name of some kind
_ASSERTE( FALSE );
return false;
}
_ASSERT( iField->m_pSchema == m_pValue );
long nMaskValue = iField->m_pSchema->getNumber( iField );
// Walk through the mask values and load all of the fields in range
for( cMaskMap::iterator i = m_masks.begin(); i != m_masks.end(); ++ i )
{
if( ( nMaskValue & i->m_dwValue ) == 0 )
continue;
// This is a valid mask load up all teh fields in range
cMessage::cElementList::iterator m_end = m_members.begin() + i->m_dwLastChild;
for( cMessage::cElementList::iterator j = m_members.begin() + i->m_dwFirstChild; j != m_end; ++ j )
{
if( !j->get()->load( context ) )
return false;
}
}
return true;
}
virtual void getValue( cMessage *, cMessage::cFieldList::iterator, LPVARIANT )
{
// This element should never insert itself into the message list
_ASSERTE( FALSE );
}
};
static _bstr_t g_strMask;
static _bstr_t g_strValue;
virtual cMessage::cMessageElement *parse( cContext &context, MSXML::IXMLDOMElementPtr &pElement )
{
_variant_t vName = pElement->getAttribute( cFieldParser::g_strName );
if( vName.vt != VT_BSTR )
{
// It must have the name field
_ASSERTE( vName.vt == VT_BSTR );
return NULL;
}
// Find a matching element in the schema
cMessage::cMessageElement *pName = context.findElement( vName.bstrVal );
if( pName == NULL )
{
// The mask field was not found
_ASSERTE( pName != NULL );
return NULL;
}
// Create the mask element
std::auto_ptr< cMaskElement > pMaskElement( new cMaskElement );
pMaskElement->m_pValue = pName;
// Walk through each of the mask values
USES_CONVERSION;
MSXML::IXMLDOMNodeListPtr pMaskList = pElement->selectNodes( g_strMask );
for( MSXML::IXMLDOMElementPtr pMask = pMaskList->nextNode(); pMask.GetInterfacePtr() != NULL; pMask = pMaskList->nextNode() )
{
_variant_t vValue = pMask->getAttribute( g_strValue );
if( vValue.vt != VT_BSTR )
{
_ASSERTE( vName.vt == VT_BSTR );
return NULL;
}
// Make sure it has the 'hex' prefix
if( vValue.bstrVal[ 0 ] != OLESTR( '0' ) )
{
_ASSERTE( vValue.bstrVal[ 0 ] == OLESTR( '0' ) );
return NULL;
}
if( vValue.bstrVal[ 1 ] != OLESTR( 'x' ) )
{
_ASSERTE( vValue.bstrVal[ 1 ] == OLESTR( 'x' ) );
return NULL;
}
// Attempt to convert the remaining number
long nMaskValue;
if( ::_stscanf( OLE2T( vValue.bstrVal + 2 ), _T( "%X" ), &nMaskValue ) != 1 )
{
// Could not convert value
_ASSERTE( FALSE );
return NULL;
}
long nStartOffset = pMaskElement->m_members.size();
context.parseChildren( pMaskElement->m_members, pMask );
cMaskElement::cMask mask = { nMaskValue, nStartOffset, pMaskElement->m_members.size() };
pMaskElement->m_masks.push_back( mask );
}
return pMaskElement.release();
}
};
_bstr_t cMaskParser::g_strMask( _T( "mask" ) );
_bstr_t cMaskParser::g_strValue( _T( "value" ) );
class cVectorParser
: public cElementParser
{
public:
class cVectorElement
: public cMessage::cMessageElement
{
public:
cMessage::cMessageElement *m_pLength;
std::auto_ptr< cMessage::cMessageElement > m_pStruct;
int m_nSkip;
virtual bool load( cMessage::cLoadContext &context )
{
// First, look for our value element in the message
cMessage::cFieldList::iterator iField = context.lookupField( m_pLength );
if( iField == context.getMessage()->m_fields.end() )
{
// Could not find a mask source - most likely a bad name of some kind
_ASSERTE( FALSE );
return NULL;
}
_ASSERT( iField->m_pSchema == m_pLength );
long nLength = iField->m_pSchema->getNumber( iField ) - m_nSkip;
// Insert a record for ourself
DWORD dwIndex = context.addField( this, NULL );
for( int i = 0; i < nLength; ++ i )
{
// Insert a record for the current struct
if( !m_pStruct->load( cMessage::cLoadContext( &context ) ) )
return false;
}
// Update the used field count
context.groupField( dwIndex );
return true;
}
virtual void getValue( cMessage *pMessage, cMessage::cFieldList::iterator i, LPVARIANT pDest )
{
if( i->m_pDisp.p == NULL )
{
// Create the vector object
CComObject< cMessageVector > *pVecDisp;
CComObject< cMessageVector >::CreateInstance( &pVecDisp );
pVecDisp->init( pMessage, ( i - pMessage->m_fields.begin() ) );
i->m_pDisp = pVecDisp;
}
else
i->m_pDisp->Reset();
pDest->vt = VT_DISPATCH;
pDest->pdispVal = i->m_pDisp;
pDest->pdispVal->AddRef();
}
};
static _bstr_t g_strLength,
g_strSkip;
virtual cMessage::cMessageElement *parse( cContext &context, MSXML::IXMLDOMElementPtr &pElement )
{
_variant_t vName = pElement->getAttribute( cFieldParser::g_strName );
if( vName.vt != VT_BSTR )
{
// It must have the name field
_ASSERTE( vName.vt == VT_BSTR );
return NULL;
}
_variant_t vLength = pElement->getAttribute( g_strLength ),
vSkip = pElement->getAttribute( g_strSkip );
if( vLength.vt != VT_BSTR )
{
// It must have the name field
_ASSERTE( vLength.vt == VT_BSTR );
return NULL;
}
long nSkip = 0;
if( vSkip.vt != VT_NULL )
{
try
{
nSkip = vSkip;
}
catch( ... )
{
// Failed to make the conversion
_ASSERT( FALSE );
return NULL;
}
}
cMessage::cMessageElement *pLength = context.findElement( vLength.bstrVal );
if( pLength == NULL )
{
// The mask field was not found
_ASSERTE( pLength != NULL );
return NULL;
}
std::auto_ptr< cStructElement > pStructElement( new cStructElement );
if( !context.parseChildren( pStructElement->m_members, pElement ) )
return NULL;
cVectorElement *pVector = new cVectorElement;
pVector->m_strName = vName;
pVector->m_pLength = pLength;
pVector->m_nSkip = nSkip;
pVector->m_pStruct = std::auto_ptr< cMessage::cMessageElement >( pStructElement.release() );
return pVector;
}
};
_bstr_t cVectorParser::g_strLength( _T( "length" ) );
_bstr_t cVectorParser::g_strSkip( _T( "skip" ) );
class cSwitchParser
: public cElementParser
{
public:
class cSwitchElement
: public cMessage::cMessageElement
{
public:
cMessage::cMessageElement *m_pValue;
class cCase
{
public:
DWORD m_dwValue;
DWORD m_dwFirstChild,
m_dwLastChild;
};
typedef std::vector< cCase > cCaseMap;
cCaseMap m_cases;
cMessage::cElementList m_members;
virtual bool load( cMessage::cLoadContext &context )
{
// First, look for our value element in the message
cMessage::cFieldList::iterator iField = context.lookupField( m_pValue );
if( iField == context.getMessage()->m_fields.end() )
{
// Could not find a mask source - most likely a bad name of some kind
_ASSERTE( FALSE );
return NULL;
}
_ASSERT( iField->m_pSchema == m_pValue );
long nCaseValue = iField->m_pSchema->getNumber( iField );
// Walk through the mask values and load all of the fields in range
for( cCaseMap::iterator i = m_cases.begin(); i != m_cases.end(); ++ i )
{
if( nCaseValue != i->m_dwValue )
continue;
// This is a valid mask load up all teh fields in range
cMessage::cElementList::iterator m_end = m_members.begin() + i->m_dwLastChild;
for( cMessage::cElementList::iterator j = m_members.begin() + i->m_dwFirstChild; j != m_end; ++ j )
{
if( !j->get()->load( context ) )
return false;
}
// For now we short circuit cases
break;
}
return true;
}
virtual void getValue( cMessage *, cMessage::cFieldList::iterator, LPVARIANT )
{
// This element should never insert itself into the message list
_ASSERTE( FALSE );
}
};
static _bstr_t g_strCase;
virtual cMessage::cMessageElement *parse( cContext &context, MSXML::IXMLDOMElementPtr &pElement )
{
_variant_t vName = pElement->getAttribute( cFieldParser::g_strName );
if( vName.vt != VT_BSTR )
{
// It must have the name field
_ASSERTE( vName.vt == VT_BSTR );
return NULL;
}
// Find a matching element in the schema
cMessage::cMessageElement *pName = context.findElement( vName.bstrVal );
if( pName == NULL )
{
// The mask field was not found
_ASSERTE( pName != NULL );
return NULL;
}
// Create the mask element
std::auto_ptr< cSwitchElement > pSwitchElement( new cSwitchElement );
pSwitchElement->m_pValue = pName;
// Walk through each of the mask values
USES_CONVERSION;
MSXML::IXMLDOMNodeListPtr pCaseList = pElement->selectNodes( g_strCase );
for( MSXML::IXMLDOMElementPtr pCase = pCaseList->nextNode(); pCase.GetInterfacePtr() != NULL; pCase = pCaseList->nextNode() )
{
_variant_t vValue = pCase->getAttribute( cMaskParser::g_strValue );
if( vValue.vt != VT_BSTR )
{
_ASSERTE( vName.vt == VT_BSTR );
return NULL;
}
// Make sure it has the 'hex' prefix
if( vValue.bstrVal[ 0 ] != OLESTR( '0' ) )
{
_ASSERTE( vValue.bstrVal[ 0 ] == OLESTR( '0' ) );
return NULL;
}
if( vValue.bstrVal[ 1 ] != OLESTR( 'x' ) )
{
_ASSERTE( vValue.bstrVal[ 1 ] == OLESTR( 'x' ) );
return NULL;
}
// Attempt to convert the remaining number
long nCaseValue;
if( ::_stscanf( OLE2T( vValue.bstrVal + 2 ), _T( "%X" ), &nCaseValue ) != 1 )
{
// Could not convert value
_ASSERTE( FALSE );
return NULL;
}
long nStartOffset = pSwitchElement->m_members.size();
context.parseChildren( pSwitchElement->m_members, pCase );
cSwitchElement::cCase _case = { nCaseValue, nStartOffset, pSwitchElement->m_members.size() };
pSwitchElement->m_cases.push_back( _case );
}
return pSwitchElement.release();
}
};
_bstr_t cSwitchParser::g_strCase( _T( "case" ) );
class cAlignParser
: public cElementParser
{
public:
class cAlignElement
: public cMessage::cMessageElement
{
public:
cFieldLoader *m_pLoader;
virtual bool load( cMessage::cLoadContext &context )
{
void *pAlign = m_pLoader->align( context.getMessage()->m_pEndCrack, context.getMessage()->m_pStartCrack );
if( pAlign > context.getMessage()->m_pEndData )
{
_ASSERTE( FALSE );
return false;
}
context.getMessage()->m_pEndCrack = reinterpret_cast< BYTE * >( pAlign );
return true;
}
virtual void getValue( cMessage *, cMessage::cFieldList::iterator i, LPVARIANT pDest )
{
// This should never associate itself with a field
_ASSERTE( FALSE );
}
};
virtual cMessage::cMessageElement *parse( cContext &context, MSXML::IXMLDOMElementPtr &pElement )
{
// Locate the data type in the list
_variant_t strDataType = pElement->getAttribute( cFieldParser::g_strType );
if( strDataType.vt != VT_BSTR )
{
// Schema error
_ASSERTE( strDataType.vt == VT_BSTR );
return NULL;
}
_bstr_t bstrDataType = strDataType;
cFieldLoader *pField = cFieldLoader::lookup( bstrDataType );
if( pField == NULL )
{
_ASSERTE( FALSE );
return NULL;
}
cAlignElement *pAlignElement = new cAlignElement;
pAlignElement->m_pLoader = pField;
return pAlignElement;
}
};
cMessage::cMessageElement *cElementParser::cContext::findElement( const _bstr_t &strElement )
{
for( cContext *pContext = this; pContext != NULL; pContext = pContext->m_pParent )
{
for( cMessage::cElementList::iterator i = m_pElements->begin() + m_dwStartOffset; i != m_pElements->end(); ++ i )
{
if( i->get()->m_strName == strElement )
return i->get();
}
}
return NULL;
}
bool cElementParser::cContext::parseChildren( MSXML::IXMLDOMElementPtr &pElement )
{
MSXML::IXMLDOMNodeListPtr pChildList = pElement->selectNodes( g_strAll );
for( MSXML::IXMLDOMElementPtr pChild = pChildList->nextNode(); pChild.GetInterfacePtr() != NULL; pChild = pChildList->nextNode() )
{
_bstr_t strElementName = pChild->tagName;
cElementParser *pParser = cElementParser::lookup( strElementName );
if( pParser == NULL )
{
// Could not find a parse for this element type
_ASSERTE( FALSE );
return false;
}
cMessage::cMessageElement *pElement = pParser->parse( *this, pChild );
if( pElement == NULL )
return false;
m_pElements->push_back( cMessage::cElementList::value_type( pElement ) );
}
return true;
}
_bstr_t cElementParser::cContext::g_strAll( _T( "*" ) );
bool cElementParser::cContext::parseChildren( cMessage::cElementList &elements, MSXML::IXMLDOMElementPtr &pElement )
{
cContext c( &elements, this );
return c.parseChildren( pElement );
}
cElementParser *cElementParser::lookup( const _bstr_t &strElement )
{
cElementParserMap::iterator i = g_parsers.find( strElement );
if( i == g_parsers.end() )
return NULL;
return i->second.get();
}
void cElementParser::init()
{
addParser( _T( "field" ), new cFieldParser );
addParser( _T( "maskmap" ), new cMaskParser );
addParser( _T( "vector" ), new cVectorParser );
addParser( _T( "switch" ), new cSwitchParser );
addParser( _T( "align" ), new cAlignParser );
}
void cElementParser::term()
{
g_parsers.clear();
}
void cElementParser::addParser( LPCTSTR szName, cElementParser *pParser )
{
g_parsers.insert( cElementParserMap::value_type( szName, std::auto_ptr< cElementParser >( pParser ) ) );
}
cElementParser::cElementParserMap cElementParser::g_parsers;

View file

@ -0,0 +1,704 @@
// MessageParsers.cpp
// Implementation of parsers and runtime objects for parsing message data
#include "StdAfx.h"
#include "Inject.h"
#include "MessageParsers.h"
#include "MessageLoaders.h"
#include "MessageStruct.h"
#include "MessageVector.h"
class cStructElement
: public cMessage::cMessageElement
{
public:
cMessage::cElementList m_members;
virtual bool load( cMessage::cLoadContext &context )
{
// Walk through the list of members and have them load
int nIndex = context.addField( this, NULL );
for( cMessage::cElementList::iterator i = m_members.begin(); i != m_members.end(); ++ i )
{
if( !i->get()->load( cMessage::cLoadContext( &context ) ) )
return false;
}
// Update the field count
context.groupField( nIndex );
return true;
}
virtual void getValue( cMessage *pMessage, cMessage::cFieldList::iterator i, LPVARIANT pDest )
{
if( i->m_pDisp.p == NULL )
{
// Create the vector object
CComObject< cMessageStruct > *pVecDisp;
CComObject< cMessageStruct >::CreateInstance( &pVecDisp );
pVecDisp->m_pSource = pMessage;
pVecDisp->m_dwStartIndex = ( i - pMessage->m_fields.begin() );
i->m_pDisp = pVecDisp;
}
::VariantInit (pDest);
pDest->vt = VT_DISPATCH;
pDest->pdispVal = i->m_pDisp;
pDest->pdispVal->AddRef();
}
};
class cFieldParser
: public cElementParser
{
public:
class cFieldElement
: public cMessage::cMessageElement
{
public:
cFieldLoader *m_pLoader;
virtual bool load( cMessage::cLoadContext &context )
{
if( !m_pLoader->testValue( context.getMessage()->m_pEndCrack, context.getMessage()->m_pEndData ) )
{
// The element failed, this will usually indicate bad schema
_ASSERTE( FALSE );
return false;
}
context.addField( this, context.getMessage()->m_pEndCrack );
context.getMessage()->m_pEndCrack = reinterpret_cast< BYTE * >( m_pLoader->skip( context.getMessage()->m_pEndCrack ) );
return true;
}
virtual void getValue( cMessage *, cMessage::cFieldList::iterator i, LPVARIANT pDest )
{
m_pLoader->getValue( i->m_pvData, pDest );
}
virtual long getNumber( cMessage::cFieldList::iterator i )
{
return m_pLoader->getNumber( i->m_pvData );
}
};
// Strings
static _bstr_t g_strType;
static _bstr_t g_strName;
virtual cMessage::cMessageElement *parse( cContext &context, MSXML::IXMLDOMElementPtr &pElement )
{
// Locate the data type in the list
_variant_t strDataType = pElement->getAttribute( g_strType );
if( strDataType.vt != VT_BSTR )
{
// Schema error
_ASSERTE( strDataType.vt == VT_BSTR );
return NULL;
}
_bstr_t bstrDataType = strDataType;
cFieldLoader *pField = cFieldLoader::lookup( bstrDataType );
if( pField == NULL )
return parseStruct( context, pElement, bstrDataType );
_variant_t strName = pElement->getAttribute( g_strName );
if( strName.vt != VT_BSTR )
{
_ASSERTE( strName.vt == VT_BSTR );
return NULL;
}
cFieldElement *pFieldElement = new cFieldElement;
pFieldElement->m_strName = strName;
pFieldElement->m_pLoader = pField;
return pFieldElement;
}
cMessage::cMessageElement *parseStruct( cContext &context, MSXML::IXMLDOMElementPtr &pElement, const _bstr_t &strType )
{
// Locate the data type in the list
_variant_t strName = pElement->getAttribute( cFieldParser::g_strName );
if( strName.vt != VT_BSTR )
{
// Schema error
_ASSERTE( strName.vt == VT_BSTR );
return NULL;
}
// We have the field name, now look up data type schema
USES_CONVERSION;
TCHAR szQuery[ 255 ];
::_stprintf( szQuery, _T( "/schema/datatypes/type[@name='%s']" ),
OLE2T( strType ) );
MSXML::IXMLDOMElementPtr pStruct = pElement->ownerDocument->selectSingleNode( szQuery );
if( pStruct.GetInterfacePtr() == NULL )
{
// Could not cross reference the structure
_ASSERTE( pStruct.GetInterfacePtr() != NULL );
return NULL;
}
std::auto_ptr< cStructElement > pStructElement( new cStructElement() );
pStructElement->m_strName = strName;
if( context.parseChildren( pStructElement->m_members, pStruct ) )
return pStructElement.release();
return NULL;
}
};
_bstr_t cFieldParser::g_strType( _T( "type" ) );
_bstr_t cFieldParser::g_strName( _T( "name" ) );
class cMaskParser
: public cElementParser
{
public:
class cMaskElement
: public cMessage::cMessageElement
{
public:
cMessage::cMessageElement *m_pValue;
class cMask
{
public:
DWORD m_dwValue;
DWORD m_dwFirstChild,
m_dwLastChild;
};
typedef std::vector< cMask > cMaskMap;
cMaskMap m_masks;
cMessage::cElementList m_members;
virtual bool load( cMessage::cLoadContext &context )
{
// First, look for our value element in the message
cMessage::cFieldList::iterator iField = context.lookupField( m_pValue );
if( iField == context.getMessage()->m_fields.end() )
{
// Could not find a mask source - most likely a bad name of some kind
_ASSERTE( FALSE );
return false;
}
_ASSERT( iField->m_pSchema == m_pValue );
long nMaskValue = iField->m_pSchema->getNumber( iField );
// Walk through the mask values and load all of the fields in range
for( cMaskMap::iterator i = m_masks.begin(); i != m_masks.end(); ++ i )
{
if( ( nMaskValue & i->m_dwValue ) == 0 )
continue;
// THis is a valid mask load up all teh fields in range
cMessage::cElementList::iterator m_end = m_members.begin() + i->m_dwLastChild;
for( cMessage::cElementList::iterator j = m_members.begin() + i->m_dwFirstChild; j != m_end; ++ j )
{
if( !j->get()->load( context ) )
return false;
}
}
return true;
}
virtual void getValue( cMessage *, cMessage::cFieldList::iterator, LPVARIANT )
{
// This element should never insert itself into the message list
_ASSERTE( FALSE );
}
};
static _bstr_t g_strMask;
static _bstr_t g_strValue;
virtual cMessage::cMessageElement *parse( cContext &context, MSXML::IXMLDOMElementPtr &pElement )
{
_variant_t vName = pElement->getAttribute( cFieldParser::g_strName );
if( vName.vt != VT_BSTR )
{
// It must have the name field
_ASSERTE( vName.vt == VT_BSTR );
return NULL;
}
// Find a matching element in the schema
cMessage::cMessageElement *pName = context.findElement( vName.bstrVal );
if( pName == NULL )
{
// The mask field was not found
_ASSERTE( pName != NULL );
return NULL;
}
// Create the mask element
std::auto_ptr< cMaskElement > pMaskElement( new cMaskElement );
pMaskElement->m_pValue = pName;
// Walk through each of the mask values
USES_CONVERSION;
MSXML::IXMLDOMNodeListPtr pMaskList = pElement->selectNodes( g_strMask );
for( MSXML::IXMLDOMElementPtr pMask = pMaskList->nextNode(); pMask.GetInterfacePtr() != NULL; pMask = pMaskList->nextNode() )
{
_variant_t vValue = pMask->getAttribute( g_strValue );
if( vValue.vt != VT_BSTR )
{
_ASSERTE( vName.vt == VT_BSTR );
return NULL;
}
// Make sure it has the 'hex' prefix
if( vValue.bstrVal[ 0 ] != OLESTR( '0' ) )
{
_ASSERTE( vValue.bstrVal[ 0 ] == OLESTR( '0' ) );
return NULL;
}
if( vValue.bstrVal[ 1 ] != OLESTR( 'x' ) )
{
_ASSERTE( vValue.bstrVal[ 1 ] == OLESTR( 'x' ) );
return NULL;
}
// Attempt to convert the remaining number
long nMaskValue;
if( ::_stscanf( OLE2T( vValue.bstrVal + 2 ), _T( "%X" ), &nMaskValue ) != 1 )
{
// Could not convert value
_ASSERTE( FALSE );
return NULL;
}
long nStartOffset = pMaskElement->m_members.size();
context.parseChildren( pMaskElement->m_members, pMask );
cMaskElement::cMask mask = { nMaskValue, nStartOffset, pMaskElement->m_members.size() };
pMaskElement->m_masks.push_back( mask );
}
return pMaskElement.release();
}
};
_bstr_t cMaskParser::g_strMask( _T( "mask" ) );
_bstr_t cMaskParser::g_strValue( _T( "value" ) );
class cVectorParser
: public cElementParser
{
public:
class cVectorElement
: public cMessage::cMessageElement
{
public:
cMessage::cMessageElement *m_pLength;
std::auto_ptr< cMessage::cMessageElement > m_pStruct;
int m_nSkip;
virtual bool load( cMessage::cLoadContext &context )
{
// First, look for our value element in the message
cMessage::cFieldList::iterator iField = context.lookupField( m_pLength );
if( iField == context.getMessage()->m_fields.end() )
{
// Could not find a mask source - most likely a bad name of some kind
_ASSERTE( FALSE );
return NULL;
}
_ASSERT( iField->m_pSchema == m_pLength );
long nLength = iField->m_pSchema->getNumber( iField ) - m_nSkip;
// Insert a record for ourself
DWORD dwIndex = context.addField( this, NULL );
for( int i = 0; i < nLength; ++ i )
{
// Insert a record for the current struct
if( !m_pStruct->load( cMessage::cLoadContext( &context ) ) )
return false;
}
// Update the used field count
context.groupField( dwIndex );
return true;
}
virtual void getValue( cMessage *pMessage, cMessage::cFieldList::iterator i, LPVARIANT pDest )
{
if( i->m_pDisp.p == NULL )
{
// Create the vector object
CComObject< cMessageVector > *pVecDisp;
CComObject< cMessageVector >::CreateInstance( &pVecDisp );
pVecDisp->m_pSource = pMessage;
pVecDisp->m_dwStartIndex = ( i - pMessage->m_fields.begin() );
i->m_pDisp = pVecDisp;
}
::VariantInit (pDest);
pDest->vt = VT_DISPATCH;
pDest->pdispVal = i->m_pDisp;
pDest->pdispVal->AddRef();
}
};
static _bstr_t g_strLength,
g_strSkip;
virtual cMessage::cMessageElement *parse( cContext &context, MSXML::IXMLDOMElementPtr &pElement )
{
_variant_t vName = pElement->getAttribute( cFieldParser::g_strName );
if( vName.vt != VT_BSTR )
{
// It must have the name field
_ASSERTE( vName.vt == VT_BSTR );
return NULL;
}
_variant_t vLength = pElement->getAttribute( g_strLength ),
vSkip = pElement->getAttribute( g_strSkip );
if( vLength.vt != VT_BSTR )
{
// It must have the name field
_ASSERTE( vLength.vt == VT_BSTR );
return NULL;
}
long nSkip = 0;
if( vSkip.vt != VT_NULL )
{
try
{
nSkip = vSkip;
}
catch( ... )
{
// Failed to make the conversion
_ASSERT( FALSE );
return NULL;
}
}
cMessage::cMessageElement *pLength = context.findElement( vLength.bstrVal );
if( pLength == NULL )
{
// The mask field was not found
_ASSERTE( pLength != NULL );
return NULL;
}
std::auto_ptr< cStructElement > pStructElement( new cStructElement );
if( !context.parseChildren( pStructElement->m_members, pElement ) )
return NULL;
cVectorElement *pVector = new cVectorElement;
pVector->m_strName = vName;
pVector->m_pLength = pLength;
pVector->m_nSkip = nSkip;
pVector->m_pStruct = std::auto_ptr< cMessage::cMessageElement >( pStructElement.release() );
return pVector;
}
};
_bstr_t cVectorParser::g_strLength( _T( "length" ) );
_bstr_t cVectorParser::g_strSkip( _T( "skip" ) );
class cSwitchParser
: public cElementParser
{
public:
class cSwitchElement
: public cMessage::cMessageElement
{
public:
cMessage::cMessageElement *m_pValue;
class cCase
{
public:
DWORD m_dwValue;
DWORD m_dwFirstChild,
m_dwLastChild;
};
typedef std::vector< cCase > cCaseMap;
cCaseMap m_cases;
cMessage::cElementList m_members;
virtual bool load( cMessage::cLoadContext &context )
{
// First, look for our value element in the message
cMessage::cFieldList::iterator iField = context.lookupField( m_pValue );
if( iField == context.getMessage()->m_fields.end() )
{
// Could not find a mask source - most likely a bad name of some kind
_ASSERTE( FALSE );
return NULL;
}
_ASSERT( iField->m_pSchema == m_pValue );
long nCaseValue = iField->m_pSchema->getNumber( iField );
// Walk through the mask values and load all of the fields in range
for( cCaseMap::iterator i = m_cases.begin(); i != m_cases.end(); ++ i )
{
if( nCaseValue != i->m_dwValue )
continue;
// This is a valid mask load up all teh fields in range
cMessage::cElementList::iterator m_end = m_members.begin() + i->m_dwLastChild;
for( cMessage::cElementList::iterator j = m_members.begin() + i->m_dwFirstChild; j != m_end; ++ j )
{
if( !j->get()->load( context ) )
return false;
}
// For now we short circuit cases
break;
}
return true;
}
virtual void getValue( cMessage *, cMessage::cFieldList::iterator, LPVARIANT )
{
// This element should never insert itself into the message list
_ASSERTE( FALSE );
}
};
static _bstr_t g_strCase;
virtual cMessage::cMessageElement *parse( cContext &context, MSXML::IXMLDOMElementPtr &pElement )
{
_variant_t vName = pElement->getAttribute( cFieldParser::g_strName );
if( vName.vt != VT_BSTR )
{
// It must have the name field
_ASSERTE( vName.vt == VT_BSTR );
return NULL;
}
// Find a matching element in the schema
cMessage::cMessageElement *pName = context.findElement( vName.bstrVal );
if( pName == NULL )
{
// The mask field was not found
_ASSERTE( pName != NULL );
return NULL;
}
// Create the mask element
std::auto_ptr< cSwitchElement > pSwitchElement( new cSwitchElement );
pSwitchElement->m_pValue = pName;
// Walk through each of the mask values
USES_CONVERSION;
MSXML::IXMLDOMNodeListPtr pCaseList = pElement->selectNodes( g_strCase );
for( MSXML::IXMLDOMElementPtr pCase = pCaseList->nextNode(); pCase.GetInterfacePtr() != NULL; pCase = pCaseList->nextNode() )
{
_variant_t vValue = pCase->getAttribute( cMaskParser::g_strValue );
if( vValue.vt != VT_BSTR )
{
_ASSERTE( vName.vt == VT_BSTR );
return NULL;
}
// Make sure it has the 'hex' prefix
if( vValue.bstrVal[ 0 ] != OLESTR( '0' ) )
{
_ASSERTE( vValue.bstrVal[ 0 ] == OLESTR( '0' ) );
return NULL;
}
if( vValue.bstrVal[ 1 ] != OLESTR( 'x' ) )
{
_ASSERTE( vValue.bstrVal[ 1 ] == OLESTR( 'x' ) );
return NULL;
}
// Attempt to convert the remaining number
long nCaseValue;
if( ::_stscanf( OLE2T( vValue.bstrVal + 2 ), _T( "%X" ), &nCaseValue ) != 1 )
{
// Could not convert value
_ASSERTE( FALSE );
return NULL;
}
long nStartOffset = pSwitchElement->m_members.size();
context.parseChildren( pSwitchElement->m_members, pCase );
cSwitchElement::cCase _case = { nCaseValue, nStartOffset, pSwitchElement->m_members.size() };
pSwitchElement->m_cases.push_back( _case );
}
return pSwitchElement.release();
}
};
_bstr_t cSwitchParser::g_strCase( _T( "case" ) );
class cAlignParser
: public cElementParser
{
public:
class cAlignElement
: public cMessage::cMessageElement
{
public:
cFieldLoader *m_pLoader;
virtual bool load( cMessage::cLoadContext &context )
{
void *pAlign = m_pLoader->align( context.getMessage()->m_pEndCrack, context.getMessage()->m_pStartCrack );
if( pAlign > context.getMessage()->m_pEndData )
{
_ASSERTE( FALSE );
return false;
}
context.getMessage()->m_pEndCrack = reinterpret_cast< BYTE * >( pAlign );
return true;
}
virtual void getValue( cMessage *, cMessage::cFieldList::iterator i, LPVARIANT pDest )
{
// This should never associate itself with a field
_ASSERTE( FALSE );
}
};
virtual cMessage::cMessageElement *parse( cContext &context, MSXML::IXMLDOMElementPtr &pElement )
{
// Locate the data type in the list
_variant_t strDataType = pElement->getAttribute( cFieldParser::g_strType );
if( strDataType.vt != VT_BSTR )
{
// Schema error
_ASSERTE( strDataType.vt == VT_BSTR );
return NULL;
}
_bstr_t bstrDataType = strDataType;
cFieldLoader *pField = cFieldLoader::lookup( bstrDataType );
if( pField == NULL )
{
_ASSERTE( FALSE );
return NULL;
}
cAlignElement *pAlignElement = new cAlignElement;
pAlignElement->m_pLoader = pField;
return pAlignElement;
}
};
cMessage::cMessageElement *cElementParser::cContext::findElement( const _bstr_t &strElement )
{
for( cContext *pContext = this; pContext != NULL; pContext = pContext->m_pParent )
{
for( cMessage::cElementList::iterator i = m_pElements->begin() + m_dwStartOffset; i != m_pElements->end(); ++ i )
{
if( i->get()->m_strName == strElement )
return i->get();
}
}
return NULL;
}
bool cElementParser::cContext::parseChildren( MSXML::IXMLDOMElementPtr &pElement )
{
MSXML::IXMLDOMNodeListPtr pChildList = pElement->selectNodes( g_strAll );
for( MSXML::IXMLDOMElementPtr pChild = pChildList->nextNode(); pChild.GetInterfacePtr() != NULL; pChild = pChildList->nextNode() )
{
_bstr_t strElementName = pChild->tagName;
cElementParser *pParser = cElementParser::lookup( strElementName );
if( pParser == NULL )
{
// Could not find a parse for this element type
_ASSERTE( FALSE );
return false;
}
cMessage::cMessageElement *pElement = pParser->parse( *this, pChild );
if( pElement == NULL )
return false;
m_pElements->push_back( cMessage::cElementList::value_type( pElement ) );
}
return true;
}
_bstr_t cElementParser::cContext::g_strAll( _T( "*" ) );
bool cElementParser::cContext::parseChildren( cMessage::cElementList &elements, MSXML::IXMLDOMElementPtr &pElement )
{
cContext c( &elements, this );
return c.parseChildren( pElement );
}
cElementParser *cElementParser::lookup( const _bstr_t &strElement )
{
cElementParserMap::iterator i = g_parsers.find( strElement );
if( i == g_parsers.end() )
return NULL;
return i->second.get();
}
void cElementParser::init()
{
addParser( _T( "field" ), new cFieldParser );
addParser( _T( "maskmap" ), new cMaskParser );
addParser( _T( "vector" ), new cVectorParser );
addParser( _T( "switch" ), new cSwitchParser );
addParser( _T( "align" ), new cAlignParser );
}
void cElementParser::term()
{
g_parsers.clear();
}
void cElementParser::addParser( LPCTSTR szName, cElementParser *pParser )
{
g_parsers.insert( cElementParserMap::value_type( szName, std::auto_ptr< cElementParser >( pParser ) ) );
}
cElementParser::cElementParserMap cElementParser::g_parsers;

View file

@ -0,0 +1,48 @@
// MessageParsers.h
// Declaration of class cMessageParser - base class for parsing the
// XML Schema
#ifndef __MESSAGEPARSERS_H
#define __MESSAGEPARSERS_H
#include "Message.h"
class cElementParser
{
public:
class cContext
{
cContext *m_pParent;
cMessage::cElementList *m_pElements;
DWORD m_dwStartOffset;
public:
cContext( cMessage::cElementList *pElements, cContext *pParent = NULL )
: m_pParent( pParent ),
m_pElements( pElements ),
m_dwStartOffset( pElements->size() )
{
}
cMessage::cMessageElement *findElement( const _bstr_t &strElement );
bool parseChildren( MSXML::IXMLDOMElementPtr &pElement );
bool parseChildren( cMessage::cElementList &elements, MSXML::IXMLDOMElementPtr &pElement );
static _bstr_t g_strAll;
};
virtual cMessage::cMessageElement *parse( cContext &context, MSXML::IXMLDOMElementPtr &pElement ) = 0;
static cElementParser *lookup( const _bstr_t &strElement );
static void init();
static void term();
private:
static void addParser( LPCTSTR szElement, cElementParser *pParser );
typedef std::map< _bstr_t, std::auto_ptr< cElementParser > > cElementParserMap;
static cElementParserMap g_parsers;
};
#endif

View file

@ -0,0 +1,93 @@
// MessageStruct.cpp : Implementation of cMessageStruct
#include "stdafx.h"
#include "Inject.h"
#include "MessageStruct.h"
#include "Message.h"
/////////////////////////////////////////////////////////////////////////////
// cMessageStruct
STDMETHODIMP cMessageStruct::get_Count(long *pVal)
{
_ASSERTE( pVal != NULL );
cMessage::cFieldList::iterator i_begin = m_pSource->m_fields.begin() + m_dwStartIndex;
cMessage::cFieldList::iterator i_end = i_begin + i_begin->m_nOwns;
*pVal = 0;
for( cMessage::cFieldList::iterator i = i_begin + 1; i != i_end; i += i->m_nOwns )
++ ( *pVal );
return S_OK;
}
STDMETHODIMP cMessageStruct::get_MemberName(long Index, BSTR *pVal)
{
_ASSERTE( pVal != NULL );
_ASSERTE( Index >= 0 );
USES_CONVERSION;
cMessage::cFieldList::iterator i_begin = m_pSource->m_fields.begin() + m_dwStartIndex;
cMessage::cFieldList::iterator i_end = i_begin + i_begin->m_nOwns;
for( cMessage::cFieldList::iterator i = i_begin + 1; i != i_end; i += i->m_nOwns, -- Index )
{
if( Index == 0 )
{
*pVal = OLE2BSTR( i->m_pSchema->m_strName );
return S_OK;
}
}
_ASSERTE( FALSE );
return E_INVALIDARG;
}
STDMETHODIMP cMessageStruct::get_Member(VARIANT vIndex, VARIANT *pVal)
{
cMessage::cFieldList::iterator i_begin = m_pSource->m_fields.begin() + m_dwStartIndex;
cMessage::cFieldList::iterator i_end = i_begin + i_begin->m_nOwns;
if( vIndex.vt == VT_BSTR )
{
_bstr_t bstrIndex = vIndex;
for( cMessage::cFieldList::iterator i = i_begin + 1; i != i_end; i += i->m_nOwns )
{
if( bstrIndex == i->m_pSchema->m_strName )
{
i->m_pSchema->getValue( m_pSource, i, pVal );
return S_OK;
}
}
}
HRESULT hRes = ::VariantChangeType( &vIndex, &vIndex, 0, VT_I4 );
if( FAILED( hRes ) )
{
_ASSERTE( FALSE );
return hRes;
}
// Check if the value is in range
long nIndex = vIndex.lVal;
if( nIndex < 0 )
{
_ASSERTE( nIndex >= 0 );
return E_INVALIDARG;
}
for( cMessage::cFieldList::iterator i = i_begin + 1; i != i_end; i += i->m_nOwns, -- nIndex )
{
if( nIndex == 0 )
{
i->m_pSchema->getValue( m_pSource, i, pVal );
return S_OK;
}
}
return S_OK;
}

View file

@ -0,0 +1,36 @@
// MessageStruct.h : Declaration of the cMessageStruct
#ifndef __MESSAGESTRUCT_H_
#define __MESSAGESTRUCT_H_
#include "resource.h" // main symbols
class cMessage;
/////////////////////////////////////////////////////////////////////////////
// cMessageStruct
class ATL_NO_VTABLE cMessageStruct :
public IDispatchImpl<IMessageMember, &IID_IMessageMember, &LIBID_DecalPlugins>,
public CComObjectRootEx<CComMultiThreadModel>
{
public:
cMessageStruct()
{
}
cMessage *m_pSource;
DWORD m_dwStartIndex;
BEGIN_COM_MAP(cMessageStruct)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IMessageMember)
END_COM_MAP()
// IMessageStruct
public:
STDMETHOD(get_Count)(/*[out, retval]*/ long *pVal);
STDMETHOD(get_MemberName)(long Index, /*[out, retval]*/ BSTR *pVal);
STDMETHOD(get_Member)(VARIANT vIndex, /*[out, retval]*/ VARIANT *pVal);
};
#endif //__MESSAGESTRUCT_H_

View file

@ -0,0 +1,26 @@
HKCR
{
Inject.MessageStruct.1 = s 'MessageStruct Class'
{
CLSID = s '{5F1C583E-FDAB-4751-85BA-1178E9360E39}'
}
Inject.MessageStruct = s 'MessageStruct Class'
{
CLSID = s '{5F1C583E-FDAB-4751-85BA-1178E9360E39}'
CurVer = s 'Inject.MessageStruct.1'
}
NoRemove CLSID
{
ForceRemove {5F1C583E-FDAB-4751-85BA-1178E9360E39} = s 'MessageStruct Class'
{
ProgID = s 'Inject.MessageStruct.1'
VersionIndependentProgID = s 'Inject.MessageStruct'
ForceRemove 'Programmable'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Both'
}
'TypeLib' = s '{3559E08B-827E-4DFE-9D33-3567246849CC}'
}
}
}

View file

@ -0,0 +1,75 @@
// MessageVector.cpp : Implementation of cMessageVector
#include "stdafx.h"
#include "Inject.h"
#include "MessageVector.h"
#include "Message.h"
/////////////////////////////////////////////////////////////////////////////
// cMessageVector
STDMETHODIMP cMessageVector::get_MemberName(long nIndex, BSTR *pVal)
{
_ASSERTE( pVal != NULL );
_ASSERTE( nIndex >= 0 );
USES_CONVERSION;
TCHAR strIndex[ 12 ];
::_stprintf( strIndex, _T( "%i" ), nIndex );
*pVal = T2BSTR( strIndex );
return S_OK;
}
STDMETHODIMP cMessageVector::get_Count(long *pVal)
{
_ASSERTE( pVal != NULL );
cMessage::cFieldList::iterator i_begin = m_pSource->m_fields.begin() + m_dwStartIndex;
cMessage::cFieldList::iterator i_end = i_begin + i_begin->m_nOwns;
*pVal = 0;
for( cMessage::cFieldList::iterator i = i_begin + 1; i != i_end; i += i->m_nOwns )
++ ( *pVal );
return S_OK;
}
STDMETHODIMP cMessageVector::get_Member(VARIANT vIndex, VARIANT *pVal)
{
_ASSERTE( pVal != NULL );
HRESULT hRes = ::VariantChangeType( &vIndex, &vIndex, 0, VT_I4 );
if( FAILED( hRes ) )
{
_ASSERTE( FALSE );
return hRes;
}
// Check if the value is in range
long Index = vIndex.lVal;
if( Index < 0 )
{
_ASSERTE( Index >= 0 );
return E_INVALIDARG;
}
cMessage::cFieldList::iterator i_begin = m_pSource->m_fields.begin() + m_dwStartIndex;
cMessage::cFieldList::iterator i_end = i_begin + i_begin->m_nOwns;
for( cMessage::cFieldList::iterator i = i_begin + 1; i != i_end; i += i->m_nOwns, -- Index )
{
if( Index == 0 )
{
i->m_pSchema->getValue( m_pSource, i, pVal );
return S_OK;
}
}
_ASSERTE( FALSE );
return E_INVALIDARG;
}

View file

@ -0,0 +1,37 @@
// MessageVector.h : Declaration of the cMessageVector
#ifndef __MESSAGEVECTOR_H_
#define __MESSAGEVECTOR_H_
#include "resource.h" // main symbols
#include "Message.h"
class cMessage;
/////////////////////////////////////////////////////////////////////////////
// cMessageVector
class ATL_NO_VTABLE cMessageVector :
public IDispatchImpl<IMessageMember, &IID_IMessageMember, &LIBID_DecalPlugins>,
public CComObjectRootEx<CComMultiThreadModel>
{
public:
cMessageVector()
{
}
cMessage *m_pSource;
DWORD m_dwStartIndex;
BEGIN_COM_MAP(cMessageVector)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IMessageMember)
END_COM_MAP()
// IMessageVector
public:
STDMETHOD(get_Count)(/*[out, retval]*/ long *pVal);
STDMETHOD(get_Member)(VARIANT vIndex, /*[out, retval]*/ VARIANT *pVal);
STDMETHOD(get_MemberName)(long Index, BSTR *pVal);
};
#endif //__MESSAGEVECTOR_H_

View file

@ -0,0 +1,26 @@
HKCR
{
Inject.MessageVector.1 = s 'MessageVector Class'
{
CLSID = s '{7D1D98C1-B850-4B7F-B0DD-CE221F3FD132}'
}
Inject.MessageVector = s 'MessageVector Class'
{
CLSID = s '{7D1D98C1-B850-4B7F-B0DD-CE221F3FD132}'
CurVer = s 'Inject.MessageVector.1'
}
NoRemove CLSID
{
ForceRemove {7D1D98C1-B850-4B7F-B0DD-CE221F3FD132} = s 'MessageVector Class'
{
ProgID = s 'Inject.MessageVector.1'
VersionIndependentProgID = s 'Inject.MessageVector'
ForceRemove 'Programmable'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Both'
}
'TypeLib' = s '{3559E08B-827E-4DFE-9D33-3567246849CC}'
}
}
}

View file

@ -0,0 +1,210 @@
// ProtocolStack.cpp
// Implementation of class cProtocolStack
#include "stdafx.h"
#include "ProtocolStack.h"
cMessageStack::cMessage::cMessage( BYTE *pbData )
: m_pbData( NULL ),
m_bOwn( false )
{
cMessageHeader *pHeader = reinterpret_cast< cMessageHeader * >( pbData );
if( pHeader->m_wFragmentCount == 1 )
{
// This is the only fragment, we use a direct pointer for dispatching
m_pbData = pbData;
return;
}
// This message has multiple fragments, create a buffer
m_pbData = new BYTE[ calcMessageLength( pbData ) ];
// Two initializers, with
// Copy the header into the new buffer
::memcpy( m_pbData, pbData, sizeof( cMessageHeader ) );
// First calculate the number of fragments we should have
m_FragmentMask.SetSize (pHeader->m_wFragmentCount);
insertFragment( pbData );
}
cMessageStack::cMessage::cMessage( const cMessage &msg )
: m_pbData( msg.m_pbData ),
m_bOwn( msg.m_bOwn )
{
m_FragmentMask = msg.m_FragmentMask;
msg.m_bOwn = false;
}
cMessageStack::cMessage::~cMessage()
{
if( m_bOwn )
delete[] m_pbData;
}
cMessageStack::cMessage &cMessageStack::cMessage::operator= ( const cMessage &msg )
{
if( m_bOwn )
delete[] m_pbData;
m_pbData = msg.m_pbData;
m_FragmentMask = msg.m_FragmentMask;
m_bOwn = msg.m_bOwn;
msg.m_bOwn = false;
return *this;
}
bool cMessageStack::cMessage::fragmentMatch( BYTE *pFragmentStart )
{
cMessageHeader *pThis = getMessageHeader(),
*pOther = reinterpret_cast< cMessageHeader * >( pFragmentStart );
return ( pThis->m_dwObjectID == pOther->m_dwObjectID && pThis->m_dwSequence == pOther->m_dwSequence );
}
#define MESSAGE_BODY 448
void cMessageStack::cMessage::insertFragment( BYTE *pFragmentStart )
{
cMessageHeader *pHeader = reinterpret_cast< cMessageHeader * >( pFragmentStart );
BYTE *pInsertLocation = m_pbData + sizeof( cMessageHeader ) + ( MESSAGE_BODY * pHeader->m_wFragmentIndex );
::memcpy( pInsertLocation, pFragmentStart + sizeof( cMessageHeader ), pHeader->m_wFragmentLength - sizeof( cMessageHeader ) );
m_FragmentMask.GotFragment (pHeader->m_wFragmentIndex);
if( pHeader->m_wFragmentIndex == ( pHeader->m_wFragmentCount - 1 ) )
getMessageHeader()->m_wFragmentLength = ( pHeader->m_wFragmentCount - 1 ) * MESSAGE_BODY + pHeader->m_wFragmentLength;
}
DWORD cMessageStack::cMessage::calcMessageLength( BYTE *pFragmentStart )
{
cMessageHeader *pHeader = reinterpret_cast< cMessageHeader * >( pFragmentStart );
return ( pHeader->m_wFragmentIndex == ( pHeader->m_wFragmentCount - 1 ) ) ?
( pHeader->m_wFragmentCount - 1 ) * MESSAGE_BODY + pHeader->m_wFragmentLength : pHeader->m_wFragmentCount * MESSAGE_BODY + sizeof( cMessageHeader );
}
cMessageStack::cMessageStack()
: m_pCallback( NULL )
{
}
cMessageStack::~cMessageStack()
{
// Make sure we clean up and intermediate steps
stop();
}
void cMessageStack::start( cCallback *pCallback )
{
// Setting this enables messages
m_pCallback = pCallback;
}
void cMessageStack::stop()
{
// Clean out the message list since these will never be matched
m_messages.clear();
m_pCallback = NULL;
}
void cMessageStack::processPacket( DWORD dwLength, BYTE *pbPayload )
{
// First filter based on our status and the message type
if( m_pCallback == NULL )
// We currently only support send or receive type messages
return;
// AC messages must be at least as big as a packet header.+ a message header
if (dwLength < (sizeof (cPacketHeader) + sizeof (cMessageHeader)))
{
return;
}
// Filter non-application messages
cPacketHeader *pHeader = reinterpret_cast< cPacketHeader * >( pbPayload );
if((pHeader->m_wTotalSize) != (dwLength - sizeof(cPacketHeader)))
{
return;
}
DWORD dwOffset = 0;
if (pHeader->m_dwFlags & 0x00100000)
{
// 8 extra header bytes
dwOffset += 8;
}
if (pHeader->m_dwFlags & 0x00200000)
{
// 6 extra header bytes
dwOffset += 6;
}
if (pHeader->m_dwFlags & 0x00400000)
{
// 0 extra header bytes
}
if (pHeader->m_dwFlags & 0x00800000)
{
// 4 extra header bytes
dwOffset += 4;
}
if (dwLength < (dwOffset + sizeof (cMessageHeader)))
{
return;
}
splitPacket( dwLength - dwOffset, pbPayload + dwOffset );
}
void cMessageStack::splitPacket( DWORD dwLength, BYTE *pbPayload )
{
DWORD dwFragLength = 0;
BYTE *i_end_packet = pbPayload + dwLength;
for( BYTE *iFrag = pbPayload + sizeof( cPacketHeader ); iFrag != i_end_packet; iFrag += dwFragLength )
{
dwFragLength = reinterpret_cast< cMessageHeader * >( iFrag )->m_wFragmentLength;
if( dwFragLength == 0 || ( iFrag + dwFragLength ) > i_end_packet )
// We are off the end somehow
return;
// First walk through our cached fragments and see if one will take this fragment
for( cMessageList::iterator i = m_messages.begin(); i != m_messages.end(); ++ i )
{
if( i->fragmentMatch( iFrag ) )
{
i->insertFragment( iFrag );
if( i->isComplete() )
{
// Remove it from the list and dispatch the message
m_pCallback->onMessage( *i );
m_messages.erase( i );
}
break;
}
}
if( i != m_messages.end() )
// The fragment was found in the list
continue;
// Ok, we have a new fragment on our hands - generate the fragment object
cMessage msg( iFrag );
if( msg.isComplete() )
// It's only one piece, dispatch right away
m_pCallback->onMessage( msg );
else
// This requires more parts add it into the queue to wait
m_messages.push_back( msg );
}
}

View file

@ -0,0 +1,159 @@
// ProtocolStack.h
// Declaration of class cProtocolStack
#ifndef __PROTOCOLSTACK_H
#define __PROTOCOLSTACK_H
#include <crtdbg.h> // For assertions
#define DEFAULT_HEADER_SIZE 16
#define FRAGMENT_SIZE 448
#define MAX_FRAGMENT_COUNT 1024
#pragma pack( push, 1 )
// The packet header
struct cPacketHeader
{
DWORD m_dwSequence;
DWORD m_dwFlags;
DWORD m_dwCRC;
WORD m_wUnk1;
WORD m_wUnk2;
WORD m_wTotalSize;
WORD m_wUnk3;
};
#pragma pack( pop )
class FragmentMask
{
public:
FragmentMask () { ::memset (m_mask, 0, sizeof (m_mask)); m_size = 0; }
void SetSize (WORD wSize)
{
_ASSERTE (wSize < MAX_FRAGMENT_COUNT);
m_size = wSize;
::memset (m_mask, 0, sizeof (m_mask));
for (WORD wIndex = 0; wIndex < wSize; ++wIndex)
{
m_mask[wIndex/32] |= (1L << (wIndex % 32));
}
}
void GotFragment (WORD wWhich)
{
_ASSERTE (wWhich < m_size && wWhich >= 0);
m_mask[wWhich/32] &= ~(1 << (wWhich % 32));
}
bool IsComplete ()
{
for (WORD wLoop = 0; wLoop < (FRAGMENT_SIZE/32); ++wLoop)
{
if (m_mask[wLoop])
{
return false;
}
}
return true;
}
private:
DWORD m_mask[FRAGMENT_SIZE/32];
WORD m_size;
};
class cMessageStack
{
public:
#pragma pack( push, 1 )
struct cMessageHeader
{
DWORD m_dwSequence;
DWORD m_dwObjectID;
WORD m_wFragmentCount;
WORD m_wFragmentLength;
WORD m_wFragmentIndex,
m_wUnknown1;
};
#pragma pack( pop )
class cMessage
{
protected:
// DWORD m_dwFragmentsMask;
BYTE *m_pbData;
mutable bool m_bOwn;
mutable FragmentMask m_FragmentMask;
public:
cMessage( BYTE *pbData );
cMessage( const cMessage &msg );
~cMessage();
cMessageHeader *getMessageHeader() const
{
return reinterpret_cast< cMessageHeader * >( m_pbData );
}
cMessage &operator= ( const cMessage &msg );
BYTE *getBody() const
{
return m_pbData + sizeof( cMessageHeader );
}
DWORD getBodyLength() const
{
return getMessageHeader()->m_wFragmentLength - sizeof( cMessageHeader );
}
bool isComplete() const
{
return m_FragmentMask.IsComplete ();
}
DWORD getMessageCode() const
{
return *reinterpret_cast< DWORD * >( m_pbData + sizeof( cMessageHeader ) );
}
bool fragmentMatch( BYTE *pFragmentStart );
void insertFragment( BYTE *pFragmentStart );
static DWORD calcMessageLength( BYTE *pbHeader );
};
// Objects wishing to receive
class cCallback
{
public:
virtual void onMessage( cMessage & ) = 0;
};
private:
typedef std::list< cMessage > cMessageList;
cCallback *m_pCallback;
cMessageList m_messages;
public:
cMessageStack();
~cMessageStack();
void start( cCallback * );
void stop();
void processPacket( DWORD dwLength, BYTE *pbPayload );
private:
void splitPacket( DWORD dwLength, BYTE *pbPayload );
};
#endif

View file

@ -0,0 +1,38 @@
/*********************************************************
DllData file -- generated by MIDL compiler
DO NOT ALTER THIS FILE
This file is regenerated by MIDL on every IDL file compile.
To completely reconstruct this file, delete it and rerun MIDL
on all the IDL files in this DLL, specifying this file for the
/dlldata command line option
*********************************************************/
#define PROXY_DELEGATION
#include <rpcproxy.h>
#ifdef __cplusplus
extern "C" {
#endif
EXTERN_PROXY_FILE( Inject )
PROXYFILE_LIST_START
/* Start of list */
REFERENCE_PROXY_FILE( Inject ),
/* End of list */
PROXYFILE_LIST_END
DLLDATA_ROUTINES( aProxyFileList, GET_DLL_CLSID )
#ifdef __cplusplus
} /*extern "C" */
#endif
/* end of generated dlldata file */

1128
Native/Inject/BarLayer.cpp Normal file

File diff suppressed because it is too large Load diff

121
Native/Inject/BarLayer.h Normal file
View file

@ -0,0 +1,121 @@
// BarLayer.h : Declaration of the cBarLayer
#ifndef __BARLAYER_H_
#define __BARLAYER_H_
#include "resource.h" // main symbols
#include "SinkImpl.h"
// Control IDs
#define PAGER_CLIENT 1
#define BUTTON_BACK 2
#define BUTTON_FORWARD 3
#define BUTTON_MINMAX 4
#define BUTTON_DOCKCYCLE 5
/////////////////////////////////////////////////////////////////////////////
// cBarLayer
class ATL_NO_VTABLE cBarLayer :
public CComObjectRootEx<CComMultiThreadModel>,
public ILayerImpl< cBarLayer >,
public ILayerRenderImpl,
public IBarManager,
public ICommandEventsImpl< BUTTON_BACK, cBarLayer >,
public ICommandEventsImpl< BUTTON_FORWARD, cBarLayer >,
public ICommandEventsImpl< BUTTON_MINMAX, cBarLayer >,
public ICommandEventsImpl< BUTTON_DOCKCYCLE, cBarLayer >,
public ILayerMouseImpl,
public cNoEventsImpl,
public IPagerEventsImpl< PAGER_CLIENT, cBarLayer >
{
public:
cBarLayer();
// Important child objects
CComPtr< IPluginSite > m_pPlugin;
CComPtr< IACHooks > m_pHooks;
CComPtr< IPager > m_pPager;
CComPtr< IButton > m_pBtnForwards,
m_pBtnBackwards, m_pBtnMinMax, m_pBtnDockCycle;
CComPtr< IImageCache > m_pBackground;
// This the the list of bars
typedef std::vector< long > cOffsetList;
cOffsetList m_offsets;
unsigned long m_nPosition;
unsigned long m_nMinMax;
long m_DeltaX;
long m_DeltaY;
long m_nScreenWidth;
long m_nScreenHeight;
//long m_TotalDelta;
long *m_p3DH;
long *m_p3DW;
long m_nBarStartPos;
long m_nBarLength;
int m_nDragging;
int m_nBarDock;
bool m_bRadarDraw;
bool m_bButtonDown;
bool m_bLocked;
bool m_bDocked;
void onCreate();
void onDestroy();
BEGIN_COM_MAP(cBarLayer)
COM_INTERFACE_ENTRY(ILayer)
COM_INTERFACE_ENTRY(ILayerRender)
COM_INTERFACE_ENTRY(ILayerMouse)
COM_INTERFACE_ENTRY(IBarManager)
END_COM_MAP()
BEGIN_SINK_MAP(cBarLayer)
SINK_ENTRY_EX( BUTTON_BACK, DIID_ICommandEvents, DISPID_HIT, onCommandHit )
SINK_ENTRY_EX( BUTTON_BACK, DIID_ICommandEvents, DISPID_UNHIT, onCommandUnhit )
SINK_ENTRY_EX( BUTTON_FORWARD, DIID_ICommandEvents, DISPID_HIT, onCommandHit )
SINK_ENTRY_EX( BUTTON_FORWARD, DIID_ICommandEvents, DISPID_UNHIT, onCommandUnhit )
SINK_ENTRY_EX( BUTTON_MINMAX, DIID_ICommandEvents, DISPID_HIT, onMinMaxHit )
SINK_ENTRY_EX( BUTTON_DOCKCYCLE, DIID_ICommandEvents, DISPID_HIT, onDockCycleHit )
SINK_ENTRY_EX( PAGER_CLIENT, DIID_IPagerEvents, DISPID_GETNEXTPOSITION, onClientGetNextPosition )
END_SINK_MAP()
public:
// IBarManager
STDMETHOD(get_Bar)(long nViewID, /*[out, retval]*/ ViewParams *pVal);
STDMETHOD(put_Bar)(long nViewID, /*[in]*/ ViewParams * newVal);
STDMETHOD(RemoveBar)(long nViewID);
STDMETHOD(AddBar)(long nViewID, ViewParams *pParams);
// ILayerRender
STDMETHOD(Render)(ICanvas *pCanvas);
STDMETHOD(Reformat)();
// Button Back and Forward event handlers
void __stdcall onCommandHit( long nID )
{
m_bButtonDown = TRUE;
m_pPager->put_Command( nID );
}
void __stdcall onCommandUnhit( long )
{
m_bButtonDown = FALSE;
m_bLocked = FALSE;
m_pPager->FinishCommand();
}
void __stdcall onMinMaxHit(long nID);
void __stdcall onDockCycleHit(long nID);
// Pager event handlers
VARIANT_BOOL __stdcall onClientGetNextPosition( long nID, long nCommand, long *pnX, long *pnY );
STDMETHOD(MouseEvent)(long nMsg, long wParam, long lParam);
};
#endif //__BARLAYER_H_

244
Native/Inject/Button.cpp Normal file
View file

@ -0,0 +1,244 @@
// Button.cpp : Implementation of cButton
#include "stdafx.h"
#include "Inject.h"
#include "Button.h"
/////////////////////////////////////////////////////////////////////////////
// cButton
cButton::cButton()
: m_nModule( 0 ),
m_nBackground( 0 ),
m_nPressed( 0 ),
m_nReleased( 0 ),
m_bPressed( VARIANT_FALSE ),
m_bMouseIn( VARIANT_FALSE ),
m_nMatte( RGB( 0, 255, 255 ) )
{
}
STDMETHODIMP cButton::SetImages(long dwModule, long dwReleased, long dwPressed)
{
m_nModule = dwModule;
m_nReleased = dwReleased;
m_nPressed = dwPressed;
m_pSite->Invalidate();
return S_OK;
}
STDMETHODIMP cButton::Render(ICanvas *pCanvas)
{
_ASSERTE( pCanvas != NULL );
// ::MessageBox( NULL, _T( "cButton::Render" ), _T( "Inject.dll" ), MB_OK );
_ASSERTE( m_pSite.p != NULL );
RECT rc;
m_pSite->get_Position( &rc );
if( m_nMatte != RGB( 0, 255, 255 ) )
{
// That's the transparent color
RECT rcMatte = { 0, 0, rc.right - rc.left, rc.bottom - rc.top };
pCanvas->Fill( &rcMatte, m_nMatte );
}
CComPtr< IPluginSite > pPlugin;
m_pSite->get_PluginSite( &pPlugin );
_ASSERTE( pPlugin.p != NULL );
CComPtr< IIconCache > pIcons;
SIZE sz = { rc.right - rc.left, rc.bottom - rc.top };
pPlugin->GetIconCache( &sz, &pIcons );
_ASSERTE( pIcons.p != NULL );
long nImage = ( m_bPressed && m_bMouseIn ) ? m_nPressed : m_nReleased;
POINT pt = { 0, 0 };
if (m_nBackground != 0) pIcons->DrawIcon( &pt, m_nBackground, 0, pCanvas );
pIcons->DrawIcon( &pt, nImage, m_nModule, pCanvas );
_ASSERTMEM( _CrtCheckMemory( ) );
return S_OK;
}
STDMETHODIMP cButton::MouseEnter(struct MouseState *)
{
_ASSERTE( !m_bMouseIn );
m_bMouseIn = VARIANT_TRUE;
if( m_bPressed )
{
long nID;
m_pSite->get_ID( &nID );
Fire_Hit( nID );
_ASSERTE( m_pSite.p != NULL );
m_pSite->Invalidate();
}
return S_OK;
}
STDMETHODIMP cButton::MouseExit(struct MouseState *)
{
_ASSERTE( m_bMouseIn );
m_bMouseIn = VARIANT_FALSE;
if( m_bPressed )
{
long nID;
m_pSite->get_ID( &nID );
Fire_Unhit( nID );
_ASSERTE( m_pSite.p != NULL );
m_pSite->Invalidate();
}
return S_OK;
}
STDMETHODIMP cButton::MouseDown(struct MouseState *)
{
_ASSERTE( m_pSite != NULL );
long nID;
m_pSite->get_ID( &nID );
Fire_Hit( nID );
m_bPressed = VARIANT_TRUE;
m_pSite->Invalidate();
return S_OK;
}
STDMETHODIMP cButton::MouseUp(struct MouseState *)
{
m_bPressed = VARIANT_FALSE;
long nID;
m_pSite->get_ID( &nID );
if( m_bMouseIn )
{
_ASSERTE( m_pSite.p != NULL );
m_pSite->Invalidate();
// NOTE: The command may destroy the control synchronously
// so we make a stack copy of the target in case our instance is destroyed
// for the purpose of completing the command
Fire_Accepted( nID );
Fire_Unhit( nID );
}
else
Fire_Canceled( nID );
return S_OK;
}
STDMETHODIMP cButton::get_Matte(long *pVal)
{
*pVal = m_nMatte;
return S_OK;
}
STDMETHODIMP cButton::put_Matte(long newVal)
{
m_nMatte = newVal;
m_pSite->Invalidate();
return S_OK;
}
STDMETHODIMP cButton::SchemaLoad(IView *, IUnknown *pSchema)
{
USES_CONVERSION;
CComPtr< IPluginSite > pPlugin;
m_pSite->get_PluginSite( &pPlugin );
MSXML::IXMLDOMElementPtr pElement = pSchema;
// Get the suspected variables out
_variant_t vModule = pElement->getAttribute( _T( "iconlibrary" ) ),
vReleased = pElement->getAttribute( _T( "icon" ) ),
vPressed = pElement->getAttribute( _T( "pressedicon" ) ),
vMatte = pElement->getAttribute( _T( "matte" ) ),
vBackground = pElement->getAttribute( _T( "background" ) );
if( vModule.vt == VT_BSTR )
pPlugin->LoadResourceModule( vModule.bstrVal, &m_nModule );
if( vReleased.vt != VT_NULL )
{
try
{
m_nReleased = static_cast< long >( vReleased ) + 0x06000000;
}
catch( ... )
{
// Type conversion error
_ASSERTE( FALSE );
}
}
if( vPressed.vt != VT_NULL )
{
try
{
m_nPressed = static_cast< long >( vPressed ) + 0x06000000;
}
catch( ... )
{
// Type conversion error
_ASSERTE( FALSE );
}
}
else
m_nPressed = m_nReleased;
if( vMatte.vt != VT_NULL )
{
try
{
m_nMatte = static_cast< long >( vMatte );
}
catch( ... )
{
// Type conversion error
_ASSERTE( FALSE );
}
}
if( vBackground.vt != VT_NULL )
{
try
{
m_nBackground = static_cast< long >( vBackground ) + 0x06000000;
}
catch( ... )
{
// Type conversion error
_ASSERTE( FALSE );
}
}
else
{
m_nBackground = 0;
}
return S_OK;
}

79
Native/Inject/Button.h Normal file
View file

@ -0,0 +1,79 @@
// Button.h : Declaration of the cButton
#ifndef __BUTTON_H_
#define __BUTTON_H_
#include "resource.h" // main symbols
#include "SinkImpl.h"
#include "InjectCP.h"
/////////////////////////////////////////////////////////////////////////////
// cButton
class ATL_NO_VTABLE cButton :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<cButton, &CLSID_Button>,
public IControlImpl< cButton, IButton, &IID_IButton, &LIBID_DecalPlugins >,
public ILayerImpl< cButton >,
public ILayerRenderImpl,
public ILayerMouseImpl,
public ILayerSchema,
public IProvideClassInfo2Impl< &CLSID_Button, &DIID_ICommandEvents, &LIBID_DecalPlugins >,
public IConnectionPointContainerImpl<cButton>,
public CProxyICommandEvents< cButton >
{
public:
cButton();
long m_nModule;
long m_nReleased;
long m_nPressed;
long m_nBackground;
VARIANT_BOOL m_bPressed,
m_bMouseIn;
long m_nMatte;
DECLARE_REGISTRY_RESOURCEID(IDR_BUTTON)
DECLARE_PROTECT_FINAL_CONSTRUCT()
public :
BEGIN_COM_MAP(cButton)
COM_INTERFACE_ENTRY(ILayerRender)
COM_INTERFACE_ENTRY(ILayerMouse)
COM_INTERFACE_ENTRY(ILayer)
COM_INTERFACE_ENTRY(ILayerSchema)
COM_INTERFACE_ENTRY(IButton)
COM_INTERFACE_ENTRY(IControl)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IProvideClassInfo)
COM_INTERFACE_ENTRY(IProvideClassInfo2)
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
END_COM_MAP()
BEGIN_CONNECTION_POINT_MAP(cButton)
CONNECTION_POINT_ENTRY(DIID_ICommandEvents)
END_CONNECTION_POINT_MAP()
// IButton
public:
// IButton Methods
STDMETHOD(SetImages)(long dwModule, long dwReleased, long dwPressed);
STDMETHOD(get_Matte)(/*[out, retval]*/ long *pVal);
STDMETHOD(put_Matte)(/*[in]*/ long newVal);
// ILayerRender Methods
STDMETHOD(Render)(ICanvas *pCanvas);
// ILayerMouse Methods
STDMETHOD(MouseEnter)(struct MouseState *);
STDMETHOD(MouseExit)(struct MouseState *);
STDMETHOD(MouseDown)(struct MouseState *);
STDMETHOD(MouseUp)(struct MouseState *);
// ILayerSchema Methods
STDMETHOD(SchemaLoad)(IView *, IUnknown *pSchema);
};
#endif //__BUTTON_H_

25
Native/Inject/Button.rgs Normal file
View file

@ -0,0 +1,25 @@
HKCR
{
DecalControls.Button.1 = s 'Button Class'
{
CLSID = s '{C22BF2FC-F144-4d17-9C12-A344F980BB17}'
}
DecalControls.Button = s 'Button Class'
{
CLSID = s '{C22BF2FC-F144-4d17-9C12-A344F980BB17}'
CurVer = s 'DecalControls.Button.1'
}
NoRemove CLSID
{
ForceRemove {C22BF2FC-F144-4d17-9C12-A344F980BB17} = s 'DecalControls Button'
{
ProgID = s 'DecalControls.Button.1'
VersionIndependentProgID = s 'DecalControls.Button'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Both'
}
'TypeLib' = s '{3559E08B-827E-4DFE-9D33-3567246849CC}'
}
}
}

748
Native/Inject/Canvas.cpp Normal file
View file

@ -0,0 +1,748 @@
// Canvas.cpp : Implementation of cCanvas
#include "stdafx.h"
#include "Inject.h"
#include "Canvas.h"
#include "Manager.h"
/////////////////////////////////////////////////////////////////////////////
// cCanvas
cCanvas::~cCanvas()
{
_ASSERTE( m_hdc == NULL );
if( m_rgn != NULL )
::DeleteObject( m_rgn );
}
void cCanvas::testSurface()
{
if( m_pSurface.p == NULL )
cManager::_p->createSurface( &m_sz, &m_pSurface );
else if( m_pSurface->IsLost() != DD_OK )
m_pSurface->Restore();
}
STDMETHODIMP cCanvas::PushClipRect(LPRECT prc, VARIANT_BOOL *pbVisible)
{
_ASSERTE( prc != NULL );
_ASSERTE( prc->right >= prc->left && prc->bottom >= prc->top );
_ASSERTE( pbVisible != NULL );
ClipParams &current = m_clipping.top();
if( !current.visible )
{
// Not visible means just push and hope for a pop
m_clipping.push( current );
return S_OK;
}
int nChildLeft = prc->left + current.window.left - current.org.x,
nChildTop = prc->top + current.window.top - current.org.y,
nChildWidth = prc->right - prc->left,
nChildHeight = prc->bottom - prc->top;
ClipParams p = {
{ nChildLeft, nChildTop, nChildLeft + nChildWidth, nChildTop + nChildHeight },
{ 0, 0 },
VARIANT_TRUE };
// Clip the four sides of the rectangle
if( p.window.left < current.window.left )
{
// Clip left edge
p.org.x += current.window.left - p.window.left;
p.window.left = current.window.left;
}
if( p.window.top < current.window.top )
{
// Clip top edge
p.org.y += current.window.top - p.window.top;
p.window.top = current.window.top;
}
if( p.window.right > current.window.right )
// Clip right edge
p.window.right = current.window.right;
if( p.window.bottom > current.window.bottom )
// Clip bottom edge
p.window.bottom = current.window.bottom;
// Check for clipping out of existance
if( p.window.left >= p.window.right || p.window.top >= p.window.bottom )
// This rectangle is no longer visible
p.visible = VARIANT_FALSE;
// Return the remainder of the rectangle
*pbVisible = p.visible;
m_clipping.push( p );
return S_OK;
}
STDMETHODIMP cCanvas::PopClipRect()
{
_ASSERTE( m_clipping.size() > 1 );
m_clipping.pop();
return S_OK;
}
STDMETHODIMP cCanvas::GetDC(HDC *pdc)
{
_ASSERTE( pdc != NULL );
testSurface();
if( m_hdc != NULL )
// Already checked out
return E_FAIL;
m_pSurface->GetDC( &m_hdc );
// Create a clipping region
ClipParams &param = m_clipping.top();
if( m_rgn == NULL )
m_rgn = ::CreateRectRgnIndirect( &param.window );
else
::SetRectRgn( m_rgn, param.window.left, param.window.top, param.window.right, param.window.bottom );
::SelectObject( m_hdc, m_rgn );
// Set the origin
::SetWindowOrgEx( m_hdc, -param.window.left + param.org.x, -param.window.top + param.org.y, NULL );
*pdc = m_hdc;
return S_OK;
}
STDMETHODIMP cCanvas::ReleaseDC()
{
if( m_hdc == NULL )
return E_FAIL;
m_pSurface->ReleaseDC( m_hdc );
m_hdc = NULL;
return S_OK;
}
STDMETHODIMP cCanvas::GetSurface(REFIID iid, void **ppvItf)
{
_ASSERTE( iid == IID_IDirectDrawSurface4 );
_ASSERTE( ppvItf != NULL );
testSurface();
return m_pSurface->QueryInterface( iid, ppvItf );
}
STDMETHODIMP cCanvas::GetClipParams(ClipParams *pParams)
{
_ASSERTE( pParams != NULL );
*pParams = m_clipping.top();
return S_OK;
}
STDMETHODIMP cCanvas::Fill(LPRECT prc, long nRGB)
{
_ASSERTE( prc != NULL );
_ASSERTE( prc->right > prc->left && prc->bottom > prc->top );
testSurface();
VARIANT_BOOL bVisible;
PushClipRect( prc, &bVisible );
if( bVisible )
{
DDBLTFX fx;
::memset( &fx, 0, sizeof( DDBLTFX ) );
fx.dwSize = sizeof( DDBLTFX );
DownMixRGB((BYTE)nRGB, (BYTE)(nRGB >> 8), (BYTE)(nRGB >> 16), (WORD *)&fx.dwFillColor);
m_pSurface->Blt( &m_clipping.top().window, NULL, NULL, DDBLT_COLORFILL, &fx );
}
PopClipRect();
return S_OK;
}
STDMETHODIMP cCanvas::Frame(LPRECT prc, long nRGB)
{
_ASSERTE( prc != NULL );
_ASSERTE( prc->right > prc->left && prc->bottom > prc->top );
testSurface();
// TODO: Add your implementation code here
return S_OK;
}
STDMETHODIMP cCanvas::get_WasLost(VARIANT_BOOL *pVal)
{
_ASSERTE( pVal != NULL );
*pVal = VARIANT_FALSE;
if( m_pSurface.p != NULL )
{
if( m_pSurface->IsLost() != DD_OK )
*pVal = VARIANT_TRUE;
}
else
*pVal = VARIANT_TRUE;
return S_OK;
}
STDMETHODIMP cCanvas::get_Size(LPSIZE pVal)
{
_ASSERTE( pVal != NULL );
*pVal = m_sz;
return S_OK;
}
STDMETHODIMP cCanvas::put_Size(LPSIZE newVal)
{
_ASSERTE( newVal->cx > 0 && newVal->cy > 0 );
_ASSERTE( m_clipping.size() == 1 );
if( m_sz.cx != newVal->cx || m_sz.cy != newVal->cy )
{
m_sz = *newVal;
if( m_pSurface.p )
// Next frame this'll be marked as lost
m_pSurface.Release();
// Reset the bounds in the root clip rectangle
ClipParams &clip = m_clipping.top();
clip.window.right = clip.window.left + newVal->cx;
clip.window.bottom = clip.window.top + newVal->cy;
}
return S_OK;
}
STDMETHODIMP cCanvas::Blt(LPRECT prcSrc, ICanvas *pSrc, LPPOINT pptDest)
{
_ASSERTE( pSrc != NULL );
_ASSERTE( prcSrc != NULL );
_ASSERTE( prcSrc->right > prcSrc->left && prcSrc->bottom > prcSrc->top );
_ASSERTE( pptDest != NULL );
testSurface();
// Ok, first, make up the clip rect
RECT rc = { pptDest->x, pptDest->y, pptDest->x + ( prcSrc->right - prcSrc->left ),
pptDest->y + ( prcSrc->bottom - prcSrc->top ) };
VARIANT_BOOL bVisible;
PushClipRect( &rc, &bVisible );
if( bVisible )
{
CComPtr< IDirectDrawSurface4 > pSurf;
pSrc->GetSurface( IID_IDirectDrawSurface4, reinterpret_cast< void ** >( &pSurf ) );
_ASSERTE( pSurf.p != NULL );
_ASSERTE( pSurf->IsLost() == DD_OK );
// Calculate the metrics
#ifdef _DEBUG
SIZE sz;
pSrc->get_Size( &sz );
_ASSERTE( prcSrc->left >= 0 && prcSrc->top >= 0 && prcSrc->right <= sz.cx && prcSrc->bottom <= sz.cy );
#endif
ClipParams &current = m_clipping.top();
RECT rcSrcClipped = { prcSrc->left + current.org.x, prcSrc->top + current.org.y,
prcSrc->left + current.org.x + ( current.window.right - current.window.left ),
prcSrc->top + current.org.y + ( current.window.bottom - current.window.top ) };
HRESULT hRes = S_OK;
if ( sourceAlpha < 255) {
if( cManager::_p->m_eAlphaBlendMode == eAlphaBlendSoftware )
{
// Software alpha blending
// It's actually plausible to implement this entirely using D3D and thus get hardware acceleration
// Perhaps we should detect device caps and use a suitable method?
// This should work on every Decal configuration though (except bank switched video cards, but who has them? :)
//Lock and calculate metrics for destination
DDSURFACEDESC2 ddsd;
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
int left = current.window.left;
int top = current.window.top;
int width = rcSrcClipped.right - rcSrcClipped.left;
int height = rcSrcClipped.bottom - rcSrcClipped.top;
if (FAILED(m_pSurface->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_NOSYSLOCK, NULL)))
_ASSERTE("Failed to destination lock surface!");
WORD *dest = (WORD *)ddsd.lpSurface;
int iPitch = ddsd.lPitch / 2;
int initialJump = (top * iPitch) + left;
int jump = (iPitch - (width + left)) + left + width;
//Lock and calculate metrics for source
DDSURFACEDESC2 srcddsd;
memset(&srcddsd, 0, sizeof(srcddsd));
srcddsd.dwSize = sizeof(srcddsd);
if (FAILED(pSurf->Lock(NULL, &srcddsd, DDLOCK_WAIT | DDLOCK_NOSYSLOCK, NULL)))
_ASSERTE("Failed to lock source surface!");
WORD *src = (WORD *)srcddsd.lpSurface;
//Do it
int iSrcPitch = srcddsd.lPitch / 2;
int alpha = sourceAlpha;
int ialpha = 255 - alpha;
WORD *srcLine = new WORD[width];
WORD *destLine = new WORD[width];
WORD sB, dB, sG, dG, sR, dR;
dest += initialJump;
for (int y = 0; y < height; y++) {
// We'll read 1 line at a time - 80% of the speed decrease here is reading/writing against the surface
memcpy((void *)srcLine, src, width * 2);
memcpy((void *)destLine, dest, width * 2);
for (int x = 0; x < width; x++) {
// This method is very fast, but assumes a constant 128 alpha
// destLine[x] = ( (srcLine[x] & 0xF7DE) >> 1) + ( (destLine[x] & 0xF7DE) >> 1);
// Basically ((alpha * (src - dest) / MAXALPHA) + dest) for each component
// There's some significant room for MMX parrallelism here (~20% more FPS, methinks), but do we want to
// be writing ASM?
sB = srcLine[x] & ddsd.ddpfPixelFormat.dwBBitMask;
dB = destLine[x] & ddsd.ddpfPixelFormat.dwBBitMask;
sG = srcLine[x] & ddsd.ddpfPixelFormat.dwGBitMask;
dG = destLine[x] & ddsd.ddpfPixelFormat.dwGBitMask;
sR = srcLine[x] & ddsd.ddpfPixelFormat.dwRBitMask;
dR = destLine[x] & ddsd.ddpfPixelFormat.dwRBitMask;
destLine[x] = ddsd.ddpfPixelFormat.dwBBitMask & ((alpha * (sB - dB) >> 8) + dB) |
ddsd.ddpfPixelFormat.dwGBitMask & (((alpha * (sG - dG) >> 8) + dG)) |
ddsd.ddpfPixelFormat.dwRBitMask & (((alpha * (sR - dR) >> 8) + dR));
// The below is eversoslightly faster by assuming RGB 565 surface exposure. Some stupid old cards
// blow up however. Fiddle if you like, YMMV. I'm sticking with something that works :)
//sB = srcLine[x] & 0x1f;
//dB = destLine[x] & 0x1f;
//sG = (srcLine[x] >> 5) & 0x3f;
//dG = (destLine[x] >> 5) & 0x3f;
//sR = (srcLine[x] >> 11) & 0x1f;
//dR = (destLine[x] >> 11) & 0x1f;
//destLine[x] = ((alpha * (sB - dB) >> 8) + dB) |
// (((alpha * (sG - dG) >> 8) + dG) << 5) |
// (((alpha * (sR - dR) >> 8) + dR) << 11);*/
}
memcpy(dest, destLine, width * 2);
src += iSrcPitch;
dest += jump;
}
//Release
delete srcLine;
delete destLine;
if (FAILED(pSurf->Unlock(NULL)))
_ASSERTE("Failed to unlock source surface!");
if (FAILED(m_pSurface->Unlock(NULL)))
_ASSERTE("Failed to unlock destination surface!");
}
else if ((cManager::_p->m_eAlphaBlendMode == eAlphaBlendGDIPlus) && (AlphaBlendF!=NULL))
{
HDC hdcd;
HDC hdcs;
GetDC(&hdcd);
pSrc->GetDC(&hdcs);
hRes = AlphaBlendF(hdcd, current.org.x, current.org.y, rcSrcClipped.right-rcSrcClipped.left, rcSrcClipped.bottom-rcSrcClipped.top, hdcs, current.org.x, current.org.y, rcSrcClipped.right-rcSrcClipped.left, rcSrcClipped.bottom-rcSrcClipped.top, m_bf);
pSrc->ReleaseDC();
ReleaseDC();
}
}
else
{
hRes = m_pSurface->BltFast( current.window.left, current.window.top, pSurf, &rcSrcClipped, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT );
}
/* if(!SUCCEEDED(hRes))
{
POINT pt = { 0, 0 };
ClientToScreen(cManager::_p->m_hMain, &pt);
/*if((pt.x==0) || (pt.y==0))
MessageBox(0,"asd","asd",0);*/
//RECT rcd = {pt.x, pt.y, rcSrcClipped.right-rcSrcClipped.left, rcSrcClipped.bottom-rcSrcClipped.top};
//m_pSurface->Blt(&rcd,pSurf,&rcSrcClipped,DDBLT_WAIT,NULL);
// RECT rcd = {0, 0, 640, 480};
/* rcSrcClipped.left+=current.window.left+pt.x;
rcSrcClipped.right+=current.window.left+pt.x;
rcSrcClipped.top+=current.window.top+pt.y+28;
rcSrcClipped.bottom+=current.window.top+pt.y+28;
/*
DDBLTFX ddbltfx;
ddbltfx.dwSize=sizeof(ddbltfx);
ddbltfx.dwFillColor=5;
m_pSurface->Blt(&rcSrcClipped,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);*/
/* CComPtr< ICanvas > pCan;
cManager::_p->GetPrimarySurface(&pCan);
CComPtr< IDirectDrawSurface4 > pDDS4;
pCan->GetSurface( IID_IDirectDrawSurface4, reinterpret_cast< void ** >( &pDDS4 ) );
// if(m_pSurface.p==pDDS4.p)
if(cManager::_p->m_lpSurface!=NULL)
{
MessageBeep(0);
DDSURFACEDESC2 ddesc;
ddesc.dwSize=sizeof(DDSURFACEDESC2);
pSurf->Lock(&rcSrcClipped, &ddesc, DDLOCK_SURFACEMEMORYPTR , NULL);
//m_pSurface->Blt(&rcSrcClipped,pSurf,NULL,DDBLT_KEYSRC | DDBLT_WAIT ,NULL);
memcpy(cManager::_p->m_lpSurface, ddesc.lpSurface, 1000);
pSurf->Unlock(&rcSrcClipped);
SetEvent(cManager::_p->m_hDrawSync);
}
//m_pSurface->Blt(&rcSrcClipped,pSurf,NULL,DDBLT_KEYSRC | DDBLT_WAIT ,NULL);
/* RECT rc;
::GetWindowRect( cManager::_p->m_hMain, &rc );*/
/*
HDC hdcd;
HDC hdcs;
m_pSurface->GetDC(&hdcd);
pSurf->GetDC(&hdcs);
BitBlt(hdcd, pt.x+current.window.left, pt.y+28+current.window.top, 332, current.window.bottom-current.window.top, hdcs, rcSrcClipped.left, rcSrcClipped.top, SRCCOPY);
pSurf->ReleaseDC(hdcs);
m_pSurface->ReleaseDC(hdcd);*/
/* hRes=0;
}
/*if(!SUCCEEDED(hRes))
SetEvent(cManager::_p->m_hDrawSync);*/
_ASSERTE( SUCCEEDED( hRes ) );
}
PopClipRect();
_ASSERTMEM( _CrtCheckMemory() );
return S_OK;
}
STDMETHODIMP cCanvas::HitTest(LPPOINT ppt, VARIANT_BOOL *pbHit)
{
_ASSERTE( ppt != NULL );
_ASSERTE( pbHit != NULL );
// Assuming we're in screen coords
ClipParams &clip = m_clipping.top();
if( ppt->x >= clip.window.left && ppt->y >= clip.window.top &&
ppt->x <= clip.window.right && ppt->y <= clip.window.bottom )
{
*pbHit = VARIANT_TRUE;
}
else
*pbHit = VARIANT_FALSE;
return S_OK;
}
STDMETHODIMP cCanvas::ToClient(LPPOINT pt)
{
_ASSERTE( pt != NULL );
ClipParams &clip = m_clipping.top();
pt->x -= clip.window.left - clip.org.x;
pt->y -= clip.window.top - clip.org.y;
return S_OK;
}
STDMETHODIMP cCanvas::ToScreen(LPPOINT ppt)
{
_ASSERTE( ppt != NULL );
ClipParams &clip = m_clipping.top();
ppt->x += clip.window.left - clip.org.x;
ppt->y += clip.window.top - clip.org.y;
return S_OK;
}
STDMETHODIMP cCanvas::OffsetOrg(LPPOINT ppt, VARIANT_BOOL *pbVisible)
{
_ASSERTE( ppt != NULL );
_ASSERTE( pbVisible != NULL );
_ASSERTE( m_clipping.size() != 1 );
ClipParams &clip = m_clipping.top();
clip.org.x += ppt->x;
clip.org.y += ppt->y;
*pbVisible = clip.visible;
return S_OK;
}
STDMETHODIMP cCanvas::SetClipRect(LPRECT prc, VARIANT_BOOL *pbVisible)
{
_ASSERTE( prc != NULL );
_ASSERTE( prc->right >= prc->left && prc->bottom >= prc->top );
_ASSERTE( pbVisible != NULL );
_ASSERTE( m_clipping.size() != 1 );
ClipParams &current = m_clipping.top();
int nChildLeft = prc->left + current.window.left - current.org.x,
nChildTop = prc->top + current.window.top - current.org.y,
nChildWidth = prc->right - prc->left,
nChildHeight = prc->bottom - prc->top;
ClipParams p = {
{ nChildLeft, nChildTop, nChildLeft + nChildWidth, nChildTop + nChildHeight },
{ 0, 0 },
VARIANT_TRUE };
// Clip the four sides of the rectangle
if( p.window.left < current.window.left )
{
// Clip left edge
p.org.x += current.window.left - p.window.left;
p.window.left = current.window.left;
}
if( p.window.top < current.window.top )
{
// Clip top edge
p.org.y += current.window.top - p.window.top;
p.window.top = current.window.top;
}
if( p.window.right > current.window.right )
// Clip right edge
p.window.right = current.window.right;
if( p.window.bottom > current.window.bottom )
// Clip bottom edge
p.window.bottom = current.window.bottom;
// Check for clipping out of existance
if( p.window.left >= p.window.right || p.window.top >= p.window.bottom )
// This rectangle is no longer visible
p.visible = VARIANT_FALSE;
// Return the remainder of the rectangle
*pbVisible = p.visible;
m_clipping.top() = p;
return S_OK;
}
STDMETHODIMP cCanvas::put_Alpha(long Alpha)
{
m_bf.SourceConstantAlpha = sourceAlpha = Alpha;
return S_OK;
}
// processMask - Support function for DownMixRGB
void cCanvas::processMask(WORD bitMask, WORD *loBit, WORD *bitCount) {
_ASSERTE(loBit);
_ASSERTE(bitCount);
WORD mask = 1;
for (*loBit = 0; *loBit < 16; (*loBit)++) {
if (bitMask & mask)
break;
mask <<= 1;
}
for (*bitCount = 1; *bitCount < 32; (*bitCount)++) {
mask <<= 1;
if (!(bitMask & mask))
break;
}
}
// DownMixRGB - Returns a 16 bit RGB value suitable for this canvas from a standard R, G, B set
STDMETHODIMP cCanvas::DownMixRGB(WORD wRed, WORD wGreen, WORD wBlue, WORD *wDMRGB) {
_ASSERTE(wDMRGB);
if (wRBitCount == 0) {
// We've never obtained surface information before for this canvas
DDSURFACEDESC2 desc;
desc.dwSize = sizeof( DDSURFACEDESC2 );
if (FAILED(m_pSurface->GetSurfaceDesc(&desc)))
return S_FALSE;
processMask(desc.ddpfPixelFormat.dwRBitMask, &wRLoBit, &wRBitCount);
processMask(desc.ddpfPixelFormat.dwGBitMask, &wGLoBit, &wGBitCount);
processMask(desc.ddpfPixelFormat.dwBBitMask, &wBLoBit, &wBBitCount);
}
// Transparent color handling
if (wRed == 0 && wGreen == 255 && wBlue == 255) {
// We are a transparent colour - The downmix would've destroyed it
*wDMRGB = 0x07FF;
} else {
// Safe for a normal mix
*wDMRGB = ((wRed * (1 << wRBitCount)) / 256) << wRLoBit |
((wGreen * (1 << wGBitCount)) / 256) << wGLoBit |
((wBlue * (1 << wBBitCount)) / 256) << wBLoBit;
}
return S_OK;
}
STDMETHODIMP cCanvas::GetDCLong(long *DC)
{
HDC pdc;
GetDC(&pdc);
*DC = reinterpret_cast< long >( pdc );
return S_OK;
}
STDMETHODIMP cCanvas::SetTransparentColor(long TransColor)
{
unsigned short wDownmix;
DownMixRGB((BYTE)TransColor, (BYTE)(TransColor >> 8), (BYTE)(TransColor >> 16), &wDownmix );
_DDCOLORKEY colorkey;
colorkey.dwColorSpaceHighValue = wDownmix;
colorkey.dwColorSpaceLowValue = wDownmix;
m_pSurface->SetColorKey( DDCKEY_SRCBLT, &colorkey );
return S_OK;
}
STDMETHODIMP cCanvas::StretchBlt(LPRECT prcSrc, ICanvas *pSrc, LPRECT prcDest)
{
_ASSERTE( pSrc != NULL );
_ASSERTE( prcSrc != NULL );
_ASSERTE( prcSrc->right > prcSrc->left && prcSrc->bottom > prcSrc->top );
//_ASSERTE( pptDest != NULL );
testSurface();
//RECT rc = { pptDest->x, pptDest->y, pptDest->x + ( prcSrc->right - prcSrc->left ), pptDest->y + ( prcSrc->bottom - prcSrc->top ) };
// Ok, first, make up the clip rect
RECT rc = { prcDest->left, prcDest->top, prcDest->right, prcDest->bottom };
VARIANT_BOOL bVisible = TRUE;
PushClipRect( &rc, &bVisible );
//if( bVisible )
{
CComPtr< IDirectDrawSurface4 > pSurf;
pSrc->GetSurface( IID_IDirectDrawSurface4, reinterpret_cast< void ** >( &pSurf ) );
_ASSERTE( pSurf.p != NULL );
_ASSERTE( pSurf->IsLost() == DD_OK );
// Calculate the metrics
#ifdef _DEBUG
SIZE sz;
pSrc->get_Size( &sz );
_ASSERTE( prcSrc->left >= 0 && prcSrc->top >= 0 && prcSrc->right <= sz.cx && prcSrc->bottom <= sz.cy );
#endif
ClipParams &current = m_clipping.top();
RECT rcSrcClipped = {
prcSrc->left,
prcSrc->top,
prcSrc->right,// + ( current.window.right - current.window.left ),
prcSrc->bottom// + ( current.window.bottom - current.window.top )
};
RECT rcDestClipped = {
prcDest->left + current.org.x + current.window.left,
prcDest->top + current.org.y + current.window.top,
prcDest->left + prcDest->right + current.org.x,
prcDest->top + prcDest->bottom + current.org.y
};
HRESULT hRes = m_pSurface->Blt( &rcDestClipped, pSurf, &rcSrcClipped, DDBLT_KEYSRC | DDBLT_WAIT, NULL );
_ASSERTE( SUCCEEDED( hRes ) );
}
PopClipRect();
_ASSERTMEM( _CrtCheckMemory() );
return S_OK;
}

79
Native/Inject/Canvas.h Normal file
View file

@ -0,0 +1,79 @@
// Canvas.h : Declaration of the cCanvas
#ifndef __CANVAS_H_
#define __CANVAS_H_
#include "resource.h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// cCanvas
class ATL_NO_VTABLE cCanvas :
public CComObjectRootEx<CComMultiThreadModel>,
public ICanvas
{
public:
cCanvas()
: m_hdc( NULL ),
m_rgn( NULL )
{
m_bf.SourceConstantAlpha = 255;
m_bf.BlendOp = AC_SRC_OVER;
m_bf.BlendFlags = 0;
m_bf.AlphaFormat = 0;
sourceAlpha = 255;
wRBitCount = 0;
}
~cCanvas();
CComPtr< IDirectDrawSurface4 > m_pSurface;
SIZE m_sz;
typedef std::stack< ClipParams > cClipStack;
cClipStack m_clipping;
HDC m_hdc;
HRGN m_rgn;
BLENDFUNCTION m_bf;
WORD wRBitCount, wGBitCount, wBBitCount;
WORD wRLoBit, wGLoBit, wBLoBit;
long sourceAlpha;
void testSurface();
void processMask(WORD bitMask, WORD *loBit, WORD *bitCount);
BEGIN_COM_MAP(cCanvas)
COM_INTERFACE_ENTRY(ICanvas)
END_COM_MAP()
// ICanvas
public:
STDMETHOD(SetTransparentColor)(/*[in]*/ long TransColor);
STDMETHOD(GetDCLong)(long *DC);
STDMETHOD(SetClipRect)(LPRECT prcClip, VARIANT_BOOL *pbVisible);
STDMETHOD(OffsetOrg)(LPPOINT ppt, VARIANT_BOOL *pbVisible);
STDMETHOD(ToScreen)(/*[in, out]*/ LPPOINT ppt);
STDMETHOD(ToClient)(/*[in, out]*/ LPPOINT pt);
STDMETHOD(HitTest)(LPPOINT ppt, /*[out, retval]*/ VARIANT_BOOL *pbHit);
STDMETHOD(Blt)(LPRECT prcSrc, ICanvas *pSrc, LPPOINT pptDest);
STDMETHOD(get_Size)(/*[out, retval]*/ LPSIZE pVal);
STDMETHOD(put_Size)(/*[in]*/ LPSIZE newVal);
STDMETHOD(get_WasLost)(/*[out, retval]*/ VARIANT_BOOL *pVal);
STDMETHOD(Frame)(LPRECT prc, long nRGB);
STDMETHOD(Fill)(LPRECT prc, long nRGB);
STDMETHOD(GetClipParams)(/*[out, retval]*/ ClipParams *pParams);
STDMETHOD(GetSurface)(REFIID iid, /*[out, retval, iid_is(iid)]*/ void **ppvItf);
STDMETHOD(ReleaseDC)();
STDMETHOD(GetDC)(/*[out,retval]*/ HDC *pdc);
STDMETHOD(PopClipRect)();
STDMETHOD(PushClipRect)(LPRECT prc, /*[out, retval]*/ VARIANT_BOOL *pbVisible);
STDMETHOD(put_Alpha)(long Alpha);
STDMETHOD(DownMixRGB)(WORD wRed, WORD wGreen, WORD wBlue, /*[out, retval]*/ WORD *wDMRGB);
STDMETHOD(StretchBlt)(LPRECT prcSrc, ICanvas *pSrc, LPRECT prcDest);
};
#endif //__CANVAS_H_

164
Native/Inject/DatFile.cpp Normal file
View file

@ -0,0 +1,164 @@
// ACFile.cpp
// Implementation of class cACFile
#include "stdafx.h"
#include "DatFile.h"
#define AC_NUMFILELOC 0x03E
#define AC_ROOTDIRPTRLOC 0x148
#define new DEBUG_NEW
cDatFile::cFile::cFile( cDatFile *pSource, BYTE *pFirstSector, DWORD dwSize )
: m_pFirstSector( pFirstSector ),
m_pCurrentSector( pFirstSector ),
m_pCurrentByte( pFirstSector + sizeof( DWORD ) ),
m_dwSize( dwSize ),
m_dwOffset( 0 ),
m_pSource( pSource )
{
}
void cDatFile::cFile::reset()
{
m_pCurrentSector = m_pFirstSector;
m_pCurrentByte = m_pFirstSector + sizeof( DWORD );
m_dwOffset = 0;
}
DWORD cDatFile::cFile::read( BYTE *pbBuffer, DWORD dwSize )
{
// Check if we can fit
if( dwSize + m_dwOffset > m_dwSize )
dwSize = m_dwSize - m_dwOffset;
DWORD dwRemaining = dwSize;
while( dwRemaining > 0 )
{
if( ( m_pCurrentByte + dwRemaining ) > m_pCurrentSector + m_pSource->m_dwSectorSize )
{
// We are reading over a sector boundary, read what we've got and reset for the next sector
DWORD dwSection = ( m_pCurrentSector + m_pSource->m_dwSectorSize ) - m_pCurrentByte;
::memcpy( pbBuffer, m_pCurrentByte, dwSection );
m_pCurrentSector = m_pSource->m_pData + *reinterpret_cast< DWORD * >( m_pCurrentSector );
m_pCurrentByte = m_pCurrentSector + sizeof( DWORD );
dwRemaining -= dwSection;
pbBuffer += dwSection;
}
else
{
::memcpy( pbBuffer, m_pCurrentByte, dwRemaining );
m_pCurrentByte += dwRemaining;
dwRemaining = 0;
}
}
m_dwOffset += dwSize;
return dwSize;
}
DWORD cDatFile::cFile::skip( DWORD dwSize )
{
// Check if we can fit
if( dwSize + m_dwOffset > m_dwSize )
dwSize = m_dwSize - m_dwOffset;
DWORD dwRemaining = dwSize;
while( dwRemaining > 0 )
{
if( ( m_pCurrentByte + dwRemaining ) > m_pCurrentSector + m_pSource->m_dwSectorSize )
{
// We are reading over a sector boundary, read what we've got and reset for the next sector
DWORD dwSection = ( m_pCurrentSector + m_pSource->m_dwSectorSize ) - m_pCurrentByte;
m_pCurrentSector = m_pSource->m_pData + *reinterpret_cast< DWORD * >( m_pCurrentSector );
m_pCurrentByte = m_pCurrentSector + sizeof( DWORD );
dwRemaining -= dwSection;
}
else
{
m_pCurrentByte += dwRemaining;
dwRemaining = 0;
}
}
m_dwOffset += dwSize;
return dwSize;
}
cDatFile::cDatFile( LPCTSTR szFilename, DWORD dwSectorSize )
: m_hFile( NULL ),
m_hMapping( NULL ),
m_pData( NULL ),
m_dwSectorSize( dwSectorSize )
{
m_hFile = ::CreateFile( szFilename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL );
if( m_hFile == INVALID_HANDLE_VALUE )
throw std::exception();
// Proceed to create the file mapping
m_hMapping = ::CreateFileMapping( m_hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL );
if( m_hMapping == NULL )
{
::CloseHandle( m_hFile );
throw std::exception();
}
m_pData = reinterpret_cast< BYTE * >( ::MapViewOfFileEx( m_hMapping, FILE_MAP_READ, 0, 0, 0, NULL ) );
if( m_pData == NULL )
{
::CloseHandle( m_hMapping );
::CloseHandle( m_hFile );
throw std::exception();
}
}
cDatFile::~cDatFile()
{
::UnmapViewOfFile( m_pData );
::CloseHandle( m_hMapping );
::CloseHandle( m_hFile );
}
cDatFile::cFile cDatFile::getFile( DWORD dwFileNumber )
{
cDirectory dir;
// Search for our golden file
for ( DWORD dwDirStart = *reinterpret_cast< DWORD * >( m_pData + AC_ROOTDIRPTRLOC ); dwDirStart != 0; )
{
cFile dir_entry( this, m_pData + dwDirStart, sizeof( cDirectory ) );
dir_entry.read( reinterpret_cast< BYTE * >( &dir ), sizeof( cDirectory ) );
// Now, the files are located like triplets, so copy the triplets
cFileEntry *pEntry = dir.m_files,
*pEndEntry = pEntry + dir.m_dwFiles;
for( cFileEntry *pIter = pEntry; pIter != pEndEntry && pIter->m_dwID < dwFileNumber; ++ pIter );
// We either got an exact match - or we attempt to further narrow down the file
if( pIter != pEndEntry )
{
// We found some sort of match
if( pIter->m_dwID == dwFileNumber )
// This is an exact match hooray
return cFile( this, m_pData + pIter->m_dwOffset, pIter->m_dwSize );
}
// We have an inexact match, but now we attempt to recurse
if( dir.m_subdirs[ 0 ] == 0 )
// If the first entry in the directory is 0, there are no
// helpers - we lose, it's not here
break;
dwDirStart = dir.m_subdirs[ pIter - pEntry ];
}
// If we get here, the file wasn't found - sniff
throw std::exception();
}

76
Native/Inject/DatFile.h Normal file
View file

@ -0,0 +1,76 @@
// DatFile.h
// Declaration of class cDatFile
// Class for extracting data from portal.dat and cell.dat
#ifndef __ACFILE_H
#define __ACFILE_H
#define FILE_COUNT 62
class cDatFile
{
// The AC File is created as a memory mapped file
// so we let the memory manager cache manage - it's also quite a bit nicer than
// code to seek/read everything
HANDLE m_hFile,
m_hMapping;
BYTE *m_pData;
DWORD m_dwSectorSize;
public:
class cFile
{
BYTE *m_pFirstSector,
*m_pCurrentSector,
*m_pCurrentByte;
DWORD m_dwSize,
m_dwOffset;
cDatFile *m_pSource;
public:
// Locate the file in a directory
cFile( cDatFile *pSource, BYTE *pFirstSector, DWORD dwSize );
DWORD getSize() const
{
return m_dwSize;
}
DWORD tell() const
{
return m_dwOffset;
}
void reset();
DWORD read( BYTE *pbBuffer, DWORD dwSize );
DWORD skip( DWORD dwSize );
};
cDatFile( LPCTSTR szFilename, DWORD dwSectorSize = 256 );
~cDatFile();
cFile getFile( DWORD dwFileNumber );
// Structures
#pragma pack( push, 1 )
struct cFileEntry
{
DWORD m_dwID,
m_dwOffset,
m_dwSize;
};
struct cDirectory
{
DWORD m_subdirs[ FILE_COUNT ];
DWORD m_dwFiles;
cFileEntry m_files[ FILE_COUNT ];
};
#pragma pack( pop )
friend cFile;
};
#endif

View file

@ -0,0 +1,43 @@
// Direct3DHook.cpp : Implementation of CDirect3DHook
#include "stdafx.h"
#include "Inject.h"
#include "Direct3DHook.h"
#include "InjectApi.h"
#include "Manager.h"
/////////////////////////////////////////////////////////////////////////////
// CDirect3DHook
void CDirect3DHook::setObject( IUnknown *pDevice )
{
pDevice->QueryInterface( IID_IDirect3DDevice, reinterpret_cast< void ** >( &m_pDevice ) );
pDevice->QueryInterface( IID_IDirect3DDevice2, reinterpret_cast< void ** >( &m_pDevice2 ) );
pDevice->QueryInterface( IID_IDirect3DDevice3, reinterpret_cast< void ** >( &m_pDevice3 ) );
}
STDMETHODIMP CDirect3DHook::BeginScene()
{
cManager::_p->sendPreBeginScene();
HRESULT hRes = m_pDevice->BeginScene();
cManager::_p->sendPostBeginScene();
return hRes;
}
STDMETHODIMP CDirect3DHook::EndScene()
{
cManager::_p->draw3D();
cManager::_p->sendPreEndScene();
HRESULT hRes = m_pDevice->EndScene();
// Draw the user 2D layer
cManager::_p->draw2D();
cManager::_p->sendPostEndScene();
return hRes;
}

View file

@ -0,0 +1,371 @@
// Direct3DHook.h : Declaration of the CDirect3DHook
#ifndef __DIRECT3DHOOK_H_
#define __DIRECT3DHOOK_H_
#include "resource.h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// CDirect3DHook
class ATL_NO_VTABLE CDirect3DHook :
public CComObjectRootEx<CComMultiThreadModel>,
public IDirect3DDevice,
public IDirect3DDevice2,
public IDirect3DDevice3
{
public:
CDirect3DHook()
{
}
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CDirect3DHook)
COM_INTERFACE_ENTRY_IID( IID_IDirect3DDevice, IDirect3DDevice )
COM_INTERFACE_ENTRY_IID( IID_IDirect3DDevice2, IDirect3DDevice2 )
COM_INTERFACE_ENTRY_IID( IID_IDirect3DDevice3, IDirect3DDevice3 )
END_COM_MAP()
CComPtr< IDirect3DDevice > m_pDevice;
CComPtr< IDirect3DDevice2 > m_pDevice2;
CComPtr< IDirect3DDevice3 > m_pDevice3;
void setObject( IUnknown *pDevice );
// IDirect3DHook
public:
// Functions from IDirect3DDevice
STDMETHOD(Initialize)(LPDIRECT3D p1,LPGUID p2,LPD3DDEVICEDESC p3)
{
return m_pDevice->Initialize( p1, p2, p3 );
}
STDMETHOD(GetCaps)(LPD3DDEVICEDESC p1,LPD3DDEVICEDESC p2)
{
return m_pDevice->GetCaps( p1, p2 );
}
STDMETHOD(SwapTextureHandles)(LPDIRECT3DTEXTURE p1,LPDIRECT3DTEXTURE p2)
{
return m_pDevice->SwapTextureHandles( p1, p2 );
}
STDMETHOD(CreateExecuteBuffer)(LPD3DEXECUTEBUFFERDESC p1,LPDIRECT3DEXECUTEBUFFER*p2,IUnknown*p3)
{
return m_pDevice->CreateExecuteBuffer( p1, p2, p3 );
}
STDMETHOD(GetStats)(LPD3DSTATS p1)
{
return m_pDevice->GetStats( p1 );
}
STDMETHOD(Execute)(LPDIRECT3DEXECUTEBUFFER p1,LPDIRECT3DVIEWPORT p2,DWORD p3)
{
return m_pDevice->Execute( p1, p2, p3 );
}
STDMETHOD(AddViewport)(LPDIRECT3DVIEWPORT p1)
{
return m_pDevice->AddViewport( p1 );
}
STDMETHOD(DeleteViewport)(LPDIRECT3DVIEWPORT p1)
{
return m_pDevice->DeleteViewport( p1 );
}
STDMETHOD(NextViewport)(LPDIRECT3DVIEWPORT p1,LPDIRECT3DVIEWPORT*p2,DWORD p3)
{
return m_pDevice->NextViewport( p1, p2, p3 );
}
STDMETHOD(Pick)(LPDIRECT3DEXECUTEBUFFER p1,LPDIRECT3DVIEWPORT p2,DWORD p3,LPD3DRECT p4)
{
return m_pDevice->Pick( p1, p2, p3, p4 );
}
STDMETHOD(GetPickRecords)(LPDWORD p1,LPD3DPICKRECORD p2)
{
return m_pDevice->GetPickRecords( p1, p2 );
}
STDMETHOD(EnumTextureFormats)(LPD3DENUMTEXTUREFORMATSCALLBACK p1,LPVOID p2)
{
return m_pDevice->EnumTextureFormats( p1, p2 );
}
STDMETHOD(CreateMatrix)(LPD3DMATRIXHANDLE p1)
{
return m_pDevice->CreateMatrix( p1 );
}
STDMETHOD(SetMatrix)(D3DMATRIXHANDLE p1,const LPD3DMATRIX p2)
{
return m_pDevice->SetMatrix( p1, p2 );
}
STDMETHOD(GetMatrix)(D3DMATRIXHANDLE p1,LPD3DMATRIX p2)
{
return m_pDevice->GetMatrix( p1, p2 );
}
STDMETHOD(DeleteMatrix)(D3DMATRIXHANDLE p1)
{
return m_pDevice->DeleteMatrix( p1 );
}
STDMETHOD(BeginScene)();
STDMETHOD(EndScene)();
STDMETHOD(GetDirect3D)(LPDIRECT3D*p1)
{
return m_pDevice->GetDirect3D( p1 );
}
// Functions from IDirect3DDevice2
STDMETHOD(SwapTextureHandles)(LPDIRECT3DTEXTURE2 p1,LPDIRECT3DTEXTURE2 p2)
{
return m_pDevice2->SwapTextureHandles( p1, p2 );
}
STDMETHOD(AddViewport)(LPDIRECT3DVIEWPORT2 p1)
{
return m_pDevice2->AddViewport( p1 );
}
STDMETHOD(DeleteViewport)(LPDIRECT3DVIEWPORT2 p1)
{
return m_pDevice2->DeleteViewport( p1 );
}
STDMETHOD(NextViewport)(LPDIRECT3DVIEWPORT2 p1,LPDIRECT3DVIEWPORT2*p2,DWORD p3)
{
return m_pDevice2->NextViewport( p1, p2, p3 );
}
STDMETHOD(GetDirect3D)(LPDIRECT3D2*p1)
{
return m_pDevice2->GetDirect3D( p1 );
}
STDMETHOD(SetCurrentViewport)(LPDIRECT3DVIEWPORT2 p1)
{
return m_pDevice2->SetCurrentViewport( p1 );
}
STDMETHOD(GetCurrentViewport)(LPDIRECT3DVIEWPORT2 *p1)
{
return m_pDevice2->GetCurrentViewport( p1 );
}
STDMETHOD(SetRenderTarget)(LPDIRECTDRAWSURFACE p1,DWORD p2)
{
return m_pDevice2->SetRenderTarget( p1, p2 );
}
STDMETHOD(GetRenderTarget)(LPDIRECTDRAWSURFACE *p1)
{
return m_pDevice2->GetRenderTarget( p1 );
}
STDMETHOD(Begin)(D3DPRIMITIVETYPE p1,D3DVERTEXTYPE p2,DWORD p3)
{
return m_pDevice2->Begin( p1, p2, p3 );
}
STDMETHOD(BeginIndexed)(D3DPRIMITIVETYPE p1,D3DVERTEXTYPE p2,LPVOID p3,DWORD p4,DWORD p5)
{
return m_pDevice2->BeginIndexed( p1, p2, p3, p4, p5 );
}
STDMETHOD(Vertex)(LPVOID p1)
{
return m_pDevice2->Vertex( p1 );
}
STDMETHOD(Index)(WORD p1)
{
return m_pDevice2->Index( p1 );
}
STDMETHOD(End)(DWORD p1)
{
return m_pDevice2->End( p1 );
}
STDMETHOD(GetRenderState)(D3DRENDERSTATETYPE p1,LPDWORD p2)
{
return m_pDevice2->GetRenderState( p1, p2 );
}
STDMETHOD(SetRenderState)(D3DRENDERSTATETYPE p1,DWORD p2)
{
return m_pDevice2->SetRenderState( p1, p2 );
}
STDMETHOD(GetLightState)(D3DLIGHTSTATETYPE p1,LPDWORD p2)
{
return m_pDevice2->GetLightState( p1, p2 );
}
STDMETHOD(SetLightState)(D3DLIGHTSTATETYPE p1,DWORD p2)
{
return m_pDevice2->SetLightState( p1, p2 );
}
STDMETHOD(SetTransform)(D3DTRANSFORMSTATETYPE p1,LPD3DMATRIX p2)
{
return m_pDevice2->SetTransform( p1, p2 );
}
STDMETHOD(GetTransform)(D3DTRANSFORMSTATETYPE p1,LPD3DMATRIX p2)
{
return m_pDevice2->GetTransform( p1, p2 );
}
STDMETHOD(MultiplyTransform)(D3DTRANSFORMSTATETYPE p1,LPD3DMATRIX p2)
{
return m_pDevice2->MultiplyTransform( p1, p2 );
}
STDMETHOD(DrawPrimitive)(D3DPRIMITIVETYPE p1,D3DVERTEXTYPE p2,LPVOID p3,DWORD p4,DWORD p5)
{
return m_pDevice2->DrawPrimitive( p1, p2, p3, p4, p5 );
}
STDMETHOD(DrawIndexedPrimitive)(D3DPRIMITIVETYPE p1,D3DVERTEXTYPE p2,LPVOID p3,DWORD p4,LPWORD p5, DWORD p6, DWORD p7)
{
return m_pDevice2->DrawIndexedPrimitive( p1, p2, p3, p4, p5, p6, p7 );
}
STDMETHOD(SetClipStatus)(LPD3DCLIPSTATUS p1)
{
return m_pDevice2->SetClipStatus( p1 );
}
STDMETHOD(GetClipStatus)(LPD3DCLIPSTATUS p1)
{
return m_pDevice2->GetClipStatus( p1 );
}
// Functions from IDirect3DDevice3
STDMETHOD(AddViewport)(LPDIRECT3DVIEWPORT3 p1)
{
return m_pDevice3->AddViewport( p1 );
}
STDMETHOD(DeleteViewport)(LPDIRECT3DVIEWPORT3 p1)
{
return m_pDevice3->DeleteViewport( p1 );
}
STDMETHOD(NextViewport)(LPDIRECT3DVIEWPORT3 p1,LPDIRECT3DVIEWPORT3*p2,DWORD p3)
{
return m_pDevice3->NextViewport( p1, p2, p3 );
}
STDMETHOD(EnumTextureFormats)(LPD3DENUMPIXELFORMATSCALLBACK p1,LPVOID p2)
{
return m_pDevice3->EnumTextureFormats( p1, p2 );
}
STDMETHOD(GetDirect3D)(LPDIRECT3D3* p1)
{
return m_pDevice3->GetDirect3D( p1 );
}
STDMETHOD(SetCurrentViewport)(LPDIRECT3DVIEWPORT3 p1)
{
return m_pDevice3->SetCurrentViewport( p1 );
}
STDMETHOD(GetCurrentViewport)(LPDIRECT3DVIEWPORT3 *p1)
{
return m_pDevice3->GetCurrentViewport( p1 );
}
STDMETHOD(SetRenderTarget)(LPDIRECTDRAWSURFACE4 p1,DWORD p2)
{
return m_pDevice3->SetRenderTarget( p1, p2 );
}
STDMETHOD(GetRenderTarget)(LPDIRECTDRAWSURFACE4 *p1)
{
return m_pDevice3->GetRenderTarget( p1 );
}
STDMETHOD(Begin)(D3DPRIMITIVETYPE p1,DWORD p2,DWORD p3)
{
return m_pDevice3->Begin( p1, p2, p3 );
}
STDMETHOD(BeginIndexed)(D3DPRIMITIVETYPE p1,DWORD p2,LPVOID p3,DWORD p4,DWORD p5)
{
return m_pDevice3->BeginIndexed( p1, p2, p3, p4, p5 );
}
STDMETHOD(DrawPrimitive)(D3DPRIMITIVETYPE p1,DWORD p2,LPVOID p3,DWORD p4,DWORD p5)
{
return m_pDevice3->DrawPrimitive( p1, p2, p3, p4, p5 );
}
STDMETHOD(DrawIndexedPrimitive)(D3DPRIMITIVETYPE p1,DWORD p2,LPVOID p3,DWORD p4,LPWORD p5,DWORD p6,DWORD p7)
{
return m_pDevice3->DrawIndexedPrimitive( p1, p2, p3, p4, p5, p6, p7 );
}
STDMETHOD(DrawPrimitiveStrided)(D3DPRIMITIVETYPE p1,DWORD p2,LPD3DDRAWPRIMITIVESTRIDEDDATA p3,DWORD p4,DWORD p5)
{
return m_pDevice3->DrawPrimitiveStrided( p1, p2, p3, p4, p5 );
}
STDMETHOD(DrawIndexedPrimitiveStrided)(D3DPRIMITIVETYPE p1,DWORD p2,LPD3DDRAWPRIMITIVESTRIDEDDATA p3,DWORD p4 ,LPWORD p5,DWORD p6,DWORD p7)
{
return m_pDevice3->DrawIndexedPrimitiveStrided( p1, p2, p3, p4, p5, p6, p7 );
}
STDMETHOD(DrawPrimitiveVB)(D3DPRIMITIVETYPE p1,LPDIRECT3DVERTEXBUFFER p2,DWORD p3,DWORD p4,DWORD p5)
{
return m_pDevice3->DrawPrimitiveVB( p1, p2, p3, p4, p5 );
}
STDMETHOD(DrawIndexedPrimitiveVB)(D3DPRIMITIVETYPE p1,LPDIRECT3DVERTEXBUFFER p2,LPWORD p3,DWORD p4,DWORD p5)
{
return m_pDevice3->DrawIndexedPrimitiveVB( p1, p2, p3, p4, p5 );
}
STDMETHOD(ComputeSphereVisibility)(LPD3DVECTOR p1,LPD3DVALUE p2,DWORD p3,DWORD p4,LPDWORD p5)
{
return m_pDevice3->ComputeSphereVisibility( p1, p2, p3, p4, p5 );
}
STDMETHOD(GetTexture)(DWORD p1,LPDIRECT3DTEXTURE2 *p2)
{
return m_pDevice3->GetTexture( p1, p2 );
}
STDMETHOD(SetTexture)(DWORD p1,LPDIRECT3DTEXTURE2 p2)
{
return m_pDevice3->SetTexture( p1, p2 );
}
STDMETHOD(GetTextureStageState)(DWORD p1,D3DTEXTURESTAGESTATETYPE p2,LPDWORD p3)
{
return m_pDevice3->GetTextureStageState( p1, p2, p3 );
}
STDMETHOD(SetTextureStageState)(DWORD p1,D3DTEXTURESTAGESTATETYPE p2,DWORD p3)
{
return m_pDevice3->SetTextureStageState( p1, p2, p3 );
}
STDMETHOD(ValidateDevice)(LPDWORD p1)
{
return m_pDevice3->ValidateDevice( p1 );
}
};
#endif //__DIRECT3DHOOK_H_

View file

@ -0,0 +1,284 @@
// DirectDrawHook.cpp : Implementation of CDirectDrawHook
#include "stdafx.h"
#include "Inject.h"
#include "DirectDrawHook.h"
#include "MaterialHook.h"
#include "DirectDrawSurfaceHook.h"
#include "Manager.h"
/////////////////////////////////////////////////////////////////////////////
// CDirectDrawHook
void CDirectDrawHook::setObject( IDirectDraw *pDD )
{
m_pDD = pDD;
m_pDD->QueryInterface( IID_IDirectDraw2, reinterpret_cast< void ** >( &m_pDD2 ) );
m_pDD->QueryInterface( IID_IDirectDraw4, reinterpret_cast< void ** >( &m_pDD4 ) );
m_pDD->QueryInterface( IID_IDirect3D, reinterpret_cast< void ** >( &m_pD3D ) );
m_pDD->QueryInterface( IID_IDirect3D2, reinterpret_cast< void ** >( &m_pD3D2 ) );
m_pDD->QueryInterface( IID_IDirect3D3, reinterpret_cast< void ** >( &m_pD3D3 ) );
cManager::_p->setDirectDraw( m_pDD4, m_pD3D3, NULL);
}
STDMETHODIMP CDirectDrawHook::SetCooperativeLevel(HWND p1, DWORD p2)
{
cManager::_p->setWindow( p1 );
return m_pDD->SetCooperativeLevel( p1, p2 );
}
STDMETHODIMP CDirectDrawHook::SetDisplayMode(DWORD p1, DWORD p2, DWORD p3)
{
return m_pDD->SetDisplayMode( p1, p2, p3 );
}
HRESULT (__stdcall *pfnOldLock)(IDirectDrawSurface4 *pDDS, LPRECT rc, LPDDSURFACEDESC2 *pddesc, DWORD dwFlags, HANDLE hEvent);
HRESULT (__stdcall *pfnOldUnlock)(IDirectDrawSurface4 *pDDS, LPRECT rc);
HRESULT __stdcall myLock (IDirectDrawSurface4 *pDDS, LPRECT rc, LPDDSURFACEDESC2 *pddesc, DWORD dwFlags, HANDLE hEvent)
{
HRESULT hRes = pfnOldLock(pDDS, rc, pddesc, dwFlags, hEvent);
//if(rc==NULL)
cManager::_p->m_lpSurface = (*pddesc)->lpSurface;
return hRes;
}
HRESULT __stdcall myUnlock ( IDirectDrawSurface4 *pDDS, LPRECT rc)
{
if(rc==NULL)
{
cManager::_p->draw2D();
//WaitForSingleObject(cManager::_p->m_hDrawSync, INFINITE);
//ResetEvent(cManager::_p->m_hDrawSync);
cManager::_p->m_lpSurface = NULL;
}
// EnterCriticalSection(&cs);
HRESULT hRes = pfnOldUnlock(pDDS, rc);
// LeaveCriticalSection(&cs);
//MessageBox(0, _bstr_t(" left: ") + _bstr_t((long)rc->left) + _bstr_t(" top: ") + _bstr_t((long)rc->top) + _bstr_t(" right: ") + _bstr_t((long)rc->right) + _bstr_t(" bottom: ") + _bstr_t((long)rc->bottom), "Asd", 0);
return hRes;
}
STDMETHODIMP CDirectDrawHook::CreateSurface(LPDDSURFACEDESC2 p1, LPDIRECTDRAWSURFACE4 FAR *ppDDS, IUnknown FAR *p3)
{
static long sc = 0;
//static bool bGotPrimary=false;
//static DWORD dwCaps=-1;
//I have no idea if this serves any purpose anymore, but its causing freezing on software clients. 'Removed' for now.
#if 0
if(cManager::_p->getSoftwareMode())// && (!bGotPrimary))
{
CComPtr< IDirectDrawSurface4 > pDDS;
HRESULT hRes = m_pDD4->CreateSurface( p1, &pDDS, p3 );
if( FAILED( hRes ) )
return hRes;
pDDS->QueryInterface(IID_IDirectDrawSurface4, reinterpret_cast< void ** >(ppDDS));
// Get the configured width from the registry
/* DWORD dwConfiguredWidth;
{
RECT rc;
::GetClientRect( cManager::_p->m_hMain, &rc );
dwConfiguredWidth = rc.right - rc.left;
}*/
/*if( p1->dwWidth < ( dwConfiguredWidth - 330 ) )
{
}
*/
if(p1->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
{
//MessageBox(0, _bstr_t("Width: ") + _bstr_t((long)p1->dwWidth) + _bstr_t(" Height: ") + _bstr_t((long)p1->dwHeight), "asd", 0);
sc++;
/*if(dwCaps!=-1)
if(dwCaps!=p1->ddsCaps.dwCaps)
MessageBox(0, "Diff", "asd", 0);*/
// dwCaps = p1->ddsCaps.dwCaps;
//if(/*(((sc%2)==0) && (bGotPrimary)) || */(sc==3) || (sc==4))
{
/*if(sc==1)
InitializeCriticalSection(&cs);*/
/*if(bGotPrimary)
{
if(m_pDDS4.p!=NULL)
{
HRESULT (__stdcall *&pfnUnlockPrev)(IDirectDrawSurface4 *pDDS, LPRECT rc) = reinterpret_cast< HRESULT (__stdcall**)(IDirectDrawSurface4 *pDDS, LPRECT rc) > ( *reinterpret_cast< DWORD * > ( m_pDDS4.p ) )[ 32 ];
pfnUnlockPrev = pfnOldUnlock;
}
}*/
//EnterCriticalSection(&cs);
if(sc==1)
{
HRESULT (__stdcall *&pfnLock)(IDirectDrawSurface4 *, LPRECT, LPDDSURFACEDESC2, DWORD, HANDLE) = reinterpret_cast< HRESULT (__stdcall**)(IDirectDrawSurface4 *, LPRECT, LPDDSURFACEDESC2, DWORD, HANDLE) > ( *reinterpret_cast< DWORD * > ( pDDS.p ) )[ 25 ];
HRESULT (__stdcall *&pfnUnlock)(IDirectDrawSurface4 *, LPRECT) = reinterpret_cast< HRESULT (__stdcall**)(IDirectDrawSurface4 *, LPRECT) > ( *reinterpret_cast< DWORD * > ( pDDS.p ) )[ 32 ];
pfnOldUnlock = *pfnUnlock;
pfnUnlock = myUnlock;
cManager::_p->setDirectDraw(m_pDD4, NULL, pDDS);
cManager::_p->setSurface(NULL);
}
//bGotPrimary=true;
//m_pDDS4 = pDDS;
//LeaveCriticalSection(&cs);
}
}
return hRes;
}
else
#endif
return m_pDD4->CreateSurface(p1, ppDDS, p3);
}
STDMETHODIMP CDirectDrawHook::SetDisplayMode(DWORD p1, DWORD p2, DWORD p3, DWORD p4, DWORD p5)
{
return m_pDD2->SetDisplayMode( p1, p2, p3, p4, p5 );
}
STDMETHODIMP CDirectDrawHook::CreateMaterial(LPDIRECT3DMATERIAL *p1,IUnknown *p2)
{
CComPtr< IDirect3DMaterial > pMat;
HRESULT hRes = m_pD3D->CreateMaterial( &pMat, p2 );
if( FAILED( hRes ) )
return hRes;
CComObject< CMaterialHook > *pHook;
CComObject< CMaterialHook >::CreateInstance( &pHook );
pHook->setObject( pMat, m_pDevice2, m_pDevice3 );
pHook->QueryInterface( IID_IDirect3DMaterial, reinterpret_cast< void ** >( p1 ) );
return hRes;
}
STDMETHODIMP CDirectDrawHook::CreateMaterial(LPDIRECT3DMATERIAL2*p1,IUnknown*p2)
{
CComPtr< IDirect3DMaterial2 > pMat;
HRESULT hRes = m_pD3D2->CreateMaterial( &pMat, p2 );
if( FAILED( hRes ) )
return hRes;
CComObject< CMaterialHook > *pHook;
CComObject< CMaterialHook >::CreateInstance( &pHook );
pHook->setObject( pMat, m_pDevice2, m_pDevice3 );
pHook->QueryInterface( IID_IDirect3DMaterial2, reinterpret_cast< void ** >( p1 ) );
return hRes;
}
STDMETHODIMP CDirectDrawHook::CreateMaterial(LPDIRECT3DMATERIAL3*p1,LPUNKNOWN p2)
{
CComPtr< IDirect3DMaterial3 > pMat;
HRESULT hRes = m_pD3D3->CreateMaterial( &pMat, p2 );
if( FAILED( hRes ) )
return hRes;
CComObject< CMaterialHook > *pHook;
CComObject< CMaterialHook >::CreateInstance( &pHook );
pHook->setObject( pMat, m_pDevice2, m_pDevice3 );
pHook->QueryInterface( IID_IDirect3DMaterial3, reinterpret_cast< void ** >( p1 ) );
return hRes;
}
STDMETHODIMP CDirectDrawHook::CreateDevice( REFCLSID cls,LPDIRECTDRAWSURFACE pDDS,LPDIRECT3DDEVICE2 *ppD3D )
{
CComPtr< IDirect3DDevice2 > pD3D;
HRESULT hRes = m_pD3D2->CreateDevice( cls, pDDS, &pD3D );
if( FAILED( hRes ) )
{
//::MessageBox (NULL, "2COULDN'T CreateDevice IN D3D HOOK", "ERROR", MB_OK);
return hRes;
}
CComObject< CDirect3DHook > *pHook;
CComObject< CDirect3DHook >::CreateInstance( &pHook );
pHook->setObject( pD3D );
pHook->QueryInterface( IID_IDirect3DDevice2, reinterpret_cast< void ** >( ppD3D ) );
m_pDevice2 = *ppD3D;
return hRes;
}
STDMETHODIMP CDirectDrawHook::CreateDevice(REFCLSID cls,LPDIRECTDRAWSURFACE4 pDDS,LPDIRECT3DDEVICE3* ppD3D,LPUNKNOWN pUnk)
{
CComPtr< IDirect3DDevice3 > pD3D;
HRESULT hRes = m_pD3D3->CreateDevice( cls, pDDS, &pD3D, pUnk );
if( FAILED( hRes ) )
{
//::MessageBox (NULL, "3COULDN'T CreateDevice IN D3D HOOK", "ERROR", MB_OK);
return hRes;
}
// Ok, figure out if this is the "primary" 3d device
DDSURFACEDESC2 ddsd;
ddsd.dwSize = sizeof( DDSURFACEDESC2 );
pDDS->GetSurfaceDesc( &ddsd );
// Get the configured width from the registry
DWORD dwConfiguredWidth;
{
RECT rc;
::GetClientRect( cManager::_p->m_hMain, &rc );
dwConfiguredWidth = rc.right - rc.left;
}
if( ddsd.dwWidth < ( dwConfiguredWidth - 330 ) )
{
// This is a secondary 3ddevice - do not hook it
return pD3D->QueryInterface( IID_IDirect3DDevice3, reinterpret_cast< void ** >( ppD3D ) );
}
// Ok, we're past the wrong device, get to the right device
cManager::_p->setSurface( pD3D );
CComObject< CDirect3DHook > *pHook;
CComObject< CDirect3DHook >::CreateInstance( &pHook );
pHook->setObject( pD3D );
pHook->QueryInterface( IID_IDirect3DDevice3, reinterpret_cast< void ** >( ppD3D ) );
m_pDevice3 = *ppD3D;
return hRes;
}

View file

@ -0,0 +1,278 @@
// DirectDrawHook.h : Declaration of the CDirectDrawHook
#ifndef __DIRECTDRAWHOOK_H_
#define __DIRECTDRAWHOOK_H_
#include "resource.h" // main symbols
#include "Direct3DHook.h"
/////////////////////////////////////////////////////////////////////////////
// CDirectDrawHook
class ATL_NO_VTABLE CDirectDrawHook :
public CComObjectRootEx<CComMultiThreadModel>,
public IDirectDraw,
public IDirectDraw2,
public IDirectDraw4,
public IDirect3D,
public IDirect3D2,
public IDirect3D3
{
public:
CDirectDrawHook()
: m_pDevice2( NULL ),
m_pDevice3( NULL ), m_nSurfaceCount( 0 )
{
}
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CDirectDrawHook)
COM_INTERFACE_ENTRY_IID(IID_IDirectDraw, IDirectDraw)
COM_INTERFACE_ENTRY_IID(IID_IDirectDraw2, IDirectDraw2)
COM_INTERFACE_ENTRY_IID(IID_IDirectDraw4, IDirectDraw4)
COM_INTERFACE_ENTRY_IID(IID_IDirect3D, IDirect3D)
COM_INTERFACE_ENTRY_IID(IID_IDirect3D2, IDirect3D2)
COM_INTERFACE_ENTRY_IID(IID_IDirect3D3, IDirect3D3)
END_COM_MAP()
void setObject( IDirectDraw *pDD );
CComPtr< IDirectDraw > m_pDD;
CComPtr< IDirectDraw2 > m_pDD2;
CComPtr< IDirectDraw4 > m_pDD4;
CComPtr< IDirect3D > m_pD3D;
CComPtr< IDirect3D2 > m_pD3D2;
CComPtr< IDirect3D3 > m_pD3D3;
IDirect3DDevice2 *m_pDevice2;
IDirect3DDevice3 *m_pDevice3;
CComPtr< IDirectDrawSurface4 > m_pDDS4;
long m_nSurfaceCount;
public:
// IDirectDraw Methods
STDMETHOD(Compact)()
{
return m_pDD->Compact();
}
STDMETHOD(CreateClipper)(DWORD p1, LPDIRECTDRAWCLIPPER FAR *p2, IUnknown FAR *p3 )
{
return m_pDD->CreateClipper( p1, p2, p3 );
}
STDMETHOD(CreatePalette)(DWORD p1, LPPALETTEENTRY p2, LPDIRECTDRAWPALETTE FAR*p3, IUnknown FAR *p4 )
{
return m_pDD->CreatePalette( p1, p2, p3, p4 );
}
STDMETHOD(CreateSurface)(LPDDSURFACEDESC p1, LPDIRECTDRAWSURFACE FAR *p2, IUnknown FAR *p3 )
{
return m_pDD->CreateSurface( p1, p2, p3 );
}
STDMETHOD(DuplicateSurface)( LPDIRECTDRAWSURFACE p1, LPDIRECTDRAWSURFACE FAR *p2 )
{
return m_pDD->DuplicateSurface( p1, p2 );
}
STDMETHOD(EnumDisplayModes)( DWORD p1, LPDDSURFACEDESC p2, LPVOID p3, LPDDENUMMODESCALLBACK p4 )
{
return m_pDD->EnumDisplayModes( p1, p2, p3, p4 );
}
STDMETHOD(EnumSurfaces)(DWORD p1, LPDDSURFACEDESC p2, LPVOID p3, LPDDENUMSURFACESCALLBACK p4 )
{
return m_pDD->EnumSurfaces( p1, p2, p3, p4 );
}
STDMETHOD(FlipToGDISurface)()
{
return m_pDD4->FlipToGDISurface();
}
STDMETHOD(GetCaps)( LPDDCAPS p1, LPDDCAPS p2 )
{
return m_pDD4->GetCaps( p1, p2 );
}
STDMETHOD(GetDisplayMode)( LPDDSURFACEDESC p1 )
{
return m_pDD->GetDisplayMode( p1 );
}
STDMETHOD(GetFourCCCodes)(LPDWORD p1, LPDWORD p2 )
{
return m_pDD->GetFourCCCodes( p1, p2 );
}
STDMETHOD(GetGDISurface)(LPDIRECTDRAWSURFACE FAR *p1)
{
return m_pDD->GetGDISurface( p1 );
}
STDMETHOD(GetMonitorFrequency)(LPDWORD p1)
{
return m_pDD->GetMonitorFrequency( p1 );
}
STDMETHOD(GetScanLine)(LPDWORD p1)
{
return m_pDD->GetScanLine( p1 );
}
STDMETHOD(GetVerticalBlankStatus)(LPBOOL p1 )
{
return m_pDD->GetVerticalBlankStatus( p1 );
}
STDMETHOD(Initialize)(GUID FAR *p1)
{
return m_pDD->Initialize( p1 );
}
STDMETHOD(RestoreDisplayMode)()
{
return m_pDD->RestoreDisplayMode();
}
STDMETHOD(SetCooperativeLevel)(HWND p1, DWORD p2);
STDMETHOD(SetDisplayMode)(DWORD p1, DWORD p2, DWORD p3);
STDMETHOD(WaitForVerticalBlank)(DWORD p1, HANDLE p2 )
{
return m_pDD->WaitForVerticalBlank( p1, p2 );
}
/*** Added in the v2 interface ***/
STDMETHOD(GetAvailableVidMem)(LPDDSCAPS p1, LPDWORD p2, LPDWORD p3)
{
return m_pDD2->GetAvailableVidMem( p1, p2, p3 );
}
/*** Added in the V4 Interface ***/
STDMETHOD(GetAvailableVidMem)(LPDDSCAPS2 p1, LPDWORD p2, LPDWORD p3)
{
return m_pDD4->GetAvailableVidMem( p1, p2, p3 );
}
STDMETHOD(CreateSurface)(LPDDSURFACEDESC2 p1, LPDIRECTDRAWSURFACE4 FAR *p2, IUnknown FAR *p3);
STDMETHOD(DuplicateSurface)( LPDIRECTDRAWSURFACE4 p1, LPDIRECTDRAWSURFACE4 FAR *p2 )
{
return m_pDD4->DuplicateSurface( p1, p2 );
}
STDMETHOD(EnumDisplayModes)( DWORD p1, LPDDSURFACEDESC2 p2, LPVOID p3, LPDDENUMMODESCALLBACK2 p4 )
{
return m_pDD4->EnumDisplayModes( p1, p2, p3, p4 );
}
STDMETHOD(EnumSurfaces)(DWORD p1, LPDDSURFACEDESC2 p2, LPVOID p3, LPDDENUMSURFACESCALLBACK2 p4 )
{
return m_pDD4->EnumSurfaces( p1, p2, p3, p4 );
}
STDMETHOD(GetDisplayMode)( LPDDSURFACEDESC2 p1 )
{
return m_pDD4->GetDisplayMode( p1 );
}
STDMETHOD(GetGDISurface)(LPDIRECTDRAWSURFACE4 FAR *p1)
{
return m_pDD4->GetGDISurface( p1 );
}
STDMETHOD(GetSurfaceFromDC) (HDC p1, LPDIRECTDRAWSURFACE4 *p2)
{
return m_pDD4->GetSurfaceFromDC( p1, p2 );
}
STDMETHOD(RestoreAllSurfaces)()
{
return m_pDD4->RestoreAllSurfaces();
}
STDMETHOD(TestCooperativeLevel)()
{
return m_pDD4->TestCooperativeLevel();
}
STDMETHOD(GetDeviceIdentifier)(LPDDDEVICEIDENTIFIER p1, DWORD p2 )
{
return m_pDD4->GetDeviceIdentifier( p1, p2 );
}
// Methods for the IDirect3D Interface
STDMETHOD(Initialize)(REFCLSID p1)
{
return m_pD3D->Initialize( p1 );
}
STDMETHOD(EnumDevices)(LPD3DENUMDEVICESCALLBACK p1,LPVOID p2)
{
return m_pD3D->EnumDevices( p1, p2 );
}
STDMETHOD(CreateLight)(LPDIRECT3DLIGHT*p1,IUnknown*p2)
{
return m_pD3D->CreateLight( p1, p2 );
}
STDMETHOD(CreateMaterial)(LPDIRECT3DMATERIAL *p1,IUnknown *p2);
STDMETHOD(CreateViewport)(LPDIRECT3DVIEWPORT*p1,IUnknown*p2)
{
return m_pD3D->CreateViewport( p1, p2 );
}
STDMETHOD(FindDevice)(LPD3DFINDDEVICESEARCH p1,LPD3DFINDDEVICERESULT p2)
{
return m_pD3D->FindDevice( p1, p2 );
}
// Methods for the IDirect3D2 Interface
STDMETHOD(SetDisplayMode)(DWORD p1, DWORD p2, DWORD p3, DWORD p4, DWORD p5);
STDMETHOD(CreateMaterial)(LPDIRECT3DMATERIAL2*p1,IUnknown*p2);
STDMETHOD(CreateViewport)(LPDIRECT3DVIEWPORT2*p1,IUnknown*p2)
{
return m_pD3D2->CreateViewport( p1, p2 );
}
STDMETHOD(CreateDevice)(REFCLSID cls,LPDIRECTDRAWSURFACE pDDS,LPDIRECT3DDEVICE2 *ppD3D);
// Methods for the IDirect3D3 Interface
STDMETHOD(CreateMaterial)(LPDIRECT3DMATERIAL3*p1,LPUNKNOWN p2);
STDMETHOD(CreateViewport)(LPDIRECT3DVIEWPORT3*p1,LPUNKNOWN p2)
{
return m_pD3D3->CreateViewport( p1, p2 );
}
STDMETHOD(CreateDevice)(REFCLSID cls,LPDIRECTDRAWSURFACE4 pDDS,LPDIRECT3DDEVICE3* ppD3D,LPUNKNOWN pUnk);
STDMETHOD(CreateVertexBuffer)(LPD3DVERTEXBUFFERDESC p1,LPDIRECT3DVERTEXBUFFER*p2,DWORD p3,LPUNKNOWN p4)
{
return m_pD3D3->CreateVertexBuffer( p1, p2, p3, p4 );
}
STDMETHOD(EnumZBufferFormats)(REFCLSID p1,LPD3DENUMPIXELFORMATSCALLBACK p2,LPVOID p3)
{
return m_pD3D3->EnumZBufferFormats( p1, p2, p3 );
}
STDMETHOD(EvictManagedTextures)()
{
return m_pD3D3->EvictManagedTextures();
}
};
#endif //__DIRECTDRAWHOOK_H_

View file

@ -0,0 +1,85 @@
// DirectDrawSurfaceHook.cpp : Implementation of CDirectDrawSurfaceHook
#include "stdafx.h"
#include "Inject.h"
#include "DirectDrawSurfaceHook.h"
#include "InjectApi.h"
#include "Manager.h"
void CDirectDrawSurfaceHook::setObject( IUnknown *pDevice )
{
pDevice->QueryInterface( IID_IDirectDrawSurface, reinterpret_cast< void ** >( &m_pDDS ) );
pDevice->QueryInterface( IID_IDirectDrawSurface2, reinterpret_cast< void ** >( &m_pDDS2 ) );
pDevice->QueryInterface( IID_IDirectDrawSurface3, reinterpret_cast< void ** >( &m_pDDS3 ) );
pDevice->QueryInterface( IID_IDirectDrawSurface4, reinterpret_cast< void ** >( &m_pDDS4 ) );
}
void CDirectDrawSurfaceHook::setSurfaceNum( long nSurfaceNum )
{
m_nSurfaceNum = nSurfaceNum;
}
STDMETHODIMP CDirectDrawSurfaceHook::Blt(LPRECT p1,LPDIRECTDRAWSURFACE4 p2, LPRECT p3,DWORD p4, LPDDBLTFX p5)
{
// MessageBeep(0);
// MessageBox(0, "I AM FROM DIRECTDRAWSURFACEHOOK BLT", "YAY!", 0);
// cManager::_p->draw2D();
/* DDSURFACEDESC2 ddsd;
ddsd.dwSize = sizeof( DDSURFACEDESC2 );
m_pDDS4->GetSurfaceDesc( &ddsd );
*/
/* HANDLE hFile;
hFile = CreateFile("c:\\acpoo72.txt", GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
SetFilePointer(hFile, 0, 0, FILE_END);
DWORD lpbw;
char tmp[1024];
//if(p1 != NULL && p3 != NULL)
if(p5==NULL)
wsprintf(tmp, "%d left:%d top:%d right:%d bottom:%d -> left:%d top:%d right:%d bottom:%d\r\n", m_pDDS4, p1->left, p1->top, p1->right, p1->bottom, p3->left, p3->top, p3->right, p3->bottom);
WriteFile(hFile, tmp, strlen(tmp), &lpbw, NULL);
//WriteFile(hFile, (char*)(_bstr_t((long)ddsd.dwWidth) + _bstr_t("\r\n")), _bstr_t((long)ddsd.dwWidth).length() + 2, &lpbw, NULL);
CloseHandle(hFile);
*//*
if(p3!=NULL)
if(p3->right-p3->left==640)
MessageBeep(0);
*/
/* DDBLTFX ddbltfx;
ddbltfx.dwSize=sizeof(ddbltfx);
ddbltfx.dwFillColor=2;
HRESULT hRes = m_pDDS4->Blt(NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);*/
/* if(p3!=NULL)
if((p3->right-p3->left)==332)
MessageBox(0, _bstr_t(m_nSurfaceNum), "asd", 0);
*/
// MessageBeep(0);
//HRESULT hRes = m_pDDS4->Blt(p1, p2, p3, p4, p5);
// cManager::_p->draw2D();
// MessageBeep(0);
return m_pDDS4->Blt(p1, p2, p3, p4, p5);
// return 0;//hRes;
}
STDMETHODIMP CDirectDrawSurfaceHook::Flip( LPDIRECTDRAWSURFACE4 p1, DWORD p2)
{
/*
DDSURFACEDESC2 ddsd;
ddsd.dwSize = sizeof( DDSURFACEDESC2 );
m_pDDS4->GetSurfaceDesc( &ddsd );
HANDLE hFile;
hFile = CreateFile("c:\\acpoo4.txt", GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
SetFilePointer(hFile, 0, 0, FILE_END);
DWORD lpbw;
WriteFile(hFile, (char*)(_bstr_t((long)ddsd.dwWidth) + _bstr_t("\r\n")), _bstr_t((long)ddsd.dwWidth).length() + 2, &lpbw, NULL);
CloseHandle(hFile);*/
return m_pDDS4->Flip(p1, p2);
}

View file

@ -0,0 +1,879 @@
#ifndef __DIRECTDRAWSURFACEHOOK_H_
#define __DIRECTDRAWSURFACEHOOK_H_
#include "resource.h"
#define BEGIN_COM_MAP_EX(x) \
public: typedef x _ComMapClass; \
static HRESULT WINAPI _Cache(void* pv, REFIID iid, void** ppvObject, DWORD dw) \
{ \
_ComMapClass* p = (_ComMapClass*)pv; \
HRESULT hRes = CComObjectRootBase::_Cache(pv, iid, ppvObject, dw); \
return hRes; \
} \
IUnknown* _GetRawUnknown() \
{ ATLASSERT(_GetEntries()[0].pFunc == _ATL_SIMPLEMAPENTRY); return (IUnknown*)((int)this+_GetEntries()->dw); } \
_ATL_DECLARE_GET_UNKNOWN(x) \
HRESULT _InternalQueryInterface(REFIID iid, void** ppvObject) \
{ return InternalQueryInterface(this, _GetEntries(), iid, ppvObject); } \
const static _ATL_INTMAP_ENTRY* WINAPI _GetEntries() { \
static const _ATL_INTMAP_ENTRY _entries[] = { DEBUG_QI_ENTRY(x)
/*
#define BEGIN_COM_MAP(x) public: \
typedef x _ComMapClass; \
static HRESULT WINAPI _Cache(void* pv, REFIID iid, void** ppvObject, DWORD_PTR dw)\
{\
_ComMapClass* p = (_ComMapClass*)pv;\
p->Lock();\
HRESULT hRes = CComObjectRootBase::_Cache(pv, iid, ppvObject, dw);\
p->Unlock();\
return hRes;\
}\
IUnknown* _GetRawUnknown() \
{ ATLASSERT(_GetEntries()[0].pFunc == _ATL_SIMPLEMAPENTRY); return (IUnknown*)((DWORD_PTR)this+_GetEntries()->dw); } \
_ATL_DECLARE_GET_UNKNOWN(x)\
HRESULT _InternalQueryInterface(REFIID iid, void** ppvObject) \
{ return InternalQueryInterface(this, _GetEntries(), iid, ppvObject); } \
const static _ATL_INTMAP_ENTRY* WINAPI _GetEntries() { \
static const _ATL_INTMAP_ENTRY _entries[] = { DEBUG_QI_ENTRY(x)
/////
public: typedef CDirectDrawSurfaceHook _ComMapClass;
static HRESULT WINAPI _Cache(void* pv, REFIID iid, void** ppvObject, DWORD dw)
{
_ComMapClass* p = (_ComMapClass*)pv;
HRESULT hRes = CComObjectRootBase::_Cache(pv, iid, ppvObject, dw);
return hRes;
}
IUnknown* _GetRawUnknown()
{
ATLASSERT(_GetEntries()[0].pFunc == _ATL_SIMPLEMAPENTRY);
return (IUnknown*)((int)this+_GetEntries()->dw);
}
_ATL_DECLARE_GET_UNKNOWN(x)
HRESULT _InternalQueryInterface(REFIID iid, void** ppvObject)
{
return InternalQueryInterface(this, _GetEntries(), iid, ppvObject);
}
const static _ATL_INTMAP_ENTRY* WINAPI _GetEntries()
{
static const _ATL_INTMAP_ENTRY _entries[] = { DEBUG_QI_ENTRY(x)
/////
*/
class ATL_NO_VTABLE CDirectDrawSurfaceHook :
public CComObjectRootEx<CComMultiThreadModel>,
public IDirectDrawSurface,
public IDirectDrawSurface2,
public IDirectDrawSurface3,
public IDirectDrawSurface4
{
public:
CDirectDrawSurfaceHook()
{
}
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP_EX(CDirectDrawSurfaceHook)
COM_INTERFACE_ENTRY_IID( IID_IDirectDrawSurface, IDirectDrawSurface )
COM_INTERFACE_ENTRY_IID( IID_IDirectDrawSurface2, IDirectDrawSurface2 )
COM_INTERFACE_ENTRY_IID( IID_IDirectDrawSurface3, IDirectDrawSurface3 )
COM_INTERFACE_ENTRY_IID( IID_IDirectDrawSurface4, IDirectDrawSurface4 )
END_COM_MAP()
CComPtr< IDirectDrawSurface > m_pDDS;
CComPtr< IDirectDrawSurface2 > m_pDDS2;
CComPtr< IDirectDrawSurface3 > m_pDDS3;
CComPtr< IDirectDrawSurface4 > m_pDDS4;
void setObject( IUnknown *pDevice );
void setSurfaceNum( long nSurfaceNum );
long m_nSurfaceNum;
public:
/* IDirectDrawSurface */
STDMETHOD(AddAttachedSurface)(LPDIRECTDRAWSURFACE p1)
{
return m_pDDS->AddAttachedSurface(p1);
}
STDMETHOD(AddOverlayDirtyRect)(LPRECT p1)
{
return m_pDDS4->AddOverlayDirtyRect(p1);
//return m_pDDS->AddOverlayDirtyRect(p1);
}
STDMETHOD(Blt)(LPRECT p1,LPDIRECTDRAWSURFACE p2, LPRECT p3,DWORD p4, LPDDBLTFX p5)
{
return m_pDDS->Blt(p1, p2, p3, p4, p5);
}
STDMETHOD(BltBatch)(LPDDBLTBATCH p1, DWORD p2, DWORD p3)
{
return m_pDDS4->BltBatch(p1, p2, p3);
//return m_pDDS->BltBatch(p1, p2, p3);
}
STDMETHOD(BltFast)(DWORD p1,DWORD p2,LPDIRECTDRAWSURFACE p3, LPRECT p4,DWORD p5)
{
return m_pDDS->BltFast(p1,p2,p3,p4,p5);
}
STDMETHOD(DeleteAttachedSurface)(DWORD p1,LPDIRECTDRAWSURFACE p2)
{
return m_pDDS->DeleteAttachedSurface(p1,p2);
}
STDMETHOD(EnumAttachedSurfaces)(LPVOID p1,LPDDENUMSURFACESCALLBACK p2)
{
return m_pDDS->EnumAttachedSurfaces(p1, p2);
}
STDMETHOD(EnumOverlayZOrders)(DWORD p1,LPVOID p2,LPDDENUMSURFACESCALLBACK p3)
{
return m_pDDS->EnumOverlayZOrders(p1, p2, p3);
}
STDMETHOD(Flip)(LPDIRECTDRAWSURFACE p1, DWORD p2)
{
return m_pDDS->Flip(p1, p2);
}
STDMETHOD(GetAttachedSurface)(LPDDSCAPS p1, LPDIRECTDRAWSURFACE FAR *p2)
{
return m_pDDS->GetAttachedSurface(p1, p2);
}
STDMETHOD(GetBltStatus)(DWORD p1)
{
return m_pDDS4->GetBltStatus(p1);
} //turn m_pDDS->GetBltStatus(p1);
STDMETHOD(GetCaps)(LPDDSCAPS p1)
{
return m_pDDS->GetCaps(p1);
}
STDMETHOD(GetClipper)(LPDIRECTDRAWCLIPPER FAR* p1)
{
return m_pDDS4->GetClipper(p1);
//turn m_pDDS->GetClipper(p1);
}
STDMETHOD(GetColorKey)(DWORD p1, LPDDCOLORKEY p2)
{
return m_pDDS4->GetColorKey(p1, p2);
//return m_pDDS->GetColorKey(p1, p2);
}
STDMETHOD(GetDC)(HDC FAR *p1)
{
//MessageBox(0, "I gota DC", "asd", 0);
return m_pDDS4->GetDC(p1);
//return m_pDDS->GetDC(p1);
}
STDMETHOD(GetFlipStatus)(DWORD p1)
{
return m_pDDS4->GetFlipStatus(p1);
//return m_pDDS->GetFlipStatus(p1);
}
STDMETHOD(GetOverlayPosition)(LPLONG p1, LPLONG p2)
{
return m_pDDS4->GetOverlayPosition(p1, p2);
//return m_pDDS->GetOverlayPosition(p1, p2);
}
STDMETHOD(GetPalette)(LPDIRECTDRAWPALETTE FAR* p1)
{
return m_pDDS4->GetPalette(p1);
//return m_pDDS->GetPalette(p1);
}
STDMETHOD(GetPixelFormat)(LPDDPIXELFORMAT p1)
{
return m_pDDS4->GetPixelFormat(p1);
//return m_pDDS->GetPixelFormat(p1);
}
STDMETHOD(GetSurfaceDesc)(LPDDSURFACEDESC p1)
{
return m_pDDS->GetSurfaceDesc(p1);
}
STDMETHOD(Initialize)(LPDIRECTDRAW p1, LPDDSURFACEDESC p2)
{
return m_pDDS->Initialize(p1, p2);
}
STDMETHOD(IsLost)()
{
return m_pDDS4->IsLost();
//return m_pDDS->IsLost();
}
STDMETHOD(Lock)(LPRECT p1,LPDDSURFACEDESC p2,DWORD p3,HANDLE p4)
{
return m_pDDS->Lock(p1, p2, p3, p4);
}
STDMETHOD(ReleaseDC)(HDC p1)
{
return m_pDDS4->ReleaseDC(p1);
//return m_pDDS->ReleaseDC(p1);
}
STDMETHOD(Restore)()
{
return m_pDDS4->Restore();
//return m_pDDS->Restore();
}
STDMETHOD(SetClipper)(LPDIRECTDRAWCLIPPER p1)
{
return m_pDDS4->SetClipper(p1);
//return m_pDDS->SetClipper(p1);
}
STDMETHOD(SetColorKey)(DWORD p1, LPDDCOLORKEY p2)
{
return m_pDDS4->SetColorKey(p1, p2);
//return m_pDDS->SetColorKey(p1, p2);
}
STDMETHOD(SetOverlayPosition)(LONG p1, LONG p2)
{
return m_pDDS4->SetOverlayPosition(p1, p2);
//return m_pDDS->SetOverlayPosition(p1, p2);
}
STDMETHOD(SetPalette)(LPDIRECTDRAWPALETTE p1)
{
return m_pDDS4->SetPalette(p1);
//return m_pDDS->SetPalette(p1);
}
STDMETHOD(Unlock)(LPVOID p1)
{
return m_pDDS->Unlock(p1);
}
STDMETHOD(UpdateOverlay)(LPRECT p1, LPDIRECTDRAWSURFACE p2,LPRECT p3,DWORD p4, LPDDOVERLAYFX p5)
{
return m_pDDS->UpdateOverlay(p1,p2,p3,p4,p5);
}
STDMETHOD(UpdateOverlayDisplay)(DWORD p1)
{
return m_pDDS4->UpdateOverlayDisplay(p1);
//return m_pDDS->UpdateOverlayDisplay(p1);
}
STDMETHOD(UpdateOverlayZOrder)(DWORD p1, LPDIRECTDRAWSURFACE p2)
{
return m_pDDS->UpdateOverlayZOrder(p1, p2);
}
/* IDirectDrawSurface2*/
STDMETHOD(AddAttachedSurface)(LPDIRECTDRAWSURFACE2 p1)
{
return m_pDDS2->AddAttachedSurface(p1);
}
/*
STDMETHOD(AddOverlayDirtyRect)(LPRECT p1)
{
return m_pDDS2->AddOverlayDirtyRect(p1);
}
*/
STDMETHOD(Blt)(LPRECT p1,LPDIRECTDRAWSURFACE2 p2, LPRECT p3,DWORD p4, LPDDBLTFX p5)
{
return m_pDDS2->Blt(p1,p2,p3,p4,p5);
}
/* STDMETHOD(BltBatch)(LPDDBLTBATCH p1, DWORD p2, DWORD p3)
{
return m_pDDS2->BltBatch(p1,p2,p3);
}
*/
STDMETHOD(BltFast)(DWORD p1,DWORD p2,LPDIRECTDRAWSURFACE2 p3, LPRECT p4,DWORD p5)
{
return m_pDDS2->BltFast(p1,p2,p3,p4,p5);
}
STDMETHOD(DeleteAttachedSurface)(DWORD p1,LPDIRECTDRAWSURFACE2 p2)
{
return m_pDDS2->DeleteAttachedSurface(p1,p2);
}
/* STDMETHOD(EnumAttachedSurfaces)(LPVOID p1,LPDDENUMSURFACESCALLBACK p2)
{
return m_pDDS2->EnumAttachedSurfaces(p1,p2);
}
*/
/* STDMETHOD(EnumOverlayZOrders)(DWORD p1,LPVOID p2,LPDDENUMSURFACESCALLBACK p3)
{
return m_pDDS2->EnumOverlayZOrders(p1,p2,p3);
}
*/
STDMETHOD(Flip)(LPDIRECTDRAWSURFACE2 p1, DWORD p2)
{
return m_pDDS2->Flip(p1, p2);
}
STDMETHOD(GetAttachedSurface)(LPDDSCAPS p1, LPDIRECTDRAWSURFACE2 FAR *p2)
{
return m_pDDS2->GetAttachedSurface(p1, p2);
}
/* STDMETHOD(GetBltStatus)(DWORD p1)
{
return m_pDDS2->GetBltStatus(p1);
}
*/
/* STDMETHOD(GetCaps)(LPDDSCAPS p1)
{
return m_pDDS2->GetCaps(p1);
}
*/
/* STDMETHOD(GetClipper)(LPDIRECTDRAWCLIPPER FAR* p1)
{
return m_pDDS2->GetClipper(p1);
}
*/
/* STDMETHOD(GetColorKey)(DWORD p1, LPDDCOLORKEY p2)
{
return m_pDDS2->GetColorKey(p1, p2);
}
*/
/* STDMETHOD(GetDC)(HDC FAR *p1)
{
return m_pDDS2->GetDC(p1);
}
*/
/* STDMETHOD(GetFlipStatus)(DWORD p1)
{
return m_pDDS2->GetFlipStatus(p1);
}
*/
/* STDMETHOD(GetOverlayPosition)(LPLONG p1, LPLONG p2)
{
return m_pDDS2->GetOverlayPosition(p1,p2);
}
*/
/* STDMETHOD(GetPalette)(LPDIRECTDRAWPALETTE FAR* p1)
{
return m_pDDS2->GetPalette(p1);
}
*/
/* STDMETHOD(GetPixelFormat)(LPDDPIXELFORMAT p1)
{
return m_pDDS2->GetPixelFormat(p1);
}
*/
/* STDMETHOD(GetSurfaceDesc)(LPDDSURFACEDESC p1)
{
return m_pDDS2->GetSurfaceDesc(p1);
}
*/
/* STDMETHOD(Initialize)(LPDIRECTDRAW p1, LPDDSURFACEDESC p2)
{
return m_pDDS2->Initialize(p1, p2);
}
*/
/* STDMETHOD(IsLost)()
{
return m_pDDS2->IsLost();
}
*/
/* STDMETHOD(Lock)(LPRECT p1,LPDDSURFACEDESC p2,DWORD p3,HANDLE p4)
{
return m_pDDS2->Lock(p1, p2, p3, p4);
}
*/
/* STDMETHOD(ReleaseDC)(HDC p1)
{
return m_pDDS2->ReleaseDC(p1);
}
*/
/* STDMETHOD(Restore)()
{
return m_pDDS2->Restore();
}
*/
/* STDMETHOD(SetClipper)(LPDIRECTDRAWCLIPPER p1)
{
return m_pDDS2->SetClipper(p1);
}
*/
/* STDMETHOD(SetColorKey)(DWORD p1, LPDDCOLORKEY p2)
{
return m_pDDS2->SetColorKey(p1, p2);
}
*/
/* STDMETHOD(SetOverlayPosition)(LONG p1, LONG p2)
{
return m_pDDS2->SetOverlayPosition(p1, p2);
}
*/
/* STDMETHOD(SetPalette)(LPDIRECTDRAWPALETTE p1)
{
return m_pDDS2->SetPalette(p1);
}
*/
/* STDMETHOD(Unlock)(LPVOID p1)
{
return m_pDDS2->Unlock(p1);
}
*/
STDMETHOD(UpdateOverlay)(LPRECT p1, LPDIRECTDRAWSURFACE2 p2,LPRECT p3,DWORD p4, LPDDOVERLAYFX p5)
{
return m_pDDS2->UpdateOverlay(p1, p2, p3, p4, p5);
}
/* STDMETHOD(UpdateOverlayDisplay)(DWORD p1)
{
return m_pDDS2->UpdateOverlayDisplay(p1);
}
*/
STDMETHOD(UpdateOverlayZOrder)(DWORD p1, LPDIRECTDRAWSURFACE2 p2)
{
return m_pDDS2->UpdateOverlayZOrder(p1, p2);
}
STDMETHOD(GetDDInterface)(LPVOID FAR *p1)
{
return m_pDDS4->GetDDInterface(p1);
//return m_pDDS2->GetDDInterface(p1);
}
STDMETHOD(PageLock)(DWORD p1)
{
return m_pDDS4->PageLock(p1);
//return m_pDDS2->PageLock(p1);
}
STDMETHOD(PageUnlock)(DWORD p1)
{
return m_pDDS4->PageUnlock(p1);
//return m_pDDS2->PageUnlock(p1);
}
/* IDirectDrawSurface3 */
STDMETHOD(AddAttachedSurface)(LPDIRECTDRAWSURFACE3 p1)
{
return m_pDDS3->AddAttachedSurface(p1);
}
/* STDMETHOD(AddOverlayDirtyRect)(LPRECT p1)
{
return m_pDDS3->AddOverlayDirtyRect(p1);
}
*/
STDMETHOD(Blt)(LPRECT p1,LPDIRECTDRAWSURFACE3 p2, LPRECT p3,DWORD p4, LPDDBLTFX p5)
{
return m_pDDS3->Blt(p1,p2,p3,p4,p5);
}
/* STDMETHOD(BltBatch)(LPDDBLTBATCH p1, DWORD p2, DWORD p3)
{
return m_pDDS3->BltBatch(p1, p2, p3);
}
*/
STDMETHOD(BltFast)(DWORD p1,DWORD p2,LPDIRECTDRAWSURFACE3 p3, LPRECT p4,DWORD p5)
{
return m_pDDS3->BltFast(p1,p2,p3,p4,p5);
}
STDMETHOD(DeleteAttachedSurface)(DWORD p1,LPDIRECTDRAWSURFACE3 p2)
{
return m_pDDS3->DeleteAttachedSurface(p1,p2);
}
/* STDMETHOD(EnumAttachedSurfaces)(LPVOID p1,LPDDENUMSURFACESCALLBACK p2)
{
return m_pDDS3->EnumAttachedSurfaces(p1, p2);
}
*/
/* STDMETHOD(EnumOverlayZOrders)(DWORD p1,LPVOID p2,LPDDENUMSURFACESCALLBACK p3)
{
return m_pDDS3->EnumOverlayZOrders(p1,p2,p3);
}
*/
STDMETHOD(Flip)(LPDIRECTDRAWSURFACE3 p1, DWORD p2)
{
return m_pDDS3->Flip(p1,p2);
}
STDMETHOD(GetAttachedSurface)(LPDDSCAPS p1, LPDIRECTDRAWSURFACE3 FAR *p2)
{
return m_pDDS3->GetAttachedSurface(p1,p2);
}
/* STDMETHOD(GetBltStatus)(DWORD p1)
{
return m_pDDS3->GetBltStatus(p1);
}
*/
/* STDMETHOD(GetCaps)(LPDDSCAPS p1)
{
return m_pDDS3->GetCaps(p1);
}
*/
/* STDMETHOD(GetClipper)(LPDIRECTDRAWCLIPPER FAR* p1)
{
return m_pDDS3->GetClipper(p1);
}
*/
/* STDMETHOD(GetColorKey)(DWORD p1, LPDDCOLORKEY p2)
{
return m_pDDS3->GetColorKey(p1, p2);
}
*/
/* STDMETHOD(GetDC)(HDC FAR *p1)
{
return m_pDDS3->GetDC(p1);
}
*/
/* STDMETHOD(GetFlipStatus)(DWORD p1)
{
return m_pDDS3->GetFlipStatus(p1);
}
*/
/* STDMETHOD(GetOverlayPosition)(LPLONG p1, LPLONG p2)
{
return m_pDDS3->GetOverlayPosition(p1, p2);
}
*/
/* STDMETHOD(GetPalette)(LPDIRECTDRAWPALETTE FAR* p1)
{
return m_pDDS3->GetPalette(p1);
}
*/
/* STDMETHOD(GetPixelFormat)(LPDDPIXELFORMAT p1)
{
return m_pDDS3->GetPixelFormat(p1);
}
*/
/* STDMETHOD(GetSurfaceDesc)(LPDDSURFACEDESC p1)
{
return m_pDDS3->GetSurfaceDesc(p1);
}
*/
/* STDMETHOD(Initialize)(LPDIRECTDRAW p1, LPDDSURFACEDESC p2)
{
return m_pDDS3->Initialize(p1, p2);
}
*/
/* STDMETHOD(IsLost)()
{
return m_pDDS3->IsLost();
}
*/
/* STDMETHOD(Lock)(LPRECT p1,LPDDSURFACEDESC p2,DWORD p3,HANDLE p4)
{
return m_pDDS3->Lock(p1, p2, p3, p4);
}
*/
/* STDMETHOD(ReleaseDC)(HDC p1)
{
return m_pDDS3->ReleaseDC(p1);
}
*/
/* STDMETHOD(Restore)()
{
return m_pDDS3->Restore();
}
*/
/* STDMETHOD(SetClipper)(LPDIRECTDRAWCLIPPER p1)
{
return m_pDDS3->SetClipper(p1);
}
*/
/* STDMETHOD(SetColorKey)(DWORD p1, LPDDCOLORKEY p2)
{
return m_pDDS3->SetColorKey(p1, p2);
}
*/
/* STDMETHOD(SetOverlayPosition)(LONG p1, LONG p2)
{
return m_pDDS3->SetOverlayPosition(p1,p2);
}
*/
/* STDMETHOD(SetPalette)(LPDIRECTDRAWPALETTE p1)
{
return m_pDDS3->SetPalette(p1);
}
*/
/* STDMETHOD(Unlock)(LPVOID p1)
{
return m_pDDS3->Unlock(p1);
}
*/
STDMETHOD(UpdateOverlay)(LPRECT p1, LPDIRECTDRAWSURFACE3 p2, LPRECT p3,DWORD p4, LPDDOVERLAYFX p5)
{
return m_pDDS3->UpdateOverlay(p1,p2,p3,p4,p5);
}
/* STDMETHOD(UpdateOverlayDisplay)(DWORD p1)
{
return m_pDDS3->UpdateOverlayDisplay(p1);
}
*/
STDMETHOD(UpdateOverlayZOrder)(DWORD p1, LPDIRECTDRAWSURFACE3 p2)
{
return m_pDDS3->UpdateOverlayZOrder(p1, p2);
}
/* STDMETHOD(GetDDInterface)(LPVOID FAR *p1)
{
return m_pDDS3->GetDDInterface(p1);
}
*/
/* STDMETHOD(PageLock)(DWORD p1)
{
return m_pDDS3->PageLock(p1);
}
*/
/* STDMETHOD(PageUnlock)(DWORD p1)
{
return m_pDDS3->PageUnlock(p1);
}
*/
STDMETHOD(SetSurfaceDesc)(LPDDSURFACEDESC p1, DWORD p2)
{
return m_pDDS3->SetSurfaceDesc(p1, p2);
}
/* IDirectDrawSurface4 */
STDMETHOD(AddAttachedSurface)(LPDIRECTDRAWSURFACE4 p1)
{
return m_pDDS4->AddAttachedSurface(p1);
}
/* STDMETHOD(AddOverlayDirtyRect)(LPRECT p1)
{
return m_pDDS4->AddOverlayDirtyRect(p1);
}
*/
STDMETHOD(Blt)(LPRECT p1, LPDIRECTDRAWSURFACE4 p2, LPRECT p3, DWORD p4, LPDDBLTFX p5);
/* STDMETHOD(BltBatch)( LPDDBLTBATCH p1, DWORD p2, DWORD p3)
{
return m_pDDS4->BltBatch(p1, p2, p3);
}
*/
STDMETHOD(BltFast)( DWORD p1,DWORD p2,LPDIRECTDRAWSURFACE4 p3, LPRECT p4,DWORD p5)
{
MessageBeep(0);
return m_pDDS4->BltFast(p1, p2, p3, p4, p5);
}
STDMETHOD(DeleteAttachedSurface)( DWORD p1,LPDIRECTDRAWSURFACE4 p2)
{
return m_pDDS4->DeleteAttachedSurface(p1, p2);
}
STDMETHOD(EnumAttachedSurfaces)( LPVOID p1,LPDDENUMSURFACESCALLBACK2 p2)
{
return m_pDDS4->EnumAttachedSurfaces(p1, p2);
}
STDMETHOD(EnumOverlayZOrders)( DWORD p1,LPVOID p2,LPDDENUMSURFACESCALLBACK2 p3)
{
return m_pDDS4->EnumOverlayZOrders(p1, p2, p3);
}
STDMETHOD(Flip)( LPDIRECTDRAWSURFACE4 p1, DWORD p2);
STDMETHOD(GetAttachedSurface)( LPDDSCAPS2 p1, LPDIRECTDRAWSURFACE4 FAR *p2)
{
return m_pDDS4->GetAttachedSurface(p1, p2);
}
/* STDMETHOD(GetBltStatus)( DWORD p1)
{
return m_pDDS4->GetBltStatus(p1);
}
*/
STDMETHOD(GetCaps)( LPDDSCAPS2 p1)
{
return m_pDDS4->GetCaps(p1);
}
/* STDMETHOD(GetClipper)( LPDIRECTDRAWCLIPPER FAR* p1)
{
return m_pDDS4->GetClipper(p1);
}
*/
/* STDMETHOD(GetColorKey)( DWORD p1, LPDDCOLORKEY p2)
{
return m_pDDS4->GetColorKey(p1, p2);
}
*/
/* STDMETHOD(GetDC)( HDC FAR *p1)
{
return m_pDDS4->GetDC(p1);
}
*/
/* STDMETHOD(GetFlipStatus)( DWORD p1)
{
return m_pDDS4->GetFlipStatus(p1);
}
*/
/* STDMETHOD(GetOverlayPosition)( LPLONG p1, LPLONG p2)
{
return m_pDDS4->GetOverlayPosition(p1, p2);
}
*/
/* STDMETHOD(GetPalette)( LPDIRECTDRAWPALETTE FAR* p1)
{
return m_pDDS4->GetPalette(p1);
}
*/
/* STDMETHOD(GetPixelFormat)( LPDDPIXELFORMAT p1)
{
return m_pDDS4->GetPixelFormat(p1);
}
*/
STDMETHOD(GetSurfaceDesc)( LPDDSURFACEDESC2 p1)
{
return m_pDDS4->GetSurfaceDesc(p1);
}
STDMETHOD(Initialize)( LPDIRECTDRAW p1, LPDDSURFACEDESC2 p2)
{
return m_pDDS4->Initialize(p1, p2);
}
/* STDMETHOD(IsLost)()
{
return m_pDDS4->IsLost();
}
*/
STDMETHOD(Lock)(LPRECT p1,LPDDSURFACEDESC2 p2,DWORD p3,HANDLE p4)
{
return m_pDDS4->Lock(p1, p2, p3, p4);
}
/* STDMETHOD(ReleaseDC)( HDC p1)
{
return m_pDDS4->ReleaseDC(p1);
}
*/
/* STDMETHOD(Restore)()
{
return m_pDDS4->Restore();
}
*/
/* STDMETHOD(SetClipper)( LPDIRECTDRAWCLIPPER p1)
{
return m_pDDS4->SetClipper(p1);
}
*/
/* STDMETHOD(SetColorKey)( DWORD p1, LPDDCOLORKEY p2)
{
return m_pDDS4->SetColorKey(p1, p2);
}
*/
/* STDMETHOD(SetOverlayPosition)( LONG p1, LONG p2)
{
return m_pDDS4->SetOverlayPosition(p1, p2);
}
*/
/* STDMETHOD(SetPalette)( LPDIRECTDRAWPALETTE p1)
{
return m_pDDS4->SetPalette(p1);
}
*/
STDMETHOD(Unlock)(LPRECT p1)
{
return m_pDDS4->Unlock(p1);
}
STDMETHOD(UpdateOverlay)( LPRECT p1, LPDIRECTDRAWSURFACE4 p2,LPRECT p3,DWORD p4, LPDDOVERLAYFX p5)
{
return m_pDDS4->UpdateOverlay(p1, p2, p3, p4, p5);
}
/* STDMETHOD(UpdateOverlayDisplay)( DWORD p1)
{
return m_pDDS4->UpdateOverlayDisplay(p1);
}
*/
STDMETHOD(UpdateOverlayZOrder)( DWORD p1, LPDIRECTDRAWSURFACE4 p2)
{
return m_pDDS4->UpdateOverlayZOrder(p1, p2);
}
/* STDMETHOD(GetDDInterface)( LPVOID FAR *p1)
{
return m_pDDS4->GetDDInterface(p1);
}
*/
/* STDMETHOD(PageLock)( DWORD p1)
{
return m_pDDS4->PageLock(p1);
}
*/
/* STDMETHOD(PageUnlock)( DWORD p1)
{
return m_pDDS4->PageUnlock(p1);
}
*/
STDMETHOD(SetSurfaceDesc)( LPDDSURFACEDESC2 p1, DWORD p2)
{
return m_pDDS4->SetSurfaceDesc(p1, p2);
}
STDMETHOD(SetPrivateData)( REFGUID p1, LPVOID p2, DWORD p3, DWORD p4)
{
return m_pDDS4->SetPrivateData(p1, p2, p3, p4);
}
STDMETHOD(GetPrivateData)( REFGUID p1, LPVOID p2, LPDWORD p3)
{
return m_pDDS4->GetPrivateData(p1, p2, p3);
}
STDMETHOD(FreePrivateData)( REFGUID p1)
{
return m_pDDS4->FreePrivateData(p1);
}
STDMETHOD(GetUniquenessValue)( LPDWORD p1)
{
return m_pDDS4->GetUniquenessValue(p1);
}
STDMETHOD(ChangeUniquenessValue)()
{
return m_pDDS4->ChangeUniquenessValue();
}
};
#endif //__DIRECTDRAWSURFACEHOOK_H_

View file

@ -0,0 +1,26 @@
/* HANDLE hFile;
hFile = CreateFile("aclogs.txt", GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
SetFilePointer(hFile, 0, 0, FILE_END);
DWORD lpbw;
WriteFile(hFile, buf, iRes, &lpbw, NULL);
CloseHandle(hFile);*/
void InitManager()
{
cManager::_p->init();
return;
}
void TermManager()
{
cManager::_p->term();
return;
}
void SendOnMessage()
{
BYTE buf[] = { "\x07\xF4\x24\x00\x00\x00\x00\x80\x01\x00\x14\x00\x00\x00\x04\x00\xC7\xF7\x00\x00\xC8\xF7\x00\x00\x6D\x65\x2E\x20\x54\x68\x65\x20\x61\x72\x74\x69\x63\x6C\x65\x73" };
cManager::_p->m_stack.processPacket( static_cast< DWORD >( sizeof(buf) ), reinterpret_cast< BYTE * >( buf ) );
return;
}

284
Native/Inject/FontCache.cpp Normal file
View file

@ -0,0 +1,284 @@
// FontCache.cpp : Implementation of cFontCache
#include "stdafx.h"
#include "Inject.h"
#include "FontCache.h"
#include "Manager.h"
/////////////////////////////////////////////////////////////////////////////
// cFontCache
cFontCache::~cFontCache()
{
cManager::_p->removeFont( this );
}
#define BUFFER_WIDTHCHARS 32
#define BUFFER_HEIGHTCHARS 8
#define BUFFER_CHARCOUNT (BUFFER_WIDTHCHARS * BUFFER_HEIGHTCHARS)
bool cFontCache::checkBuffer()
{
if( m_pBuffer.p )
{
VARIANT_BOOL bWasLost;
m_pBuffer->get_WasLost( &bWasLost );
if( bWasLost )
m_pBuffer.Release();
}
if( m_pBuffer.p )
// The character buff is intact
return true;
// Get a dummy DC from the primary surface
CComPtr< ICanvas > pSurf;
if( FAILED(cManager::_p->GetPrimarySurface( &pSurf )) )
return false;
// Madar: This can happen if you set an edit-text during plugin initialization.
if (!pSurf)
{
return false;
}
HDC hdc;
pSurf->GetDC( &hdc );
// Drakier: reset error, try to create font, then check for error.
SetLastError(ERROR_SUCCESS);
HFONT hfnt = ::CreateFontIndirect( &m_lf );
if (GetLastError() != ERROR_SUCCESS)
{
_ASSERTE(GetLastError());
// Drakier: try arial instead
strcpy(m_lf.lfFaceName, "Arial");
SetLastError(ERROR_SUCCESS);
HFONT hfnt = ::CreateFontIndirect( &m_lf );
if (GetLastError() != ERROR_SUCCESS)
return false;
}
HFONT hfntOld = reinterpret_cast< HFONT >( ::SelectObject( hdc, hfnt ) );
TEXTMETRIC tm;
::GetTextMetrics( hdc, &tm );
m_szCharCell.cy = tm.tmHeight;
m_szCharCell.cx = tm.tmMaxCharWidth;
// Create the buffer
SIZE szBuffer = { m_szCharCell.cx * BUFFER_WIDTHCHARS, m_szCharCell.cy * BUFFER_HEIGHTCHARS };
cManager::_p->CreateCanvas( &szBuffer, &m_pBuffer );
INT widths[ BUFFER_CHARCOUNT ];
BOOL b = ::GetCharWidth( hdc, 0, ( BUFFER_CHARCOUNT - 1 ), widths );
_ASSERTE( b );
DWORD dwError = ::GetLastError();
for( short nChar = 0; nChar < BUFFER_CHARCOUNT; ++ nChar )
{
// TODO: Render the chars
// Figure out the character cell size
m_nWidths[ nChar ].m_nWidth = widths[ nChar ];
}
// TODO: Render all the chars into the buffer
::SelectObject( hdc, hfntOld );
::DeleteObject( hfnt );
pSurf->ReleaseDC();
return true;
}
STDMETHODIMP cFontCache::DrawText( LPPOINT ppt, BSTR strText, long clr, ICanvas *pCanvas )
{
/* _ASSERTE( ppt != NULL );
_ASSERTE( strText != NULL );
_ASSERTE( pCanvas != NULL );
if( !checkBuffer() )
return E_FAIL;
USES_CONVERSION;
LPCTSTR szText = OLE2T( strText );
// TODO: Draw this a lot faster from a cached bitmap value
HDC hdc;
pCanvas->GetDC( &hdc );
// Draw the text
HFONT hfnt = ::CreateFontIndirect( &m_lf ),
hfntOld = reinterpret_cast< HFONT >( ::SelectObject( hdc, hfnt ) );
::SetBkMode( hdc, TRANSPARENT );
::SetTextColor( hdc, clr );
::SetTextAlign( hdc, TA_TOP | TA_LEFT );
LPCSTR szAnsi = OLE2A( strText );
int cbLength = ::strlen( szAnsi );
INT *pDeltas = new INT[ cbLength ];
// Fill in the character deltas
const char *i_src = szAnsi;
INT *i_end_deltas = pDeltas + cbLength;
for( INT *i_delta = pDeltas; i_delta != i_end_deltas; ++ i_delta, ++ i_src )
*i_delta = m_nWidths[ *i_src ].m_nWidth;
if( m_bFontSmoothing )
SystemParametersInfo( SPI_SETFONTSMOOTHING, FALSE, NULL, 0 );
::ExtTextOut( hdc, ppt->x, ppt->y, 0, NULL, szAnsi, cbLength, pDeltas );
if( m_bFontSmoothing )
SystemParametersInfo( SPI_SETFONTSMOOTHING, TRUE, NULL, 0 );
delete[] pDeltas;
::SelectObject( hdc, hfntOld );
::DeleteObject( hfnt );
pCanvas->ReleaseDC();
return S_OK;*/
return DrawTextEx( ppt, strText, clr, 0, 0, pCanvas );
}
STDMETHODIMP cFontCache::DrawTextEx( LPPOINT ppt, BSTR strText, long clr1, long clr2, long lFlags, ICanvas *pCanvas )
{
_ASSERTE( ppt != NULL );
_ASSERTE( strText != NULL );
_ASSERTE( pCanvas != NULL );
if( !checkBuffer() )
return E_FAIL;
USES_CONVERSION;
LPCTSTR szText = OLE2T( strText );
// TODO: Draw this a lot faster from a cached bitmap value
HDC hdc;
pCanvas->GetDC( &hdc );
// Draw the text
// Drakier: reset error, try to create font, then check for error.
SetLastError(ERROR_SUCCESS);
HFONT hfnt = ::CreateFontIndirect( &m_lf );
if (GetLastError() != ERROR_SUCCESS)
{
_ASSERTE(GetLastError());
// Drakier: try arial instead
strcpy(m_lf.lfFaceName, "Arial");
SetLastError(ERROR_SUCCESS);
HFONT hfnt = ::CreateFontIndirect( &m_lf );
if (GetLastError() != ERROR_SUCCESS)
return E_FAIL;
}
HFONT hfntOld = reinterpret_cast< HFONT >( ::SelectObject( hdc, hfnt ) );
::SetBkMode( hdc, TRANSPARENT );
::SetTextAlign( hdc, TA_TOP | TA_LEFT );
LPCSTR szAnsi = OLE2A( strText );
int cbLength = ::strlen( szAnsi );
INT *pDeltas = new INT[ cbLength ];
// Fill in the character deltas
const char *i_src = szAnsi;
INT *i_end_deltas = pDeltas + cbLength;
for( INT *i_delta = pDeltas; i_delta != i_end_deltas; ++ i_delta, ++ i_src )
*i_delta = m_nWidths[ *i_src ].m_nWidth;
if( !(lFlags & eAA) )
if( m_bFontSmoothing )
SystemParametersInfo( SPI_SETFONTSMOOTHING, FALSE, NULL, 0 );
if( lFlags & eOutlined )
{
::SetTextColor( hdc, clr2 );
::ExtTextOut( hdc, ppt->x - 1, ppt->y - 1, 0, NULL, szAnsi, cbLength, pDeltas );
::ExtTextOut( hdc, ppt->x - 1, ppt->y + 1, 0, NULL, szAnsi, cbLength, pDeltas );
::ExtTextOut( hdc, ppt->x + 1, ppt->y - 1, 0, NULL, szAnsi, cbLength, pDeltas );
::ExtTextOut( hdc, ppt->x + 1, ppt->y + 1, 0, NULL, szAnsi, cbLength, pDeltas );
}
::SetTextColor( hdc, clr1 );
::ExtTextOut( hdc, ppt->x, ppt->y, 0, NULL, szAnsi, cbLength, pDeltas );
if( !(lFlags & eAA) )
if( m_bFontSmoothing )
SystemParametersInfo( SPI_SETFONTSMOOTHING, TRUE, NULL, 0 );
delete[] pDeltas;
::SelectObject( hdc, hfntOld );
::DeleteObject( hfnt );
pCanvas->ReleaseDC();
return S_OK;
}
STDMETHODIMP cFontCache::MeasureText( BSTR strText, LPSIZE pszExt )
{
_ASSERTE( strText != NULL );
_ASSERTE( pszExt != NULL );
if( !checkBuffer() )
return E_FAIL;
USES_CONVERSION;
LPCSTR szText = OLE2T( strText ),
i_end_text = szText + strlen( szText );
pszExt->cy = m_szCharCell.cy;
pszExt->cx = 0;
for( LPCSTR i_text = szText; i_text != i_end_text; ++ i_text )
pszExt->cx += m_nWidths[ *i_text ].m_nWidth;
return S_OK;
}
STDMETHODIMP cFontCache::HitTest(BSTR szText, long nPos, long *nIndex)
{
_ASSERTE( szText != NULL );
_ASSERTE( nIndex != NULL );
if( !checkBuffer() )
return E_FAIL;
USES_CONVERSION;
LPCSTR szAText = OLE2T( szText ),
i_end_text = szAText + strlen( szAText );
for( LPCSTR i_text = szAText; i_text != i_end_text; ++ i_text )
{
short nWidth = m_nWidths[ *i_text ].m_nWidth;
if( nPos < nWidth )
{
*nIndex = ( i_text - szAText );
return S_OK;
}
nPos -= nWidth;
}
*nIndex = -1;
return S_OK;
}

50
Native/Inject/FontCache.h Normal file
View file

@ -0,0 +1,50 @@
// FontCache.h : Declaration of the cFontCache
#ifndef __FONTCACHE_H_
#define __FONTCACHE_H_
#include "resource.h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// cFontCache
class ATL_NO_VTABLE cFontCache :
public CComObjectRootEx<CComMultiThreadModel>,
public IDispatchImpl< IFontCache, &IID_IFontCacheDisp, &LIBID_DecalPlugins >
{
public:
cFontCache()
{
m_bFontSmoothing = FALSE;
SystemParametersInfo( SPI_GETFONTSMOOTHING, 0, &m_bFontSmoothing, 0 );
}
~cFontCache();
struct cCharMetrics
{
short m_nWidth;
};
BOOL m_bFontSmoothing;
SIZE m_szCharCell;
cCharMetrics m_nWidths[ 256 ];
LOGFONT m_lf;
CComPtr< ICanvas > m_pBuffer;
bool checkBuffer();
BEGIN_COM_MAP(cFontCache)
COM_INTERFACE_ENTRY(IFontCache)
COM_INTERFACE_ENTRY(IFontCacheDisp)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
// IFontCache
public:
STDMETHOD(HitTest)(BSTR szText, long nPos, /*[out, retval]*/ long *nIndex);
STDMETHOD(MeasureText)( BSTR szText, /*[out]*/ LPSIZE pszExt );
STDMETHOD(DrawText)( LPPOINT pt, BSTR szText, long clr, ICanvas *pCanvas );
STDMETHOD(DrawTextEx)( LPPOINT pt, BSTR szText, long clr1, long clr2, long lFlags, ICanvas *pCanvas );
};
#endif //__FONTCACHE_H_

7
Native/Inject/Guids.cpp Normal file
View file

@ -0,0 +1,7 @@
#include <initguid.h>
#include <ddraw.h>
#include <d3d.h>
#define DIRECTINPUT_VERSION 0x600
#include <dinput.h>

View file

@ -0,0 +1,104 @@
extern void (*pfnOldChatMessage)(char*, unsigned long);
extern void (*pfnOldChatText)(void);
bool DispatchChatMessage ( char *pText, long *pdwColor );
bool DispatchChatText ( char *pText );
void __declspec(naked) OnChatMessage(char* pText, long dwColor)
{
/* __asm
{
//int 3
push ecx
push esi
lea esi, dwColor
push esi
push pText
call DispatchChatMessage
// Pop the two arguments
add esp, 8
test al, al
jz dont_kill_text
mov esi, pText
mov BYTE PTR [esi], 0
dont_kill_text:
pop esi
pop ecx
jmp pfnOldChatMessage
}*/
__asm
{
push ebp
mov ebp, esp
sub esp, 20h
push esi
push ecx
lea esi, dwColor
push esi
push pText
call DispatchChatMessage
add esp, 8
test al, al
jz dont_kill_text
mov DWORD PTR [pText], 0
dont_kill_text:
pop ecx
push dwColor
push pText
call pfnOldChatMessage
pop esi
mov esp, ebp
pop ebp
retn 8
}
}
void __declspec(naked) OnChatText()
{
__asm
{
push ebp
mov ebp, esp
sub esp, 0xC
call pfnOldChatText
mov [ebp-4], ecx
mov [ebp-8], eax
push eax
call DispatchChatText
mov edx, eax
mov ecx, [ebp-4]
mov eax, [ebp-8]
test dl, dl
jz dont_eat_chat_text
mov BYTE PTR [eax], 0
dont_eat_chat_text:
mov esp, ebp
pop ebp
ret
}
}

291
Native/Inject/IconCache.cpp Normal file
View file

@ -0,0 +1,291 @@
// IconCache.cpp : Implementation of cIconCache
#include "stdafx.h"
#include "Inject.h"
#include "IconCache.h"
#include "Manager.h"
//Moputu - 05172002: Added long lColor to make icons with different colored borders unique.
bool cIconCache::findIcon( HMODULE hMod, DWORD dwFile, cIconCache::cIconBuffer *&pBuffer, int &nIndex, long lColor )
{
for( cIconBufferList::iterator i = m_icons.begin(); i != m_icons.end(); )
{
VARIANT_BOOL bLost;
i->m_pSurface->get_WasLost( &bLost );
if( bLost )
{
i = m_icons.erase( i );
continue;
}
// Search inside this buffer
for( cIDList::iterator j = i->m_icons.begin(); j != i->m_icons.end(); ++ j )
{
//if( j->m_hMod == hMod && j->m_dwID == dwFile ) // Original Code
if( j->m_hMod == hMod && j->m_dwID == dwFile && j->m_lBColor == lColor )
{
// We found the icon, return happy
pBuffer = &( *i );
nIndex = j - i->m_icons.begin();
return true;
}
}
++ i;
}
// Icon not found
return false;
}
void cIconCache::findFreeSlot( cIconBuffer *&pBuffer, int &nIndex )
{
// First find a buffer with an unused icon slot, note that we test
// the buffers
for( cIconBufferList::iterator i = m_icons.begin(); i != m_icons.end(); )
{
VARIANT_BOOL bLost;
i->m_pSurface->get_WasLost( &bLost );
if( bLost )
{
i = m_icons.erase( i );
continue;
}
if( i->m_icons.size() < ( m_nEdge * m_nEdge ) )
break;
++ i;
}
if( i == m_icons.end() )
{
// There were no surfaces with free slots, make a new one
cIconBuffer buf;
buf.m_icons.reserve( m_nEdge * m_nEdge );
SIZE sz = { m_szIcon.cx * m_nEdge, m_szIcon.cy * m_nEdge };
cManager::_p->CreateCanvas( &sz, &buf.m_pSurface );
m_icons.push_back( buf );
// Reset to last entry
i = -- m_icons.end();
}
pBuffer = &( *i );
nIndex = i->m_icons.size();
}
//Modified by Moputu 05/12/2002 to allow the replacement of icon border colors.
bool cIconCache::loadIcon( DWORD dwFile, cIconCache::cIconBuffer *&pBuffer, int &nIndex, long lColor )
{
findFreeSlot( pBuffer, nIndex );
struct cColorImage
{
DWORD m_dwID,
m_dwX,
m_dwY;
};
try
{
cDatFile::cFile icon = cManager::_p->m_portal.getFile( dwFile );
cColorImage header;
icon.read( reinterpret_cast< BYTE * >( &header ), sizeof( cColorImage ) );
int nXScale, nYScale;
if( header.m_dwX % m_szIcon.cx != 0 )
{
// Bad size - only linear filtering here
_ASSERT( FALSE );
return false;
}
nXScale = header.m_dwX / m_szIcon.cx;
if( header.m_dwY % m_szIcon.cy != 0 )
{
// Bad size - only linear filtering here
_ASSERT( FALSE );
return false;
}
nYScale = header.m_dwY / m_szIcon.cy;
// Can't fail now, transfering bits to the buffer
POINT ptIconOrg = { ( nIndex % m_nEdge ) * m_szIcon.cx, ( nIndex / m_nEdge ) * m_szIcon.cy };
RECT rcSrc = { ptIconOrg.x, ptIconOrg.y, ptIconOrg.x + m_szIcon.cx, ptIconOrg.y + m_szIcon.cy };
DDSURFACEDESC2 desc;
desc.dwSize = sizeof( DDSURFACEDESC2 );
CComPtr< IDirectDrawSurface4 > pSurface;
pBuffer->m_pSurface->GetSurface( IID_IDirectDrawSurface4, reinterpret_cast< void ** >( &pSurface ) );
pSurface->Lock( &rcSrc, &desc, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY, NULL );
BYTE srcLine[ 3 * 64 ],
*pEndLine = srcLine + 3 * header.m_dwX;
{
for( int i = 0; i < m_szIcon.cy; ++ i )
{
// Read in a line
icon.read( srcLine, 3 * header.m_dwX );
icon.skip( 3 * header.m_dwX * ( nYScale - 1 ) );
WORD *pwDest = reinterpret_cast< WORD * >( reinterpret_cast< BYTE * >( desc.lpSurface ) + desc.lPitch * i );
for( BYTE *pbSrc = srcLine; pbSrc != pEndLine; pbSrc += 3 * nXScale, ++ pwDest )
{
// Check for black (transparent)
if( ( pbSrc[ 0 ] == 0 && pbSrc[ 1 ] == 0 && pbSrc[ 2 ] == 0 ) ||
( pbSrc[ 0 ] == 255 && pbSrc[ 1 ] == 255 && pbSrc[ 2 ] == 255 ) )
// *pwDest = 0x07FF; // Original code
if( pbSrc[ 0 ] == 255 && pbSrc[ 1 ] == 255 && pbSrc[ 2 ] == 255 ) //Check for White (border)
{
if ( lColor == -1 ) // No argument was passed, treat it like the original code would have.
{
*pwDest = 0x07FF;
}
else //Replace with specified color.
{
pBuffer->m_pSurface->DownMixRGB((BYTE)lColor, (BYTE)(lColor >> 8), (BYTE)(lColor >> 16), pwDest);
}
}
else
{
*pwDest = 0x07FF;
}
else
{
pBuffer->m_pSurface->DownMixRGB(pbSrc[0], pbSrc[1], pbSrc[2], pwDest);
}
}
}
}
pSurface->Unlock( &rcSrc );
cIconID iid = { NULL, dwFile, lColor }; //Moputu - 05172002: Added lColor to make icons with different colored borders unique.
pBuffer->m_icons.push_back( iid );
// Survived the encounter
return true;
}
catch( ... )
{
// Failure, return false at end
}
// File not found, fail
_ASSERT( FALSE );
return false;
}
bool cIconCache::loadIconResource( HMODULE hMod, DWORD dwResourceID, cIconBuffer *&pBuffer, int &nIndex, long lColor )
{
HICON hIcon = reinterpret_cast< HICON >( ::LoadImage( hMod, MAKEINTRESOURCE( dwResourceID ), IMAGE_ICON, m_szIcon.cx, m_szIcon.cy, LR_DEFAULTCOLOR ) );
if( hIcon == NULL )
return false;
findFreeSlot( pBuffer, nIndex );
// TODO: Write a fast version of this function, use GDI for now
HDC hdc;
pBuffer->m_pSurface->GetDC( &hdc );
HBRUSH br = ::CreateSolidBrush( RGB( 0, 255, 255 ) );
POINT ptIconOrg = { ( nIndex % m_nEdge ) * m_szIcon.cx, ( nIndex / m_nEdge ) * m_szIcon.cy };
RECT rcSrc = { ptIconOrg.x, ptIconOrg.y, ptIconOrg.x + m_szIcon.cx, ptIconOrg.y + m_szIcon.cy };
::FillRect( hdc, &rcSrc, br );
::DrawIconEx( hdc, ptIconOrg.x, ptIconOrg.y, hIcon, m_szIcon.cx, m_szIcon.cy, 0, NULL, DI_NORMAL );
::DeleteObject( br );
pBuffer->m_pSurface->ReleaseDC();
::DestroyIcon( hIcon );
cIconID iid = { hMod, dwResourceID, lColor }; //Moputu - 05172002: Added long lColor to make icons with different colored borders unique.
pBuffer->m_icons.push_back( iid );
return true;
}
void cIconCache::drawIcon( LPPOINT pPos, ICanvas *pDest, cIconBuffer *pBuffer, int nIndex )
{
_ASSERTE( pPos != NULL );
_ASSERTE( pDest != NULL );
_ASSERTE( pBuffer != NULL );
_ASSERTE( nIndex >= 0 && nIndex < ( m_nEdge * m_nEdge ) );
POINT ptIconOrg = { ( nIndex % m_nEdge ) * m_szIcon.cx, ( nIndex / m_nEdge ) * m_szIcon.cy };
RECT rcSrc = { ptIconOrg.x, ptIconOrg.y, ptIconOrg.x + m_szIcon.cx, ptIconOrg.y + m_szIcon.cy };
pDest->Blt( &rcSrc, pBuffer->m_pSurface, pPos );
}
/////////////////////////////////////////////////////////////////////////////
// cIconCache
STDMETHODIMP cIconCache::DrawIcon( LPPOINT ppt, long nFile, long nModule, ICanvas *pCanvas )
{
_ASSERTE( ppt != NULL );
_ASSERTE( pCanvas != NULL );
cIconBuffer *pBuffer;
int nIndex;
// GKusnick: Handle no-icon case without asserting.
if (nModule == 0 && nFile == 0) return S_OK;
if( !findIcon( reinterpret_cast< HMODULE >( nModule ), *reinterpret_cast< DWORD* >( &nFile ), pBuffer, nIndex ) )
{
if( nModule == 0 )
{
if( !loadIcon( *reinterpret_cast< DWORD* >( &nFile ), pBuffer, nIndex ) )
return E_FAIL;
}
else
{
if( !loadIconResource( reinterpret_cast< HMODULE >( nModule ), *reinterpret_cast< DWORD* >( &nFile ), pBuffer, nIndex ) )
return E_FAIL;
}
}
drawIcon( ppt, pCanvas, pBuffer, nIndex );
return S_OK;
}
STDMETHODIMP cIconCache::DrawIconEx( LPPOINT ppt, long nFile, long nModule, ICanvas *pCanvas, long lColor )
{
_ASSERTE( ppt != NULL );
_ASSERTE( pCanvas != NULL );
cIconBuffer *pBuffer;
int nIndex;
if( !findIcon( reinterpret_cast< HMODULE >( nModule ), *reinterpret_cast< DWORD* >( &nFile ), pBuffer, nIndex, lColor ) ) //Moputu - 05172002: Added long lColor to make icons with different colored borders unique.
{
if( nModule == 0 )
{
if( !loadIcon( *reinterpret_cast< DWORD* >( &nFile ), pBuffer, nIndex, lColor ) )
return E_FAIL;
}
else
{
if( !loadIconResource( reinterpret_cast< HMODULE >( nModule ), *reinterpret_cast< DWORD* >( &nFile ), pBuffer, nIndex, lColor ) ) //Moputu - 05172002: Added long lColor to make icons with different colored borders unique.
return E_FAIL;
}
}
drawIcon( ppt, pCanvas, pBuffer, nIndex );
return S_OK;
}

59
Native/Inject/IconCache.h Normal file
View file

@ -0,0 +1,59 @@
// IconCache.h : Declaration of the cIconCache
#ifndef __ICONCACHE_H_
#define __ICONCACHE_H_
#include "resource.h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// cIconCache
class ATL_NO_VTABLE cIconCache :
public CComObjectRootEx<CComMultiThreadModel>,
public IIconCache
{
public:
cIconCache()
{
}
SIZE m_szIcon;
long m_nEdge;
struct cIconID
{
HMODULE m_hMod;
DWORD m_dwID;
long m_lBColor; //Moputu - 05172002: Added to make icons with different colored bordered unique.
};
typedef std::vector< cIconID > cIDList;
class cIconBuffer
{
public:
cIDList m_icons;
CComPtr< ICanvas > m_pSurface;
};
typedef std::list< cIconBuffer > cIconBufferList;
cIconBufferList m_icons;
bool findIcon( HMODULE hMod, DWORD dwFile, cIconBuffer *&pBuffer, int &nIndex, long lColor = -1 ); //Moputu - 05172002: Added long lColor = -1 to make icons with different colored borders unique.
void findFreeSlot( cIconBuffer *&pBuffer, int &nIndex );
bool loadIcon( DWORD dwFile, cIconBuffer *&pBuffer, int &nIndex, long lColor = -1 );
bool loadIconResource( HMODULE hMod, DWORD dwResourceID, cIconBuffer *&pBuffer, int &nIndex, long lColor = -1 ); //Moputu - 05172002: Added long lColor = -1 to make icons with different colored borders unique.
void drawIcon( LPPOINT pPos, ICanvas *pDest, cIconBuffer *pBuffer, int nIndex );
BEGIN_COM_MAP(cIconCache)
COM_INTERFACE_ENTRY(IIconCache)
END_COM_MAP()
// IIconCache
public:
STDMETHOD(DrawIcon)( LPPOINT ppt, long nFile, long nModule, ICanvas *pTarget );
STDMETHOD(DrawIconEx)( LPPOINT ppt, long nFile, long nModule, ICanvas *pTarget, long lColor );
};
#endif //__ICONCACHE_H_

344
Native/Inject/Image.cpp Normal file
View file

@ -0,0 +1,344 @@
// Image.cpp : Implementation of cImage
#include "stdafx.h"
#include "Inject.h"
#include "Image.h"
#include "Manager.h"
/////////////////////////////////////////////////////////////////////////////
// cImage
cImage::~cImage()
{
cManager::_p->removeImage( this );
}
void cImage::loadFile()
{
// ::MessageBox( NULL, _T( "cImage::loadFile" ), _T( "Inject.dll" ), MB_OK );
HANDLE hBitmap = ::CreateFile( m_szFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL );
if( hBitmap == INVALID_HANDLE_VALUE )
{
int nError = ::GetLastError();
return;
}
BITMAPFILEHEADER bfh;
DWORD dwRead;
::ReadFile( hBitmap, &bfh, sizeof( BITMAPFILEHEADER ), &dwRead, NULL );
BITMAPINFOHEADER bih;
::ReadFile( hBitmap, &bih, sizeof( BITMAPINFOHEADER ), &dwRead, NULL );
RGBQUAD pal[ 256 ];
::memset( pal, 0, sizeof( RGBQUAD[ 256 ] ) );
// Figure out the number of colors used
int nEntries = 1 << ( bih.biBitCount );
if( bih.biClrUsed != 0 )
nEntries = bih.biClrUsed;
::ReadFile( hBitmap, pal, sizeof( RGBQUAD ) * nEntries, &dwRead, NULL );
SIZE szImage = { bih.biWidth, bih.biHeight };
cManager::_p->CreateCanvas( &szImage, &m_pImage );
CComPtr< IDirectDrawSurface4 > pSurface;
m_pImage->GetSurface( IID_IDirectDrawSurface4, reinterpret_cast< void ** >( &pSurface ) );
DDSURFACEDESC2 desc;
desc.dwSize = sizeof( DDSURFACEDESC2 );
pSurface->Lock( NULL, &desc, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY, NULL );
WORD wDownMixed[ 256 ];
RGBQUAD *pSrc = pal;
for( WORD *pDest = wDownMixed; pDest != wDownMixed + ( nEntries - 1 ); ++ pDest, ++ pSrc ) {
m_pImage->DownMixRGB(pSrc->rgbRed, pSrc->rgbGreen, pSrc->rgbBlue, pDest);
}
*pDest = 0x07FF;
// Mekle: Added the (bih.biWidth % 4) sections below, as BMP rows MUST end on a 32bit boundry
BYTE *pbSurf = reinterpret_cast< BYTE * >( desc.lpSurface ) + ( desc.dwHeight - 1 ) * desc.lPitch;
BYTE *pbRow = new BYTE[ bih.biWidth + (bih.biWidth % 4) ];
for( int nRow = 0; nRow < bih.biHeight; ++ nRow )
{
::ReadFile( hBitmap, pbRow, bih.biWidth + (bih.biWidth % 4), &dwRead, NULL );
WORD *pwDest = reinterpret_cast< WORD * >( pbSurf );
for( BYTE *pbSrc = pbRow; pbSrc != pbRow + bih.biWidth; ++ pbSrc, ++ pwDest )
// Lookup the color in the downmixed palette
*pwDest = wDownMixed[ *pbSrc ];
pbSurf -= desc.lPitch;
}
delete[] pbRow;
pSurface->Unlock( NULL );
::CloseHandle( hBitmap );
}
void cImage::loadResource()
{
}
void cImage::loadPortal()
{
// ::MessageBox( NULL, _T( "cImage::loadPortal" ), _T( "Inject.dll" ), MB_OK );
struct cColorImage
{
DWORD m_dwID,
m_dwX,
m_dwY;
};
try
{
cDatFile::cFile icon = cManager::_p->m_portal.getFile( m_dwID );
cColorImage header;
icon.read( reinterpret_cast< BYTE * >( &header ), sizeof( cColorImage ) );
SIZE szImage = { header.m_dwX, header.m_dwY };
cManager::_p->CreateCanvas( &szImage, &m_pImage );
CComPtr< IDirectDrawSurface4 > pSurface;
m_pImage->GetSurface( IID_IDirectDrawSurface4, reinterpret_cast< void ** >( &pSurface ) );
DDSURFACEDESC2 desc;
desc.dwSize = sizeof( DDSURFACEDESC2 );
pSurface->Lock( NULL, &desc, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY, NULL );
BYTE *pSrcLine = new BYTE[ 3 * header.m_dwX ],
*pEndLine = pSrcLine + 3 * header.m_dwX;
for( int i = 0; i < header.m_dwY; ++ i )
{
// Read in a line
icon.read( pSrcLine, 3 * header.m_dwX );
WORD *pwDest = reinterpret_cast< WORD * >( reinterpret_cast< BYTE * >( desc.lpSurface ) + desc.lPitch * i );
for( BYTE *pbSrc = pSrcLine; pbSrc != pEndLine; pbSrc += 3, ++ pwDest )
{
// Check for black (transparent)
if( pbSrc[ 0 ] == 0 && pbSrc[ 1 ] == 0 && pbSrc[ 2 ] == 0 )
*pwDest = 0x07FF;
else
{
// Downmix the pixel value
m_pImage->DownMixRGB(pbSrc[0], pbSrc[1], pbSrc[2], pwDest);
}
}
}
delete[] pSrcLine;
pSurface->Unlock( NULL );
}
catch( ... )
{
// Failure, file not found
}
}
bool cImage::testImage()
{
bool bReload = false;
if( m_pImage.p == NULL )
bReload = true;
else
{
VARIANT_BOOL bLost;
m_pImage->get_WasLost( &bLost );
if( bLost )
{
m_pImage.Release();
bReload = true;
}
}
if( bReload )
{
// Reload the image
switch( m_source )
{
case eFile:
loadFile();
break;
case eResource:
loadResource();
break;
case ePortal:
loadPortal();
break;
}
}
return ( m_pImage.p != NULL );
}
STDMETHODIMP cImage::PatBlt(ICanvas *pDest, LPRECT prcDest, LPPOINT ptOrigin)
{
// ::MessageBox( NULL, _T( "cImage::PatBlt" ), _T( "Inject.dll" ), MB_OK );
if( !testImage() )
return E_FAIL;
SIZE sz;
m_pImage->get_Size( &sz );
POINT ptAdjOrigin = { ptOrigin->x % sz.cx, ptOrigin->y % sz.cy };
if( ptAdjOrigin.x > 0 )
ptAdjOrigin.x -= sz.cx;
if( ptAdjOrigin.y > 0 )
ptAdjOrigin.y -= sz.cy;
RECT rcPlacement;
RECT rcSrc;
POINT ptSrcOrigin;
// Scan down
for( int y = prcDest->top + ptAdjOrigin.y; y < prcDest->bottom; y += sz.cy )
{
rcPlacement.top = y;
rcPlacement.bottom = y + sz.cy;
if( rcPlacement.top < prcDest->top )
rcPlacement.top = prcDest->top;
if( rcPlacement.bottom > prcDest->bottom )
rcPlacement.bottom = prcDest->bottom;
ptSrcOrigin.y = ( rcPlacement.top - prcDest->top - ptAdjOrigin.y ) % sz.cy;
rcSrc.top = ptSrcOrigin.y;
rcSrc.bottom = rcSrc.top + ( rcPlacement.bottom - rcPlacement.top );
// Scan across
for( int x = prcDest->left + ptAdjOrigin.x; x < prcDest->right; x += sz.cx )
{
rcPlacement.left = x;
rcPlacement.right = x + sz.cx;
if( rcPlacement.left < prcDest->left )
rcPlacement.left = prcDest->left;
if( rcPlacement.right > prcDest->right )
rcPlacement.right = prcDest->right;
ptSrcOrigin.x = ( rcPlacement.left - prcDest->left - ptAdjOrigin.x ) % sz.cx;
rcSrc.left = ptSrcOrigin.x;
rcSrc.right = rcSrc.left + ( rcPlacement.right - rcPlacement.left );
POINT pt = { rcPlacement.left, rcPlacement.top };
pDest->Blt( &rcSrc, m_pImage, &pt );
}
}
_ASSERTMEM( _CrtCheckMemory( ) );
return S_OK;
}
STDMETHODIMP cImage::StretchBlt(ICanvas *pDest, LPPOINT pptDest, long nWidth, long nStartStretch, long nEndStretch)
{
if( !testImage() )
return E_FAIL;
// Ok, the image is getting placed in three sections, fixed beginning and end
// and variable length middle sections (delimited by nStartStretch and nEndStretch)
// First we place the fixed beginning and end lengths
SIZE sz;
m_pImage->get_Size( &sz );
RECT rcSrcHead = { 0, 0, nStartStretch, sz.cy },
rcSrcTail = { nEndStretch, 0, sz.cx, sz.cy },
rcSrcMiddle = { nStartStretch, 0, nEndStretch, sz.cy };
int nTailPlacement = pptDest->x + nWidth - ( sz.cx - nEndStretch );
POINT ptHead = { pptDest->x, pptDest->y },
ptTail = { nTailPlacement, pptDest->y },
ptStretch = { 0, pptDest->y };
// Do the first Blts
pDest->Blt( &rcSrcHead, m_pImage, &ptHead );
pDest->Blt( &rcSrcTail, m_pImage, &ptTail );
// Now do the middle sections
for( ptStretch.x = pptDest->x + nStartStretch; ptStretch.x < nTailPlacement; ptStretch.x += ( nEndStretch - nStartStretch ) )
{
if( ( nTailPlacement - ptStretch.x ) < ( rcSrcMiddle.right - rcSrcMiddle.left ) )
rcSrcMiddle.right = rcSrcMiddle.left + ( nTailPlacement - ptStretch.x );
pDest->Blt( &rcSrcMiddle, m_pImage, &ptStretch );
}
return S_OK;
}
STDMETHODIMP cImage::Blt(LPRECT rcSrc, ICanvas *pDest, LPPOINT pptDest)
{
if( !testImage() )
return E_FAIL;
SIZE sz;
m_pImage->get_Size( &sz );
RECT rcImage = { 0, 0, sz.cx, sz.cy };
pDest->Blt( &rcImage, m_pImage, pptDest );
return S_OK;
}
STDMETHODIMP cImage::get_Size(SIZE *pVal)
{
if( !testImage() )
return E_FAIL;
m_pImage->get_Size( pVal );
return S_OK;
}
STDMETHODIMP cImage::StretchBltArea(LPRECT prcSrc, ICanvas *pDest, LPRECT prcDest)
{
if( !testImage() )
return E_FAIL;
SIZE sizeImage;
get_Size( &sizeImage );
if( prcSrc->right > sizeImage.cx )
prcSrc->right = sizeImage.cx ;
if( prcSrc->bottom > sizeImage.cy )
prcSrc->bottom = sizeImage.cy;
if( prcSrc->left < 0 )
prcSrc->left = 0;
if( prcSrc->top < 0 )
prcSrc->top = 0;
if( prcSrc->left >= prcSrc->right )
prcSrc->left = prcSrc->right - 1;
if( prcSrc->top >= prcSrc->bottom )
prcSrc->top = prcSrc->bottom - 1;
pDest->StretchBlt( prcSrc, m_pImage, prcDest );
return S_OK;
}

56
Native/Inject/Image.h Normal file
View file

@ -0,0 +1,56 @@
// Image.h : Declaration of the cImage
#ifndef __IMAGE_H_
#define __IMAGE_H_
#include "resource.h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// cImage
class ATL_NO_VTABLE cImage :
public CComObjectRootEx<CComMultiThreadModel>,
public IDispatchImpl< IImageCache, &IID_IImageCacheDisp, &LIBID_DecalPlugins >
{
public:
cImage()
{
}
~cImage();
enum eSourceType
{
eFile,
eResource,
ePortal
};
eSourceType m_source;
TCHAR m_szFilename[ MAX_PATH ];
HMODULE m_hLibrary;
DWORD m_dwID;
CComPtr< ICanvas > m_pImage;
void loadFile();
void loadResource();
void loadPortal();
bool testImage();
BEGIN_COM_MAP(cImage)
COM_INTERFACE_ENTRY(IImageCache)
COM_INTERFACE_ENTRY(IImageCacheDisp)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
// IImage
public:
STDMETHOD(get_Size)(/*[out, retval]*/ SIZE *pVal);
STDMETHOD(Blt)(LPRECT rcSrc, ICanvas *pDest, LPPOINT pptDest);
STDMETHOD(StretchBlt)(ICanvas *pDest, LPPOINT pptDest, long nWidth, long nStartStretch, long nEndStretch);
STDMETHOD(PatBlt)(ICanvas *pDest, LPRECT prcDest, LPPOINT ptOrigin);
STDMETHOD(StretchBltArea)(LPRECT prcSrc, ICanvas *pDest, LPRECT prcDest);
};
#endif //__IMAGE_H_

1029
Native/Inject/Inject.cpp Normal file

File diff suppressed because it is too large Load diff

24
Native/Inject/Inject.def Normal file
View file

@ -0,0 +1,24 @@
; Inject.def : Declares the module parameters.
LIBRARY "Inject.DLL"
SECTIONS
.InjectDll READ WRITE SHARED
EXPORTS
DllCanUnloadNow PRIVATE
DllGetClassObject PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
Container_Initialize @6
Container_StartPlugins @7
Container_StopPlugins @8
Container_Terminate @9
Container_SetSurface @10
Container_Draw @11
XMLViewer_Initialize @12
XMLViewer_LoadView @13
XMLViewer_RemoveView @14
XMLViewer_Terminate @15
XMLViewer_Draw @16

401
Native/Inject/Inject.dsp Normal file
View file

@ -0,0 +1,401 @@
# Microsoft Developer Studio Project File - Name="Inject" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=Inject - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "Inject.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "Inject.mak" CFG="Inject - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Inject - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "Inject - Win32 Release MinDependency" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "Inject - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "..\Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /Gi /GX /ZI /Od /I "..\Include" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "INJECT_IMPL" /Yu"stdafx.h" /FD /GZ /c
# SUBTRACT CPP /u
# ADD MTL /nologo /I "..\Include" /Oicf
# ADD BASE RSC /l 0x1009 /d "_DEBUG"
# ADD RSC /l 0x1009 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ddraw.lib winmm.lib ws2_32.lib version.lib /nologo /subsystem:windows /dll /debug /machine:I386
# Begin Custom Build - Performing registration
OutDir=.\..\Debug
TargetPath=\Code\source\Debug\Inject.dll
InputPath=\Code\source\Debug\Inject.dll
SOURCE="$(InputPath)"
"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
regsvr32 /s /c "$(TargetPath)"
echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg"
# End Custom Build
!ELSEIF "$(CFG)" == "Inject - Win32 Release MinDependency"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "ReleaseMinDependency"
# PROP BASE Intermediate_Dir "ReleaseMinDependency"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "..\Release"
# PROP Intermediate_Dir "ReleaseMinDependency"
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "_ATL_STATIC_REGISTRY" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /MD /W3 /GX /Zi /Oa /Og /Oi /Os /Oy /Ob1 /Gf /Gy /I "..\Include" /D "INJECT_IMPL" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Yu"stdafx.h" /FD /c
# SUBTRACT CPP /u
# ADD MTL /nologo /I "..\Include" /Oicf
# ADD BASE RSC /l 0x1009 /d "NDEBUG"
# ADD RSC /l 0x1009 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ddraw.lib winmm.lib ws2_32.lib version.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"..\Release"
# SUBTRACT LINK32 /nodefaultlib
# Begin Custom Build - Performing registration
OutDir=.\..\Release
TargetPath=\Code\source\Release\Inject.dll
InputPath=\Code\source\Release\Inject.dll
SOURCE="$(InputPath)"
"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
regsvr32 /s /c "$(TargetPath)"
echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg"
# End Custom Build
!ENDIF
# Begin Target
# Name "Inject - Win32 Debug"
# Name "Inject - Win32 Release MinDependency"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\BarLayer.cpp
# End Source File
# Begin Source File
SOURCE=.\Button.cpp
# End Source File
# Begin Source File
SOURCE=.\Canvas.cpp
# End Source File
# Begin Source File
SOURCE=.\DatFile.cpp
# End Source File
# Begin Source File
SOURCE=.\Direct3DHook.cpp
# End Source File
# Begin Source File
SOURCE=.\DirectDrawHook.cpp
# End Source File
# Begin Source File
SOURCE=.\DirectDrawSurfaceHook.cpp
# End Source File
# Begin Source File
SOURCE=.\FontCache.cpp
# End Source File
# Begin Source File
SOURCE=.\Guids.cpp
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# Begin Source File
SOURCE=.\IconCache.cpp
# End Source File
# Begin Source File
SOURCE=.\Image.cpp
# End Source File
# Begin Source File
SOURCE=.\Inject.cpp
# End Source File
# Begin Source File
SOURCE=.\Inject.def
# End Source File
# Begin Source File
SOURCE=.\Inject.idl
# ADD MTL /tlb ".\Inject.tlb" /h "Inject.h" /iid "Inject_i.c" /Oicf
# End Source File
# Begin Source File
SOURCE=.\Inject.rc
# End Source File
# Begin Source File
SOURCE=.\InjectService.cpp
# End Source File
# Begin Source File
SOURCE=.\InputBuffer.cpp
# End Source File
# Begin Source File
SOURCE=.\LayerSite.cpp
# End Source File
# Begin Source File
SOURCE=.\Manager.cpp
# End Source File
# Begin Source File
SOURCE=.\MaterialHook.cpp
# End Source File
# Begin Source File
SOURCE=.\Pager.cpp
# End Source File
# Begin Source File
SOURCE=.\Panel.cpp
# End Source File
# Begin Source File
SOURCE=.\PluginAdapterV1.cpp
# End Source File
# Begin Source File
SOURCE=.\RootLayer.cpp
# End Source File
# Begin Source File
SOURCE=.\SimpleBar.cpp
# End Source File
# Begin Source File
SOURCE=.\SinkImpl.cpp
# End Source File
# Begin Source File
SOURCE=.\SolidImage.cpp
# End Source File
# Begin Source File
SOURCE=.\StdAfx.cpp
# ADD CPP /Yc"stdafx.h"
# End Source File
# Begin Source File
SOURCE=.\View.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\BarLayer.h
# End Source File
# Begin Source File
SOURCE=.\Button.h
# End Source File
# Begin Source File
SOURCE=.\Canvas.h
# End Source File
# Begin Source File
SOURCE=.\DatFile.h
# End Source File
# Begin Source File
SOURCE=.\Direct3DHook.h
# End Source File
# Begin Source File
SOURCE=.\DirectDrawHook.h
# End Source File
# Begin Source File
SOURCE=.\DirectDrawSurfaceHook.h
# End Source File
# Begin Source File
SOURCE=.\EventsImpl.h
# End Source File
# Begin Source File
SOURCE=.\FontCache.h
# End Source File
# Begin Source File
SOURCE=.\IconCache.h
# End Source File
# Begin Source File
SOURCE=.\Image.h
# End Source File
# Begin Source File
SOURCE=.\InjectApi.h
# End Source File
# Begin Source File
SOURCE=.\InjectCP.h
# End Source File
# Begin Source File
SOURCE=.\InjectService.h
# End Source File
# Begin Source File
SOURCE=.\InputBuffer.h
# End Source File
# Begin Source File
SOURCE=.\LayerSite.h
# End Source File
# Begin Source File
SOURCE=.\Manager.h
# End Source File
# Begin Source File
SOURCE=.\MaterialHook.h
# End Source File
# Begin Source File
SOURCE=.\Pager.h
# End Source File
# Begin Source File
SOURCE=.\Panel.h
# End Source File
# Begin Source File
SOURCE=.\Plugin2Impl.h
# End Source File
# Begin Source File
SOURCE=.\PluginAdapterV1.h
# End Source File
# Begin Source File
SOURCE=.\PluginImpl.h
# End Source File
# Begin Source File
SOURCE=.\Resource.h
# End Source File
# Begin Source File
SOURCE=.\RootLayer.h
# End Source File
# Begin Source File
SOURCE=.\SimpleBar.h
# End Source File
# Begin Source File
SOURCE=.\SinkImpl.h
# End Source File
# Begin Source File
SOURCE=.\SolidImage.h
# End Source File
# Begin Source File
SOURCE=.\StdAfx.h
# End Source File
# Begin Source File
SOURCE=.\View.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=.\Button.rgs
# End Source File
# Begin Source File
SOURCE=.\res\DenAgent.ico
# End Source File
# Begin Source File
SOURCE=.\InjectService.rgs
# End Source File
# Begin Source File
SOURCE=.\InputBuffer.rgs
# End Source File
# Begin Source File
SOURCE=.\MessageStruct.rgs
# End Source File
# Begin Source File
SOURCE=.\MessageVector.rgs
# End Source File
# Begin Source File
SOURCE=.\Pager.rgs
# End Source File
# Begin Source File
SOURCE=.\PluginAdapterV1.rgs
# End Source File
# Begin Source File
SOURCE=.\SolidImage.rgs
# End Source File
# End Group
# End Target
# End Project

960
Native/Inject/Inject.idl Normal file
View file

@ -0,0 +1,960 @@
// Inject.idl : IDL source for Inject.dll
//
// This file will be processed by the MIDL tool to
// produce the type library (Inject.tlb) and marshalling code.
import "oaidl.idl";
import "ocidl.idl";
import "decal.idl";
import "unknwn.idl";
interface IBarManager;
interface ILayerSite;
interface IIconCache;
interface IImageCache;
interface IFontCache;
interface ISimpleBar;
interface ICanvas;
interface IView;
interface ILayer;
interface IPanelSink;
interface IInputBuffer;
struct ClipParams
{
RECT window;
POINT org;
VARIANT_BOOL visible;
};
enum eAlphaBlendOptions
{
eAlphaBlendSoftware = 0x01,
eAlphaBlendGDIPlus = 0x02
};
enum eRenderOptions
{
eRenderClipped = 0x01,
eRenderNext = 0x02,
eRenderTransparent = 0x08,
eRenderReformatNext = 0x20
};
enum eViewFlags
{
eTransparent = 0x01,
};
enum eFontOptions
{
eFontBold = 0x01,
eFontItalic = 0x02,
eFontUnderline = 0x04
};
enum eFontJustify
{
eFontLeft,
eFontRight,
eFontCenter
};
enum eDrawTextExFlags
{
eAA = 0x1,
eOutlined = 0x2,
};
enum eDefaultControlType
{
eCtlButton,
eCtlPager
};
enum ePositionType
{
ePositionByIndex,
ePositionByID
};
enum eMinMaxState
{
eStateMax = 0,
eStateMin = 1
};
enum eCombatState
{
ePeace = 1,
eMelee = 2,
eMissile = 3,
eMagic = 4
};
struct LayerParams
{
long ID;
RECT pos;
long render;
};
struct ViewParams
{
long icon;
long iconLibrary;
BSTR label;
long left;
long top;
long width;
long height;
long alpha;
long state;
};
struct MouseState
{
ILayer *over;
POINT screen,
client;
VARIANT_BOOL ctrl;
VARIANT_BOOL shift;
};
struct KeyState
{
short vkey;
VARIANT_BOOL ctrl;
VARIANT_BOOL shift;
};
enum eMouseInput
{
eMouseLeftClick,
eMouseRightClick,
eMouseLeftDoubleClick,
eMouseRightDoubleClick
};
enum eInputStatus
{
eInputIdle,
eInputWaiting,
eInputRunning,
eInputPaused
};
enum eManagerSinkCaps
{
eManagerSinkCapWindowMessage = 0x01,
eManagerSinkCapPlugin = 0x02,
eManagerSinkCapRender = 0x04,
eManagerSinkCapRender3D = 0x08,
};
[
object,
uuid(702D3901-C13A-448e-8871-ECDC8BC8D079),
helpstring("Interface passed to plugins for access to global services."),
pointer_default(unique)
]
interface IPluginSite : IUnknown
{
[helpstring("Unloads a plugin by ID - used by plugins that want to unload themselves")] HRESULT UnloadPlugin(long nID);
[helpstring("The DirectDraw object used by AC")] HRESULT GetDirectDraw(REFIID iid, [iid_is(iid)] void **ppvItf);
[helpstring("The current surface used for 3d drawing - the offscreen buff in windowed mode or the backbuffer in fullscreen mode")] HRESULT GetPrimarySurface([out, retval] ICanvas **ppPrimary);
[helpstring("The Direct3DDevice used by AC")] HRESULT Get3DDevice(REFIID iid, [iid_is(iid)] void **ppvItf);
[helpstring("Loads a bitmap into a surface from a file. Do not use of measure the bitmap until in a rendering pass.")] HRESULT LoadBitmapFile(BSTR strFilename, [out, retval] IImageCache **ppImage);
[helpstring("Returns an icon cache for a particular size")] HRESULT GetIconCache(LPSIZE psz, [out, retval] IIconCache **ppCache);
[helpstring("Loads a bitmap into a surface directly from portal.dat. Do not use of measure the bitmap until in a rendering pass.")] HRESULT LoadBitmapPortal(long nFile, IImageCache **);
[helpstring("Create a cached font for drawing and measuring text")] HRESULT CreateFont(BSTR szFaceName, long nHeight, long dwFlags, [out, retval] IFontCache **ppFont);
[helpstring("Returns the current resolution, in windowed mode it is the client area")] HRESULT GetScreenSize(LPSIZE sz);
[helpstring("Creates an offscreen buffer for drawing. Drawing is not guaranteed to be successful outside of the rendering pass.")] HRESULT CreateCanvas(LPSIZE psz, [out, retval] ICanvas **ppCanvas);
[helpstring("Creates a new view (icon and panel surface) using the control as the panel root")] HRESULT CreateView(struct ViewParams *pParams, ILayer *pLayer, [out, retval] IView **ppView);
[helpstring("Creates a new view from a view schema, if the text is an XML document (beginning with <?xml version=\"1.0\"?>) it is loaded directly, otherwise it is interpretted as a moniker (file or URL source).")] HRESULT LoadView(BSTR strSchema, [out, retval] IView **ppView);
[helpstring("method CreateBrushImage")] HRESULT CreateBrushImage(long nColor, [out, retval] IImageCache **ppImg);
[helpstring("method LoadImageSchema")] HRESULT LoadImageSchema(IUnknown *pSchema, [out, retval] IImageCache **ppImg);
[helpstring("method CreateFontSchema")] HRESULT CreateFontSchema(long nDefHeight, long nDefOptions, IUnknown *pSchema, [out, retval] IFontCache **ppCache);
[helpstring("method LoadResourceModule")] HRESULT LoadResourceModule(BSTR strLibrary, [out, retval] long *pnModule);
[propget, helpstring("property ResourcePath")] HRESULT ResourcePath([out, retval] BSTR *pVal);
[propget, helpstring("property Plugin")] HRESULT Plugin(BSTR strProgID, [out, retval] LPDISPATCH *pVal);
[propget, helpstring("property NetworkFilter")] HRESULT NetworkFilter(BSTR strProgID, [out, retval] LPDISPATCH *pVal);
[helpstring("method LoadViewObject")] HRESULT LoadViewObject(IUnknown *pSchema, [out, retval] IView **ppView);
[helpstring("method CreateInputBuffer")] HRESULT CreateInputBuffer([out, retval] IInputBuffer **ppInput);
[propget, helpstring("property HWND")] HRESULT HWND([out, retval] long *pVal);
[propget, helpstring("property Focus")] HRESULT Focus([out, retval] VARIANT_BOOL *pVal);
[propget, helpstring("property OldWndProc")] HRESULT OldWndProc([out, retval] long *pOldWndProc);
[propput, helpstring("property Current Selection")] HRESULT CurrentSelection([in] long nID);
[propget, helpstring("property Current Selection")] HRESULT CurrentSelection([out, retval] long *nID);
[propput, helpstring("property Previous Selection")] HRESULT PreviousSelection([in] long nID);
[propget, helpstring("property Previous Selection")] HRESULT PreviousSelection([out, retval] long *nID);
[helpstring("Writes text to AC's Chat Window")] HRESULT WriteToChatWindow(BSTR szText, [defaultvalue(0)] long lColor);
[helpstring("Sets the Current Mouse Position")] HRESULT SetCursorPosition(long x, long y);
[helpstring("Gets a key's binding from the current keymap")] HRESULT QueryKeyboardMap([in] BSTR bstrName, [out, retval] long *pAsciiVal);
[helpstring("Gets known MemLocs from the xml.")] HRESULT QueryMemLoc([in] BSTR bstrName, [out, retval] long *pVal);
[helpstring("Writes raw text to AC's Chat Window (Doesn't include a newline)")] HRESULT RawWriteToChatWindow(BSTR szText, [defaultvalue(0)] long lColor);
[helpstring("Casts a specific Spell on the Object specified")] HRESULT CastSpell(long lSpellID, long lObjectID);
[helpstring("Moves items within your inventory")] HRESULT MoveItem(long lObjectID, long lPackID, long lSlot, long lStack);
[helpstring("Selects an item")] HRESULT SelectItem(long lObjectID);
[helpstring("Uses an item")] HRESULT UseItem(long lObjectID, long lUseOnSelectedItem);
[propget, helpstring("property CombatState")] HRESULT CombatState([out, retval] long *pVal);
[propget, helpstring("property ChatState")] HRESULT ChatState([out, retval] VARIANT_BOOL *pVal);
[helpstring("method UseItemEx")] HRESULT UseItemEx(long Use, long UseOn);
[helpstring("Decal itself")] HRESULT get_Decal([out, retval] IDecal **pVal);
[helpstring("Gets the vital stats of a member of your fellowship")] HRESULT GetFellowStats(long charID);
[propget, helpstring("property Hooks")] HRESULT Hooks([out, retval] IACHooks **pVal);
[helpstring("Force redraw of the Decal bar")] HRESULT RedrawBar();
[propget, helpstring("Fetch the font set in DenAgent")] HRESULT FontName([out, retval] BSTR *pFontName);
};
[
object,
uuid(BA3E677F-8E44-4829-982E-58BBBC5C5F9B),
helpstring("IPlugin Interface - All plugin components are required to implement this interface"),
pointer_default(unique)
]
interface IPlugin : IUnknown
{
[helpstring("Create all objects and views within your plugin. The assigned ID can be used for self termiantion and the plugin site should be stored.")] HRESULT Initialize(IPluginSite *pSite, long nID);
[helpstring("Release all your objects including the stored IPluginSite")] HRESULT Terminate();
[propget, helpstring("Return a short text string describing your plugin.")] HRESULT FriendlyName([out, retval] BSTR *pVal);
};
[
object,
uuid(D216BA6C-D328-4765-B40A-9BC57C96F75E),
helpstring("IPluginSink Interface"),
pointer_default(unique)
]
interface IPluginSink : IUnknown
{
[helpstring("method ChatText")] HRESULT ChatText(BSTR bstrMsg, [out, retval] VARIANT_BOOL *pbEat);
[helpstring("method ChatMessage")] HRESULT ChatMessage(BSTR bstrMsg, long *pColor, [out, retval] VARIANT_BOOL *pbEat);
};
[
object,
uuid(65C6CE3D-B66B-4B64-8EA3-18AB2328484E),
helpstring("IRenderSink Interface"),
pointer_default(unique)
]
interface IRenderSink : IUnknown
{
[helpstring("method CustomDraw")] HRESULT CustomDraw(ICanvas* pCanvas);
};
[
object,
uuid(E4FBF228-D2AA-4298-96EC-6D89A1960731),
helpstring("IRender3DSink Interface"),
pointer_default(unique)
]
interface IRender3DSink : IUnknown
{
[helpstring("method PreBeginScene")] HRESULT PreBeginScene(IUnknown* pD3D);
[helpstring("method PostBeginScene")] HRESULT PostBeginScene(IUnknown* pD3D);
[helpstring("method PreEndScene")] HRESULT PreEndScene(IUnknown* pD3D);
[helpstring("method PostEndScene")] HRESULT PostEndScene(IUnknown* pD3D);
};
[
object,
uuid(996B377C-1953-4db1-AAC1-157F72592D3E),
dual,
helpstring("Base interface for all controls."),
pointer_default(unique)
]
interface IControl : IDispatch
{
[id(1), helpstring("Remove this control from the hierarchy.")] HRESULT DestroyChild(long nIndex, [defaultvalue(ePositionByIndex)] enum ePositionType posType);
[id(2), propget, helpstring("Returns the numerical ID used by this control for events.")] HRESULT ID([out, retval] long *pVal);
[id(3), propget, helpstring("The number of direct children.")] HRESULT ChildCount([out, retval] long *pVal);
[id(4), propget, helpstring("Select a child by ID (ePositionByID) or index (ePositionByIndex).")] HRESULT Child(long nIndex, [defaultvalue(ePositionByIndex)] enum ePositionType posType, [out, retval] IControl* *pVal);
//[id(5), propget, helpstring("property Position")] HRESULT Position([out, retval] RECT *pVal);
//[id(5), propput, helpstring("property Position")] HRESULT Position([in] RECT *newVal);
};
[
uuid(2FEBCBC3-488C-444f-AD08-5D3097D2D1ED),
helpstring("Base events interface for all controls, copy these member(s) into the specific control interface.")
]
dispinterface IControlEvents
{
properties:
methods:
[id(1), helpstring("This control is about to be destroyed, release any references to this object.")] void Destroy(long nID);
};
[
object,
uuid(0D63504F-DEEF-4a2d-9742-28DD1BADDA7C),
helpstring("Base interface for Layers, all control must implement this interface."),
pointer_default(unique)
]
interface ILayer : IUnknown
{
[helpstring("Initialize your layer and you must store the ILayerSite.")] HRESULT LayerCreate(ILayerSite *pSite);
[helpstring("Release all objects including the ILayerSite")] HRESULT LayerDestroy();
[propget, helpstring("property Position")] HRESULT Position([out, retval] RECT *pVal);
[propput, helpstring("property Position")] HRESULT Position([in, out] RECT *newVal);
[helpstring("Invalidate the layer through ILayerSite")] HRESULT Invalidate();
};
[
object,
uuid(D1C71B85-62C2-42a3-AE2E-4BF5A6BE1784),
helpstring("Layers that perform drawing should implement this interface."),
pointer_default(unique)
]
interface ILayerRender : IUnknown
{
[helpstring("Sent to every layer before the drawing cycle. It can use this opportunity to invalidate.")] HRESULT PreRender();
[helpstring("Draw your layer into the provided canvas.")] HRESULT Render(ICanvas *pDest);
[helpstring("Perform any formatting before drawing.")] HRESULT Reformat();
[helpstring("Use either ICanvas::OffsetOrg or ICanvas::SetClipRect to adjust the clipping area before clipped child layers draw. The visibility return value from those commands should be returned from this function.")] HRESULT AdjustRenderArea(ICanvas *pDest, [out, retval] VARIANT_BOOL *pbVisible);
[helpstring("For non-square layers - do a fine level of hit testing.")] HRESULT HitTest(LPPOINT pt, [out, retval] VARIANT_BOOL *pbHit);
};
[
object,
uuid(5B7E9D99-BB3A-475D-842D-43EBEA8284EA),
helpstring("Base windowing interface. Through here, a layer can manipualte itself and it's children."),
pointer_default(unique)
]
interface ILayerSite : IUnknown
{
[helpstring("Destroy this layer, all of it's children and release the controls.")] HRESULT Destroy();
[helpstring("Append a child layer to the list and create an associated Layer Site.")] HRESULT CreateChild(struct LayerParams *params, ILayer *pSink);
[helpstring("Returns a specific interface from the layer sink.")] HRESULT GetSink(REFIID iid, [iid_is(iid)] void **ppvItf);
[helpstring("Redraw this layer for the next render pass. If the layer is transparent, the parent will be invalidated.")] HRESULT Invalidate();
[propget, helpstring("Returns the default PluginSite - this is used for loading bitmaps and fonts.")] HRESULT PluginSite([out, retval] IPluginSite **ppSite);
[helpstring("Marks this layer for formatting, this function will also Invalidate.")] HRESULT Reformat();
[helpstring("Walks up the parent list until it find a parent that implements a particular interface.")] HRESULT GetParentSink(REFIID iid, [iid_is(iid)] void **ppvItf);
[propget, helpstring("The layer render area, if clipped it is relative parent coordinates, if unclipped it's in screen coordinates.")] HRESULT Position([out, retval] LPRECT pVal);
[propput, helpstring("The layer render area, if clipped it is relative parent coordinates, if unclipped it's in screen coordinates.")] HRESULT Position([in] LPRECT newVal);
[propget, helpstring("The layer ID assigned at layer creation - this is used in callbacks.")] HRESULT ID([out, retval] long *pVal);
[propget, helpstring("The number of direct child layers (clipped and unclipped).")] HRESULT ChildCount([out, retval] long *pVal);
[propget, helpstring("Returns a direct child by ID or by index.")] HRESULT Child(long nIndex, [defaultvalue(ePositionByIndex)] enum ePositionType posType, [out, retval] ILayerSite* *pVal);
[helpstring("Captures keyboard input from AC until an event happens. The layer must implement ILayerKeyboard to receive these events.")] HRESULT CaptureKeyboard();
[helpstring("Determines if a layer is either equal or a descendant of the current layer. If bTextUnclipped is false, the method will only test clipped layers.")] HRESULT IsChild(ILayerSite *pSite, [defaultvalue(0)] VARIANT_BOOL bTestUnclipped, [out, retval] VARIANT_BOOL *pbIsChild);
[propput, helpstring("Sets the layer to receive notification when an action that cancels popups occurs. Layers that self-terminate popup mode should set this to False when complete. The layer must implement ILayerPopup to receive notifications.")] HRESULT Popup([in] VARIANT_BOOL newVal);
[propget, helpstring("Returns the position of this layer in screen coordinates.")] HRESULT ScreenPosition([out, retval] LPRECT pVal);
[helpstring("Begins a timer with a particular ID (first notification is in nInterval ms). The layer must implement ILayerTimer to receive these notifications.")] HRESULT StartTimer(long nID, long nInterval);
[helpstring("Kill this timer.")] HRESULT EndTimer(long nID);
[propget, helpstring("property Transparent")] HRESULT Transparent([out, retval] VARIANT_BOOL *pVal);
[propput, helpstring("property Transparent")] HRESULT Transparent([in] VARIANT_BOOL newVal);
[propput, helpstring("property Alpha")] HRESULT Alpha(long Alpha);
[helpstring("Moves the view to the front of the list")] HRESULT moveToFront();
};
[
object,
uuid(E4CCDC92-8658-4caa-8955-FB891D5BDCF7),
helpstring("Internal interface for accessing the switch-bar at the top of the screen."),
pointer_default(unique)
]
interface IBarManager : IUnknown
{
[helpstring("Appends a bar on the bar maanger.")] HRESULT AddBar(long nViewID, struct ViewParams *pParams);
[helpstring("Deletes a bar from the manager.")] HRESULT RemoveBar(long nViewID);
[propget, helpstring("The properties of a particular bar.")] HRESULT Bar(long nViewID, [out, retval] struct ViewParams *pVal);
[propput, helpstring("The properties of a particular bar.")] HRESULT Bar(long nViewID, [in] struct ViewParams *newVal);
[helpstring("Force redraw of the Decal bar.")] HRESULT Reformat() ;
};
[
object,
uuid(DEDCD5AA-F6CA-4DA5-A657-E82F126ABBCD),
helpstring("Icon cache, this object is a tileset for icon images"),
pointer_default(unique)
]
interface IIconCache : IUnknown
{
[helpstring("Renders an icon to a canvas. This function is only guarnateed to work in the rendering cycle.")] HRESULT DrawIcon(LPPOINT ppt, long nFile, long nModule, ICanvas *pTarget);
[helpstring("Renders an icon to a canvas, Replacing any white pixels with the specified lColor. This function is only guarnateed to work in the rendering cycle.")] HRESULT DrawIconEx(LPPOINT ppt, long nFile, long nModule, ICanvas *pTarget, long lColor);
};
[
object,
uuid(F88548BC-D11E-4ac2-9A27-3607004D359F),
dual,
helpstring("Stores a bitmap loaded from a variety of sources"),
pointer_default(unique)
]
interface IImageCacheDisp : IDispatch
{
};
[
object,
uuid(BE566CEC-6881-481C-A146-9F5A32576BE6),
helpstring("Stores a bitmap loaded from a variety of sources"),
pointer_default(unique)
]
interface IImageCache : IImageCacheDisp
{
[helpstring("Uses the image to fill an area on the canvas. The origin is the offset of the image at the top/left corner of the fill area.")] HRESULT PatBlt(ICanvas *pDest, LPRECT prcDest, LPPOINT ptOrigin);
[helpstring("Stretches an image to a particular width by drawing the head and tail, then pattern filling the middle area. nStartStretch and nEndStretch indicate the area to replicate.")] HRESULT StretchBlt(ICanvas *pDest, LPPOINT pptDest, long nWidth, long nStartStretch, long nEndStretch);
[helpstring("Copies a portion of an image to a canvas.")] HRESULT Blt(LPRECT rcSrc, ICanvas *pDest, LPPOINT pptDest);
[propget, helpstring("Returns the dimension of the currently loaded image.")] HRESULT Size([out, retval] SIZE *pVal);
[helpstring("Copies a portion of an image to a canvas and stretches it.")] HRESULT StretchBltArea(LPRECT prcSrc, ICanvas *pDest, LPRECT prcDest);
};
[
object,
uuid(9394E96D-2B29-4c29-AF3E-DB5C476122DB),
dual,
helpstring("IFontCache Interface"),
pointer_default(unique)
]
interface IFontCacheDisp : IDispatch
{
};
[
object,
uuid(12ECCB0F-36A6-451C-B086-1306B74AAEC2),
helpstring("IFontCache Interface"),
pointer_default(unique)
]
interface IFontCache : IFontCacheDisp
{
[helpstring("Renders text to a canvas. Only guaranteed to work within the render cycle.")] HRESULT DrawText( LPPOINT pt, BSTR szText, long clr, ICanvas *pTarget );
[helpstring("Returns the width and height of a string of text.")] HRESULT MeasureText(BSTR szText, [out, retval] LPSIZE pszExt);
[helpstring("method HitTest")] HRESULT HitTest(BSTR szText, long nPos, [out, retval] long *nIndex);
[helpstring("Renders text to a canvas. Only guaranteed to work within the render cycle.")] HRESULT DrawTextEx( LPPOINT pt, BSTR szText, long clr1, long clr2, long flags, ICanvas *pTarget );
};
[
object,
uuid(4A2D87CD-BFB4-4723-B959-FFF3FDD49278),
helpstring("ISimpleBar Interface"),
pointer_default(unique)
]
interface ISimpleBar : IUnknown
{
[propget, helpstring("The horizontal area required by this tab.")] HRESULT RenderWidth([out, retval] long *nWidth);
[propget, helpstring("The text and icon.")] HRESULT Params([out, retval] struct ViewParams *pVal);
[propput, helpstring("The text and icon.")] HRESULT Params([in] struct ViewParams *newVal);
};
[
object,
uuid(5014E0B2-9156-412c-946D-9D4BAA9F4C51),
helpstring("ILayerMouse Interface"),
pointer_default(unique)
]
interface ILayerMouse : IUnknown
{
[helpstring("The mouse has entered the control")] HRESULT MouseEnter(struct MouseState *pMouse);
[helpstring("The mouse has left the control")] HRESULT MouseExit(struct MouseState *pMouse);
[helpstring("The user pressed the mouse button within the control. This control will have capture until the button is released.")] HRESULT MouseDown(struct MouseState *pMouse);
[helpstring("The user released the mouse button. Capture is also released.")] HRESULT MouseUp(struct MouseState *pMouse);
[helpstring("The mouse moved within the area of the layer.")] HRESULT MouseMove(struct MouseState *pMouse);
[helpstring("The user double clicked inside the layer.")] HRESULT MouseDblClk(struct MouseState *pMouse);
[helpstring("Generic Mouse Message, parameters are uninterpretted.")] HRESULT MouseEvent(long nMsg, long wParam, long lParam);
};
[
object,
uuid(829E0FB2-D0B5-4814-BCF9-6ECFA06C9AED),
helpstring("ILayerSchema Interface"),
pointer_default(unique)
]
interface ILayerSchema : IUnknown
{
[helpstring("Load schema from an XML DOM source. Query IXMLDOMElement from the IUnknown pointer.")] HRESULT SchemaLoad(IView *pView, IUnknown *pXMLSchema);
};
[
object,
uuid(0F5765A4-9F83-4077-8884-6CBDDCE348F7),
dual,
helpstring("IButton Interface"),
pointer_default(unique)
]
interface IButton : IControl
{
[id(101), helpstring("Set the pressed and released images.")] HRESULT SetImages(long nModule, long nReleased, long nPressed);
[id(102), propget, helpstring("The background color for this button - usually black (#000000).")] HRESULT Matte([out, retval] long *pVal);
[id(102), propput, helpstring("The background color for this button - usually black (#000000).")] HRESULT Matte([in] long newVal);
};
[
uuid(F029D3A1-29AF-45ef-927E-729FEDD87403),
helpstring("ICommandEvents Interface")
]
dispinterface ICommandEvents
{
properties:
methods:
[id(1), helpstring("method Destroy")] void Destroy(long nID);
[id(2), helpstring("method CommandHit")] void Hit(long nID);
[id(3), helpstring("method CommandUnhit")] void Unhit(long nID);
[id(4), helpstring("method CommandAccepted")] void Accepted(long nID);
[id(5), helpstring("method CommandCanceled")] void Canceled(long nID);
};
[
object,
uuid(BD9FC464-C0D8-4823-8255-E818F8836B08),
helpstring("IPager Interface"),
pointer_default(unique)
]
interface IPager : IControl
{
[helpstring("method FinishCommand")] HRESULT FinishCommand();
[helpstring("method ScrollTo")] HRESULT ScrollTo(LPPOINT ppt);
[propget, helpstring("property Command")] HRESULT Command([out, retval] long *pVal);
[propput, helpstring("property Command")] HRESULT Command([in] long newVal);
[propget, helpstring("property Offset")] HRESULT Offset([out, retval] LPPOINT pVal);
[propput, helpstring("property Offset")] HRESULT Offset([in] LPPOINT newVal);
[helpstring("method CreateClient")] HRESULT CreateClient(ILayer *pLayer);
};
[
uuid(7499EB61-6992-4e21-8A55-CF44D44C0A07),
helpstring("IPagerEvents Interface")
]
dispinterface IPagerEvents
{
properties:
methods:
[id(1), helpstring("method Destroy")] void Destroy(long nID);
[id(6), helpstring("method PagerUpdatePosition")] void Change(long nID, long nCommand, long nX, long nY);
[id(7), helpstring("method PagerGetNextPosition")] VARIANT_BOOL GetNextPosition(long nID, long nCommand, [in, out] long *nX, [in, out] long *nY);
};
[
object,
uuid(2B52B5CB-9E10-4238-8F62-A501406E3EAB),
helpstring("IPanel Interface"),
pointer_default(unique)
]
interface IPanel : IUnknown
{
[helpstring("method AddView")] HRESULT AddView(long nViewID, ILayer *pLayer);
[helpstring("method ActivateView")] HRESULT ActivateView(long nViewID, struct ViewParams *pParams, long *pVal);
[helpstring("method RemoveView")] HRESULT RemoveView(long nViewID);
[propget, helpstring("property ActiveView")] HRESULT ActiveView([out, retval] long *pVal);
[helpstring("method LoadView")] HRESULT LoadView(long nViewID, IView *pView, IUnknown *pSchema);
[helpstring("method Deactivate")] HRESULT Deactivate();
[propputref, helpstring("property Sink")] HRESULT Sink([in] IPanelSink* newVal);
[helpstring("method LoadViewEx")] HRESULT LoadViewEx(long nViewID, IView *pView, IUnknown *pSchema, long lViewFlags);
[propget, helpstring("property Transparent")] HRESULT Transparent([out, retval] VARIANT_BOOL* pVal);
[propput, helpstring("property Transparent")] HRESULT Transparent([in] VARIANT_BOOL newVal);
[propput, helpstring("property Params")] HRESULT Params([in] struct ViewParams *newVal);
};
[
object,
uuid(85D70924-917D-41bb-995D-C40E6AB21C71),
helpstring("IPanelSink Interface"),
pointer_default(unique)
]
interface IPanelSink : IUnknown
{
[helpstring("method PanelDeactivate")] HRESULT PanelDeactivate( long nViewID );
};
[
object,
uuid(9241862D-BA71-4317-8166-3A3E61CE3E5F),
helpstring("ICanvas Interface"),
pointer_default(unique)
]
interface ICanvas : IUnknown
{
[helpstring("method PushClipRect")] HRESULT PushClipRect(LPRECT prc, [out, retval] VARIANT_BOOL *pbVisible);
[helpstring("method PopClipRect")] HRESULT PopClipRect();
[helpstring("method GetDC")] HRESULT GetDC([out,retval] HDC *pdc);
[helpstring("method ReleaseDC")] HRESULT ReleaseDC();
[helpstring("method GetSurface")] HRESULT GetSurface(REFIID iid, [out, retval, iid_is(iid)] void **ppvItf);
[helpstring("method Fill")] HRESULT Fill(LPRECT prc, long nRGB);
[helpstring("method Frame")] HRESULT Frame(LPRECT prc, long nRGB);
[helpstring("method GetClipParams")] HRESULT GetClipParams([out, retval] struct ClipParams *pParams);
[propget, helpstring("property WasLost")] HRESULT WasLost([out, retval] VARIANT_BOOL *pVal);
[propget, helpstring("property Size")] HRESULT Size([out, retval] LPSIZE pVal);
[propput, helpstring("property Size")] HRESULT Size([in] LPSIZE newVal);
[helpstring("method Blt")] HRESULT Blt(LPRECT prcSrc, ICanvas *pSrc, LPPOINT pptDest);
[helpstring("method HitTest")] HRESULT HitTest(LPPOINT ppt, [out, retval] VARIANT_BOOL *pbHit);
[helpstring("method ToClient")] HRESULT ToClient([in, out] LPPOINT pt);
[helpstring("method ToScreen")] HRESULT ToScreen([in, out] LPPOINT ppt);
[helpstring("method OffsetOrg")] HRESULT OffsetOrg(LPPOINT ppt, [out, retval] VARIANT_BOOL *pbVisible);
[helpstring("method SetClipRect")] HRESULT SetClipRect(LPRECT prcClip, [out, retval] VARIANT_BOOL *pbVisible);
[propput, helpstring("method Alpha")] HRESULT Alpha(long Alpha);
[helpstring("method DownMixRGB")] HRESULT DownMixRGB(WORD wRed, WORD wGreen, WORD wBlue, [out, retval] WORD *wDMRGB);
[helpstring("method GetDCLong")] HRESULT GetDCLong([out, retval] long *DC);
[helpstring("method SetTransparentColor")] HRESULT SetTransparentColor([in] long TransColor);
[helpstring("method StretchBlt")] HRESULT StretchBlt(LPRECT prcSrc, ICanvas *pSrc, LPRECT prcDest);
};
[
object,
uuid(F3B54A0C-61B9-4B7A-9FD8-82B0477FB7D9),
dual,
helpstring("IView Interface"),
pointer_default(unique)
]
interface IViewDisp : IDispatch
{
[propget, helpstring("property Control")] HRESULT Control(BSTR strName, [out, retval] IControl * *pVal);
[propputref, helpstring("property Control")] HRESULT Control(BSTR strName, [in] IControl * newVal);
[propget, helpstring("property Title")] HRESULT Title([out, retval] BSTR *pVal);
[propput, helpstring("property Title")] HRESULT Title([in] BSTR newVal);
[helpstring("property Alert")] HRESULT Alert();
[helpstring("method SetIcon")] HRESULT SetIcon(long icon, [optional] VARIANT iconlibrary);
[helpstring("method Activate")] HRESULT Activate();
[helpstring("method Deactivate")] HRESULT Deactivate();
[propput, helpstring("property Position")] HRESULT Position([in, out] RECT *newVal);
[propget, helpstring("property Position")] HRESULT Position([out, retval] RECT *pVal);
};
[
object,
uuid(A2AE18B7-85C9-451c-8CC3-D0FFE6B86EEB),
helpstring("IView Interface"),
pointer_default(unique)
]
interface IView : IViewDisp
{
[helpstring("method LoadControl")] HRESULT LoadControl(ILayerSite *pParent, long nID, IUnknown *pXMLSource, [out, retval] long *pAssignedID);
[helpstring("method LoadSchema")] HRESULT LoadSchema(BSTR strXMLSchema);
[propput, helpstring("property Alpha")] HRESULT Alpha(long Alpha);
[propget, helpstring("property Activated")] HRESULT Activated([out, retval] VARIANT_BOOL* pVal);
[propput, helpstring("property Activated")] HRESULT Activated([in] VARIANT_BOOL newVal);
[propget, helpstring("property Transparent")] HRESULT Transparent([out, retval] VARIANT_BOOL* pVal);
[propput, helpstring("property Transparent")] HRESULT Transparent([in] VARIANT_BOOL newVal);
[propget, helpstring("property Alpha")] HRESULT Alpha([out, retval] long *pVal);
};
[
uuid(4B7B19D5-61A2-4ab0-8B1B-381A303A937F),
helpstring("IViewEvents Interface")
]
dispinterface IViewEvents
{
properties:
methods:
[id(8), helpstring("method ViewActivate")] void Activate();
[id(9), helpstring("method ViewDeactivate")] void Deactivate();
[id(13), helpstring("method ViewSize")] VARIANT_BOOL Size();
[id(14), helpstring("method ViewSizing")] void Sizing([in] /*IView *pView*/ /*struct ViewParams *pViewParams RECT *pRect*/ long left, long top, long width, long height);
};
[
object,
uuid(D3006096-B293-47f5-9377-C12DEF5C1D34),
helpstring("IRootLayer Interface"),
pointer_default(unique)
]
interface IRootLayer : IUnknown
{
[helpstring("method CreateView")] HRESULT CreateView(struct ViewParams *pParams, ILayer *pLayer, [out, retval] IView **ppView);
[helpstring("method SelectBar")] HRESULT SelectBar(long nID);
[helpstring("method LoadView")] HRESULT LoadView(BSTR strXML, [out, retval] IView **ppView);
[helpstring("method LoadViewObject")] HRESULT LoadViewObject(IUnknown *pSchema, [out, retval] IView **ppView);
};
[
object,
uuid(7500929F-4251-4373-B978-286A8A8BECED),
helpstring("ILayerKeyboard Interface"),
pointer_default(unique)
]
interface ILayerKeyboard : IUnknown
{
[helpstring("method KeyboardChar")] HRESULT KeyboardChar(struct KeyState *pKS);
[helpstring("method KeyboardEndCapture")] HRESULT KeyboardEndCapture(VARIANT_BOOL bCancel);
[helpstring("method KeyboardEvent")] HRESULT KeyboardEvent(long nMsg, long wParam, long lParam);
};
[
object,
uuid(22072A97-E5E6-4d91-A344-807235BFA5D8),
helpstring("ILayerPopup Interface"),
pointer_default(unique)
]
interface ILayerPopup : IUnknown
{
[helpstring("method PopupCancel")] HRESULT PopupCancel(struct MouseState *pMouse, [out, retval] VARIANT_BOOL *pbContinue);
};
[
object,
uuid(5D6B8A1B-321A-479f-9347-55725BDA3DA9),
helpstring("ILayerTimer Interface"),
pointer_default(unique)
]
interface ILayerTimer : IUnknown
{
[helpstring("method TimerTimeout")] HRESULT TimerTimeout(long nID, long nInterval, long nReps, [out, retval] VARIANT_BOOL *pbContinue);
};
[
object,
uuid(EDB7EE44-2368-4382-97A4-D4F55C63D818),
helpstring("IDecalTimer Interface"),
pointer_default(unique)
]
interface IDecalTimer : IUnknown
{
[helpstring("method TimerTimeout")] HRESULT TimerTimeout(long nID, long nInterval, long nReps, [out, retval] VARIANT_BOOL *pbContinue);
};
[
object,
uuid(A68BE455-C241-49c5-9F8A-070E4CBE430F),
helpstring("IWindowsMessageSink Interface"),
pointer_default(unique)
]
interface IWindowsMessageSink : IUnknown
{
[helpstring("method WindowsMessage")] HRESULT WindowMessage(long hWnd, short uMsg, long wParam, long lParam, [out, retval] VARIANT_BOOL *pbEat);
[helpstring("method WindowsMessageEnd")] HRESULT WindowMessageEnd();
};
[
object,
uuid(50CDFD25-4F3B-4412-96BE-947A6C7B93A2),
helpstring("IBrushImage Interface"),
pointer_default(unique)
]
interface IBrushImage : IUnknown
{
[propget, helpstring("property Color")] HRESULT Color([out, retval] long *pVal);
[propput, helpstring("property Color")] HRESULT Color([in] long newVal);
};
[
object,
uuid(634D74B8-AFED-4710-82C9-B530326E1AFA),
dual,
helpstring("IInputBuffer Interface"),
pointer_default(unique)
]
interface IInputBuffer : IDispatch
{
[id(1), helpstring("method Clear")] HRESULT Clear();
[id(2), helpstring("method Input")] HRESULT TypeText(BSTR strText);
[id(3), helpstring("method Delay")] HRESULT Delay(long nMilliseconds, [defaultvalue( 0 )] VARIANT_BOOL bAllowInput );
[id(4), helpstring("method MouseClick")] HRESULT MouseClick(long nX, long nY, enum eMouseInput eAction);
[propget, id(5), helpstring("property Status")] HRESULT Status([out, retval] enum eInputStatus *pVal);
[id(6), helpstring("method Run")] HRESULT Run();
};
[
uuid(BD33BADC-F909-4eb6-AD15-B1569B58898B),
helpstring("IInputEvents event interface")
]
dispinterface IInputEvents
{
properties:
methods:
[id(10), helpstring("method Begin")] HRESULT Begin();
[id(11), helpstring("method End")] HRESULT End();
[id(12), helpstring("method Pause")] HRESULT Pause();
};
[
object,
uuid(E288C465-2DD6-4fcd-95E2-5BBC1A1D2D32),
dual,
helpstring("IInputNotify Interface"),
pointer_default(unique)
]
interface IInputNotify : IDispatch
{
[id(1), helpstring("method NotifyBegin")] HRESULT NotifyBegin();
[id(2), helpstring("method NotifyEnd")] HRESULT NotifyEnd();
[id(3), helpstring("method SetMousePos")] HRESULT SetMousePos(long nX, long nY);
[id(4), helpstring("method NotifyPause")] HRESULT NotifyPause();
};
[
object,
uuid(47761792-2520-4802-8548-5CA580697614),
helpstring("IInjectService Interface"),
pointer_default(unique)
]
interface IInjectService : IUnknown
{
[propget, id(1), helpstring("property Site")] HRESULT Site([out, retval] IPluginSite **pVal);
[helpstring("method InitPlugin")] HRESULT InitPlugin(IUnknown *pUnk);
};
[
object,
uuid(93D72C31-CBC3-4471-AE4B-395FBB4D3B45),
helpstring("IPluginAdapterV1 Interface"),
pointer_default(unique)
]
interface IPluginAdapterV1 : IUnknown
{
};
[
uuid(3559E08B-827E-4DFE-9D33-3567246849CC),
version(1.0),
helpstring("Decal Plugins Type Library")
]
library DecalPlugins
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");
interface IPlugin;
interface IPluginSink;
interface IRenderSink;
interface IRender3DSink;
interface ILayerSite;
interface IControl;
interface ILayer;
interface ILayerRender;
interface ILayerMouse;
interface ILayerKeyboard;
interface ILayerPopup;
interface ILayerSchema;
interface ILayerTimer;
interface IControlEvents;
interface IIconCache;
interface IImageCache;
interface IFontCache;
interface IBarManager;
interface ISimpleBar;
interface IRootLayer;
interface IPanelSink;
interface IInputNotify;
interface IWindowsMessageSink;
dispinterface IControlEvents;
dispinterface ICommandEvents;
dispinterface IPagerEvents;
dispinterface IViewEvents;
dispinterface IInputEvents;
interface IFontCacheDisp;
interface IImageCacheDisp;
interface IViewDisp;
[
uuid(91892F16-31A3-4E23-9CFD-89A5A5174A59),
helpstring("Canvas Class"),
noncreatable
]
coclass Canvas
{
[default] interface ICanvas;
};
[
uuid(B2FBD583-B64C-4dfc-BAAA-34B8C21482F8),
helpstring("PluginSite Class"),
noncreatable
]
coclass PluginSite
{
[default] interface IPluginSite;
};
[
uuid(6FEA2219-7438-4f76-8165-C47AA060D811),
helpstring("Layer Class"),
noncreatable
]
coclass Layer
{
[default] interface ILayerSite;
};
[
uuid(19BF46E4-5CB8-4CFC-A17A-8E6673E60ABF),
helpstring("View Class"),
noncreatable
]
coclass View
{
[default] interface IViewDisp;
[default, source] interface IViewEvents;
};
[
uuid(C22BF2FC-F144-4d17-9C12-A344F980BB17),
helpstring("Button Class")
]
coclass Button
{
[default] interface IButton;
[default, source] interface ICommandEvents;
};
[
uuid(C79E2F76-06F8-4cd0-A613-4829237D297D),
helpstring("Pager Class")
]
coclass Pager
{
[default] interface IControl;
[default, source] interface IPagerEvents;
};
[
uuid(918C0333-5714-4C8D-A95C-2C137B76D364),
noncreatable,
helpstring("SolidImage Class")
]
coclass BrushImage
{
[default] interface IBrushImage;
interface IImageCache;
};
[
uuid(2F91FC21-4D89-4B64-94AE-A124D54563AE),
helpstring("InputBuffer Class"),
noncreatable
]
coclass InputBuffer
{
[default] interface IInputBuffer;
[default, source] interface IInputEvents;
};
[
uuid(FEFE5CAB-10E4-404F-AD4D-184BCB506099),
helpstring("DecalPlugins Inject Service Gateway")
]
coclass InjectService
{
[default] interface IInjectService;
};
[
uuid(3D837F6E-B5CA-4604-885F-7AB45FCFA62A),
helpstring("Version 1 Plugin Surrogate")
]
coclass PluginAdapterV1
{
[default] interface IPluginAdapterV1;
};
};

163
Native/Inject/Inject.rc Normal file
View file

@ -0,0 +1,163 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#include "..\Include\DecalVersion.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Neutral resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
#ifdef _WIN32
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// REGISTRY
//
IDR_PLUGINADAPTERV1 REGISTRY "PluginAdapterV1.rgs"
#endif // Neutral resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"1 TYPELIB ""Inject.tlb""\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION DECAL_MAJOR, DECAL_MINOR, DECAL_BUGFIX, DECAL_RELEASE
PRODUCTVERSION DECAL_MAJOR, DECAL_MINOR, DECAL_BUGFIX, DECAL_RELEASE
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "Inject is the heart of Decal, it places itself within the memory space of the AC Client and is responsible for drawing the UI on the screen"
VALUE "FileDescription", "Inject Module"
VALUE "FileVersion", DECAL_VERSION_STRING
VALUE "InternalName", "Inject"
VALUE "LegalCopyright", "Copyright 2000, 2001"
VALUE "OriginalFilename", "Inject.DLL"
VALUE "ProductName", "Inject Module"
VALUE "ProductVersion", DECAL_VERSION_STRING
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_PROJNAME "Decal"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (Canada) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENC)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_CAN
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// REGISTRY
//
IDR_BUTTON REGISTRY "Button.rgs"
IDR_PAGER REGISTRY "Pager.rgs"
IDR_INJECTSERVICE REGISTRY "InjectService.rgs"
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME ICON "res\\DenAgent.ico"
#endif // English (Canada) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
1 TYPELIB "Inject.tlb"
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

835
Native/Inject/Inject.vcproj Normal file
View file

@ -0,0 +1,835 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="Inject"
SccProjectName=""
SccLocalPath="">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\..\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\Include"
PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="3"
PrecompiledHeaderThrough="stdafx.h"
PrecompiledHeaderFile=".\Debug/Inject.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
IgnoreImportLibrary="TRUE"
AdditionalDependencies="odbc32.lib odbccp32.lib ddraw.lib winmm.lib ws2_32.lib version.lib"
OutputFile=".\..\Debug/Inject.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ModuleDefinitionFile=".\Inject.def"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\..\Debug/Inject.pdb"
SubSystem="2"
ImportLibrary=".\..\Debug/Inject.lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
AdditionalIncludeDirectories="..\Include"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
GenerateStublessProxies="TRUE"
TypeLibraryName=".\..\Debug/Inject.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="4105"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release MinDependency|Win32"
OutputDirectory=".\..\Release"
IntermediateDirectory=".\ReleaseMinDependency"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="4"
GlobalOptimizations="TRUE"
InlineFunctionExpansion="1"
EnableIntrinsicFunctions="TRUE"
FavorSizeOrSpeed="2"
OmitFramePointers="TRUE"
AdditionalIncludeDirectories="..\Include"
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_USRDLL"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="3"
PrecompiledHeaderThrough="stdafx.h"
PrecompiledHeaderFile=".\ReleaseMinDependency/Inject.pch"
AssemblerListingLocation=".\ReleaseMinDependency/"
ObjectFile=".\ReleaseMinDependency/"
ProgramDataBaseFileName=".\ReleaseMinDependency/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
IgnoreImportLibrary="TRUE"
AdditionalDependencies="odbc32.lib odbccp32.lib ddraw.lib winmm.lib ws2_32.lib version.lib"
OutputFile=".\..\Release/Inject.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\Release"
ModuleDefinitionFile=".\Inject.def"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\..\Release/Inject.pdb"
SubSystem="2"
ImportLibrary=".\..\Release/Inject.lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
AdditionalIncludeDirectories="..\Include"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
GenerateStublessProxies="TRUE"
TypeLibraryName=".\..\Release/Inject.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="4105"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath="BarLayer.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="Button.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="Canvas.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="DatFile.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="Direct3DHook.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="DirectDrawHook.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="DirectDrawSurfaceHook.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="FontCache.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="Guids.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
<File
RelativePath="IconCache.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="Image.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="Inject.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="Inject.def">
</File>
<File
RelativePath="Inject.idl">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCMIDLTool"
AdditionalIncludeDirectories=""
TargetEnvironment="1"
TypeLibraryName=".\Inject.tlb"
HeaderFileName="Inject.h"
InterfaceIdentifierFileName="Inject_i.c"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCMIDLTool"
AdditionalIncludeDirectories=""
TargetEnvironment="1"
TypeLibraryName=".\Inject.tlb"
HeaderFileName="Inject.h"
InterfaceIdentifierFileName="Inject_i.c"/>
</FileConfiguration>
</File>
<File
RelativePath="Inject.rc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions=""
AdditionalIncludeDirectories="$(OUTDIR)"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions=""
AdditionalIncludeDirectories="$(OUTDIR)"/>
</FileConfiguration>
</File>
<File
RelativePath="InjectService.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="InputBuffer.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="LayerSite.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="Manager.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="MaterialHook.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="Pager.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="Panel.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="PluginAdapterV1.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="RootLayer.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="SimpleBar.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="SinkImpl.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="SolidImage.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
<File
RelativePath="StdAfx.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"
UsePrecompiledHeader="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"
UsePrecompiledHeader="1"/>
</FileConfiguration>
</File>
<File
RelativePath="View.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_DEBUG;_MBCS;WIN32;_WINDOWS;_USRDLL;INJECT_IMPL;$(NoInherit)"
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release MinDependency|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="INJECT_IMPL;WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
RelativePath="BarLayer.h">
</File>
<File
RelativePath="Button.h">
</File>
<File
RelativePath="Canvas.h">
</File>
<File
RelativePath="DatFile.h">
</File>
<File
RelativePath="Direct3DHook.h">
</File>
<File
RelativePath="DirectDrawHook.h">
</File>
<File
RelativePath="DirectDrawSurfaceHook.h">
</File>
<File
RelativePath="EventsImpl.h">
</File>
<File
RelativePath="FontCache.h">
</File>
<File
RelativePath="IconCache.h">
</File>
<File
RelativePath="Image.h">
</File>
<File
RelativePath="InjectApi.h">
</File>
<File
RelativePath="InjectCP.h">
</File>
<File
RelativePath="InjectService.h">
</File>
<File
RelativePath="InputBuffer.h">
</File>
<File
RelativePath="LayerSite.h">
</File>
<File
RelativePath="Manager.h">
</File>
<File
RelativePath="MaterialHook.h">
</File>
<File
RelativePath="Pager.h">
</File>
<File
RelativePath="Panel.h">
</File>
<File
RelativePath="Plugin2Impl.h">
</File>
<File
RelativePath="PluginAdapterV1.h">
</File>
<File
RelativePath="PluginImpl.h">
</File>
<File
RelativePath="Resource.h">
</File>
<File
RelativePath="RootLayer.h">
</File>
<File
RelativePath="SimpleBar.h">
</File>
<File
RelativePath="SinkImpl.h">
</File>
<File
RelativePath="SolidImage.h">
</File>
<File
RelativePath="StdAfx.h">
</File>
<File
RelativePath="View.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
<File
RelativePath="Button.rgs">
</File>
<File
RelativePath="res\DenAgent.ico">
</File>
<File
RelativePath="InjectService.rgs">
</File>
<File
RelativePath="InputBuffer.rgs">
</File>
<File
RelativePath="MessageStruct.rgs">
</File>
<File
RelativePath="MessageVector.rgs">
</File>
<File
RelativePath="Pager.rgs">
</File>
<File
RelativePath="PluginAdapterV1.rgs">
</File>
<File
RelativePath="SolidImage.rgs">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

47
Native/Inject/InjectApi.h Normal file
View file

@ -0,0 +1,47 @@
// InjectApi.h
// Declaration of global injection functions
#include <ddraw.h>
#include <d3d.h>
#ifndef __INJECTAPI_H
#define __INJECTAPI_H
#ifdef INJECT_IMPL
#define INJECT_API __declspec(dllexport)
#else
#define INJECT_API __declspec(dllimport)
#endif
#include "Inject.h"
// Enumerations
enum eInjectPath
{
eInjectPathDatFile,
eInjectPathAgent
};
// Exported functions from Inject.dll
// Adds a reference to the registered hook function
void INJECT_API InjectEnable();
// Removes a reference to the registered hook function
void INJECT_API InjectDisable();
// Prepends a path to your filename, returns szBuffer
LPTSTR INJECT_API InjectMapPath( eInjectPath pathType, LPCTSTR szFilename, LPTSTR szBuffer );
// Checksum - Added for my test container
void INJECT_API Container_Initialize( HWND hWnd, IDirectDraw4* pDD4, IDirectDrawSurface4 *pDDS4 );
void INJECT_API Container_StartPlugins( );
void INJECT_API Container_StopPlugins( );
void INJECT_API Container_Terminate( );
void INJECT_API Container_SetSurface( IDirectDrawSurface4 *pDDS4 );
void INJECT_API Container_Draw( );
void INJECT_API XMLViewer_Initialize( HWND hWnd, IDirectDraw4* pDD4, IDirectDrawSurface4 *pDDS4 );
void INJECT_API XMLViewer_LoadView( BSTR bstrSchema );
void INJECT_API XMLViewer_RemoveView( IView* pView );
void INJECT_API XMLViewer_Terminate( );
void INJECT_API XMLViewer_Draw( );
#endif

390
Native/Inject/InjectCP.h Normal file
View file

@ -0,0 +1,390 @@
#ifndef _INJECTCP_H_
#define _INJECTCP_H_
template <class T>
class CProxyICommandEvents : public IConnectionPointImpl<T, &DIID_ICommandEvents, CComDynamicUnkArray>
{
//Warning this class may be recreated by the wizard.
public:
VOID Fire_Destroy(LONG nID)
{
T* pT = static_cast<T*>(this);
int nConnectionIndex;
CComVariant* pvars = new CComVariant[1];
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
pvars[0] = nID;
DISPPARAMS disp = { pvars, NULL, 1, 0 };
pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
}
}
delete[] pvars;
}
VOID Fire_Hit(LONG nID)
{
T* pT = static_cast<T*>(this);
int nConnectionIndex;
CComVariant* pvars = new CComVariant[1];
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
pvars[0] = nID;
DISPPARAMS disp = { pvars, NULL, 1, 0 };
pDispatch->Invoke(0x2, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
}
}
delete[] pvars;
}
VOID Fire_Unhit(LONG nID)
{
T* pT = static_cast<T*>(this);
int nConnectionIndex;
CComVariant* pvars = new CComVariant[1];
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
pvars[0] = nID;
DISPPARAMS disp = { pvars, NULL, 1, 0 };
pDispatch->Invoke(0x3, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
}
}
delete[] pvars;
}
VOID Fire_Accepted(LONG nID)
{
T* pT = static_cast<T*>(this);
int nConnectionIndex;
CComVariant* pvars = new CComVariant[1];
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
pvars[0] = nID;
DISPPARAMS disp = { pvars, NULL, 1, 0 };
pDispatch->Invoke(0x4, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
}
}
delete[] pvars;
}
VOID Fire_Canceled(LONG nID)
{
T* pT = static_cast<T*>(this);
int nConnectionIndex;
CComVariant* pvars = new CComVariant[1];
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
pvars[0] = nID;
DISPPARAMS disp = { pvars, NULL, 1, 0 };
pDispatch->Invoke(0x5, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
}
}
delete[] pvars;
}
};
template <class T>
class CProxyIPagerEvents : public IConnectionPointImpl<T, &DIID_IPagerEvents, CComDynamicUnkArray>
{
//Warning this class may be recreated by the wizard.
public:
VOID Fire_Destroy(LONG nID)
{
T* pT = static_cast<T*>(this);
int nConnectionIndex;
CComVariant* pvars = new CComVariant[1];
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
pvars[0] = nID;
DISPPARAMS disp = { pvars, NULL, 1, 0 };
pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
}
}
delete[] pvars;
}
VOID Fire_Change(LONG nID, LONG nCommand, LONG nX, LONG nY)
{
T* pT = static_cast<T*>(this);
int nConnectionIndex;
CComVariant* pvars = new CComVariant[4];
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
pvars[3] = nID;
pvars[2] = nCommand;
pvars[1] = nX;
pvars[0] = nY;
DISPPARAMS disp = { pvars, NULL, 4, 0 };
pDispatch->Invoke(0x6, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
}
}
delete[] pvars;
}
VARIANT_BOOL Fire_GetNextPosition(LONG nID, LONG nCommand, LONG * nX, LONG * nY)
{
CComVariant varResult;
T* pT = static_cast<T*>(this);
int nConnectionIndex;
CComVariant* pvars = new CComVariant[4];
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
VariantClear(&varResult);
pvars[3] = nID;
pvars[2] = nCommand;
pvars[1].vt = VT_BYREF | VT_I4;
pvars[1].plVal = nX;
pvars[0].vt = VT_BYREF | VT_I4;
pvars[0].plVal = nY;
DISPPARAMS disp = { pvars, NULL, 4, 0 };
pDispatch->Invoke(0x7, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
}
}
delete[] pvars;
return varResult.boolVal;
}
};
template <class T>
class CProxyIViewEvents : public IConnectionPointImpl<T, &DIID_IViewEvents, CComDynamicUnkArray>
{
//Warning this class may be recreated by the wizard.
public:
VOID Fire_Activate()
{
T* pT = static_cast<T*>(this);
int nConnectionIndex;
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
DISPPARAMS disp = { NULL, NULL, 0, 0 };
pDispatch->Invoke(0x8, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
}
}
}
VOID Fire_Deactivate()
{
T* pT = static_cast<T*>(this);
int nConnectionIndex;
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
DISPPARAMS disp = { NULL, NULL, 0, 0 };
pDispatch->Invoke(0x9, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
}
}
}
VARIANT_BOOL Fire_Size()
{
CComVariant varResult;
T* pT = static_cast<T*>(this);
int nConnectionIndex;
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
VariantClear(&varResult);
DISPPARAMS disp = { NULL, NULL, 0, 0 };
pDispatch->Invoke(0xd, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
}
}
return varResult.boolVal;
}
VOID Fire_Sizing(/*IView *pView */ /*ViewParams *pViewParams*/ LONG left, LONG top, LONG width, LONG height)
{
T* pT = static_cast<T*>(this);
int nConnectionIndex;
CComVariant* pvars = new CComVariant[4];
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
pvars[3] = left;
pvars[2] = top;
pvars[1] = width;
pvars[0] = height;
//pvars[0].plVal = reinterpret_cast<long*>(pViewParams);
//pvars[0] = pView;
DISPPARAMS disp = { pvars, NULL, 4, 0 };
HRESULT ass = pDispatch->Invoke(0xe, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
}
}
delete[] pvars;
}
};
template <class T>
class CProxyIInputEvents : public IConnectionPointImpl<T, &DIID_IInputEvents, CComDynamicUnkArray>
{
//Warning this class may be recreated by the wizard.
public:
HRESULT Fire_Begin()
{
CComVariant varResult;
T* pT = static_cast<T*>(this);
int nConnectionIndex;
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
VariantClear(&varResult);
DISPPARAMS disp = { NULL, NULL, 0, 0 };
pDispatch->Invoke(0xa, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
}
}
return varResult.scode;
}
HRESULT Fire_End()
{
CComVariant varResult;
T* pT = static_cast<T*>(this);
int nConnectionIndex;
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
VariantClear(&varResult);
DISPPARAMS disp = { NULL, NULL, 0, 0 };
pDispatch->Invoke(0xb, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
}
}
return varResult.scode;
}
HRESULT Fire_Pause()
{
CComVariant varResult;
T* pT = static_cast<T*>(this);
int nConnectionIndex;
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
VariantClear(&varResult);
DISPPARAMS disp = { NULL, NULL, 0, 0 };
pDispatch->Invoke(0xc, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
}
}
return varResult.scode;
}
};
#endif

View file

@ -0,0 +1,42 @@
// InjectService.cpp : Implementation of cInjectService
#include "stdafx.h"
#include "Inject.h"
#include "InjectService.h"
#include "Manager.h"
/////////////////////////////////////////////////////////////////////////////
// cInjectService
STDMETHODIMP cInjectService::BeforePlugins ()
{
_ASSERTE ( cManager::_p != NULL );
cManager::_p->init ();
return S_OK;
}
STDMETHODIMP cInjectService::AfterPlugins ()
{
_ASSERTE ( cManager::_p != NULL );
cManager::_p->unloadPlugins ();
cManager::_p->term ();
return S_OK;
}
STDMETHODIMP cInjectService::get_Site(IPluginSite **pVal)
{
_ASSERTE ( cManager::_p != NULL );
return static_cast< IPluginSite * > ( cManager::_p )->QueryInterface ( pVal );
}
STDMETHODIMP cInjectService::InitPlugin(IUnknown *pUnk)
{
_ASSERTE ( cManager::_p != NULL );
cManager::_p->loadPlugin ( pUnk );
return S_OK;
}

View file

@ -0,0 +1,52 @@
// InjectService.h : Declaration of the cInjectService
#ifndef __INJECTSERVICE_H_
#define __INJECTSERVICE_H_
#include "resource.h" // main symbols
#include <DecalImpl.h>
/////////////////////////////////////////////////////////////////////////////
// cInjectService
class ATL_NO_VTABLE cInjectService :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<cInjectService, &CLSID_InjectService>,
public IInjectService,
public IDecalServiceImpl<cInjectService>,
public IDecalDirectory
{
public:
cInjectService()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_INJECTSERVICE)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(cInjectService)
COM_INTERFACE_ENTRY(IInjectService)
COM_INTERFACE_ENTRY(IDecalService)
COM_INTERFACE_ENTRY(IDecalDirectory)
END_COM_MAP()
// IDecalService
STDMETHOD(BeforePlugins)();
STDMETHOD(AfterPlugins)();
// IDecalDirectory
STDMETHOD(Lookup)(BSTR strName, IUnknown **ppvItf)
{
if ( ::wcsicmp ( strName, L"site" ) != 0 )
return E_INVALIDARG;
return get_Site ( reinterpret_cast< IPluginSite ** > ( ppvItf ) );
}
// IInjectService
public:
STDMETHOD(InitPlugin)(IUnknown *pUnk);
STDMETHOD(get_Site)(/*[out, retval]*/ IPluginSite **pVal);
};
#endif //__INJECTSERVICE_H_

View file

@ -0,0 +1,43 @@
HKCR
{
DecalPlugins.InjectService.1 = s 'DecalPlugins Inject Service Gateway'
{
CLSID = s '{FEFE5CAB-10E4-404F-AD4D-184BCB506099}'
}
DecalPlugins.InjectService = s 'DecalPlugins Inject Service Gateway'
{
CLSID = s '{FEFE5CAB-10E4-404F-AD4D-184BCB506099}'
CurVer = s 'DecalPlugins.InjectService.1'
}
NoRemove CLSID
{
ForceRemove {FEFE5CAB-10E4-404F-AD4D-184BCB506099} = s 'DecalPlugins Inject Service Gateway'
{
ProgID = s 'DecalPlugins.InjectService.1'
VersionIndependentProgID = s 'DecalPlugins.InjectService'
ForceRemove 'Programmable'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
'TypeLib' = s '{3559E08B-827E-4DFE-9D33-3567246849CC}'
}
}
}
HKLM
{
NoRemove SOFTWARE
{
NoRemove Decal
{
NoRemove Services
{
ForceRemove {FEFE5CAB-10E4-404F-AD4D-184BCB506099} = s 'Decal Inject Gateway Service'
{
val Enabled = d '1'
}
}
}
}
}

View file

@ -0,0 +1,11 @@
LIBRARY "InjectPS"
DESCRIPTION 'Proxy/Stub DLL'
EXPORTS
DllGetClassObject @1 PRIVATE
DllCanUnloadNow @2 PRIVATE
GetProxyDllInfo @3 PRIVATE
DllRegisterServer @4 PRIVATE
DllUnregisterServer @5 PRIVATE

16
Native/Inject/Injectps.mk Normal file
View file

@ -0,0 +1,16 @@
Injectps.dll: dlldata.obj Inject_p.obj Inject_i.obj
link /dll /out:Injectps.dll /def:Injectps.def /entry:DllMain dlldata.obj Inject_p.obj Inject_i.obj \
kernel32.lib rpcndr.lib rpcns4.lib rpcrt4.lib oleaut32.lib uuid.lib \
.c.obj:
cl /c /Ox /DWIN32 /D_WIN32_WINNT=0x0400 /DREGISTER_PROXY_DLL \
$<
clean:
@del Injectps.dll
@del Injectps.lib
@del Injectps.exp
@del dlldata.obj
@del Inject_p.obj
@del Inject_i.obj

View file

@ -0,0 +1,530 @@
// InputBuffer.cpp : Implementation of cInputBuffer
#include "stdafx.h"
#include "Inject.h"
#include "InputBuffer.h"
#include "Manager.h"
/////////////////////////////////////////////////////////////////////////////
// cInputBuffer
struct cCharNames
{
LPCTSTR szName;
WORD m_nVKey;
};
static cCharNames _charnames[] = {
{ _T( "BACKSPACE" ), VK_BACK },
{ _T( "BS" ), VK_BACK },
{ _T( "BKSP" ), VK_BACK },
{ _T( "CAPSLOCK" ), VK_CAPITAL },
{ _T( "DELETE" ), VK_DELETE },
{ _T( "DEL" ), VK_DELETE },
{ _T( "DOWN" ), VK_DOWN },
{ _T( "END" ), VK_END },
{ _T( "ENTER" ), VK_RETURN },
{ _T( "ESC" ), VK_ESCAPE },
{ _T( "HELP" ), VK_HELP },
{ _T( "HOME" ), VK_HOME },
{ _T( "INS" ), VK_INSERT },
{ _T( "INSERT" ), VK_INSERT },
{ _T( "LEFT" ), VK_LEFT },
{ _T( "NUMLOCK" ), VK_NUMLOCK },
{ _T( "PGDN" ), VK_NEXT },
{ _T( "PGUP" ), VK_PRIOR },
{ _T( "PRTSC" ), VK_SNAPSHOT },
{ _T( "RIGHT" ), VK_RIGHT },
{ _T( "SCROLLLOCK" ), VK_SCROLL },
{ _T( "TAB" ), VK_TAB },
{ _T( "UP" ), VK_UP },
{ _T( "F1" ), VK_F1 },
{ _T( "F2" ), VK_F2 },
{ _T( "F3" ), VK_F3 },
{ _T( "F4" ), VK_F4 },
{ _T( "F5" ), VK_F5 },
{ _T( "F6" ), VK_F6 },
{ _T( "F7" ), VK_F7 },
{ _T( "F8" ), VK_F8 },
{ _T( "F9" ), VK_F9 },
{ _T( "F10" ), VK_F10 },
{ _T( "F11" ), VK_F11 },
{ _T( "F12" ), VK_F12 },
{ _T( "F13" ), VK_F13 },
{ _T( "F14" ), VK_F14 },
{ _T( "F15" ), VK_F15 },
{ _T( "F16" ), VK_F16 },
{ _T( "+" ), VK_ADD } },
*_end_charnames = _charnames + ( sizeof(_charnames ) / sizeof( cCharNames ) );
#define MASK_SHIFT 0x0100
#define MASK_CTRL 0x0200
#define MASK_ALT 0x0400
#define SHIFT_MASK 0x0700
#define VKEY_MASK 0x00FF
void pushVirtualKey( WORD vk, cInputVec &vec, bool bDown )
{
INPUT i;
::memset( &i, 0, sizeof( INPUT ) );
i.type = INPUT_KEYBOARD;
i.ki.wVk = vk;
i.ki.wScan = MapVirtualKey( vk, 0 );
i.ki.dwFlags = ( bDown ) ? 0 : KEYEVENTF_KEYUP;
vec.push_back( i );
}
void processKeyboardChars( BSTR strChars, cInputVec &vec )
{
USES_CONVERSION;
typedef std::stack< WORD > cMaskStack;
cMaskStack mask;
WORD wCurrentMask = 0;
std::string strParse = OLE2T( strChars );
for( std::string::iterator i = strParse.begin(); i != strParse.end(); )
{
switch( *i )
{
case _T( '+' ):
_ASSERTE( ( i + 2 ) < strParse.end() );
_ASSERTE( *( i + 1 ) == _T( '(' ) );
_ASSERTE( !( wCurrentMask & MASK_SHIFT ) );
wCurrentMask |= MASK_SHIFT;
mask.push( MASK_SHIFT );
// Send the keydown
pushVirtualKey( VK_SHIFT, vec, true );
i += 2;
break;
case _T( '^' ):
_ASSERTE( ( i + 2 ) < strParse.end() );
_ASSERTE( *( i + 1 ) == _T( '(' ) );
_ASSERTE( !( wCurrentMask & MASK_CTRL ) );
wCurrentMask |= MASK_CTRL;
mask.push( MASK_CTRL );
// Send the keydown
pushVirtualKey( VK_CONTROL, vec, true );
i += 2;
break;
case _T( '%' ):
_ASSERTE( ( i + 2 ) < strParse.end() );
_ASSERTE( *( i + 1 ) == _T( '(' ) );
_ASSERTE( !( wCurrentMask & MASK_ALT ) );
wCurrentMask |= MASK_ALT;
mask.push( MASK_ALT );
// Send the keydown
pushVirtualKey( VK_MENU, vec, true );
i += 2;
break;
case _T( ')' ):
_ASSERTE( mask.size() > 0 );
{
DWORD wMask = mask.top();
mask.pop();
switch( wMask )
{
case MASK_SHIFT:
pushVirtualKey( VK_SHIFT, vec, false );
break;
case MASK_CTRL:
pushVirtualKey( VK_CONTROL, vec, false );
break;
case MASK_ALT:
pushVirtualKey( VK_MENU, vec, false );
break;
default:
// Bad value in the stack
_ASSERTE( FALSE );
break;
}
wCurrentMask &= ~wMask;
}
++ i;
break;
case _T( '{' ):
// This is a special key
++ i;
{
for( std::string::iterator j = i; *j != _T( '}' ); ++ j )
{
_ASSERTE( j != strParse.end() );
}
std::string strSpecial( i, j );
for( cCharNames *i_name = _charnames; i_name != _end_charnames; ++ i_name )
{
if( strSpecial.compare( i_name->szName ) == 0 )
{
// We found the match, push and release the vkey
pushVirtualKey( i_name->m_nVKey, vec, true );
pushVirtualKey( i_name->m_nVKey, vec, false );
break;
}
}
// The special key was not found in the list
_ASSERTE( i_name != _end_charnames );
i = j + 1;
}
break;
default:
// Assume everything else is a text character but may require additional
// shifting
{
WORD wVkScan = VkKeyScan( *i ),
wAdditionalShift = ( wVkScan & SHIFT_MASK ) & ~wCurrentMask,
wVKey = wVkScan & VKEY_MASK;
if( wAdditionalShift & MASK_SHIFT )
pushVirtualKey( VK_SHIFT, vec, true );
if( wAdditionalShift & MASK_CTRL )
pushVirtualKey( VK_CONTROL, vec, true );
if( wAdditionalShift & MASK_ALT )
pushVirtualKey( VK_MENU, vec, true );
pushVirtualKey( wVKey, vec, true );
pushVirtualKey( wVKey, vec, false );
if( wAdditionalShift & MASK_ALT )
pushVirtualKey( VK_MENU, vec, false );
if( wAdditionalShift & MASK_CTRL )
pushVirtualKey( VK_CONTROL, vec, false );
if( wAdditionalShift & MASK_SHIFT )
pushVirtualKey( VK_SHIFT, vec, false );
}
++ i;
break;
}
}
// Make sure we released all shifts
_ASSERTE( wCurrentMask == 0 );
}
void pushMouseEvent( DWORD dwFlags, cInputVec &vec )
{
INPUT i;
::memset( &i, 0, sizeof( INPUT ) );
i.type = INPUT_MOUSE;
i.mi.dwFlags = dwFlags;
vec.push_back( i );
}
void processMouseInput( eMouseInput eType, cInputVec &vec )
{
DWORD dwError = ::GetLastError();
switch( eType )
{
case eMouseLeftDoubleClick:
pushMouseEvent( MOUSEEVENTF_LEFTDOWN, vec );
pushMouseEvent( MOUSEEVENTF_LEFTUP, vec );
case eMouseLeftClick:
pushMouseEvent( MOUSEEVENTF_LEFTDOWN, vec );
pushMouseEvent( MOUSEEVENTF_LEFTUP, vec );
break;
case eMouseRightDoubleClick:
pushMouseEvent( MOUSEEVENTF_RIGHTDOWN, vec );
pushMouseEvent( MOUSEEVENTF_RIGHTUP, vec );
case eMouseRightClick:
pushMouseEvent( MOUSEEVENTF_RIGHTDOWN, vec );
pushMouseEvent( MOUSEEVENTF_RIGHTUP, vec );
break;
default:
_ASSERTE( FALSE );
break;
}
}
HANDLE cInputBuffer::m_hThread = NULL;
HANDLE cInputBuffer::m_hInputWaiting = NULL;
HANDLE cInputBuffer::m_hTerm = NULL;
CRITICAL_SECTION cInputBuffer::m_csQueue;
cInputBuffer::cInputQueue cInputBuffer::m_queue;
DWORD WINAPI inputThreadProc( LPVOID pvParam );
void cInputBuffer::init()
{
::InitializeCriticalSection( &m_csQueue );
m_hTerm = ::CreateEvent( NULL, TRUE, FALSE, NULL );
m_hInputWaiting = ::CreateEvent( NULL, TRUE, FALSE, NULL );
DWORD dwThreadID;
m_hThread = ::CreateThread( NULL, 0, inputThreadProc, NULL, 0, &dwThreadID );
}
void cInputBuffer::term()
{
// Clear out the queue
::EnterCriticalSection( &m_csQueue );
while( m_queue.size() > 0 )
m_queue.pop_front();
::SetEvent( m_hTerm );
::LeaveCriticalSection( &m_csQueue );
::WaitForSingleObject( m_hThread, INFINITE );
::CloseHandle( m_hThread );
::CloseHandle( m_hInputWaiting );
::CloseHandle( m_hTerm );
::DeleteCriticalSection( &m_csQueue );
}
void cInputBuffer::postBuffer()
{
::EnterCriticalSection( &m_csQueue );
if( m_queue.empty() )
::SetEvent( m_hInputWaiting );
// Marshal our interface into a drop in in the queue
IStream *pStream;
::CoMarshalInterThreadInterfaceInStream( IID_IInputNotify, static_cast< IInputNotify * >( this ), &pStream );
m_queue.push_back( cInputQueue::value_type( this, pStream ) );
m_status = eInputWaiting;
::LeaveCriticalSection( &m_csQueue );
}
cInputVec *cInputBuffer::getLastInput()
{
if( m_actions.size() == 0 || m_actions.back().first != eActionInput )
// Add in a new buffer
m_actions.push_back( cActionList::value_type( eActionInput, VSBridge::auto_ptr< cAction >( new cInput ) ) );
// Return the last buffer
return &( static_cast< cInput * >( m_actions.back().second.get() )->m_input );
}
DWORD WINAPI inputThreadProc( LPVOID pvParam )
{
// This thread must join the mult-threaded apartment becasue it does
// not create a message loop
::CoInitializeEx( NULL, COINIT_MULTITHREADED );
BYTE prevKeyboard[ 256 ],
blankKeyboard[ 256 ];
::memset( blankKeyboard, 0, sizeof( blankKeyboard ) );
HANDLE hEvent[2] = { cInputBuffer::m_hInputWaiting, cInputBuffer::m_hTerm };
while( ::WaitForMultipleObjects( 2, hEvent, FALSE, INFINITE ) == WAIT_OBJECT_0 )
{
// Extract the next item from the stream
::EnterCriticalSection( &cInputBuffer::m_csQueue );
cInputBuffer *pBuffer = cInputBuffer::m_queue.front().first;
CComPtr< IInputNotify > pNotify;
::CoGetInterfaceAndReleaseStream( cInputBuffer::m_queue.front().second, IID_IInputNotify, reinterpret_cast< void ** >( &pNotify ) );
cInputBuffer::m_queue.pop_front();
if( cInputBuffer::m_queue.empty() )
::ResetEvent( cInputBuffer::m_hInputWaiting );
::LeaveCriticalSection( &cInputBuffer::m_csQueue );
// Save the keyboard state and take control of the input queue
::BlockInput( TRUE );
::GetKeyboardState( prevKeyboard );
::SetKeyboardState( blankKeyboard );
// Looking good, process the messages
pNotify->NotifyBegin();
// The delay list contains the breaks in the input, so we use the delay list as a master
// and use segments of the input queue
for( cInputBuffer::cActionList::iterator i = pBuffer->m_actions.begin(); i != pBuffer->m_actions.end(); ++ i )
i->second->execute( pNotify );
// Restore keyboard state
::SetKeyboardState( prevKeyboard );
pNotify->NotifyEnd();
::BlockInput( FALSE );
}
::CoUninitialize();
return 0;
}
// The action execution functions
void cInputBuffer::cInput::execute( IInputNotify * )
{
UINT nSent = SendInput( m_input.size(), &(*(m_input.begin())), sizeof( INPUT ) );
DWORD dwError = GetLastError();
_ASSERTE( nSent == m_input.size() );
}
void cInputBuffer::cDelay::execute( IInputNotify *pNotify )
{
if( m_bAllowInput )
{
BlockInput( FALSE );
pNotify->NotifyPause();
}
::Sleep( m_nMillis );
if( m_bAllowInput )
{
BlockInput( TRUE );
pNotify->NotifyBegin();
}
}
void cInputBuffer::cMouseMove::execute( IInputNotify *pib )
{
pib->SetMousePos( m_ptClient.x, m_ptClient.y );
}
STDMETHODIMP cInputBuffer::Clear()
{
if( m_status != eInputIdle )
{
_ASSERTE( FALSE );
return E_FAIL;
}
m_actions.clear();
return S_OK;
}
STDMETHODIMP cInputBuffer::TypeText(BSTR strText)
{
if( m_status != eInputIdle )
{
_ASSERTE( FALSE );
return E_FAIL;
}
processKeyboardChars( strText, *getLastInput() );
return S_OK;
}
STDMETHODIMP cInputBuffer::Delay(long nMilliseconds, VARIANT_BOOL bAllowInput )
{
if( m_status != eInputIdle )
{
_ASSERTE( FALSE );
return E_FAIL;
}
cDelay *pDelay = new cDelay;
pDelay->m_bAllowInput = !!bAllowInput;
pDelay->m_nMillis = nMilliseconds;
m_actions.push_back( cActionList::value_type( eActionDelay, VSBridge::auto_ptr< cAction >( pDelay ) ) );
return S_OK;
}
STDMETHODIMP cInputBuffer::MouseClick(long nX, long nY, eMouseInput eAction)
{
if( m_status != eInputIdle )
{
_ASSERTE( FALSE );
return E_FAIL;
}
// First insert a mouse movement
cMouseMove *pMM = new cMouseMove;
pMM->m_ptClient.x = nX;
pMM->m_ptClient.y = nY;
m_actions.push_back( cActionList::value_type( eActionMouseMove, VSBridge::auto_ptr< cAction >( pMM ) ) );
processMouseInput( eAction, *getLastInput() );
return S_OK;
}
STDMETHODIMP cInputBuffer::get_Status(eInputStatus *pVal)
{
_ASSERTE( pVal != NULL );
*pVal = m_status;
return S_OK;
}
STDMETHODIMP cInputBuffer::Run()
{
postBuffer();
return S_OK;
}
STDMETHODIMP cInputBuffer::NotifyBegin()
{
m_status = eInputRunning;
Fire_Begin();
return S_OK;
}
STDMETHODIMP cInputBuffer::NotifyEnd()
{
m_status = eInputIdle;
Fire_End();
return S_OK;
}
STDMETHODIMP cInputBuffer::SetMousePos(long nX, long nY)
{
// Convert to screen coords
POINT pt = { nX, nY };
::ClientToScreen( cManager::_p->m_hMain, &pt );
::SetCursorPos( pt.x, pt.y );
// Force the mouse message on the into the window proc
// This updates AC to be the new message location
cManager::_p->m_pfnOld( cManager::_p->m_hMain, WM_MOUSEMOVE, 0, MAKELONG( nX, nY ) );
return S_OK;
}
STDMETHODIMP cInputBuffer::NotifyPause()
{
Fire_Pause();
return S_OK;
}

123
Native/Inject/InputBuffer.h Normal file
View file

@ -0,0 +1,123 @@
// InputBuffer.h : Declaration of the cInputBuffer
#ifndef __INPUTBUFFER_H_
#define __INPUTBUFFER_H_
#include "resource.h" // main symbols
#include "InjectCP.h"
typedef std::vector< INPUT > cInputVec;
/////////////////////////////////////////////////////////////////////////////
// cInputBuffer
class ATL_NO_VTABLE cInputBuffer :
public CComObjectRootEx<CComMultiThreadModel>,
public IDispatchImpl<IInputNotify, &IID_IInputNotify, &LIBID_DecalPlugins>,
public IDispatchImpl<IInputBuffer, &IID_IInputBuffer, &LIBID_DecalPlugins>,
public IProvideClassInfo2Impl< &CLSID_InputBuffer, &DIID_IInputEvents, &LIBID_DecalPlugins >,
public CProxyIInputEvents< cInputBuffer >,
public IConnectionPointContainerImpl<cInputBuffer>
{
public:
cInputBuffer()
: m_status( eInputIdle )
{
}
BEGIN_COM_MAP(cInputBuffer)
COM_INTERFACE_ENTRY(IInputNotify)
COM_INTERFACE_ENTRY(IInputBuffer)
COM_INTERFACE_ENTRY(IProvideClassInfo)
COM_INTERFACE_ENTRY(IProvideClassInfo2)
COM_INTERFACE_ENTRY2(IDispatch, IInputBuffer)
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
END_COM_MAP()
BEGIN_CONNECTION_POINT_MAP(cInputBuffer)
CONNECTION_POINT_ENTRY(DIID_IInputEvents)
END_CONNECTION_POINT_MAP()
// Global functions to set up the input processing
// thread
static HANDLE m_hThread;
static HANDLE m_hTerm;
static HANDLE m_hInputWaiting;
static CRITICAL_SECTION m_csQueue;
typedef std::deque< std::pair< cInputBuffer *, LPSTREAM > > cInputQueue;
static cInputQueue m_queue;
static void init();
static void term();
void postBuffer();
cInputVec *getLastInput();
// Quick and dirty class hierarchy for input operations
class cAction
{
public:
// Run the action
virtual void execute( IInputNotify *pib ) = 0;
};
enum eActionType
{
eActionInput,
eActionDelay,
eActionMouseMove
};
class cInput
: public cAction
{
public:
cInputVec m_input;
virtual void execute( IInputNotify *pib );
};
class cDelay
: public cAction
{
public:
long m_nMillis;
bool m_bAllowInput;
virtual void execute( IInputNotify *pib );
};
class cMouseMove
: public cAction
{
public:
POINT m_ptClient;
virtual void execute( IInputNotify *pib );
};
typedef std::list< std::pair< eActionType, VSBridge::auto_ptr< cAction > > > cActionList;
cActionList m_actions;
eInputStatus m_status;
public:
// IInputBuffer Methods
STDMETHOD(Run)();
STDMETHOD(get_Status)(/*[out, retval]*/ eInputStatus *pVal);
STDMETHOD(MouseClick)(long nX, long nY, eMouseInput eAction);
STDMETHOD(Delay)(long nMilliseconds, VARIANT_BOOL bAllowInput);
STDMETHOD(TypeText)(BSTR strText);
STDMETHOD(Clear)();
// IInputNotify Methods
STDMETHOD(NotifyBegin)();
STDMETHOD(NotifyEnd)();
STDMETHOD(SetMousePos)(long nX, long nY);
STDMETHOD(NotifyPause)();
};
#endif //__INPUTBUFFER_H_

View file

@ -0,0 +1,26 @@
HKCR
{
Inject.InputBuffer.1 = s 'InputBuffer Class'
{
CLSID = s '{2F91FC21-4D89-4B64-94AE-A124D54563AE}'
}
Inject.InputBuffer = s 'InputBuffer Class'
{
CLSID = s '{2F91FC21-4D89-4B64-94AE-A124D54563AE}'
CurVer = s 'Inject.InputBuffer.1'
}
NoRemove CLSID
{
ForceRemove {2F91FC21-4D89-4B64-94AE-A124D54563AE} = s 'InputBuffer Class'
{
ProgID = s 'Inject.InputBuffer.1'
VersionIndependentProgID = s 'Inject.InputBuffer'
ForceRemove 'Programmable'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Both'
}
'TypeLib' = s '{3559E08B-827E-4DFE-9D33-3567246849CC}'
}
}
}

992
Native/Inject/LayerSite.cpp Normal file
View file

@ -0,0 +1,992 @@
// BarSite.cpp : Implementation of cBarSite
#include "stdafx.h"
#include "Inject.h"
#include "LayerSite.h"
#include "Manager.h"
#include "Button.h"
#include "Pager.h"
/////////////////////////////////////////////////////////////////////////////
// cBarSite
enum eSinkCaps
{
eSinkCapRender = 0x01,
eSinkCapMouse = 0x02,
eSinkCapKeyboard = 0x04,
eSinkCapPopup = 0x08,
eSinkCapTimer = 0x10
};
cLayerSite::cLayerSite()
: m_pParent( NULL ),
m_dwSinkCaps( 0 ),
m_Alpha( 255 )
{
}
cLayerSite::~cLayerSite()
{
// Make sure we're really destroyed
_ASSERTE( m_pParent == NULL );
_ASSERTE( m_children.size() == 0 );
}
void cLayerSite::removeChild( cLayerSite *pChild )
{
for( cChildList::iterator i = m_children.begin(); i != m_children.end(); ++ i )
{
if( *i == pChild )
{
m_children.erase( i );
break;
}
}
}
struct cSinkCapTest
{
eSinkCaps m_mask;
const IID *m_iid;
};
void cLayerSite::create( LayerParams *pParams, cLayerSite *pParent, ILayer *pSink )
{
// First copy all the relevant data
m_params = *pParams;
m_pParent = pParent;
static cSinkCapTest _capstest[] = {
{ eSinkCapRender, &IID_ILayerRender },
{ eSinkCapMouse, &IID_ILayerMouse },
{ eSinkCapKeyboard, &IID_ILayerKeyboard },
{ eSinkCapPopup, &IID_ILayerPopup },
{ eSinkCapTimer, &IID_ILayerTimer },
};
static cSinkCapTest *_end_caps = _capstest + ( sizeof( _capstest ) / sizeof( cSinkCapTest ) );
m_pSink = pSink;
// Probe for relevant interfaces
for( cSinkCapTest *i = _capstest; i != _end_caps; ++ i )
{
CComPtr< IUnknown > pUnk;
if( SUCCEEDED( pSink->QueryInterface( *( i->m_iid ), reinterpret_cast< void ** >( &pUnk ) ) ) )
m_dwSinkCaps |= i->m_mask;
}
// Do initialization activities
if( !( m_params.render & eRenderClipped ) )
{
// Create the back buffer
SIZE sz = { m_params.pos.right - m_params.pos.left, m_params.pos.bottom - m_params.pos.top };
if( sz.cx > 0 && sz.cy > 0 )
cManager::_p->CreateCanvas( &sz, &m_pBuffer );
}
// Add in the default render flags
// All layer begin their life transparent until set otherwise
m_params.render |= eRenderTransparent;
// Make this control format itself next round
Reformat();
Invalidate();
m_pSink->LayerCreate( this );
}
void cLayerSite::destroy()
{
// First destroy all of our children
while( !m_children.empty() )
{
#ifdef _DEBUG
int nChildren = m_children.size();
m_children.front()->destroy();
_ASSERTE( m_children.size() == ( nChildren - 1 ) );
#else
m_children.front()->destroy();
#endif
}
// Remove from parent
if( m_pParent != NULL )
{
m_pParent->removeChild( this );
m_pParent = NULL;
}
// The child now releases the reference - this should trick our reference count to 0
m_pSink->LayerDestroy();
// After LayerDestroy returns this object has already been deleted -
// do not touch any data members and we're OK
// Reset capture pointers
if( cManager::_p->m_pMouseDown == this )
cManager::_p->m_pMouseDown = NULL;
if( cManager::_p->m_pMouseOver == this )
cManager::_p->m_pMouseOver = NULL;
if( cManager::_p->m_pKeyboard == this )
cManager::_p->m_pKeyboard = NULL;
for( cManager::cLayerList::iterator i = cManager::_p->m_popups.begin(); i != cManager::_p->m_popups.end(); ++ i )
{
if( *i == this )
{
cManager::_p->m_popups.erase( i );
break;
}
}
}
void cLayerSite::format()
{
// ::MessageBox( NULL, _T( "cLayerSite::format" ), _T( "Inject.dll" ), MB_OK );
// This is no longer recursive - in all cases, parents position their children
formatLayer();
}
void cLayerSite::formatLayer()
{
// Check for timers
if( m_timers.size() > 0 )
{
long nCurrentTime = ::timeGetTime();
for( cTimerList::iterator i = m_timers.begin(); i != m_timers.end(); )
{
if( ( i->m_nLastTimeout + i->m_nInterval ) <= nCurrentTime )
{
// Default to false, prevent the assert from going off *lots*
VARIANT_BOOL bContinue = VARIANT_FALSE;
++ i->m_nRepetitions;
if( m_dwSinkCaps & eSinkCapTimer )
{
CComPtr< ILayerTimer > pTimer;
m_pSink->QueryInterface( &pTimer );
pTimer->TimerTimeout( i->m_nID, nCurrentTime - i->m_nLastTimeout, i->m_nRepetitions, &bContinue );
}
if( bContinue )
i->m_nLastTimeout = nCurrentTime;
else
{
// Do not continue timing
i = m_timers.erase( i );
continue;
}
}
++ i;
}
}
// When reformatting - never reformat a surface that's 0,0 size
if( ( m_params.render & eRenderReformatNext ) &&
m_params.pos.right > m_params.pos.left &&
m_params.pos.bottom > m_params.pos.top )
{
// Do a reformat - NOTE: it's done here becasue a reformat will almost
// always destroy the surface
if( m_dwSinkCaps & eSinkCapRender )
{
CComPtr< ILayerRender > pLayer;
m_pSink->QueryInterface( &pLayer );
pLayer->Reformat();
}
// Clear the reformat flag
m_params.render &= ~eRenderReformatNext;
}
// Iterate over the children
for( cChildList::iterator i = m_children.begin(); i != m_children.end(); ++ i )
( *i )->formatLayer();
}
void cLayerSite::prerender()
{
if( m_dwSinkCaps & eSinkCapRender )
{
CComPtr< ILayerRender > pRender;
m_pSink->QueryInterface( &pRender );
pRender->PreRender();
}
// Iterate over the children
for( cChildList::iterator i = m_children.begin(); i != m_children.end(); ++ i )
( *i )->prerender();
}
void cLayerSite::render(ICanvas *pPrimary)
{
if( !( m_params.render & eRenderClipped ) )
{
// Check for 0,0 size
if( m_params.pos.right > m_params.pos.left && m_params.pos.bottom > m_params.pos.top )
{
// ::MessageBox( NULL, _T( "cLayerSite::render" ), _T( "Inject.dll" ), MB_OK );
_ASSERTE( m_pBuffer.p != NULL );
VARIANT_BOOL bRedraw;
m_pBuffer->get_WasLost( &bRedraw );
// Here we push a scratch clip rect for the entire area
// This is intended for unclipped layers that modfiy their
// child clipping area.
RECT rcAll = { 0, 0, m_params.pos.right - m_params.pos.left, m_params.pos.bottom - m_params.pos.top };
VARIANT_BOOL bDrawChildren;
m_pBuffer->PushClipRect( &rcAll, &bDrawChildren );
// Assuming this area is non-0 size
_ASSERTE( bDrawChildren );
renderBuffer( m_pBuffer, !!bRedraw );
m_pBuffer->PopClipRect();
// Place it on the screen
POINT pt = { m_params.pos.left, m_params.pos.top };
RECT rc = { 0, 0, m_params.pos.right - m_params.pos.left, m_params.pos.bottom - m_params.pos.top };
pPrimary->put_Alpha(m_Alpha);
pPrimary->Blt( &rc, m_pBuffer, &pt );
}
else
// This object has no size, it should have no canvas
_ASSERTE( m_pBuffer.p == NULL );
}
// Iterate through children - look for more non-clipped layers to render
for( cChildList::iterator i = m_children.begin(); i != m_children.end(); ++ i )
( *i )->render( pPrimary );
}
void cLayerSite::renderBuffer( ICanvas *pBuffer, bool bForce )
{
// Remove the next flag
VARIANT_BOOL bRenderChildren = VARIANT_TRUE;
bool bRendered = bForce;
if( m_dwSinkCaps & eSinkCapRender )
{
CComPtr< ILayerRender > pLayer;
m_pSink->QueryInterface( &pLayer );
if( bForce || ( m_params.render & eRenderNext ) )
{
if( !( m_params.render & eRenderClipped ) )
{
RECT rcClient = { 0, 0, m_params.pos.right - m_params.pos.left, m_params.pos.bottom - m_params.pos.top };
// Unclipped layers all get an inital transparent fill
m_pBuffer->Fill( &rcClient, RGB( 0, 255, 255 ) );
}
bRendered = true;
pLayer->Render( pBuffer );
}
pLayer->AdjustRenderArea( pBuffer, &bRenderChildren );
}
m_params.render &= ~eRenderNext;
if( !bRenderChildren )
// While adjusting the render parameters, the rectangle got clipped out of existance
return;
// Walk through the children and transform the surface params
for( cChildList::iterator i = m_children.begin(); i != m_children.end(); ++ i )
{
if( !( ( *i )->m_params.render & eRenderClipped ) )
// Only clipped children
continue;
// Clip the child rectangle
VARIANT_BOOL bRenderChild;
pBuffer->PushClipRect( &( *i )->m_params.pos, &bRenderChild );
if( bRenderChild )
// Iterate
( *i )->renderBuffer( pBuffer, bRendered );
pBuffer->PopClipRect();
}
}
void cLayerSite::reformat()
{
if( m_dwSinkCaps & eSinkCapRender )
// Schedule a reformat for next render cycle
m_params.render |= eRenderReformatNext;
// Propagate reformat to children
for( cChildList::iterator i = m_children.begin(); i != m_children.end(); ++ i )
( *i )->reformat();
}
cLayerSite *cLayerSite::hitTestUnclipped( POINTS pt, ICanvas *pCanvas )
{
// First test if any children have been hit and delegate to them
// as children have a higher z-order value
cLayerSite *pSite;
for( cChildList::reverse_iterator i = m_children.rbegin(); i != m_children.rend(); ++ i )
{
pSite = ( *i )->hitTestUnclipped( pt, pCanvas );
if( pSite != NULL )
// Found a child hit - overlapping children are not tested
// as there is no sibling clipping
return pSite;
}
// Children are not hit, check if we hit ourselves
if( !( m_params.render & eRenderClipped ) )
{
POINT ptl = { pt.x, pt.y };
VARIANT_BOOL bVisible;
pCanvas->PushClipRect( &m_params.pos, &bVisible );
cLayerSite *pHit = NULL;
if( bVisible )
{
VARIANT_BOOL bHit;
pCanvas->HitTest( &ptl, &bHit );
if( bHit )
{
// Check for transparent area hitting
if( ( m_dwSinkCaps & eSinkCapRender ) && ( m_params.render & eRenderTransparent ) )
{
// This may contain transparent areas
// TODO: Check for transparent areas
pHit = this;
}
else
pHit = this;
}
}
pCanvas->PopClipRect();
return pHit;
}
// Nothing hit in this branch
return NULL;
}
cLayerSite *cLayerSite::hitTestClipped( POINTS pt, LPPOINT pptHit, ICanvas *pCanvas )
{
// ::MessageBox( NULL, _T( "cLayerSite::hitTestClipped" ), _T( "Inject.dll" ), MB_OK );
// Convert the render params
VARIANT_BOOL bRenderChildren = VARIANT_TRUE;
if( m_dwSinkCaps & eSinkCapRender )
{
CComPtr< ILayerRender > pLayer;
m_pSink->QueryInterface( &pLayer );
pLayer->AdjustRenderArea( pCanvas, &bRenderChildren );
}
POINT ptm = { pt.x, pt.y };
if( bRenderChildren )
{
for( cChildList::reverse_iterator i = m_children.rbegin(); i != m_children.rend(); ++ i )
{
if( !( ( *i )->m_params.render & eRenderClipped ) )
// Only clipped children
continue;
// Clip the child rectangle
VARIANT_BOOL bVisible;
pCanvas->PushClipRect( &( *i )->m_params.pos, &bVisible );
if( bVisible )
{
VARIANT_BOOL bHit;
pCanvas->HitTest( &ptm, &bHit );
if( bHit )
{
cLayerSite *pRet = ( *i )->hitTestClipped( pt, pptHit, pCanvas );
pCanvas->PopClipRect();
return pRet;
}
}
pCanvas->PopClipRect();
}
}
*pptHit = ptm;
pCanvas->ToClient( pptHit );
return this;
}
cLayerSite *cLayerSite::hitTest( POINTS pt, LPPOINT pptHit, ICanvas *pCanvas )
{
// First, find the unclipped parent
cLayerSite *pHitUnclipped = hitTestUnclipped( pt, pCanvas );
if( pHitUnclipped == NULL )
// Absolutely nothing hit
return NULL;
VARIANT_BOOL bVisible;
pCanvas->PushClipRect( &pHitUnclipped->m_params.pos, &bVisible );
cLayerSite *pHitClipped = pHitUnclipped->hitTestClipped( pt, pptHit, pCanvas );
pCanvas->PopClipRect();
return pHitClipped;
}
void cLayerSite::clipCanvas(ICanvas *pCanvas)
{
if( m_params.render & eRenderClipped )
m_pParent->clipCanvas( pCanvas );
VARIANT_BOOL bVisible;
pCanvas->PushClipRect( &m_params.pos, &bVisible );
if( m_dwSinkCaps & eSinkCapRender )
{
CComPtr< ILayerRender > pLayer;
m_pSink->QueryInterface( &pLayer );
pLayer->AdjustRenderArea( pCanvas, &bVisible );
}
}
bool cLayerSite::isClippedChild( cLayerSite *pChild )
{
for( cLayerSite *pChildLayer = pChild; pChild != NULL; pChild = pChild->m_pParent )
{
if( pChildLayer == this )
return true;
if( !( pChildLayer->m_params.render & eRenderClipped ) )
break;
}
return false;
}
bool cLayerSite::isChild( cLayerSite *pChild )
{
for( cLayerSite *pChildLayer = pChild; pChildLayer != NULL; pChildLayer = pChildLayer->m_pParent )
{
if( pChildLayer == this )
return true;
}
return false;
}
cLayerSite *cLayerSite::getCommonClippedParent( cLayerSite *pHit )
{
for( cLayerSite *pCurrentParent = this; pCurrentParent != NULL; pCurrentParent = pCurrentParent->m_pParent )
{
for( cLayerSite *pHitParent = pHit; pHitParent != NULL; pHitParent = pHitParent->m_pParent )
{
if( pHitParent == pCurrentParent )
return pHitParent;
if( !( pCurrentParent->m_params.render & eRenderClipped ) )
break;
}
if( !( pCurrentParent->m_params.render & eRenderClipped ) )
break;
}
return NULL;
}
void cLayerSite::sendMouseEnter( cLayerSite *pCommonParent, MouseState *pMS )
{
if( pCommonParent != this && ( m_params.render & eRenderClipped ) )
// Enter our parent first - note that we stop at the unclipped parent
m_pParent->sendMouseEnter( pCommonParent, pMS );
if( m_dwSinkCaps & eSinkCapMouse )
{
CComPtr< ILayerMouse > pLayer;
m_pSink->QueryInterface( &pLayer );
pLayer->MouseEnter( pMS );
}
}
void cLayerSite::sendMouseExit( cLayerSite *pCommonParent, MouseState *pMS )
{
for( cLayerSite *pExit = this; pExit != pCommonParent; pExit = pExit->m_pParent )
{
if( !( pExit->m_params.render & eRenderClipped ) )
// Common parent may be set to NULL if we're switching
// to another unclipped parent
break;
if( pExit->m_dwSinkCaps & eSinkCapMouse )
{
CComPtr< ILayerMouse > pLayer;
pExit->m_pSink->QueryInterface( &pLayer );
pLayer->MouseExit( pMS );
}
}
}
void cLayerSite::sendMouseDown( MouseState *pMS )
{
if( m_dwSinkCaps & eSinkCapMouse )
{
CComPtr< ILayerMouse > pLayer;
m_pSink->QueryInterface( &pLayer );
pLayer->MouseDown( pMS );
}
}
void cLayerSite::sendMouseUp( MouseState *pMS )
{
if( m_dwSinkCaps & eSinkCapMouse )
{
CComPtr< ILayerMouse > pLayer;
m_pSink->QueryInterface( &pLayer );
pLayer->MouseUp( pMS );
}
}
void cLayerSite::sendMouseMove( MouseState *pMS )
{
if( m_dwSinkCaps & eSinkCapMouse )
{
CComPtr< ILayerMouse > pLayer;
m_pSink->QueryInterface( &pLayer );
pLayer->MouseMove( pMS );
}
}
void cLayerSite::sendMouseDblClk( MouseState *pMS )
{
if( m_dwSinkCaps & eSinkCapMouse )
{
CComPtr< ILayerMouse > pLayer;
m_pSink->QueryInterface( &pLayer );
pLayer->MouseDblClk( pMS );
}
}
void cLayerSite::sendMouseEvent( long nMsg, long wParam, long lParam )
{
if( m_dwSinkCaps & eSinkCapMouse )
{
CComPtr< ILayerMouse > pLayer;
m_pSink->QueryInterface( &pLayer );
pLayer->MouseEvent( nMsg, wParam, lParam );
}
}
void cLayerSite::sendKeyboardEndCapture( VARIANT_BOOL bCancel )
{
if( m_dwSinkCaps & eSinkCapKeyboard )
{
CComPtr< ILayerKeyboard > pLayer;
m_pSink->QueryInterface( &pLayer );
pLayer->KeyboardEndCapture( bCancel );
}
}
void cLayerSite::sendKeyboardChar( KeyState *pKS )
{
if( m_dwSinkCaps & eSinkCapKeyboard )
{
CComPtr< ILayerKeyboard > pLayer;
m_pSink->QueryInterface( &pLayer );
pLayer->KeyboardChar( pKS );
}
}
void cLayerSite::sendKeyboardEvent( long nMsg, long wParam, long lParam )
{
if( m_dwSinkCaps & eSinkCapKeyboard )
{
CComPtr< ILayerKeyboard > pLayer;
m_pSink->QueryInterface( &pLayer );
pLayer->KeyboardEvent( nMsg, wParam, lParam );
}
}
bool cLayerSite::sendPopupCancel( MouseState *pMS )
{
if( m_dwSinkCaps & eSinkCapPopup )
{
CComPtr< ILayerPopup > pLayer;
m_pSink->QueryInterface( &pLayer );
VARIANT_BOOL bContinue;
pLayer->PopupCancel( pMS, &bContinue );
return !!bContinue;
}
// Default action is to cancel the popup
return false;
}
STDMETHODIMP cLayerSite::Destroy()
{
cManager::_p->m_destroy.push_back( this );
AddRef();
return S_OK;
}
STDMETHODIMP cLayerSite::CreateChild(LayerParams *params, ILayer *pSink)
{
CComObject< cLayerSite > *pChild;
CComObject< cLayerSite >::CreateInstance( &pChild );
pChild->create( params, this, pSink );
m_children.push_back( pChild );
return S_OK;
}
STDMETHODIMP cLayerSite::GetSink(REFIID iid, void **ppvItf)
{
return m_pSink->QueryInterface( iid, ppvItf );
}
STDMETHODIMP cLayerSite::Invalidate()
{
for( cLayerSite *pSite = this; pSite != NULL; pSite = pSite->m_pParent )
{
if( !( pSite->m_params.render & eRenderTransparent ) || !( pSite->m_params.render & eRenderClipped ) || pSite->m_pParent == NULL )
break;
}
pSite->m_params.render |= eRenderNext;
return S_OK;
}
STDMETHODIMP cLayerSite::get_PluginSite(IPluginSite **ppSite)
{
*ppSite = cManager::_p;
( *ppSite )->AddRef();
return S_OK;
}
STDMETHODIMP cLayerSite::Reformat()
{
if( m_params.pos.right != m_params.pos.left && m_params.pos.top != m_params.pos.bottom &&
m_dwSinkCaps & eSinkCapRender )
m_params.render |= eRenderReformatNext;
return S_OK;
}
STDMETHODIMP cLayerSite::GetParentSink(REFIID iid, void **ppvItf)
{
for( cLayerSite *pSite = m_pParent; pSite != NULL; pSite = pSite->m_pParent )
{
HRESULT hRes = pSite->m_pSink->QueryInterface( iid, ppvItf );
if( SUCCEEDED( hRes ) )
// Found our requested interface, return happy
return hRes;
}
return E_NOINTERFACE;
}
STDMETHODIMP cLayerSite::get_Position(LPRECT pVal)
{
_ASSERTE( pVal != NULL );
*pVal = m_params.pos;
return S_OK;
}
STDMETHODIMP cLayerSite::put_Position(LPRECT newVal)
{
_ASSERTE( newVal != NULL );
_ASSERTE( newVal->right >= newVal->left && newVal->bottom >= newVal->top );
m_params.pos = *newVal;
if( !( m_params.render & eRenderClipped ) )
{
// This is unclipped, check the buffer size
bool bHasBuffer = ( m_params.pos.right > m_params.pos.left && m_params.pos.bottom > m_params.pos.top );
if( bHasBuffer )
{
SIZE sz = { m_params.pos.right - m_params.pos.left, m_params.pos.bottom - m_params.pos.top };
if( m_pBuffer.p == NULL )
cManager::_p->CreateCanvas( &sz, &m_pBuffer );
else
m_pBuffer->put_Size( &sz );
}
else
{
if( m_pBuffer.p != NULL )
m_pBuffer.Release();
}
}
// Mark for format change only if area > 0
Reformat();
return S_OK;
}
STDMETHODIMP cLayerSite::get_ID(long *pVal)
{
_ASSERTE( pVal != NULL );
*pVal = m_params.ID;
return S_OK;
}
STDMETHODIMP cLayerSite::get_ChildCount(long *pVal)
{
_ASSERTE( pVal != NULL );
*pVal = m_children.size();
return S_OK;
}
STDMETHODIMP cLayerSite::get_Child(long nIndex, ePositionType posType, ILayerSite **pVal)
{
_ASSERTE( pVal != NULL );
if( posType == ePositionByIndex )
{
if( nIndex < 0 || nIndex >= m_children.size() )
// Out of range
return E_INVALIDARG;
*pVal = m_children[ nIndex ];
( *pVal )->AddRef();
return S_OK;
}
if( posType != ePositionByID )
// Invalid position type
return E_INVALIDARG;
// Scan for child by ID
for( cChildList::iterator i = m_children.begin(); i != m_children.end(); ++ i )
{
if( ( *i )->m_params.ID == nIndex )
{
*pVal = *i;
( *pVal )->AddRef();
return S_OK;
}
}
// Invalid Index
return E_INVALIDARG;
}
void cLayerSite::moveChildToFront(long nIndex) {
// TODO : Fix this, it doesn't properly move the Z order of the children if they are at the front
if( m_children.back()->m_params.ID == nIndex )
return;
for (cChildList::iterator i = m_children.begin(); i != m_children.end(); ++i) {
if((*i)->m_params.ID == nIndex) {
cLayerSite *layerSite = *i;
m_children.erase(i);
m_children.push_back(layerSite);
break;
}
}
}
STDMETHODIMP cLayerSite::moveToFront() {
_ASSERTE(m_pParent);
m_pParent->moveChildToFront(m_params.ID);
return S_OK;
}
STDMETHODIMP cLayerSite::CaptureKeyboard()
{
// Cancel capture in the existing keyboard capture- if any
// Don't fire EndCapture if we already have the capture. cyn -- 15/10/2002
if( ( cManager::_p->m_pKeyboard != NULL ) && ( cManager::_p->m_pKeyboard != this ) )
cManager::_p->m_pKeyboard->sendKeyboardEndCapture( VARIANT_TRUE );
// Start capturing
cManager::_p->m_pKeyboard = this;
return S_OK;
}
STDMETHODIMP cLayerSite::IsChild(ILayerSite *pSite, VARIANT_BOOL bTestUnclipped, VARIANT_BOOL *pbIsChild)
{
cLayerSite *pInternalSite = static_cast< cLayerSite * >( pSite );
*pbIsChild = ( ( bTestUnclipped ) ? isChild( pInternalSite ) : isClippedChild( pInternalSite ) ) ? VARIANT_TRUE : VARIANT_FALSE;
return S_OK;
}
STDMETHODIMP cLayerSite::put_Popup(VARIANT_BOOL newVal)
{
if( newVal )
{
#ifdef _DEBUG
// Check for an existing popup record
for( cManager::cLayerList::iterator i = cManager::_p->m_popups.begin(); i != cManager::_p->m_popups.end(); ++ i )
_ASSERTE( *i != this );
#endif
// Ok, add it into the list
cManager::_p->m_popups.push_back( this );
}
else
{
for( cManager::cLayerList::iterator i = cManager::_p->m_popups.begin(); i != cManager::_p->m_popups.end(); ++ i )
{
if( *i == this )
{
cManager::_p->m_popups.erase( i );
return S_OK;
}
}
// This popup is not in the list
_ASSERTE( FALSE );
}
return S_OK;
}
STDMETHODIMP cLayerSite::get_ScreenPosition(LPRECT pVal)
{
CComPtr< ICanvas > pPrimary;
cManager::_p->GetPrimarySurface( &pPrimary );
{
ClipParams cp;
pPrimary->GetClipParams( &cp );
// First push the identity RECT
RECT rcIdentity = { 0, 0, cp.window.right - cp.window.left, cp.window.bottom - cp.window.top };
VARIANT_BOOL bVisible;
pPrimary->PushClipRect( &rcIdentity, &bVisible );
// Now set the origin
POINT pt = { cp.window.left, cp.window.top };
pPrimary->OffsetOrg( &pt, &bVisible );
}
// ::MessageBox( NULL, _T( "cLayerSite::get_ScreenPosition" ), _T( "Inject.dll" ), MB_OK );
clipCanvas( pPrimary );
// Extract the bounds
ClipParams cp;
pPrimary->GetClipParams( &cp );
*pVal = cp.window;
return S_OK;
}
STDMETHODIMP cLayerSite::StartTimer(long nID, long nInterval)
{
#ifdef _DEBUG
// Walk through the list of timers to make sure the ID isn't in use
for( cTimerList::iterator i = m_timers.begin(); i != m_timers.end(); ++ i )
_ASSERTE( i->m_nID != nID );
#endif
// NOTE: An interval of 0 is valid in that it'll fire every frame, this would be an
// alternate method to creating an animated layer
_ASSERTE( nInterval >= 0 );
// The layer should implement ILayerTimer
_ASSERTE( m_dwSinkCaps & eSinkCapTimer );
// Add in the timer
cTimer t = { ::timeGetTime(), nID, nInterval, 0 };
m_timers.push_back( t );
return S_OK;
}
STDMETHODIMP cLayerSite::EndTimer(long nID)
{
// Find the timer by ID
for( cTimerList::iterator i = m_timers.begin(); i != m_timers.end(); ++ i )
{
if( i->m_nID == nID )
{
m_timers.erase( i );
return S_OK;
}
}
return E_INVALIDARG;
}
STDMETHODIMP cLayerSite::get_Transparent(VARIANT_BOOL *pVal)
{
_ASSERTE( pVal != NULL );
*pVal = ( m_params.render & eRenderTransparent ) ? VARIANT_TRUE : VARIANT_FALSE;
return S_OK;
}
STDMETHODIMP cLayerSite::put_Transparent(VARIANT_BOOL newVal)
{
if( newVal )
m_params.render |= eRenderTransparent;
else
m_params.render &= ~eRenderTransparent;
return S_OK;
}
STDMETHODIMP cLayerSite::put_Alpha(long Alpha)
{
m_Alpha = Alpha;
return S_OK;
}

126
Native/Inject/LayerSite.h Normal file
View file

@ -0,0 +1,126 @@
// LayerSite.h : Declaration of the cLayerSite
#ifndef __LAYERSITE_H
#define __LAYERSITE_H
#include "resource.h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// cBarSite
class ATL_NO_VTABLE cLayerSite :
public CComObjectRootEx<CComMultiThreadModel>,
public ILayerSite
{
public:
typedef std::vector< cLayerSite * > cChildList;
cChildList m_children;
cLayerSite *m_pParent;
CComPtr< ICanvas > m_pBuffer;
DWORD m_dwSinkCaps;
CComPtr< ILayer > m_pSink;
LayerParams m_params;
struct cTimer
{
long m_nLastTimeout,
m_nID,
m_nInterval,
m_nRepetitions;
};
long m_Alpha;
typedef std::list< cTimer > cTimerList;
cTimerList m_timers;
cLayerSite();
~cLayerSite();
// Child notification of destruction, remove the child
// from the list.
void removeChild( cLayerSite *pChild );
// Scan our callback for capabilities - also perform some internal
// initialization
void create( LayerParams *pParams, cLayerSite *pParent, ILayer *pSink );
void destroy();
// Rendering operations
void format();
void formatLayer();
void prerender();
void render( ICanvas *pPrimary );
void renderBuffer( ICanvas *pCanvas, bool bForceDraw );
// Force a reformat for all layers - this usually occurs only
// on a video-mode change
void reformat();
void moveChildToFront(long nIndex);
// Mouse operations
cLayerSite *hitTestUnclipped( POINTS pt, ICanvas *pCanvas );
cLayerSite *hitTestClipped( POINTS pt, LPPOINT pptHit, ICanvas *pCanvas );
cLayerSite *hitTest( POINTS pt, LPPOINT pptHit, ICanvas *pCanvas );
void clipCanvas( ICanvas *pCanvas );
bool isClippedChild( cLayerSite *pChild );
bool isChild( cLayerSite *pChild );
cLayerSite *getCommonClippedParent( cLayerSite *pOther );
void sendMouseEnter( cLayerSite *pCommonParent, MouseState *pMS );
void sendMouseExit( cLayerSite *pCommonParent, MouseState *pMS );
void sendMouseMove( MouseState *pMS );
void sendMouseDown( MouseState *pMS );
void sendMouseUp( MouseState *pMS );
void sendMouseDblClk( MouseState *pMS );
void sendMouseEvent( long nMsg, long wParam, long lParam );
void sendKeyboardEndCapture( VARIANT_BOOL bCancel );
void sendKeyboardChar( KeyState *pKS );
void sendKeyboardEvent( long nMsg, long wParam, long lParam );
bool sendPopupCancel( MouseState *pMS );
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(cLayerSite)
COM_INTERFACE_ENTRY(ILayerSite)
END_COM_MAP()
// ILayerSite
public:
STDMETHOD(CreateChild)(LayerParams *params, ILayer *pSink);
STDMETHOD(get_Position)(/*[out, retval]*/ RECT *pVal);
STDMETHOD(put_Position)(/*[in]*/ RECT *newVal);
STDMETHOD(get_ScreenPosition)(/*[out, retval]*/ RECT *pVal);
STDMETHOD(Reformat)();
STDMETHOD(Destroy)();
STDMETHOD(Invalidate)();
STDMETHOD(get_Transparent)(/*[out, retval]*/ VARIANT_BOOL *pVal);
STDMETHOD(put_Transparent)(/*[in]*/ VARIANT_BOOL newVal);
STDMETHOD(get_PluginSite)(IPluginSite **ppSite);
STDMETHOD(GetSink)(REFIID iid, void **ppvItf);
STDMETHOD(GetParentSink)(REFIID iid, /*[iid_is(iid)]*/ void **ppvItf);
STDMETHOD(get_Child)(long nIndex, /*[defaultvalue(ePositionByIndex)]*/ ePositionType posType, /*[out, retval]*/ ILayerSite* *pVal);
STDMETHOD(get_ChildCount)(/*[out, retval]*/ long *pVal);
STDMETHOD(get_ID)(/*[out, retval]*/ long *pVal);
STDMETHOD(IsChild)(ILayerSite *pSite, /*[optional, defaultvalue(VARIANT_FALSE)]*/ VARIANT_BOOL bTestUnclipped, /*[out, retval]*/ VARIANT_BOOL *pbIsChild);
STDMETHOD(moveToFront)();
STDMETHOD(CaptureKeyboard)();
STDMETHOD(put_Popup)(/*[in]*/ VARIANT_BOOL newVal);
STDMETHOD(StartTimer)(long nID, long nInterval);
STDMETHOD(EndTimer)(long nID);
STDMETHOD(put_Alpha)(long Alpha);
};
#endif //__LAYERSITE_H

1632
Native/Inject/Manager.cpp Normal file

File diff suppressed because it is too large Load diff

237
Native/Inject/Manager.h Normal file
View file

@ -0,0 +1,237 @@
// Manager.h : Declaration of the cManager
#ifndef __MANAGER_H_
#define __MANAGER_H_
#include "resource.h" // main symbols
#include "LayerSite.h"
#include "BarLayer.h"
#include "DatFile.h"
#include "Panel.h"
#include <Decal.h>
#include "..\Decal\ACHooks.h"
class cIconCache;
class cImage;
class cFontCache;
#define ChatTextHook 102
#define ChatMessageHook 103
extern const IID EVTID_AcHooks ;
// Template class used to connect ACHooks events
template<UINT nID, class cImpl >class IACHooksEventsImpl
:public IDispEventImpl<nID, cImpl, &EVTID_AcHooks, &LIBID_Decal, 1, 0 >
{
public: HRESULT advise(IUnknown *pUnk){return DispEventAdvise(pUnk);}
HRESULT unadvise(IUnknown *pUnk){return DispEventUnadvise(pUnk);}
};
/////////////////////////////////////////////////////////////////////////////
// cManager
class ATL_NO_VTABLE cManager :
public CComObjectRootEx<CComMultiThreadModel>,
public IACHooksEventsImpl<ChatMessageHook, cManager>,
public IACHooksEventsImpl<ChatTextHook, cManager>,
public IPluginSite
{
public:
cManager();
~cManager();
void setDirectDraw( IDirectDraw4 *pDD, IDirect3D3 *pD3D, IDirectDrawSurface4 *pDDS );
void setSurface( IDirect3DDevice3 *pDevice );
void init();
void term();
void loadPlugin ( IUnknown *pUnk );
void unloadPlugins ();
void setWindow( HWND hWnd );
void draw2D();
void draw3D();
void sendPreBeginScene();
void sendPostBeginScene();
void sendPreEndScene();
void sendPostEndScene();
void clearDestroyList();
void __stdcall onChatMessage(BSTR bstrText, long lColor, VARIANT_BOOL *pbEat);
void __stdcall onChatText(BSTR bstrText, VARIANT_BOOL *pbEat);
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(cManager)
COM_INTERFACE_ENTRY(IPluginSite)
END_COM_MAP()
BEGIN_SINK_MAP(cManager)
SINK_ENTRY_EX( ChatMessageHook, EVTID_AcHooks, 2, onChatMessage)
SINK_ENTRY_EX( ChatTextHook, EVTID_AcHooks, 3, onChatText)
END_SINK_MAP()
class cMemLocs
{
public:
_bstr_t bstrName;
DWORD dwValue;
};
// Data members for the plugin objects
class cPlugin
{
public:
DWORD m_dwSinkCaps;
IUnknown *m_pPlugin;
};
long m_nNextPlugin;
typedef std::list< cPlugin > cPluginList;
cPluginList m_plugins;
// Data for windowing
// The root window pair
cLayerSite *m_pRootSite;
// Various capture information
cLayerSite *m_pMouseOver,
*m_pMouseDown,
*m_pKeyboard;
// Popup recoil structures
typedef std::list< cLayerSite * > cLayerList;
cLayerList m_popups;
// Destruction queue
cLayerList m_destroy;
// Icon Cache Management
typedef std::list< cIconCache * > cIconsList;
cIconsList m_icons;
// Image Cache Management
typedef std::list< cImage * > cImagesList;
cImagesList m_images;
void removeImage( cImage * );
// Font Cache Management
typedef std::list< cFontCache * > cFontsList;
cFontsList m_fonts;
void removeFont( cFontCache * );
// AC Data Files
cDatFile m_portal;
// Hooked stuff
HWND m_hMain;
WNDPROC m_pfnOld;
DWORD m_dwROT;
//HANDLE m_hDrawSync;
bool m_bInitialized;
bool m_bContainer;
bool m_bXMLViewViewer;
cRootLayer* m_pRootLayer;
DWORD m_dwChatMessageAddy;
long m_lPrevSelKey;
CComPtr< IACHooks > m_pHooks;
eAlphaBlendOptions m_eAlphaBlendMode;
// std::list< LPDIRECTDRAWSURFACE4 > SurfaceList;
IDirectDraw4 *m_pD;
IDirect3D3 *m_p3D;
IDirect3DDevice3 *m_p3DDevice;
IDirectDrawSurface4 *m_pPrimarySurface;
LPVOID m_lpSurface;
HMODULE m_hDecalDLL;
bool m_bSoftware;
public:
static CComObject< cManager > *_p;
CComPtr< IDecal > m_pDecal;
public:
LRESULT localWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
static LRESULT CALLBACK wndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
void createSurface( LPSIZE psz, IDirectDrawSurface4 **ppSurf );
void convertVersion( LPTSTR szVersion, DWORD &dwVersionMajor, DWORD &dwVersionMinor );
void enableSoftwareMode( );
public:
STDMETHOD(get_Hooks)(/*[out, retval]*/ IACHooks * *pVal);
STDMETHOD(get_Focus)(/*[out, retval]*/ VARIANT_BOOL *pVal);
STDMETHOD(get_HWND)(/*[out, retval]*/ long *pVal);
// IPluginSite Methods
STDMETHOD(CreateCanvas)(LPSIZE psz, /*[out, retval]*/ ICanvas **ppCanvas);
STDMETHOD(GetScreenSize)(LPSIZE sz);
STDMETHOD(CreateFont)(BSTR strFaceName, long nHeight, long nFlags, /*[out, retval]*/ IFontCache **ppFont);
STDMETHOD(LoadBitmapPortal)(long nFile, IImageCache **);
STDMETHOD(GetIconCache)(LPSIZE sz, /*[out, retval]*/ IIconCache **ppCache);
STDMETHOD(LoadBitmapFile)(BSTR strFilename, IImageCache **ppImage);
STDMETHOD(Get3DDevice)(REFIID iid, void **ppvItf);
STDMETHOD(GetPrimarySurface)(/*[out, retval]*/ ICanvas **ppCanvas);
STDMETHOD(GetDirectDraw)(REFIID iid, void **ppvItf);
STDMETHOD(UnloadPlugin)(long nID);
STDMETHOD(CreateView)(ViewParams *pParams, ILayer *pLayer, /*[out, retval]*/ IView **ppView);
STDMETHOD(LoadView)(BSTR strSchema, /*[out, retval]*/ IView **ppView);
STDMETHOD(CreateFontSchema)(long nDefHeight, long nDefOptions, IUnknown *pSchema, /*[out, retval]*/ IFontCache **ppCache);
STDMETHOD(LoadImageSchema)(IUnknown *pSchema, /*[out, retval]*/ IImageCache **ppImg);
STDMETHOD(CreateBrushImage)(long nColor, /*[out, retval]*/ IImageCache **ppImg);
STDMETHOD(LoadViewObject)(IUnknown *pSchema, /*[out, retval]*/ IView **ppView);
STDMETHOD(get_NetworkFilter)(BSTR strProgID, /*[out, retval]*/ LPDISPATCH *pVal);
STDMETHOD(get_Plugin)(BSTR strProgID, /*[out, retval]*/ LPDISPATCH *pVal);
STDMETHOD(get_ResourcePath)(/*[out, retval]*/ BSTR *pVal);
STDMETHOD(LoadResourceModule)(BSTR strLibrary, /*[out, retval]*/ long *pnModule);
STDMETHOD(CreateInputBuffer)(/*[out, retval]*/ IInputBuffer **ppInput);
STDMETHOD(get_OldWndProc)(/*[out, retval]*/ long *pOldWndProc);
STDMETHOD(put_CurrentSelection)(long nID);
STDMETHOD(get_CurrentSelection)(long *nID);
STDMETHOD(put_PreviousSelection)(long nID);
STDMETHOD(get_PreviousSelection)(long *nID);
STDMETHOD(WriteToChatWindow)(BSTR szText, long lColor);
STDMETHOD(SetCursorPosition)(long x, long y);
STDMETHOD(QueryKeyboardMap)(BSTR bstrName, long *pAsciiVal);
STDMETHOD(QueryMemLoc)(BSTR bstrTag, long *pVal);
STDMETHOD(RawWriteToChatWindow)(BSTR szText, long lColor);
STDMETHOD(CastSpell)(long lSpellID, long lObjectID); //0x004EFB10
STDMETHOD(MoveItem)(long lObjectID, long lPackID, long lSlot, long lStack); //0x4F9E80
STDMETHOD(SelectItem)(long lObjectID); //0x4CF850
STDMETHOD(UseItem)(long lObjectID, long lUseOnSelectedItem); //0x4FA9F0
STDMETHOD(get_CombatState)(/*[out, retval]*/ long *pVal);
STDMETHOD(get_ChatState)(/*[out, retval]*/ VARIANT_BOOL *pVal);
STDMETHOD(UseItemEx)(long Use, long UseOn);
STDMETHOD(GetFellowStats)(long charID);
STDMETHOD(get_Decal)(IDecal **pVal);
STDMETHOD(RedrawBar)();
STDMETHOD(get_FontName)(BSTR *pFontName);
};
#endif //__MANAGER_H_

View file

@ -0,0 +1,8 @@
// MaterialHook.cpp : Implementation of CMaterialHook
#include "stdafx.h"
#include "Inject.h"
#include "MaterialHook.h"
/////////////////////////////////////////////////////////////////////////////
// CMaterialHook

View file

@ -0,0 +1,115 @@
// MaterialHook.h : Declaration of the CMaterialHook
#ifndef __MATERIALHOOK_H_
#define __MATERIALHOOK_H_
#include "resource.h" // main symbols
#include "Direct3DHook.h"
#include "DirectDrawHook.h"
/////////////////////////////////////////////////////////////////////////////
// CMaterialHook
class ATL_NO_VTABLE CMaterialHook :
public CComObjectRootEx<CComMultiThreadModel>,
public IDirect3DMaterial,
public IDirect3DMaterial2,
public IDirect3DMaterial3
{
public:
CMaterialHook()
{
}
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CMaterialHook)
COM_INTERFACE_ENTRY_IID(IID_IDirect3DMaterial, IDirect3DMaterial)
COM_INTERFACE_ENTRY_IID(IID_IDirect3DMaterial2, IDirect3DMaterial2)
COM_INTERFACE_ENTRY_IID(IID_IDirect3DMaterial3, IDirect3DMaterial3)
END_COM_MAP()
CComPtr< IDirect3DMaterial > m_pMaterial;
CComPtr< IDirect3DMaterial2 > m_pMaterial2;
CComPtr< IDirect3DMaterial3 > m_pMaterial3;
D3DMATERIALHANDLE m_hMaterial;
void setObject( IUnknown *pUnk, IDirect3DDevice2 *pDevice2, IDirect3DDevice3 *pDevice3 )
{
pUnk->QueryInterface( IID_IDirect3DMaterial, reinterpret_cast< void ** >( &m_pMaterial ) );
pUnk->QueryInterface( IID_IDirect3DMaterial2, reinterpret_cast< void ** >( &m_pMaterial2 ) );
pUnk->QueryInterface( IID_IDirect3DMaterial3, reinterpret_cast< void ** >( &m_pMaterial3 ) );
if( pDevice2 != NULL )
m_pMaterial2->GetHandle( pDevice2, &m_hMaterial );
else if( pDevice3 != NULL )
m_pMaterial3->GetHandle( pDevice3, &m_hMaterial );
}
// IMaterialHook
public:
// Methods from IDirect3DMaterial
STDMETHOD(Initialize)(LPDIRECT3D p1)
{
CDirectDrawHook *pHook = static_cast< CDirectDrawHook * >( p1 );
return m_pMaterial->Initialize( pHook->m_pD3D );
}
STDMETHOD(SetMaterial)(LPD3DMATERIAL p1)
{
return m_pMaterial->SetMaterial( p1 );
}
STDMETHOD(GetMaterial)(LPD3DMATERIAL p1)
{
return m_pMaterial->GetMaterial( p1 );
}
STDMETHOD(GetHandle)(LPDIRECT3DDEVICE p1,LPD3DMATERIALHANDLE p2)
{
*p2 = m_hMaterial;
return S_OK;
/*
CDirect3DHook *pHook = dynamic_cast< CDirect3DHook * >( p1 );
if( pHook != NULL )
return m_pMaterial->GetHandle( pHook->m_pDevice, p2 );
return m_pMaterial->GetHandle( p1, p2 );
*/
}
STDMETHOD(Reserve)()
{
return m_pMaterial->Reserve();
}
STDMETHOD(Unreserve)()
{
return m_pMaterial->Unreserve();
}
// Methods from IDirect3DMaterial2
STDMETHOD(GetHandle)(LPDIRECT3DDEVICE2 p1,LPD3DMATERIALHANDLE p2)
{
*p2 = m_hMaterial;
return S_OK;
/*
CDirect3DHook *pHook = dynamic_cast< CDirect3DHook * >( p1 );
return m_pMaterial2->GetHandle( pHook->m_pDevice2, p2 );
*/
}
// Methods from IDirect3DMaterial3
STDMETHOD(GetHandle)(LPDIRECT3DDEVICE3 p1,LPD3DMATERIALHANDLE p2)
{
*p2 = m_hMaterial;
return S_OK;
/*
CDirect3DHook *pHook = dynamic_cast< CDirect3DHook * >( p1 );
return m_pMaterial3->GetHandle( pHook->m_pDevice3, p2 );
*/
}
};
#endif //__MATERIALHOOK_H_

215
Native/Inject/Pager.cpp Normal file
View file

@ -0,0 +1,215 @@
// Pager.cpp : Implementation of cPager
#include "stdafx.h"
#include "Inject.h"
#include "Pager.h"
/////////////////////////////////////////////////////////////////////////////
// cPager
// The velocity of the scroll in pixels/sec
#define VELOCITY 500
void cPager::setupScroll( long nCommand, LPPOINT pptDest )
{
_ASSERTE( pptDest != NULL );
m_ptScrollFrom = m_ptCurrent;
m_dwTimeStart = ::timeGetTime();
m_ptScrollTo = *pptDest;
// Figure out the time to completion
int dx = m_ptScrollTo.x - m_ptScrollFrom.x,
dy = m_ptScrollTo.y - m_ptScrollFrom.y;
m_dwTimeEnd = m_dwTimeStart + static_cast< DWORD >( sqrt( static_cast< double >( dx * dx + dy * dy ) ) ) * 1000 / VELOCITY;
// Clear command options
m_nCommand = nCommand;
m_bContinue = ( nCommand == 0 ) ? VARIANT_FALSE : VARIANT_TRUE;
m_bScrolling = VARIANT_TRUE;
}
void cPager::updatePosition()
{
long nID;
m_pSite->get_ID( &nID );
Fire_Change( nID, m_nCommand, m_ptCurrent.x, m_ptCurrent.y );
m_pSite->Invalidate();
}
void cPager::endScroll()
{
if( m_bScrolling )
{
m_bScrolling = VARIANT_FALSE;
m_ptCurrent = m_ptScrollTo;
}
updatePosition();
m_nCommand = 0;
}
void cPager::onCreate()
{
m_ptCurrent.x = 0;
m_ptCurrent.y = 0;
m_dwTimeStart = 0;
m_dwTimeEnd = 0;
m_bScrolling = VARIANT_FALSE;
m_bContinue = VARIANT_FALSE;
m_nCommand = 0;
}
STDMETHODIMP cPager::ScrollTo(LPPOINT pVal)
{
setupScroll( 0, pVal );
return S_OK;
}
STDMETHODIMP cPager::get_Command(long *pVal)
{
_ASSERTE( pVal != NULL );
*pVal = m_nCommand;
return S_OK;
}
STDMETHODIMP cPager::put_Command(long nCommand)
{
// ::MessageBox( NULL, _T( "cPager::SetCommand" ), _T( "Inject.dll" ), MB_OK );
m_bContinue = VARIANT_TRUE;
if( nCommand != m_nCommand )
{
// Prompt the callback to get a destination
long nID;
m_pSite->get_ID( &nID );
POINT ptDest;
VARIANT_BOOL bContinue;
bContinue = Fire_GetNextPosition( nID, nCommand, &ptDest.x, &ptDest.y );
if( !bContinue )
endScroll();
else
setupScroll( nCommand, &ptDest );
}
return S_OK;
}
STDMETHODIMP cPager::FinishCommand()
{
m_bContinue = VARIANT_FALSE;
return S_OK;
}
STDMETHODIMP cPager::PreRender()
{
if( !m_bScrolling )
// No scrolling means no drawing
return S_OK;
// Calculate the new position
DWORD dwTime = ::timeGetTime();
// We loop until we've used up our animation time
// so animations with short steps - a single frame
// may exceed a small step.
while( dwTime >= m_dwTimeEnd )
{
long nCommand = m_nCommand;
endScroll();
// This section of the scroll is complete
if( !m_bContinue )
{
_ASSERTMEM( _CrtCheckMemory( ) );
return S_OK;
}
// Check for a next destination
POINT ptDest;
long nID;
m_pSite->get_ID( &nID );
VARIANT_BOOL bContinue = VARIANT_FALSE;
bContinue = Fire_GetNextPosition( nID, nCommand, &ptDest.x, &ptDest.y );
if( bContinue )
{
DWORD dwLastEnd = m_dwTimeEnd;
// ::MessageBox( NULL, _T( "cPager::Render" ), _T( "Inject.dll" ), MB_OK );
setupScroll( nCommand, &ptDest );
DWORD dwOver = m_dwTimeStart - dwLastEnd;
// Adjust the time to eliminate the stutter for the next section
m_dwTimeStart -= dwOver;
m_dwTimeEnd -= dwOver;
}
else
{
_ASSERTMEM( _CrtCheckMemory( ) );
return S_OK;
}
}
// Do a time linear interpolation to figure out the current position
long nTotalTime = m_dwTimeEnd - m_dwTimeStart,
nCurrentTime = dwTime - m_dwTimeStart;
m_ptCurrent.x = m_ptScrollFrom.x + ( m_ptScrollTo.x - m_ptScrollFrom.x ) * nCurrentTime / nTotalTime;
m_ptCurrent.y = m_ptScrollFrom.y + ( m_ptScrollTo.y - m_ptScrollFrom.y ) * nCurrentTime / nTotalTime;
updatePosition();
_ASSERTMEM( _CrtCheckMemory( ) );
return S_OK;
}
STDMETHODIMP cPager::AdjustRenderArea( ICanvas *pCanvas, VARIANT_BOOL *pbDrawChildren )
{
pCanvas->OffsetOrg( &m_ptCurrent, pbDrawChildren );
return S_OK;
}
STDMETHODIMP cPager::get_Offset(LPPOINT pVal)
{
_ASSERTE( pVal != NULL );
*pVal = m_ptCurrent;
return S_OK;
}
STDMETHODIMP cPager::put_Offset(LPPOINT newVal)
{
// Terminate scrolling
endScroll();
m_ptCurrent = *newVal;
// Dispatch changes
updatePosition();
return S_OK;
}
STDMETHODIMP cPager::CreateClient(ILayer *pLayer)
{
// TODO: Add your implementation code here
return S_OK;
}

79
Native/Inject/Pager.h Normal file
View file

@ -0,0 +1,79 @@
// Pager.h : Declaration of the cPager
#ifndef __PAGER_H_
#define __PAGER_H_
#include "resource.h" // main symbols
#include "SinkImpl.h"
#include "InjectCP.h"
/////////////////////////////////////////////////////////////////////////////
// cPager
class ATL_NO_VTABLE cPager :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<cPager, &CLSID_Pager>,
public ILayerImpl< cPager >,
public ILayerRenderImpl,
public IControlImpl< cPager, IPager, &IID_IControl, &LIBID_DecalPlugins >,
public IProvideClassInfo2Impl< &CLSID_Pager, &DIID_IPagerEvents, &LIBID_DecalPlugins >,
public IConnectionPointContainerImpl<cPager>,
public CProxyIPagerEvents< cPager >
{
public:
cPager()
{
}
POINT m_ptScrollFrom;
DWORD m_dwTimeStart;
POINT m_ptScrollTo;
DWORD m_dwTimeEnd;
POINT m_ptCurrent;
long m_nCommand;
VARIANT_BOOL m_bContinue, m_bScrolling;
void onCreate();
DECLARE_REGISTRY_RESOURCEID(IDR_PAGER)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(cPager)
COM_INTERFACE_ENTRY(ILayerRender)
COM_INTERFACE_ENTRY(ILayer)
COM_INTERFACE_ENTRY(IPager)
COM_INTERFACE_ENTRY(IControl)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IProvideClassInfo)
COM_INTERFACE_ENTRY(IProvideClassInfo2)
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
END_COM_MAP()
BEGIN_CONNECTION_POINT_MAP(cPager)
CONNECTION_POINT_ENTRY(DIID_IPagerEvents)
END_CONNECTION_POINT_MAP()
void setupScroll( long dwCommand, LPPOINT pptDest );
void updatePosition();
void endScroll();
// IPager
public:
// IPager Methods
STDMETHOD(get_Command)(/*[out, retval]*/ long *pVal);
STDMETHOD(put_Command)(/*[in]*/ long newVal);
STDMETHOD(ScrollTo)(LPPOINT pVal);
STDMETHOD(FinishCommand)();
STDMETHOD(get_Offset)(/*[out, retval]*/ LPPOINT pVal);
STDMETHOD(put_Offset)(/*[in]*/ LPPOINT newVal);
STDMETHOD(CreateClient)(ILayer *pLayer);
// ILayerRenderMethods
STDMETHOD(PreRender)();
STDMETHOD(AdjustRenderArea)( ICanvas *pCanvas, VARIANT_BOOL *pbDrawChildren );
};
#endif //__PAGER_H_

25
Native/Inject/Pager.rgs Normal file
View file

@ -0,0 +1,25 @@
HKCR
{
DecalControls.Pager.1 = s 'DecalControls Pager'
{
CLSID = s '{C79E2F76-06F8-4cd0-A613-4829237D297D}'
}
DecalControls.Pager = s 'DecalControls Pager'
{
CLSID = s '{C79E2F76-06F8-4cd0-A613-4829237D297D}'
CurVer = s 'DecalControls.Pager.1'
}
NoRemove CLSID
{
ForceRemove {C79E2F76-06F8-4cd0-A613-4829237D297D} = s 'DecalControls Pager'
{
ProgID = s 'DecalControls.Pager.1'
VersionIndependentProgID = s 'DecalControls.Pager'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Both'
}
'TypeLib' = s '{3559E08B-827E-4DFE-9D33-3567246849CC}'
}
}
}

647
Native/Inject/Panel.cpp Normal file
View file

@ -0,0 +1,647 @@
// Panel.cpp : Implementation of cPanel
#include "stdafx.h"
#include "Inject.h"
#include "Panel.h"
#include "Manager.h"
/////////////////////////////////////////////////////////////////////////////
// cPanel
enum ePanelChildren
{
eViewFirst = 1000
};
cPanel::cPanel()
: m_nActiveView( -1 ),
m_bDragging( false ),
m_bSizingXL( false ),
m_bSizingXR( false ),
m_bSizingYT( false ),
m_bSizingYB( false ),
m_bTransparent( false ),
m_pcView( NULL ),
m_Alpha( 255 )
{
}
void cPanel::hideView()
{
m_pSite->Invalidate();
if( m_nActiveView == -1 )
// No active view currently
return;
CComPtr< ILayerSite > pActive;
m_pSite->get_Child( m_nActiveView, ePositionByID, &pActive );
static RECT rcHide = { 0, 0, 0, 0 };
pActive->put_Position( &rcHide );
if( m_pSink.p != NULL )
m_pSink->PanelDeactivate( m_nActiveView );
m_nActiveView = -1;
}
void cPanel::onCreate()
{
CComPtr< IPluginSite > pPlugin;
m_pSite->get_PluginSite( &pPlugin );
pPlugin->LoadBitmapPortal( 0x0600126F, &m_pBackground );
pPlugin->LoadBitmapPortal( 0x06001277, &m_pBorder );
BSTR bstrFontName;
pPlugin->get_FontName(&bstrFontName);
pPlugin->CreateFont( bstrFontName /*_bstr_t( _T( "Times New Roman" ) )*/, 15, eFontBold, &m_pTitle );
// Create the Button
CComPtr< IButton > pRollup;
HRESULT hRes = ::CoCreateInstance( CLSID_Button, NULL, CLSCTX_INPROC_SERVER, IID_IButton,
reinterpret_cast< void ** >( &pRollup ) );
_ASSERTE( SUCCEEDED( hRes ) );
CComPtr< ILayer > pBtnLayer;
pRollup->QueryInterface( &pBtnLayer );
LayerParams lp = { 1, { 180 - 16, 0, 180, 16 }, eRenderClipped };
m_pSite->CreateChild( &lp, pBtnLayer );
pRollup->put_Matte( RGB( 0, 0, 0 ) );
pRollup->SetImages( 0, 0x0600113C, 0x0600113B );
ICommandEventsImpl< BUTTON_CLOSE, cPanel >::advise( pRollup );
// Create the Increment Button
hRes = ::CoCreateInstance( CLSID_Button, NULL, CLSCTX_INPROC_SERVER, IID_IButton,
reinterpret_cast< void ** >( &m_pButtonInc ) );
_ASSERTE( SUCCEEDED( hRes ) );
CComPtr< ILayer > pBtnIncLayer;
m_pButtonInc->QueryInterface( &pBtnIncLayer );
LayerParams lpInc = { 2, { 180 - 32, 0, 180 - 32 + 16, 16 }, eRenderClipped };
m_pSite->CreateChild( &lpInc, pBtnIncLayer );
m_pButtonInc->put_Matte( RGB( 0, 0, 0 ) );
m_pButtonInc->SetImages( 0, 0x06001298, 0x06001299 );
ICommandEventsImpl< BUTTON_INC, cPanel >::advise( m_pButtonInc );
// Create the Decrement Button
hRes = ::CoCreateInstance( CLSID_Button, NULL, CLSCTX_INPROC_SERVER, IID_IButton,
reinterpret_cast< void ** >( &m_pButtonDec ) );
_ASSERTE( SUCCEEDED( hRes ) );
CComPtr< ILayer > pBtnDecLayer;
m_pButtonDec->QueryInterface( &pBtnDecLayer );
LayerParams lpDec = { 3, { 180 - 48, 0, 180 - 48 + 16, 16 }, eRenderClipped };
m_pSite->CreateChild( &lpDec, pBtnDecLayer );
m_pButtonDec->put_Matte( RGB( 0, 0, 0 ) );
m_pButtonDec->SetImages( 0, 0x06001295, 0x06001296 );
ICommandEventsImpl< BUTTON_DEC, cPanel >::advise( m_pButtonDec );
// Set this layer not transparent to be transparent
m_pSite->put_Transparent( VARIANT_FALSE );
RegKey key;
key.Create( HKEY_LOCAL_MACHINE, _T( "SOFTWARE\\Decal" ) );
if(key.QueryDWORDValue("ViewAlpha", m_Alpha) != ERROR_SUCCESS)
m_Alpha = 255;
}
void cPanel::onDestroy()
{
m_pBorder.Release();
m_pBackground.Release();
m_pTitle.Release();
m_pButtonInc.Release();
m_pButtonDec.Release();
}
STDMETHODIMP cPanel::Render( ICanvas *pCanvas )
{
RECT rc;
m_pSite->get_Position( &rc );
SIZE szBorder;
m_pBorder->get_Size( &szBorder );
// Draw the background
RECT rc_pat = { 0, 0, rc.right - rc.left, rc.bottom - rc.top };
static POINT pt_pat = { 0, 0 };
if( ! m_bTransparent )
m_pBackground->PatBlt( pCanvas, &rc_pat, &pt_pat );
// Draw the borders
RECT rc_border_top = { 0, 0, rc.right - rc.left, szBorder.cy },
rc_border_bottom = { 0, rc.bottom - rc.top - szBorder.cy,
rc.right - rc.left, rc.bottom - rc.top };
pCanvas->Fill( &rc_border_top, RGB( 0, 0, 0 ) );
m_pBorder->PatBlt( pCanvas, &rc_border_top, &pt_pat );
pCanvas->Fill( &rc_border_bottom, RGB( 0, 0, 0 ) );
m_pBorder->PatBlt( pCanvas, &rc_border_bottom, &pt_pat );
// Draw the title text
if( _bstr_t(m_pVP->label).length() > 0 )
{
POINT ptText = { 24, szBorder.cy + 5 };
m_pTitle->DrawText( &ptText, m_pVP->label, 0, pCanvas );
}
if( m_pVP->icon != 0 )
{
CComPtr< IPluginSite > pPlugin;
m_pSite->get_PluginSite( &pPlugin );
CComPtr< IIconCache > pIconCache;
static SIZE szIcon = { 16, 16 };
pPlugin->GetIconCache( &szIcon, &pIconCache );
static POINT pt = { 4, szBorder.cy + 4 };
pIconCache->DrawIcon( &pt, m_pVP->icon, m_pVP->iconLibrary, pCanvas );
}
_ASSERTMEM( _CrtCheckMemory( ) );
return S_OK;
}
STDMETHODIMP cPanel::Reformat()
{
// Reset the size
CComPtr< IPluginSite > pPlugin;
m_pSite->get_PluginSite( &pPlugin );
SIZE szScreen;
pPlugin->GetScreenSize( &szScreen );
RECT rc = { m_pVP->left, m_pVP->top, m_pVP->left + m_pVP->width, m_pVP->top + m_pVP->height };
m_pSite->put_Position( &rc );
RECT rcCloseBtn = { m_pVP->width - 16, 0, m_pVP->width, 16 };
CComPtr< ILayerSite > pCloseBtnLS;
m_pSite->get_Child(1, ePositionByID, &pCloseBtnLS);
pCloseBtnLS->put_Position(&rcCloseBtn);
RECT rcIncBtn = { m_pVP->width - 32, 0, m_pVP->width - 32 + 16, 16 };
CComPtr< ILayerSite > pButtonInc;
m_pSite->get_Child(2, ePositionByID, &pButtonInc);
pButtonInc->put_Position( &rcIncBtn );
RECT rcDecBtn = { m_pVP->width - 48, 0, m_pVP->width - 48 + 16, 16 };
CComPtr< ILayerSite > pButtonDec;
m_pSite->get_Child(3, ePositionByID, &pButtonDec);
pButtonDec->put_Position( &rcDecBtn );
if( m_nActiveView != -1 )
{
// Position the active view
SIZE szBorder;
m_pBorder->get_Size( &szBorder );
CComPtr< ILayerSite > pActive;
m_pSite->get_Child( m_nActiveView, ePositionByID, &pActive );
RECT rcChild = { 0, 24 + szBorder.cy, m_pVP->width, m_pVP->height - szBorder.cy };
pActive->put_Position( &rcChild );
}
return S_OK;
}
STDMETHODIMP cPanel::AddView(long nViewID, ILayer *pLayer)
{
_ASSERTE( pLayer != NULL );
LayerParams p = { nViewID, { 0, 0, 0, 0 }, eRenderClipped };
// Set up the layer - note that it is not visible
return m_pSite->CreateChild( &p, pLayer );
}
STDMETHODIMP cPanel::ActivateView(long nViewID, ViewParams *pParams, long *pView)
{
// Hide the current view by resizing to 0,0
hideView();
m_pVP = pParams;
m_pcView = (cView*)pView;
VARIANT_BOOL isTransparent=VARIANT_FALSE ;
if (m_pcView) m_pcView->get_Transparent(&isTransparent) ;
put_Transparent(isTransparent) ;
if( m_pVP->alpha == -1 )
m_pSite->put_Alpha( m_Alpha );
else
m_pSite->put_Alpha( m_pVP->alpha );
#ifdef _DEBUG
// Make sure the child exists
CComPtr< ILayerSite > pChildSite;
_ASSERTE( SUCCEEDED( m_pSite->get_Child( nViewID, ePositionByID, &pChildSite ) ) );
#endif
// Locate the child
m_nActiveView = nViewID;
// Trick it into reformatting next frame
static RECT rcBig = { 0, 0, 1, 1 };
m_pSite->put_Position( &rcBig );
// Pop us to the front
m_pSite->moveToFront();
return S_OK;
}
STDMETHODIMP cPanel::RemoveView( long nViewID )
{
if( nViewID == m_nActiveView )
// If this is the current view, run and hide
Deactivate();
CComPtr< ILayerSite > pChildSite;
HRESULT hRes = m_pSite->get_Child( nViewID, ePositionByID, &pChildSite );
_ASSERTE( SUCCEEDED( hRes ) );
if( SUCCEEDED( hRes ) )
pChildSite->Destroy();
else
return E_FAIL;
return S_OK;
}
void cPanel::onCloseAccepted(long nID)
{
// We should only be getting commands from the button
_ASSERTE( nID == 1 );
Deactivate();
}
void cPanel::onAlphaInc(long nID)
{
// We should only be getting commands from the button
_ASSERTE( nID == 2 );
if(m_pVP->alpha == -1 )
{
m_pVP->alpha = m_Alpha + 5;
m_pSite->put_Alpha( m_pVP->alpha );
}
else
{
m_pVP->alpha += 5;
if( m_pVP->alpha > 255 )
m_pVP->alpha = 255;
m_pSite->put_Alpha( m_pVP->alpha );
}
}
void cPanel::onAlphaDec(long nID)
{
// We should only be getting commands from the button
_ASSERTE( nID == 3 );
if(m_pVP->alpha == -1 )
{
m_pVP->alpha = m_Alpha - 5;
m_pSite->put_Alpha( m_pVP->alpha );
}
else
{
m_pVP->alpha -= 5;
if( m_pVP->alpha < 0 )
m_pVP->alpha = 0;
m_pSite->put_Alpha( m_pVP->alpha );
}
}
STDMETHODIMP cPanel::get_ActiveView(long *pVal)
{
_ASSERTE( pVal != NULL );
*pVal = m_nActiveView;
return S_OK;
}
STDMETHODIMP cPanel::LoadView(long nViewID, IView *pView, IUnknown *pSchema)
{
_ASSERTE( pView != NULL );
_ASSERTE( pSchema != NULL );
long nAssigned;
// Set up the layer - note that it is not visible
return pView->LoadControl( m_pSite, nViewID, pSchema, &nAssigned );
}
STDMETHODIMP cPanel::LoadViewEx(long nViewID, IView *pView, IUnknown *pSchema, long lViewFlags)
{
_ASSERTE( pView != NULL );
_ASSERTE( pSchema != NULL );
long nAssigned;
if( lViewFlags & eTransparent )
m_bTransparent = true;
// Set up the layer - note that it is not visible
return pView->LoadControl( m_pSite, nViewID, pSchema, &nAssigned );
}
STDMETHODIMP cPanel::Deactivate()
{
if( m_nActiveView == -1 )
// No active view currently
return S_OK;
// Hide the current view by resizing to 0,0
hideView();
// Hide the entire panel
static RECT rcHide = { 0, 0, 0, 0 };
m_pSite->put_Position( &rcHide );
m_nActiveView = -1;
return S_OK;
}
STDMETHODIMP cPanel::putref_Sink(IPanelSink *newVal)
{
m_pSink = newVal;
return S_OK;
}
STDMETHODIMP cPanel::MouseEvent(long nMsg, long wParam, long lParam)
{
static RECT rcTemp;
static SIZE size;
switch(nMsg)
{
case WM_LBUTTONDOWN:
{
// Pop us to the front
m_pSite->moveToFront();
SIZE szBorder;
m_pBorder->get_Size( &szBorder );
POINTS ptm;
ptm = MAKEPOINTS(lParam);
if( !cManager::_p->m_bContainer )
ptm.y-=28;
if((ptm.x>=m_pVP->left+szBorder.cy) && (ptm.x<=m_pVP->left+m_pVP->width-szBorder.cy) && (ptm.y>=m_pVP->top+szBorder.cy) && (ptm.y<=m_pVP->top+28))
{
m_DeltaX = ptm.x-m_pVP->left;
m_DeltaY = ptm.y-m_pVP->top;
m_bDragging = true;
}
else
{
if(m_pcView->Fire_Size()==VARIANT_TRUE)
{
if((ptm.x>=m_pVP->left) && (ptm.x<=m_pVP->left+m_pVP->width))
{
if((ptm.y>=m_pVP->top) && (ptm.y<=m_pVP->top+szBorder.cy))
{
m_bSizingYT = true;
m_DeltaY = ptm.y-m_pVP->top;
} else if((ptm.y>=m_pVP->top+m_pVP->height-szBorder.cy) && (ptm.y<=m_pVP->top+m_pVP->height))
{
m_bSizingYB = true;
m_DeltaY = m_pVP->top+m_pVP->height-ptm.y;
}
}
if((ptm.y>=m_pVP->top) && (ptm.y<=m_pVP->top+m_pVP->height))
{
if((ptm.x>=m_pVP->left) && (ptm.x<=m_pVP->left+szBorder.cy))
{
m_bSizingXL = true;
m_DeltaX = ptm.x-m_pVP->left;
} else if((ptm.x>=m_pVP->left+m_pVP->width-szBorder.cy) && (ptm.x<=m_pVP->left+m_pVP->width))
{
m_bSizingXR = true;
m_DeltaX = m_pVP->left+m_pVP->width-ptm.x;
}
}
}
}
break;
}
case WM_LBUTTONUP:
{
m_bDragging = m_bSizingXL = m_bSizingXR = m_bSizingYT = m_bSizingYB = false;
break;
}
case WM_MOUSEMOVE:
{
if(wParam==MK_LBUTTON)
{
bool bUpdate = false;
POINTS ptm;
ptm = MAKEPOINTS(lParam);
if( !cManager::_p->m_bContainer )
ptm.y-=28;
if(m_bDragging)
{
m_pVP->left = ptm.x-m_DeltaX;
m_pVP->top = ptm.y-m_DeltaY;
/* Drakier: make sure they aren't being bad little kittens and
moving the view offscreen! */
// Drakier: Get the pSite and Screen Size
CComPtr< IPluginSite > pPlugin;
CComPtr< IACHooks > pHooks;
m_pSite->get_PluginSite( &pPlugin );
SIZE szScreen, sz;
pPlugin->GetScreenSize( &sz );
szScreen.cx = sz.cx;
szScreen.cy = sz.cy;
long lX = sz.cx, lY = sz.cy;
// Drakier: if we are not in the container, get the 3D Area
if ( !cManager::_p->m_bContainer )
{
pPlugin->get_Hooks( &pHooks );
pHooks->get_Area3DHeight( &lY );
pHooks->get_Area3DWidth( &lX );
pHooks.Release();
}
pPlugin.Release();
// Drakier: if we are in the container, or the 3D area's are NULL
if ( (cManager::_p->m_bContainer) || (&lX == NULL) || (&lY == NULL) )
{
szScreen.cx = sz.cx - 308; // 308 = PANEL_SIZE
szScreen.cy = sz.cy;
}
else // Drakier: If everything comes out right and we are not in container
{
if( (&lX != NULL) && (lX > 0) && (lX < 5000) )
szScreen.cx = lX;
if( (&lY != NULL) && (lY > 0) && (lY < 5000) )
szScreen.cy = lY;
}
if ( m_pVP->left < 0 )
m_pVP->left = 0;
if ( m_pVP->top < 0 )
m_pVP->top = 0;
if ( (m_pVP->left + m_pVP->width) > szScreen.cx )
m_pVP->left = szScreen.cx - m_pVP->width;
if ( (m_pVP->top + m_pVP->height) > szScreen.cy )
m_pVP->top = szScreen.cy - m_pVP->height;
bUpdate = true;
}
else
{
if(m_bSizingYT)
{
rcTemp.bottom = m_pVP->height + m_pVP->top - (ptm.y-m_DeltaY);
rcTemp.top = ptm.y-m_DeltaY;
if(rcTemp.bottom > 34)
{
m_pVP->height = rcTemp.bottom;
m_pVP->top = rcTemp.top;
}
else
{
m_pVP->top = (m_pVP->top + m_pVP->height) - 34;
m_pVP->height = 34;
}
bUpdate = true;
}
else if(m_bSizingYB)
{
rcTemp.bottom = ptm.y-m_pVP->top+m_DeltaY;
if(rcTemp.bottom > 34)
m_pVP->height = rcTemp.bottom;
else
m_pVP->height = 34;
bUpdate = true;
}
if(m_bSizingXL)
{
rcTemp.right = m_pVP->width + m_pVP->left - (ptm.x-m_DeltaX);
rcTemp.left = ptm.x-m_DeltaX;
m_pTitle->MeasureText(m_pVP->label, &size);
if(rcTemp.right > size.cx + 48)
{
m_pVP->width = rcTemp.right;
m_pVP->left = rcTemp.left;
}
else
{
m_pVP->left = (m_pVP->left + m_pVP->width) - (size.cx + 48);
m_pVP->width = size.cx+48;
}
bUpdate = true;
}
else if(m_bSizingXR)
{
rcTemp.right = ptm.x-m_pVP->left+m_DeltaX;
m_pTitle->MeasureText(m_pVP->label, &size);
if(rcTemp.right > size.cx + 48)
m_pVP->width = rcTemp.right;
else
m_pVP->width = size.cx + 48;
bUpdate = true;
}
}
if(bUpdate)
{
if(!m_bDragging)
{
//RECT rc = { m_pcView->m_VP.left, m_pcView->m_VP.top, m_pcView->m_VP.width, m_pcView->m_VP.height };
m_pcView->Fire_Sizing(/*m_pcView*//*&m_pcView->m_VP*//*m_pcView->m_VP.left, m_pcView->m_VP.top,*/ 0, 0, m_pcView->m_VP.width, m_pcView->m_VP.height-34);
}
static RECT rcBig = { 0, 0, 1, 1 };
m_pSite->put_Position( &rcBig );
}
}
break;
}
}
return S_OK;
}
STDMETHODIMP cPanel::get_Transparent(VARIANT_BOOL *pVal)
{
*pVal = ( m_bTransparent ? VARIANT_TRUE : VARIANT_FALSE );
return S_OK;
}
STDMETHODIMP cPanel::put_Transparent(VARIANT_BOOL newVal)
{
if( newVal == VARIANT_FALSE )
m_bTransparent = false;
else
m_bTransparent = true;
if( m_pVP->alpha == -1 )
m_pSite->put_Alpha( m_Alpha );
else
m_pSite->put_Alpha( m_pVP->alpha );
m_pSite->Invalidate();
m_pSite->Reformat();
return S_OK;
}
STDMETHODIMP cPanel::put_Params(ViewParams *newVal)
{
if( newVal == NULL )
return E_POINTER;
m_pVP = newVal;
return S_OK;
}

100
Native/Inject/Panel.h Normal file
View file

@ -0,0 +1,100 @@
// Panel.h : Declaration of the cPanel
#ifndef __PANEL_H_
#define __PANEL_H_
#include "resource.h" // main symbols
#include "SinkImpl.h"
#include "View.h"
#define BUTTON_CLOSE 1
#define BUTTON_INC 2
#define BUTTON_DEC 3
/////////////////////////////////////////////////////////////////////////////
// cPanel
class ATL_NO_VTABLE cPanel :
public CComObjectRootEx<CComMultiThreadModel>,
public ILayerRenderImpl,
public ILayerImpl< cPanel >,
public ILayerMouseImpl,
public ICommandEventsImpl< BUTTON_CLOSE, cPanel >,
public ICommandEventsImpl< BUTTON_INC, cPanel >,
public ICommandEventsImpl< BUTTON_DEC, cPanel >,
public cNoEventsImpl,
public IPanel
{
public:
cPanel();
long m_nActiveView;
CComPtr< IImageCache > m_pBorder;
CComPtr< IImageCache > m_pBackground;
CComPtr< IFontCache > m_pTitle;
CComPtr< IPanelSink > m_pSink;
CComPtr< IButton > m_pButtonInc;
CComPtr< IButton > m_pButtonDec;
ViewParams* m_pVP;
cView* m_pcView;
DWORD m_Alpha;
long m_DeltaX;
long m_DeltaY;
bool m_bDragging;
bool m_bSizingXL;
bool m_bSizingXR;
bool m_bSizingYT;
bool m_bSizingYB;
bool m_bTransparent;
void hideView();
void onCreate();
void onDestroy();
BEGIN_COM_MAP(cPanel)
COM_INTERFACE_ENTRY(ILayer)
COM_INTERFACE_ENTRY(ILayerRender)
COM_INTERFACE_ENTRY(IPanel)
COM_INTERFACE_ENTRY(ILayerMouse)
END_COM_MAP()
BEGIN_SINK_MAP( cPanel )
SINK_ENTRY_EX( BUTTON_CLOSE, DIID_ICommandEvents, DISPID_ACCEPTED, onCloseAccepted )
SINK_ENTRY_EX( BUTTON_INC, DIID_ICommandEvents, DISPID_ACCEPTED, onAlphaInc )
SINK_ENTRY_EX( BUTTON_DEC, DIID_ICommandEvents, DISPID_ACCEPTED, onAlphaDec )
END_SINK_MAP()
// IPanel
public:
STDMETHOD(LoadView)(long nPlugin, IView *pView, IUnknown *pSchema);
STDMETHOD(LoadViewEx)(long nPlugin, IView *pView, IUnknown *pSchema, long lViewFlags);
STDMETHOD(get_ActiveView)(/*[out, retval]*/ long *pVal);
STDMETHOD(AddView)(long nPluginID, ILayer *pLayer);
STDMETHOD(RemoveView)(long nID);
STDMETHOD(ActivateView)(long nViewID, ViewParams *pParams, long *pVal);
STDMETHOD(Deactivate)();
STDMETHOD(putref_Sink)(/*[in]*/ IPanelSink* newVal);
STDMETHOD(get_Transparent)(/*[out, retval]*/ VARIANT_BOOL *pVal);
STDMETHOD(put_Transparent)(/*[in]*/ VARIANT_BOOL newVal);
STDMETHOD(put_Params)(ViewParams *Params);
// ILayerRender Methods
STDMETHOD(Render)(ICanvas *);
STDMETHOD(Reformat)();
// ICommandEvents Methods
void __stdcall onCloseAccepted(long nID);
void __stdcall onAlphaInc(long nID);
void __stdcall onAlphaDec(long nID);
// ILayerMouse Methods
STDMETHOD(MouseEvent)(long nMsg, long wParam, long lParam);
};
#endif //__PANEL_H_

View file

@ -0,0 +1,58 @@
// Plugin2Impl.h
//
// Declaration of helper class for implementing type 2 plugins
#ifndef _PLUGIN2IMPL_H_
#define _PLUGIN2IMPL_H_
template<class cImpl> class IPlugin2Impl : public IPlugin2
{
public:
CComPtr<IPluginSite> m_pSite;
CComPtr<IPluginSite2> m_pSite2;
CComPtr<IDecal> m_pDecal;
virtual HRESULT onInitialize() = 0;
virtual HRESULT onTerminate() = 0;
STDMETHOD(Initialize)(IPluginSite2 *pSite2)
{
HRESULT hRes;
// Store the Type 2 (Decal) Plugin Site
m_pSite2 = pSite2;
// Get Decal from Type 2 Plugin Site
hRes = m_pSite2->get_Decal(&m_pDecal);
if (!SUCCEEDED(hRes))
return hRes;
// Get Type 1 (Inject) Plugin Site
hRes = m_pDecal->get_Object(_bstr_t("services\\DecalPlugins.InjectService\\site"),
__uuidof(IPluginSite), reinterpret_cast<LPVOID *> (&m_pSite));
if (!SUCCEEDED(hRes))
return hRes;
// Initialize things
hRes = static_cast<cImpl *>(this)->onInitialize();
return hRes;
}
STDMETHOD(Terminate)()
{
HRESULT hRes;
// Terminate the works
hRes = static_cast<cImpl *>(this)->onTerminate();
// Release the elements
m_pSite.Release();
m_pDecal.Release();
m_pSite2.Release();
return hRes;
}
};
#endif // _PLUGIN2IMPL_H_

View file

@ -0,0 +1,74 @@
// PluginAdapterV1.cpp : Implementation of cPluginAdapterV1
#include "stdafx.h"
#include "Inject.h"
#include "PluginAdapterV1.h"
#include "Manager.h"
/////////////////////////////////////////////////////////////////////////////
// cPluginAdapterV1
STDMETHODIMP cPluginAdapterV1::Initialize(IPluginSite2 *pSite2)
{
// First retreive the Inject service
CComPtr< IDecal > pDecal;
pSite2->get_Decal ( &pDecal );
CComPtr< IInjectService > pInject;
HRESULT hRes = pDecal->get_Object ( _bstr_t ( _T( "services\\DecalPlugins.InjectService" ) ),
__uuidof ( IInjectService ), reinterpret_cast< LPVOID * > ( &pInject ) );
if ( FAILED ( hRes ) )
return hRes;
// Try to initialize our plugin
CComPtr< IPlugin > pPlugin;
hRes = m_pUnkPlugin->QueryInterface ( &pPlugin );
if ( FAILED ( hRes ) )
return hRes;
CComPtr< IPluginSite > pSite;
pInject->get_Site ( &pSite );
try
{
pPlugin->Initialize ( pSite, 0 );
}
catch ( ... )
{
return E_FAIL;
}
pInject->InitPlugin ( m_pUnkPlugin );
// Store the site if everything is OK
m_pSite2 = pSite2;
return S_OK;
}
STDMETHODIMP cPluginAdapterV1::Terminate()
{
CComPtr< IPlugin > pPlugin;
if ( SUCCEEDED ( m_pUnkPlugin->QueryInterface ( &pPlugin ) ) )
pPlugin->Terminate ();
m_pUnkPlugin.Release ();
m_pSite2.Release ();
return S_OK;
}
STDMETHODIMP cPluginAdapterV1::CreateInstance(IDecalEnum *pEnum, REFIID riid, LPVOID *ppvItf)
{
CLSID clsidV1;
HRESULT hRes = pEnum->get_ComClass ( &clsidV1 );
if ( FAILED( hRes ) )
return hRes;
hRes = ::CoCreateInstance ( clsidV1, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, reinterpret_cast< LPVOID * > ( &m_pUnkPlugin ) );
if ( FAILED ( hRes ) )
return hRes;
return static_cast< IDecalSurrogate * > ( this )->QueryInterface ( riid, ppvItf );
}

View file

@ -0,0 +1,48 @@
// PluginAdapterV1.h : Declaration of the cPluginAdapterV1
#ifndef __PLUGINADAPTERV1_H_
#define __PLUGINADAPTERV1_H_
#include "resource.h" // main symbols
#include <Decal.h>
/////////////////////////////////////////////////////////////////////////////
// cPluginAdapterV1
class ATL_NO_VTABLE cPluginAdapterV1 :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<cPluginAdapterV1, &CLSID_PluginAdapterV1>,
public IPluginAdapterV1,
public IPlugin2,
public IDecalSurrogate
{
public:
cPluginAdapterV1()
{
}
CComPtr<IPluginSite2> m_pSite2;
CComPtr<IUnknown> m_pUnkPlugin;
DECLARE_REGISTRY_RESOURCEID(IDR_PLUGINADAPTERV1)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(cPluginAdapterV1)
COM_INTERFACE_ENTRY(IDecalSurrogate)
COM_INTERFACE_ENTRY(IPlugin2)
COM_INTERFACE_ENTRY(IPluginAdapterV1)
COM_INTERFACE_ENTRY_AGGREGATE_BLIND(m_pUnkPlugin.p)
END_COM_MAP()
// IPluginAdapterV1
public:
// IPlugin2
STDMETHOD(Initialize)(IPluginSite2 *pSite2);
STDMETHOD(Terminate)();
// IDecalSurrogate
STDMETHOD(CreateInstance)(IDecalEnum *pEnum, REFIID riid, LPVOID *ppvItf);
};
#endif //__PLUGINADAPTERV1_H_

View file

@ -0,0 +1,42 @@
HKCR
{
Decal.PluginAdapterV1.1 = s 'Version 1 Plugin Surrogate'
{
CLSID = s '{3D837F6E-B5CA-4604-885F-7AB45FCFA62A}'
}
Decal.PluginAdapterV1 = s 'Version 1 Plugin Surrogate'
{
CLSID = s '{3D837F6E-B5CA-4604-885F-7AB45FCFA62A}'
CurVer = s 'Decal.PluginAdapterV1.1'
}
NoRemove CLSID
{
ForceRemove {3D837F6E-B5CA-4604-885F-7AB45FCFA62A} = s 'Version 1 Plugin Surrogate'
{
ProgID = s 'Decal.PluginAdapterV1.1'
VersionIndependentProgID = s 'Decal.PluginAdapterV1'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
'TypeLib' = s '{FF7F5F6D-34E0-4B6F-B3BB-8141DE2EF732}'
}
}
}
HKLM
{
NoRemove SOFTWARE
{
NoRemove Decal
{
NoRemove Surrogates
{
ForceRemove {3D837F6E-B5CA-4604-885F-7AB45FCFA62A} = s 'Version 1 Plugin Surrogate'
{
val Enabled = d '1'
}
}
}
}
}

View file

@ -0,0 +1,60 @@
// PluginImpl.h
// Declaration of helper class for implementing plugins
#ifndef __PLUGINIMPL_H
#define __PLUGINIMPL_H
template< class cImpl >
class IPluginImpl
: public IPlugin
{
public:
CComPtr< IPluginSite > m_pSite;
void onInitialize()
{
}
void onTerminate()
{
}
static LPCTSTR name()
{
// You must implement this function in the derived class
_ASSERTE( FALSE );
return _T( "ERROR: <unnamed plugin>" );
}
STDMETHOD(Initialize)( IPluginSite *pSite, long nID )
{
m_pSite = pSite;
static_cast< cImpl * >( this )->onInitialize();
return S_OK;
}
STDMETHOD(Terminate)()
{
static_cast< cImpl * >( this )->onTerminate();
m_pSite.Release();
return S_OK;
}
STDMETHOD(get_FriendlyName)( BSTR *pbstrName )
{
_ASSERTE( pbstrName != NULL );
*pbstrName = T2BSTR( cImpl::name() );
return S_OK;
}
};
// Included here for backward compatibility
#include <EventsImpl.h>
#endif // __PLUGINIMPL_H

251
Native/Inject/RootLayer.cpp Normal file
View file

@ -0,0 +1,251 @@
// RootLayer.cpp : Implementation of cRootLayer
#include "stdafx.h"
#include "Inject.h"
#include "RootLayer.h"
#include "Manager.h"
#include "BarLayer.h"
#include "Panel.h"
#include "View.h"
enum eChildIDs
{
eChildBars,
eChildPanel
};
/////////////////////////////////////////////////////////////////////////////
// cRootLayer
void cRootLayer::addView( cView *pView, ILayer *pRoot )
{
m_views.push_back( pView );
// Next, make the bar entry
m_pBars->AddBar( pView->m_nViewID, &pView->m_VP );
// Last, make the view entry
pView->m_pPanel->AddView( pView->m_nViewID, pRoot );
}
void cRootLayer::removeView( cView *pView )
{
for( cViewList::iterator i = m_views.begin(); i != m_views.end(); ++ i )
{
if( *i == pView )
{
m_views.erase( i );
break;
}
}
}
void cRootLayer::onCreate()
{
LayerParams lpBars = { eChildBars, { 0, 0, 1, 1 }, 0 };
CComObject< cBarLayer > *pBars;
CComObject< cBarLayer >::CreateInstance( &pBars );
m_pBars = pBars;
m_pSite->CreateChild( &lpBars, pBars );
if( m_nViewMode == 0 ) // Single Mode
{
LayerParams lpPanel = { eChildPanel, { 0, 0, 0, 0 }, 0 };
CComObject< cPanel > *pPanel;
CComObject< cPanel >::CreateInstance( &pPanel );
m_pSite->CreateChild( &lpPanel, pPanel );
pPanel->putref_Sink( this );
m_pPanel = pPanel;
}
}
void cRootLayer::onDestroy()
{
m_pBars.Release();
}
STDMETHODIMP cRootLayer::CreateView(ViewParams *pParams, ILayer *pLayer, IView **ppView)
{
// First create the view object
CComObject< cView > *pView;
CComObject< cView >::CreateInstance( &pView );
if( m_nViewMode == 1 ) // Multi Mode
{
LayerParams lpPanel = { m_nNextViewID, { 0, 0, 0, 0 }, 0 };
CComObject< cPanel > *pPanel;
CComObject< cPanel >::CreateInstance( &pPanel );
m_pSite->CreateChild( &lpPanel, pPanel );
pPanel->putref_Sink( this );
pView->m_pPanel = pPanel;
}
else
pView->m_pPanel = m_pPanel;
pView->m_pRoot = this;
pView->m_nViewID = m_nNextViewID ++;
pView->m_VP.label = _bstr_t(pParams->label).copy();
pView->m_VP.icon = pParams->icon;
pView->m_VP.iconLibrary = pParams->iconLibrary;
pView->m_VP.left = pParams->left;
pView->m_VP.top = pParams->top;
pView->m_VP.width = pParams->width;
pView->m_VP.height = pParams->height;
addView( pView, pLayer );
*ppView = pView;
pView->AddRef();
return S_OK;
}
STDMETHODIMP cRootLayer::SelectBar(long nID)
{
// We are given the Bar ID, find the matching view
for( cViewList::iterator i = m_views.begin(); i != m_views.end(); ++ i )
{
if( ( *i )->m_nViewID == nID )
{
long nPrevActive;
( *i )->m_pPanel->get_ActiveView( &nPrevActive );
if( nPrevActive != nID )
{
( *i )->m_pPanel->ActivateView( ( *i )->m_nViewID, & (*i)->m_VP, (long*)(*i));
( *i )->Fire_Activate();
( *i )->m_bActivated = true;
}
else
{
( *i )->Deactivate();
( *i )->m_bActivated = false;
}
return S_OK;
}
}
// Invalid return value
return E_INVALIDARG;
}
STDMETHODIMP cRootLayer::LoadView(BSTR strXML, IView **ppView)
{
CComObject< cView > *pView;
CComObject< cView >::CreateInstance( &pView );
if( m_nViewMode == 1 ) // Multi Mode
{
LayerParams lpPanel = { m_nNextViewID, { 0, 0, 0, 0 }, 0 };
CComObject< cPanel > *pPanel;
CComObject< cPanel >::CreateInstance( &pPanel );
m_pSite->CreateChild( &lpPanel, pPanel );
pPanel->putref_Sink( this );
pView->m_pPanel = pPanel;
pPanel->put_Params( &pView->m_VP );
}
else
{
pView->m_pPanel = m_pPanel;
m_pPanel->put_Params( &pView->m_VP );
}
CComPtr< IUnknown > pRootControl;
pView->m_pRoot = this;
pView->m_nViewID = m_nNextViewID ++;
long lViewFlags = pView->loadSchema( strXML, &pRootControl );
if( pRootControl.p )
{
m_views.push_back( pView );
*ppView = pView;
pView->AddRef();
// Next, make the bar entry
m_pBars->AddBar( pView->m_nViewID, &pView->m_VP );
// Last, create all the controls
pView->m_pPanel->LoadViewEx( pView->m_nViewID, pView, pRootControl, lViewFlags );
if( cManager::_p->m_bXMLViewViewer )
{
pView->m_VP.top = 24;
pView->Activate( );
}
}
else
{
pView->Release( );
*ppView = NULL;
return E_FAIL;
}
return S_OK;
}
STDMETHODIMP cRootLayer::PanelDeactivate(long nViewID)
{
// Find the view of our desires and fire it's hide message
for( cViewList::iterator i = m_views.begin(); i != m_views.end(); ++ i )
{
if( ( *i )->m_nViewID == nViewID )
( *i )->Fire_Deactivate(),( *i )->m_bActivated = false;
}
return S_OK;
}
STDMETHODIMP cRootLayer::LoadViewObject(IUnknown *pSchema, IView **ppView)
{
CComObject< cView > *pView;
CComObject< cView >::CreateInstance( &pView );
if( m_nViewMode == 1 ) // Multi Mode
{
LayerParams lpPanel = { m_nNextViewID, { 0, 0, 0, 0 }, 0 };
CComObject< cPanel > *pPanel;
CComObject< cPanel >::CreateInstance( &pPanel );
m_pSite->CreateChild( &lpPanel, pPanel );
pPanel->putref_Sink( this );
pView->m_pPanel = pPanel;
}
else
pView->m_pPanel = m_pPanel;
CComPtr< IUnknown > pRootControl;
pView->m_pRoot = this;
pView->m_nViewID = m_nNextViewID ++;
pView->loadSchemaObject( pSchema, &pRootControl );
m_views.push_back( pView );
*ppView = pView;
pView->AddRef();
// Next, make the bar entry
m_pBars->AddBar( pView->m_nViewID, &pView->m_VP );
// Last, create all the controls
pView->m_pPanel->LoadView( pView->m_nViewID, pView, pRootControl );
return S_OK;
}

67
Native/Inject/RootLayer.h Normal file
View file

@ -0,0 +1,67 @@
// RootLayer.h : Declaration of the cRootLayer
#ifndef __ROOTLAYER_H_
#define __ROOTLAYER_H_
#include "resource.h" // main symbols
// This special layer implements no sinks, it is merely a container
// layer for the bar manager and the window manager - it server no other purpose
// than to forward event on and avoid redundant looping in the manager object.
#include "SinkImpl.h"
class cView;
/////////////////////////////////////////////////////////////////////////////
// cRootLayer
class ATL_NO_VTABLE cRootLayer :
public CComObjectRootEx<CComMultiThreadModel>,
public ILayerImpl< cRootLayer >,
public IPanelSink,
public cNoEventsImpl,
public IRootLayer
{
public:
cRootLayer() : m_nNextViewID( 1000 ), m_nViewMode( 0 )
{
RegKey key;
key.Create( HKEY_LOCAL_MACHINE, _T( "SOFTWARE\\Decal" ) );
if( key.QueryDWORDValue( _T("ViewMode"), m_nViewMode ) != ERROR_SUCCESS)
m_nViewMode = 0;
}
DWORD m_nViewMode;
CComPtr< IBarManager > m_pBars;
CComPtr< IPanel > m_pPanel;
typedef std::list< cView * > cViewList;
cViewList m_views;
long m_nNextViewID;
long m_lDefaultX;
long m_lDefaultY;
void addView( cView *pView, ILayer *pRootLayer );
void removeView( cView *pView );
void onCreate();
void onDestroy();
BEGIN_COM_MAP(cRootLayer)
COM_INTERFACE_ENTRY(IPanelSink)
COM_INTERFACE_ENTRY(IRootLayer)
COM_INTERFACE_ENTRY(ILayer)
END_COM_MAP()
public:
// IRootLayer Methods
STDMETHOD(CreateView)(ViewParams *pParams, ILayer *pLayer, /*[out, retval]*/ IView **ppView);
STDMETHOD(SelectBar)(long nID);
STDMETHOD(LoadView)(BSTR strXML, /*[out, retval]*/ IView **ppView);
STDMETHOD(LoadViewObject)(IUnknown *pSchema, /*[out, retval]*/ IView **ppView);
// IPanelSink Methods
STDMETHOD(PanelDeactivate)( long nViewID );
};
#endif //__ROOTLAYER_H_

146
Native/Inject/SimpleBar.cpp Normal file
View file

@ -0,0 +1,146 @@
// SimpleBar.cpp : Implementation of cSimpleBar
#include "stdafx.h"
#include "Inject.h"
#include "SimpleBar.h"
/////////////////////////////////////////////////////////////////////////////
// cSimpleBar
void cSimpleBar::onCreate()
{
CComPtr< IPluginSite > pPlugin;
m_pSite->get_PluginSite( &pPlugin );
pPlugin->LoadBitmapFile( _bstr_t( _T( "Switch-Active.bmp" ) ), &m_pSwitch );
pPlugin->LoadBitmapFile( _bstr_t( _T( "Switch-Inactive.bmp" ) ), &m_pSwitchDisabled );
BSTR bstrFontName;
pPlugin->get_FontName(&bstrFontName);
pPlugin->CreateFont( bstrFontName /*_bstr_t( _T( "Times New Roman" ) )*/, 14, 0, &m_pFont );
m_nMinMax = 0;
m_pSite->put_Transparent( VARIANT_FALSE );
}
void cSimpleBar::onDestroy()
{
m_pSwitch.Release();
m_pSwitchDisabled.Release();
m_pFont.Release();
}
#define SWITCH_STRETCH_START 25
#define SWITCH_STRETCH_END 55
#define TEXT_ICON_GAP 4
#define END_GAP 8
#define ICON_TOP 2
#define TEXT_TOP 2
#define ICON_SIZE 16
STDMETHODIMP cSimpleBar::Render(ICanvas *pCanvas)
{
RECT rc;
m_pSite->get_Position( &rc );
int nWidth = rc.right - rc.left;
// First draw the background image
static POINT ptOrg = { 0, 0 };
if( m_bSelected )
m_pSwitch->StretchBlt( pCanvas, &ptOrg, nWidth, SWITCH_STRETCH_START, SWITCH_STRETCH_END );
else
m_pSwitchDisabled->StretchBlt( pCanvas, &ptOrg, nWidth, SWITCH_STRETCH_START, SWITCH_STRETCH_END );
// Next the icon
CComPtr< IPluginSite > pPlugin;
m_pSite->get_PluginSite( &pPlugin );
CComPtr< IIconCache > pIcons;
static SIZE szIcon = { ICON_SIZE, ICON_SIZE };
pPlugin->GetIconCache( &szIcon, &pIcons );
static POINT ptIcon = { 0, ICON_TOP };
pIcons->DrawIcon( &ptIcon, m_nIconID, m_nIconModule, pCanvas );
if (m_nMinMax == eStateMax)
{
static POINT ptText = { ICON_SIZE + TEXT_ICON_GAP, TEXT_TOP };
m_pFont->DrawText( &ptText, m_strLabel, ( m_bSelected ) ? RGB( 0, 0, 0 ) : RGB( 255, 255, 255 ), pCanvas );
}
_ASSERTMEM( _CrtCheckMemory( ) );
return S_OK;
}
STDMETHODIMP cSimpleBar::MouseEnter(MouseState *)
{
m_bSelected = VARIANT_TRUE;
m_pSite->Invalidate();
return S_OK;
}
STDMETHODIMP cSimpleBar::MouseExit(MouseState *)
{
m_bSelected = VARIANT_FALSE;
m_pSite->Invalidate();
return S_OK;
}
STDMETHODIMP cSimpleBar::MouseDown(MouseState *)
{
CComPtr< IRootLayer > pRoot;
m_pSite->GetParentSink( IID_IRootLayer, reinterpret_cast< void ** >( &pRoot ) );
_ASSERTE( pRoot.p != NULL );
long nID;
m_pSite->get_ID( &nID );
pRoot->SelectBar( nID );
return S_OK;
}
STDMETHODIMP cSimpleBar::get_RenderWidth(long *nWidth)
{
if (m_nMinMax == eStateMin)
{
*nWidth = 20;
}
else
{
SIZE sz;
m_pFont->MeasureText( m_strLabel, &sz );
// Add in the requested size to the parent
*nWidth = sz.cx + TEXT_ICON_GAP + END_GAP + ICON_SIZE;
}
return S_OK;
}
STDMETHODIMP cSimpleBar::get_Params(ViewParams *pVal)
{
USES_CONVERSION;
pVal->icon = m_nIconID;
pVal->iconLibrary = m_nIconModule;
pVal->label = OLE2BSTR( m_strLabel );
pVal->state = m_nMinMax;
return S_OK;
}
STDMETHODIMP cSimpleBar::put_Params(ViewParams *newVal)
{
m_nIconID = newVal->icon;
m_nIconModule = newVal->iconLibrary;
m_strLabel = newVal->label;
m_nMinMax = newVal->state;
return S_OK;
}

63
Native/Inject/SimpleBar.h Normal file
View file

@ -0,0 +1,63 @@
// SimpleBar.h : Declaration of the cSimpleBar
#ifndef __SIMPLEBAR_H_
#define __SIMPLEBAR_H_
#include "resource.h" // main symbols
#include "SinkImpl.h"
/////////////////////////////////////////////////////////////////////////////
// cSimpleBar
class ATL_NO_VTABLE cSimpleBar :
public CComObjectRootEx<CComMultiThreadModel>,
public ISimpleBar,
public cNoEventsImpl,
public ILayerImpl< cSimpleBar >,
public ILayerRenderImpl,
public ILayerMouseImpl
{
public:
cSimpleBar()
: m_bSelected( VARIANT_FALSE )
{
}
_bstr_t m_strLabel;
long m_nIconModule;
long m_nIconID;
long m_nMinMax;
VARIANT_BOOL m_bSelected;
CComPtr< IImageCache > m_pSwitch;
CComPtr< IImageCache > m_pSwitchDisabled;
CComPtr< IFontCache > m_pFont;
void onCreate();
void onDestroy();
BEGIN_COM_MAP(cSimpleBar)
COM_INTERFACE_ENTRY(ILayerRender)
COM_INTERFACE_ENTRY(ILayerMouse)
COM_INTERFACE_ENTRY(ILayer)
COM_INTERFACE_ENTRY(ISimpleBar)
END_COM_MAP()
// ISimpleBar
public:
// ISimpleBar Functions
STDMETHOD(get_Params)(/*[out, retval]*/ ViewParams *pVal);
STDMETHOD(put_Params)(/*[in]*/ ViewParams * newVal);
STDMETHOD(get_RenderWidth)(long *nWidth);
// ILayerRender Functions
STDMETHOD(Render)(ICanvas *pCanvas);
// ILayerMouse Functions
STDMETHOD(MouseEnter)(MouseState *);
STDMETHOD(MouseExit)(MouseState *);
STDMETHOD(MouseDown)(MouseState *);
};
#endif //__SIMPLEBAR_H_

View file

@ -0,0 +1,69 @@
// SinkImpl.cpp
// Implementation of empty functions
#include "stdafx.h"
#include "Inject.h"
#include "SinkImpl.h"
STDMETHODIMP ILayerRenderImpl::PreRender()
{
return S_OK;
}
STDMETHODIMP ILayerRenderImpl::Render(ICanvas *)
{
return S_OK;
}
STDMETHODIMP ILayerRenderImpl::Reformat()
{
return S_OK;
}
STDMETHODIMP ILayerRenderImpl::AdjustRenderArea(ICanvas *, VARIANT_BOOL *pbDrawChildren)
{
*pbDrawChildren = VARIANT_TRUE;
return S_OK;
}
STDMETHODIMP ILayerRenderImpl::HitTest(LPPOINT pt, VARIANT_BOOL *pbHit)
{
*pbHit = VARIANT_TRUE;
return S_OK;
}
STDMETHODIMP ILayerMouseImpl::MouseEnter(struct MouseState *)
{
return S_OK;
}
STDMETHODIMP ILayerMouseImpl::MouseExit(struct MouseState *)
{
return S_OK;
}
STDMETHODIMP ILayerMouseImpl::MouseDown(struct MouseState *)
{
return S_OK;
}
STDMETHODIMP ILayerMouseImpl::MouseUp(struct MouseState *)
{
return S_OK;
}
STDMETHODIMP ILayerMouseImpl::MouseMove(struct MouseState *)
{
return S_OK;
}
STDMETHODIMP ILayerMouseImpl::MouseDblClk(struct MouseState *)
{
return S_OK;
}
STDMETHODIMP ILayerMouseImpl::MouseEvent(long nMsg, long wParam, long lParam)
{
return S_OK;
}

176
Native/Inject/SinkImpl.h Normal file
View file

@ -0,0 +1,176 @@
// SinkImpl.h
// Declaration of interface helpers that provide default empty implementations
// for all of the sinks defined in the IDL file.
// This can help reduce the number of functions you have to write,
// to use, derived from the *Impl class instead of the interface directly then
// implement the functions you care about.
// These function are guaranteed never to do anything at all useful,
// so never call them. If you implement all the functions in the interface
// there is no reason to use these classes.
#ifndef __SINKIMPL_H
#define __SINKIMPL_H
#include "PluginImpl.h"
class ATL_NO_VTABLE ILayerRenderImpl : public ILayerRender
{
public:
STDMETHOD(PreRender)();
STDMETHOD(Render)( ICanvas *pCanvas );
STDMETHOD(Reformat)();
STDMETHOD(AdjustRenderArea)( ICanvas *pCanvas, VARIANT_BOOL *pbDrawChildren );
STDMETHOD(HitTest)(LPPOINT pt, VARIANT_BOOL *pbHit);
};
template< class cImpl >
class ATL_NO_VTABLE ILayerImpl : public ILayer
{
public:
// Override these methods
CComPtr< ILayerSite > m_pSite;
void onCreate()
{
// Override this function to initialize the control
}
void onDestroy()
{
// Override this function to release all stored objects
}
STDMETHOD(LayerCreate)(ILayerSite *pSite)
{
_ASSERTE( m_pSite.p == NULL );
_ASSERTE( pSite != NULL );
m_pSite = pSite;
static_cast< cImpl * >( this )->onCreate();
return S_OK;
}
STDMETHOD(LayerDestroy)()
{
_ASSERTE( m_pSite.p != NULL );
long nID;
m_pSite->get_ID( &nID );
static_cast< cImpl * >( this )->Fire_Destroy( nID );
static_cast< cImpl * >( this )->onDestroy();
m_pSite.Release();
return S_OK;
}
STDMETHOD(put_Position)(RECT *newVal)
{
return m_pSite->put_Position(newVal);
}
STDMETHOD(get_Position)(RECT *pVal)
{
return m_pSite->get_Position(pVal);
}
STDMETHOD(Invalidate)()
{
return m_pSite->Invalidate();
}
};
class ATL_NO_VTABLE ILayerMouseImpl : public ILayerMouse
{
public:
STDMETHOD(MouseEnter)(struct MouseState *pMouse);
STDMETHOD(MouseExit)(struct MouseState *pMouse);
STDMETHOD(MouseDown)(struct MouseState *pMouse);
STDMETHOD(MouseUp)(struct MouseState *pMouse);
STDMETHOD(MouseMove)(struct MouseState *pMouse);
STDMETHOD(MouseDblClk)(struct MouseState *pMouse);
STDMETHOD(MouseEvent)(long nMsg, long wParam, long lParam);
};
// This class implements the code IControl functions, to use this implementation,
// derive your control interface from IControl and pass your derived interface as
// IControlItf
// In your interface map, makes sure both IControl and your control interface
// are included.
template< class cImpl, class IControlItf, const IID *pDispItf, const GUID *pbLib >
class ATL_NO_VTABLE IControlImpl
: public IDispatchImpl< IControlItf, pDispItf, pbLib >
{
public:
// Override this function if you care about child destruction
void onChildDestroy( long nID )
{
}
STDMETHOD(DestroyChild)(long nIndex, /*[defaultvalue(ePositionByIndex)]*/ enum ePositionType posType)
{
CComPtr< ILayerSite > pChildSite;
HRESULT hRes = static_cast< cImpl * >( this )->m_pSite->get_Child( nIndex, posType, &pChildSite );
if( !SUCCEEDED( hRes ) )
return hRes;
long nID;
pChildSite->get_ID( &nID );
// Do destroy preprocessing
static_cast< cImpl * >( this )->onChildDestroy( nID );
// Kill the child and return
return pChildSite->Destroy();
}
STDMETHOD(get_ID)(/*[out, retval]*/ long *pnID )
{
return static_cast< cImpl * >( this )->m_pSite->get_ID( pnID );
}
STDMETHOD(get_ChildCount)(/*[out, retval]*/ long *pnChildCount )
{
return static_cast< cImpl * >( this )->m_pSite->get_ChildCount( pnChildCount );
}
STDMETHOD(get_Child)(long nIndex, /*[optional, defaultvalue(ePositionByIndex)]*/ ePositionType ePosType, /*[out, retval]*/ IControl **ppChild )
{
CComPtr< ILayerSite > pChildSite;
HRESULT hRes = static_cast< cImpl * >( this )->m_pSite->get_Child( nIndex, ePosType, &pChildSite );
if( FAILED( hRes ) )
return hRes;
return pChildSite->GetSink( IID_IControl, reinterpret_cast< void ** >( ppChild ) );
}
STDMETHOD(put_Position)(RECT *newVal)
{
return static_cast< cImpl * >( this )->m_pSite->put_Position(newVal);
}
STDMETHOD(get_Position)(RECT *pVal)
{
return static_cast< cImpl * >( this )->m_pSite->get_Position(pVal);
}
};
// Derive from this class if your layer does not use an IControlEvents
// derived source interface. This is mainly intereded for internal framework
// classes.
class cNoEventsImpl
{
public:
HRESULT Fire_Destroy( long )
{
return E_NOTIMPL;
}
};
#endif

View file

@ -0,0 +1,27 @@
// SolidImage.cpp : Implementation of cSolidImage
#include "stdafx.h"
#include "Inject.h"
#include "SolidImage.h"
/////////////////////////////////////////////////////////////////////////////
// cSolidImage
STDMETHODIMP cBrushImage::get_Color(long *pVal)
{
_ASSERTE( pVal != NULL );
*pVal = m_nColor;
return S_OK;
}
STDMETHODIMP cBrushImage::put_Color(long newVal)
{
// Make sure the color is in range
_ASSERTE( ( newVal & 0xFF000000 ) == 0 );
m_nColor = newVal;
return S_OK;
}

View file

@ -0,0 +1,79 @@
// SolidImage.h : Declaration of the cSolidImage
#ifndef __SOLIDIMAGE_H_
#define __SOLIDIMAGE_H_
#include "resource.h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// cSolidImage
class ATL_NO_VTABLE cBrushImage :
public CComObjectRootEx<CComMultiThreadModel>,
public IBrushImage,
public IDispatchImpl< IImageCache, &IID_IImageCacheDisp, &LIBID_DecalPlugins >
{
public:
cBrushImage()
: m_nColor( RGB( 0, 255, 255 ) )
{
}
long m_nColor;
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(cBrushImage)
COM_INTERFACE_ENTRY(IBrushImage)
COM_INTERFACE_ENTRY(IImageCache)
COM_INTERFACE_ENTRY(IImageCacheDisp)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
public:
// IBrushImage Methods
STDMETHOD(get_Color)(/*[out, retval]*/ long *pVal);
STDMETHOD(put_Color)(/*[in]*/ long newVal);
// IImageCache Methods
STDMETHOD(PatBlt)(ICanvas * pDest, tagRECT * prcDest, tagPOINT * ptOrigin)
{
if( m_nColor != RGB( 0, 255, 255 ) )
pDest->Fill( prcDest, m_nColor );
return S_OK;
}
STDMETHOD(StretchBlt)(ICanvas * pDest, tagPOINT * pptDest, LONG nWidth, LONG nStartStretch, LONG nEndStretch)
{
// Not implemented, not a real image
_ASSERTE( FALSE );
return E_NOTIMPL;
}
STDMETHOD(Blt)(tagRECT * rcSrc, ICanvas * pDest, tagPOINT * pptDest)
{
// Not implemented, not a real image
_ASSERTE( FALSE );
return E_NOTIMPL;
}
STDMETHOD(get_Size)(tagSIZE * pVal)
{
_ASSERTE( pVal != NULL );
if (pVal == NULL)
return E_POINTER;
// Not implemented, not a real image
_ASSERTE( FALSE );
return E_NOTIMPL;
}
STDMETHOD(StretchBltArea)(tagRECT * prcSrc, ICanvas * pDest, tagRECT * prcDest)
{
// Not implemented, not a real image
_ASSERTE( FALSE );
return E_NOTIMPL;
}
};
#endif //__SOLIDIMAGE_H_

View file

@ -0,0 +1,25 @@
HKCR
{
Inject.SolidImage.1 = s 'SolidImage Class'
{
CLSID = s '{918C0333-5714-4C8D-A95C-2C137B76D364}'
}
Inject.SolidImage = s 'SolidImage Class'
{
CLSID = s '{918C0333-5714-4C8D-A95C-2C137B76D364}'
CurVer = s 'Inject.SolidImage.1'
}
NoRemove CLSID
{
ForceRemove {918C0333-5714-4C8D-A95C-2C137B76D364} = s 'SolidImage Class'
{
ProgID = s 'Inject.SolidImage.1'
VersionIndependentProgID = s 'Inject.SolidImage'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Both'
}
'TypeLib' = s '{3559E08B-827E-4DFE-9D33-3567246849CC}'
}
}
}

5
Native/Inject/StdAfx.cpp Normal file
View file

@ -0,0 +1,5 @@
// stdafx.cpp : source file that includes just the standard includes
// stdafx.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"

54
Native/Inject/StdAfx.h Normal file
View file

@ -0,0 +1,54 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently,
// but are changed infrequently
#if !defined(AFX_STDAFX_H__F572112C_DAE7_4CC4_9843_056AF6606BEF__INCLUDED_)
#define AFX_STDAFX_H__F572112C_DAE7_4CC4_9843_056AF6606BEF__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define STRICT
#define _WIN32_WINDOWS 0x0410
#define _WIN32_DCOM
#define _ATL_APARTMENT_THREADED
#define D3D_OVERLOADS
#define DIRECTINPUT_VERSION 0x600
#include <atlbase.h>
//You may derive a class from CComModule and use it if you want to override
//something, but do not change the name of _Module
extern CComModule _Module;
typedef UINT (CALLBACK* LPFNDLLFUNCALPHABLEND)(HDC, int, int, int, int, HDC, int, int, int, int, BLENDFUNCTION);
extern LPFNDLLFUNCALPHABLEND AlphaBlendF;
#include <atlcom.h>
#include <ddraw.h>
#include <d3d.h>
#include <winable.h>
#include <list>
#include <map>
#include <vector>
#include <stack>
#include <deque>
#include <queue>
#include <set>
#include <string>
#import <msxml.dll>
#include "../Include/Helpers.h"
#include "../Include/VSBridge.h"
#define MakePtr( cast, ptr, AddValue ) (cast)( (DWORD)(ptr)+(DWORD)(AddValue))
#ifdef _CHECKMEM
#define _ASSERTMEM(a) _ASSERTE(a)
#else
#define _ASSERTMEM(a)
#endif
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__F572112C_DAE7_4CC4_9843_056AF6606BEF__INCLUDED)

567
Native/Inject/View.cpp Normal file
View file

@ -0,0 +1,567 @@
// View.cpp : Implementation of cView
#include "stdafx.h"
#include <stdio.h>
#include "Inject.h"
#include "View.h"
#include "RootLayer.h"
#include "Manager.h"
#include "InjectApi.h"
/////////////////////////////////////////////////////////////////////////////
// cView
cView::~cView( )
{
m_bActivated = false;
m_pRoot->m_pBars->RemoveBar( m_nViewID );
m_pPanel->RemoveView( m_nViewID );
m_pRoot->removeView( this );
long nActiveView;
m_pPanel->get_ActiveView( &nActiveView );
m_pRoot->SelectBar( nActiveView );
m_pRoot->SelectBar( nActiveView );
m_pPanel.Release();
if( cManager::_p->m_bContainer )
cManager::_p->clearDestroyList( );
}
long cView::loadSchema( BSTR strSchema, IUnknown **ppRootControl )
{
USES_CONVERSION;
_ASSERTE( strSchema != NULL );
// Create a new XML document and load this up
MSXML::IXMLDOMDocumentPtr pDoc;
pDoc.CreateInstance( __uuidof( MSXML::DOMDocument ), NULL, CLSCTX_INPROC_SERVER );
VARIANT_BOOL bSuccess;
if( strSchema[ 0 ] == OLESTR( '<' ) )
bSuccess = pDoc->loadXML( strSchema );
else
{
// Load from a file source
pDoc->async = VARIANT_FALSE;
TCHAR szPath[ MAX_PATH ];
bSuccess = pDoc->load( ::InjectMapPath( eInjectPathAgent, OLE2T( strSchema ), szPath ) );
}
if( !bSuccess )
{
USES_CONVERSION;
// The document failed to load, get the error info for posterity
MSXML::IXMLDOMParseErrorPtr pErr = pDoc->parseError;
long nCode = pErr->errorCode;
long nFilePos = pErr->filepos;
long nLine = pErr->line;
long nLinePos = pErr->linepos;
_bstr_t strReason = pErr->reason;
_bstr_t strText = pErr->srcText;
TCHAR szError[ 1024 ];
::_stprintf( szError, _T( "0x%08X (%i, %i): %s" ),
nCode, nLine, nLinePos, OLE2T( strReason ) );
::MessageBox( cManager::_p->m_hMain, szError, _T( "XML Parse Error" ), MB_ICONERROR | MB_OK );
// Give the user a chance to break and look at this lovely info
_ASSERTE( FALSE );
pDoc.Release( );
return 0;
}
// Get the root element and check it out
long lViewFlags = loadSchemaObject( pDoc->documentElement, ppRootControl );
pDoc.Release( );
return lViewFlags;
}
long cView::loadSchemaObject( IUnknown *pObject, IUnknown **ppRootControl )
{
MSXML::IXMLDOMElementPtr pRoot = pObject;
_ASSERTE( pRoot->tagName == _bstr_t( _T( "view" ) ) );
// Get the view parameters
_variant_t vIconModule = pRoot->getAttribute( _T( "iconlibrary" ) ),
vIcon = pRoot->getAttribute( _T( "icon" ) ),
vTitle = pRoot->getAttribute( _T( "title" ) ),
vLeft = pRoot->getAttribute( _T( "left" ) ),
vTop = pRoot->getAttribute( _T( "top" ) ),
vWidth = pRoot->getAttribute( _T( "width" ) ),
vHeight = pRoot->getAttribute( _T( "height" ) ),
vTrans = pRoot->getAttribute( _T( "transparent" ) );
// We *must* have a title
_ASSERTE( vTitle.vt == VT_BSTR );
// Fill this into a view param
if( vIconModule.vt == VT_BSTR )
cManager::_p->LoadResourceModule( vIconModule.bstrVal, &m_VP.iconLibrary );
else
m_VP.iconLibrary = 0;
// GKusnick: Handle no-icon case without asserting.
// _ASSERTE( vIcon.vt != VT_NULL );
m_VP.icon = ( vIcon.vt != VT_NULL ) ? static_cast< long >( vIcon ) : 0;
// Para: shouldn't add 0x06000000 if there's an iconlibrary
if (m_VP.iconLibrary == 0 && m_VP.icon != 0)
m_VP.icon += 0x06000000;
if(vLeft.vt != VT_NULL)
m_VP.left = static_cast< long >(vLeft);
else
m_VP.left = 25;
if(vTop.vt != VT_NULL)
m_VP.top = static_cast< long >(vTop);
else
m_VP.top = 25;
if(vWidth.vt == VT_NULL)
m_VP.width = 180;
else
m_VP.width = static_cast< long >(vWidth);
if(vHeight.vt == VT_NULL)
{
SIZE szScreen;
cManager::_p->GetScreenSize( &szScreen );
m_VP.height = szScreen.cy/2;
}
else
m_VP.height = static_cast< long >(vHeight);
if(vTrans.vt == VT_NULL)
m_bTransparent = false;
else
m_bTransparent = static_cast< bool >( vTrans );
if( m_bTransparent )
m_VP.alpha = 255;
else
m_VP.alpha = -1;
m_VP.label = _bstr_t(vTitle.bstrVal).copy();
// The properly made schema should have a single control child
MSXML::IXMLDOMElementPtr pControl = pRoot->selectSingleNode( _T( "control" ) );
_ASSERTE( pControl.GetInterfacePtr() != NULL );
pControl->QueryInterface( ppRootControl );
long lViewFlags = 0;
if( m_bTransparent )
lViewFlags |= eTransparent;
return lViewFlags;
}
STDMETHODIMP cView::get_Control(BSTR strName, IControl **pVal)
{
_ASSERTE( strName != NULL );
_ASSERTE( pVal != NULL );
// Search for a matching control name
for( cNamedControlList::iterator i = m_controls.begin(); i != m_controls.end(); ++ i )
{
if( i->m_strName == _bstr_t( strName ) )
{
*pVal = i->m_pControl;
( *pVal )->AddRef();
return S_OK;
}
}
// The name was not found
return E_INVALIDARG;
}
STDMETHODIMP cView::putref_Control(BSTR strName, IControl *newVal)
{
_ASSERTE( strName != NULL );
// First look for a matching name
for( cNamedControlList::iterator i = m_controls.begin(); i != m_controls.end(); ++ i )
{
if( i->m_strName == _bstr_t( strName ) )
{
if( newVal == NULL )
m_controls.erase( i );
else
i->m_pControl = newVal;
return S_OK;
}
}
if( newVal == NULL )
// No value to set
return S_OK;
// Add in a new record
cNamedControl nc;
nc.m_strName = strName;
nc.m_pControl = newVal;
m_controls.push_back( nc );
return S_OK;
}
STDMETHODIMP cView::LoadControl(ILayerSite *pParent, long nID, IUnknown *pSource, long *pAssignedID)
{
// Usual parameter validation
_ASSERTE( pParent != NULL );
_ASSERTE( pSource != NULL );
_ASSERTE( pAssignedID != NULL );
MSXML::IXMLDOMElementPtr pElement = pSource;
// Make sure we're starting from the correct tag name
_ASSERTE( pElement->tagName == _bstr_t( _T( "control" ) ) );
// Get the progid and make an instance
_variant_t strProgID = pElement->getAttribute( _T( "progid" ) );
_ASSERTE( strProgID.vt == VT_BSTR );
CLSID clsid;
HRESULT hRes = ::CLSIDFromProgID( strProgID.bstrVal, &clsid );
_ASSERTE( SUCCEEDED( hRes ) );
CComPtr< ILayer > pChildLayer;
hRes = ::CoCreateInstance( clsid, NULL, CLSCTX_INPROC_SERVER, IID_ILayer,
reinterpret_cast< void ** >( &pChildLayer ) );
_ASSERTE( SUCCEEDED( hRes ) );
// Get some position metrics - note, these are optional and will be
// loaded with 0s - this is for cases when the control is formatted
// entirely by the parent
_variant_t vLeft = pElement->getAttribute( _T( "left" ) ),
vTop = pElement->getAttribute( _T( "top" ) ),
vWidth = pElement->getAttribute( _T( "width" ) ),
vHeight = pElement->getAttribute( _T( "height" ) ),
vUnclipped = pElement->getAttribute( _T( "unclipped" ) ),
vID = pElement->getAttribute( _T( "ID" ) );
// check for lower case, since all other attributes are lower case. And
// Legiondale_Superman can't seem to get it right...
if (vID.vt == VT_NULL ) {
vID = pElement->getAttribute( _T( "id" ) );
}
long nRealID = ( vID.vt == VT_NULL ) ? nID : static_cast< long >( vID );
*pAssignedID = nRealID;
POINT pt = { ( vLeft.vt != VT_NULL ) ? static_cast< long >( vLeft ) : 0,
( vTop.vt != VT_NULL ) ? static_cast< long >( vTop ) : 0 };
LayerParams lp = { nRealID, { pt.x, pt.y, pt.x + ( ( vWidth.vt != VT_NULL ) ? static_cast< long >( vWidth ) : 0 ),
pt.y + ( ( vHeight.vt != VT_NULL ) ? static_cast< long >( vHeight ) : 0 ) },
( vUnclipped.vt != VT_NULL ) ? 0 : eRenderClipped };
pParent->CreateChild( &lp, pChildLayer );
// Check if this child is named
_variant_t vName = pElement->getAttribute( _T( "name" ) );
if( vName.vt == VT_BSTR )
{
// Add the named control
CComPtr< IControl > pControl;
pChildLayer->QueryInterface( &pControl );
putref_Control( vName.bstrVal, pControl );
}
// Ok, the child is made - trick it into loading it's own parameters
CComPtr< ILayerSchema > pSchema;
if( SUCCEEDED( pChildLayer->QueryInterface( &pSchema ) ) )
pSchema->SchemaLoad( this, pSource );
return S_OK;
}
STDMETHODIMP cView::LoadSchema(BSTR strXMLSchema)
{
long nPreviousView;
m_pPanel->get_ActiveView( &nPreviousView );
m_pPanel->RemoveView( m_nViewID );
CComPtr< IUnknown > pRootControl;
loadSchema( strXMLSchema, &pRootControl );
// Set the bar params
m_pRoot->m_pBars->put_Bar( m_nViewID, &m_VP );
long lViewFlags = 0;
if( m_bTransparent )
lViewFlags |= eTransparent;
// Last, create all the controls
m_pPanel->LoadViewEx( m_nViewID, this, pRootControl, lViewFlags );
if( nPreviousView == m_nViewID )
// Reactivate the view
m_pRoot->SelectBar( m_nViewID );
return S_OK;
}
STDMETHODIMP cView::get_Title(BSTR *pVal)
{
USES_CONVERSION;
*pVal = OLE2BSTR( m_VP.label );
return S_OK;
}
STDMETHODIMP cView::put_Title(BSTR newVal)
{
_ASSERTE( newVal != NULL );
bool bActivated = m_bActivated;
m_VP.label = _bstr_t( newVal ).copy( );
m_pRoot->m_pBars->put_Bar( m_nViewID, &m_VP );
if( bActivated )
m_pPanel->Deactivate(), m_pRoot->SelectBar( m_nViewID );
return S_OK;
}
STDMETHODIMP cView::Alert()
{
return S_OK;
}
STDMETHODIMP cView::SetIcon(long icon, VARIANT iconlibrary)
{
USES_CONVERSION;
m_VP.icon = icon;
switch( iconlibrary.vt )
{
case VT_ERROR:
case VT_EMPTY:
case VT_NULL:
m_VP.iconLibrary = 0;
break;
case VT_BSTR:
m_VP.iconLibrary = reinterpret_cast< long >( ::GetModuleHandle( OLE2T( iconlibrary.bstrVal ) ) );
break;
default:
// Try and convert everything else to a number
try
{
_variant_t v = iconlibrary;
m_VP.iconLibrary = v;
}
catch( ... )
{
m_VP.iconLibrary = 0;
return E_INVALIDARG;
}
break;
}
m_pRoot->m_pBars->put_Bar( m_nViewID, &m_VP );
return S_OK;
}
STDMETHODIMP cView::Activate()
{
long nActiveView;
m_pPanel->get_ActiveView( &nActiveView );
if (nActiveView != m_nViewID)
m_pRoot->SelectBar( m_nViewID );
return S_OK;
}
STDMETHODIMP cView::Deactivate()
{
m_pPanel->Deactivate();
if(cManager::_p->m_pKeyboard!=NULL)
{
cManager::_p->m_pKeyboard->sendKeyboardEndCapture( VARIANT_TRUE );
cManager::_p->m_pKeyboard=NULL;
}
return S_OK;
}
STDMETHODIMP cView::put_Position(RECT *newVal)
{
m_VP.left = newVal->left;
m_VP.top = newVal->top;
m_VP.width = newVal->right;
m_VP.height = newVal->bottom;
/* Drakier: make sure they aren't being bad little kittens and
moving the view offscreen! */
// Drakier: Get the pSite and Screen Size
CComPtr< IPluginSite > pPlugin;
CComPtr< IACHooks > pHooks;
m_pRoot->m_pSite->get_PluginSite( &pPlugin );
SIZE szScreen, sz;
pPlugin->GetScreenSize( &sz );
szScreen.cx = sz.cx;
szScreen.cy = sz.cy;
long lX = sz.cx, lY = sz.cy;
HRESULT hW = S_FALSE, hH = S_FALSE;
// Drakier: if we are not in the container, get the 3D Area
if ( !cManager::_p->m_bContainer )
{
pPlugin->get_Hooks( &pHooks );
hH = pHooks->get_Area3DHeight( &lY );
hW = pHooks->get_Area3DWidth( &lX );
pHooks.Release();
}
pPlugin.Release();
// Drakier: if we are in the container, or the 3D area's are NULL
if ( (cManager::_p->m_bContainer) || (hW != S_OK) || (hH != S_OK) )
{
szScreen.cx = sz.cx - 308; // 308 = PANEL_SIZE
szScreen.cy = sz.cy;
}
else // Drakier: If everything comes out right and we are not in container
{
if( (hW == S_OK) && (lX > 200) && (lX < 2000) )
szScreen.cx = lX;
if( (hH == S_OK) && (lY > 200) && (lY < 2000) )
szScreen.cy = lY;
}
if ( (szScreen.cx > 200) && (szScreen.cx < 2000) && (szScreen.cy > 200) && (szScreen.cy < 2000) )
{
if ( (m_VP.left + m_VP.width) > szScreen.cx )
m_VP.left = szScreen.cx - m_VP.width;
if ( (m_VP.top + m_VP.height) > szScreen.cy )
m_VP.top = szScreen.cy - m_VP.height;
if ( m_VP.left < 0 )
m_VP.left = 0;
if ( m_VP.top < 0 )
m_VP.top = 0;
long nActiveView;
m_pPanel->get_ActiveView( &nActiveView );
if( nActiveView == m_nViewID )
m_pPanel->ActivateView(m_nViewID, &m_VP, (long*)this);
}
return S_OK;
}
STDMETHODIMP cView::get_Position(RECT *pVal)
{
pVal->left = m_VP.left;
pVal->top = m_VP.top;
pVal->right = m_VP.width;
pVal->bottom = m_VP.height;
return S_OK;
}
STDMETHODIMP cView::get_Alpha(long *pVal)
{
if( pVal == NULL )
return E_POINTER;
if (m_bTransparent) {
*pVal = m_lOldAlpha ;
} else {
*pVal = m_VP.alpha;
}
return S_OK;
}
STDMETHODIMP cView::put_Alpha(long Alpha)
{
if( m_bTransparent )
return S_FALSE;
m_VP.alpha = Alpha;
long nActiveView;
m_pPanel->get_ActiveView( &nActiveView );
if( nActiveView == m_nViewID )
m_pPanel->ActivateView(m_nViewID, &m_VP, (long*)this);
return S_OK;
}
STDMETHODIMP cView::get_Activated(VARIANT_BOOL *pVal)
{
*pVal = ( m_bActivated ? VARIANT_TRUE : VARIANT_FALSE );
return S_OK;
}
STDMETHODIMP cView::put_Activated(VARIANT_BOOL newVal)
{
if( newVal == VARIANT_FALSE )
return Deactivate();
else
return Activate();
}
STDMETHODIMP cView::get_Transparent(VARIANT_BOOL *pVal)
{
*pVal = ( m_bTransparent ? VARIANT_TRUE : VARIANT_FALSE );
return S_OK;
}
STDMETHODIMP cView::put_Transparent(VARIANT_BOOL newVal)
{
if( newVal == VARIANT_FALSE )
{
if( !m_bTransparent )
return S_OK;
m_bTransparent = false;
m_VP.alpha = m_lOldAlpha;
m_pPanel->put_Transparent( VARIANT_FALSE );
}
else
{
if( m_bTransparent )
return S_OK;
m_bTransparent = true;
m_lOldAlpha = m_VP.alpha;
m_VP.alpha = 255;
m_pPanel->put_Transparent( VARIANT_TRUE );
}
return S_OK;
}

Some files were not shown because too many files have changed in this diff Show more