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:
commit
d1442e3747
1382 changed files with 170725 additions and 0 deletions
567
Native/Inject/View.cpp
Normal file
567
Native/Inject/View.cpp
Normal 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;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue