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,197 @@
// BorderLayout.cpp : Implementation of cBorderLayout
#include "stdafx.h"
#include "DecalControls.h"
#include "BorderLayout.h"
/////////////////////////////////////////////////////////////////////////////
// cBorderLayout
void cBorderLayout::onSchemaLoad( IView *pView, MSXML::IXMLDOMElementPtr &pElement )
{
static _bstr_t _strEdge = _T( "border" ),
_strCenter = _T( "center" );
static _variant_t
_strLeft = _T( "left" ),
_strRight = _T( "right" ),
_strTop = _T( "top" ),
_strBottom = _T( "bottom" );
// Walk through the list of children - select all elements
MSXML::IXMLDOMElementPtr pChild;
for( MSXML::IXMLDOMNodeListPtr pChildren = pElement->selectNodes( _T( "*" ) );
( pChild = pChildren->nextNode() ).GetInterfacePtr() != NULL; )
{
if( pChild->tagName == _strEdge )
{
// Attempt to extract the edge indicator and the size indicator
_variant_t vEdge = pChild->getAttribute( _T( "edge" ) ),
vSize = pChild->getAttribute( _T( "size" ) );
_ASSERTE( vEdge.vt != VT_NULL );
_ASSERTE( vSize.vt != VT_NULL );
// Got values, check if they're good
eBorderEdge eEdge;
if( _strLeft == vEdge )
eEdge = eEdgeLeft;
else if( vEdge == _strRight )
eEdge = eEdgeRight;
else if( vEdge == _strTop )
eEdge = eEdgeTop;
else if( vEdge == _strBottom )
eEdge = eEdgeBottom;
#ifdef _DEBUG
else
// Invalid value here
_ASSERTE( FALSE );
#endif
// Convert the size
try
{
long nSize = vSize;
// Cannot have a 0 or negative edge size
_ASSERTE( nSize > 0 );
cEdgePlacement ep = { eEdge, nSize, loadChildControl( pView, pChild->selectSingleNode( _T( "control" ) ) ) };
m_edges.push_back( ep );
}
catch( ... )
{
// The size could no be converted to a long value
_ASSERTE( FALSE );
}
}
else if( pChild->tagName == _strCenter )
{
// Make sure there isn't a center already created
_ASSERTE( m_nCenterID == -1 );
m_nCenterID = loadChildControl( pView, pChild->selectSingleNode( _T( "control" ) ) );
}
#ifdef _DEBUG
else
// This is an invalid child element type
_ASSERTE( FALSE );
#endif
}
}
void cBorderLayout::onChildDestroy( long nID )
{
// Check if this is the center
if( nID == m_nCenterID )
{
m_nCenterID = -1;
m_pSite->Reformat();
return;
}
// Check if it on an edge
for( cEdgePlacementList::iterator i = m_edges.begin(); i != m_edges.end(); ++ i )
{
if( i->m_nID == nID )
{
m_edges.erase( i );
m_pSite->Reformat();
break;
}
}
}
STDMETHODIMP cBorderLayout::CreateEdge(eBorderEdge eEdge, long nSize, ILayer *pSink)
{
_ASSERTE( nSize > 0 );
_ASSERTE( pSink != NULL );
LayerParams lp = { dispenseID(), { 0, 0, 0, 0 }, eRenderClipped };
m_pSite->CreateChild( &lp, pSink );
cEdgePlacement ep = { eEdge, nSize, lp.ID };
m_edges.push_back( ep );
m_pSite->Reformat();
return S_OK;
}
STDMETHODIMP cBorderLayout::CreateCenter(ILayer *pSink)
{
_ASSERTE( m_nCenterID == -1 );
LayerParams lp = { dispenseID(), { 0, 0, 0, 0 }, eRenderClipped };
m_pSite->CreateChild( &lp, pSink );
m_nCenterID = lp.ID;
m_pSite->Reformat();
return S_OK;
}
STDMETHODIMP cBorderLayout::Reformat()
{
// Walk through the list of edges in order and
// set their positions
RECT rcLayer;
m_pSite->get_Position( &rcLayer );
RECT rcClient = { 0, 0, rcLayer.right - rcLayer.left, rcLayer.bottom - rcLayer.top };
for( cEdgePlacementList::iterator i = m_edges.begin(); i != m_edges.end(); ++ i )
{
RECT rcPosition = rcClient;
switch( i->m_edge )
{
case eEdgeLeft:
rcPosition.right = rcPosition.left + i->m_nSize;
rcClient.left += i->m_nSize;
break;
case eEdgeTop:
rcPosition.bottom = rcPosition.top + i->m_nSize;
rcClient.top += i->m_nSize;
break;
case eEdgeRight:
rcPosition.left = rcPosition.right - i->m_nSize;
rcClient.right -= i->m_nSize;
break;
case eEdgeBottom:
rcPosition.top = rcPosition.bottom - i->m_nSize;
rcClient.bottom -= i->m_nSize;
break;
default:
// Invalid edge value
_ASSERTE( FALSE );
}
// Sanity checks to make sure we haven't overrun our area
//_ASSERTE( rcClient.bottom > rcClient.top );
_ASSERTE( rcClient.right > rcClient.left );
_ASSERTE( rcPosition.bottom > rcPosition.top );
_ASSERTE( rcPosition.right > rcPosition.left );
CComPtr< ILayerSite > pChild;
HRESULT hRes = m_pSite->get_Child( i->m_nID, ePositionByID, &pChild );
_ASSERTE( SUCCEEDED( hRes ) );
pChild->put_Position( &rcPosition );
}
if( m_nCenterID != -1 )
{
CComPtr< ILayerSite > pChild;
HRESULT hRes = m_pSite->get_Child( m_nCenterID, ePositionByID, &pChild );
_ASSERTE( SUCCEEDED( hRes ) );
pChild->put_Position( &rcClient );
}
return S_OK;
}