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
426
Native/DecalControls/Choice.cpp
Normal file
426
Native/DecalControls/Choice.cpp
Normal file
|
|
@ -0,0 +1,426 @@
|
|||
// Choice.cpp : Implementation of cChoice
|
||||
#include "stdafx.h"
|
||||
#include "DecalControls.h"
|
||||
#include "Choice.h"
|
||||
|
||||
#include "ChoicePopup.h"
|
||||
#include "ChoiceDropDown.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// cChoice
|
||||
|
||||
cChoice::cChoice()
|
||||
: m_nSelected( -1 ),
|
||||
m_nHotSelect( -1 ),
|
||||
m_nDropLines( 8 ),
|
||||
m_bPopup( false ),
|
||||
m_bMouseDown( false ),
|
||||
m_bMouseOver( false )
|
||||
{
|
||||
}
|
||||
|
||||
void cChoice::setPopup( bool bPopup )
|
||||
{
|
||||
// Always reset hot select
|
||||
m_bPopup = bPopup;
|
||||
m_nHotSelect = -1;
|
||||
|
||||
if( bPopup )
|
||||
{
|
||||
long nID;
|
||||
m_pSite->get_ID( &nID );
|
||||
Fire_DropDown( nID );
|
||||
m_pPopup->put_Popup( VARIANT_TRUE );
|
||||
}
|
||||
|
||||
// Redraw everything
|
||||
m_pSite->Reformat();
|
||||
m_pSite->Invalidate();
|
||||
}
|
||||
|
||||
void cChoice::onCreate()
|
||||
{
|
||||
CComPtr< IPluginSite > pPluginSite;
|
||||
m_pSite->get_PluginSite( &pPluginSite );
|
||||
|
||||
// Create the image info
|
||||
pPluginSite->LoadBitmapPortal( 0x06001276, &m_pInactive );
|
||||
BSTR bstrFontName;
|
||||
pPluginSite->get_FontName(&bstrFontName);
|
||||
pPluginSite->CreateFont( bstrFontName /*_bstr_t( _T( "Times New Roman" ) )*/, 14, 0, &m_pFont );
|
||||
|
||||
// Create the dropdown
|
||||
CComObject< cChoiceDropDown > *pDropDown;
|
||||
CComObject< cChoiceDropDown >::CreateInstance( &pDropDown );
|
||||
|
||||
pDropDown->m_pChoice = this;
|
||||
|
||||
LayerParams lp = { 0, { -1, -1, 0, 0 }, 0 };
|
||||
m_pSite->CreateChild( &lp, pDropDown );
|
||||
|
||||
m_pPopup = pDropDown->m_pSite;
|
||||
|
||||
// Create the scroller
|
||||
CComPtr< ILayer > pScrollerLayer;
|
||||
HRESULT hRes = ::CoCreateInstance( CLSID_Scroller, NULL, CLSCTX_INPROC_SERVER, IID_ILayer, reinterpret_cast< void ** >( &pScrollerLayer ) );
|
||||
_ASSERTE( SUCCEEDED( hRes ) );
|
||||
pScrollerLayer->QueryInterface( &m_pScroller );
|
||||
|
||||
// Create the scroller object
|
||||
LayerParams lpScroller = { 0, { 0, 0, 0, 0 }, eRenderClipped };
|
||||
m_pPopup->CreateChild( &lpScroller, pScrollerLayer );
|
||||
|
||||
// Configure the scroller
|
||||
SIZE szLine = { 18, 1 };
|
||||
m_pScroller->put_Increments( &szLine );
|
||||
|
||||
// Create the popup window
|
||||
CComObject< cChoicePopup > *pPopup;
|
||||
CComObject< cChoicePopup >::CreateInstance( &pPopup );
|
||||
|
||||
pPopup->m_pChoice = this;
|
||||
m_pScroller->CreateClient( pPopup );
|
||||
|
||||
m_pPopup->put_Transparent( VARIANT_FALSE );
|
||||
m_pSite->put_Transparent( VARIANT_FALSE );
|
||||
}
|
||||
|
||||
void cChoice::onDestroy()
|
||||
{
|
||||
m_pPopup.Release();
|
||||
|
||||
m_pFont.Release();
|
||||
m_pInactive.Release();
|
||||
}
|
||||
|
||||
STDMETHODIMP cChoice::MouseUp(MouseState *)
|
||||
{
|
||||
m_bMouseDown = false;
|
||||
|
||||
if( m_bMouseOver )
|
||||
{
|
||||
setPopup( !m_bPopup );
|
||||
|
||||
if( !m_bPopup )
|
||||
m_pPopup->put_Popup( VARIANT_FALSE );
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#define RENDER_LEFTSTRETCH 10
|
||||
#define RENDER_RIGHTSTRETCH 7
|
||||
#define ROW_HEIGHT 18
|
||||
|
||||
#define ICON_WIDTH 20
|
||||
#define ICON_HEIGHT 19
|
||||
|
||||
STDMETHODIMP cChoice::Render(ICanvas *pCanvas)
|
||||
{
|
||||
// First draw the background
|
||||
RECT rcPos;
|
||||
m_pSite->get_Position( &rcPos );
|
||||
|
||||
SIZE szImage;
|
||||
m_pInactive->get_Size( &szImage );
|
||||
|
||||
static POINT ptBack = { 0, 0 };
|
||||
m_pInactive->StretchBlt( pCanvas, &ptBack, rcPos.right - rcPos.left, RENDER_LEFTSTRETCH, szImage.cx - RENDER_RIGHTSTRETCH );
|
||||
|
||||
if( m_nSelected != -1 )
|
||||
{
|
||||
// Draw the selected text
|
||||
static POINT ptText = { 12, 2 };
|
||||
m_pFont->DrawTextEx( &ptText, m_options[ m_nSelected ].m_strText, 0, 0, eAA, pCanvas );
|
||||
}
|
||||
|
||||
// Draw the up/down icon
|
||||
CComPtr< IPluginSite > pPluginSite;
|
||||
m_pSite->get_PluginSite( &pPluginSite );
|
||||
|
||||
SIZE szIcon = { ICON_WIDTH, ICON_HEIGHT };
|
||||
CComPtr< IIconCache > pIconCache;
|
||||
pPluginSite->GetIconCache( &szIcon, &pIconCache );
|
||||
|
||||
POINT ptIcon = { rcPos.right - rcPos.left - ICON_WIDTH, 0 };
|
||||
pIconCache->DrawIcon( &ptIcon, ( ( m_bMouseDown && m_bMouseOver ) ? !m_bPopup : m_bPopup ) ? 0x06001275 : 0x06001274, 0, pCanvas );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cChoice::Reformat()
|
||||
{
|
||||
if( !m_bPopup || m_options.size() == 0 )
|
||||
{
|
||||
// If it's hidden great, hide it well
|
||||
static RECT rcHidden = { -1, -1, 0, 0 };
|
||||
m_pPopup->put_Position( &rcHidden );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Calculate the correct position
|
||||
RECT rc;
|
||||
m_pSite->get_ScreenPosition( &rc );
|
||||
|
||||
// Two modes, with scroll bar and without
|
||||
if( m_options.size() > m_nDropLines )
|
||||
{
|
||||
// With a scroller
|
||||
RECT rcPopup = { rc.left, rc.bottom, rc.right - ICON_WIDTH + 16, rc.bottom +
|
||||
ROW_HEIGHT * m_nDropLines };
|
||||
m_pPopup->put_Position( &rcPopup );
|
||||
|
||||
m_pScroller->put_VerticalEnabled( VARIANT_TRUE );
|
||||
|
||||
SIZE szArea = { rc.right - ICON_WIDTH, ROW_HEIGHT * m_options.size() };
|
||||
m_pScroller->put_Area( &szArea );
|
||||
}
|
||||
else
|
||||
{
|
||||
RECT rcPopup = { rc.left, rc.bottom, rc.right - ICON_WIDTH, rc.bottom +
|
||||
ROW_HEIGHT * m_options.size() };
|
||||
m_pPopup->put_Position( &rcPopup );
|
||||
|
||||
POINT ptOffset = { 0, 0 };
|
||||
m_pScroller->put_Offset( &ptOffset );
|
||||
m_pScroller->put_VerticalEnabled( VARIANT_FALSE );
|
||||
|
||||
SIZE szArea = { rc.right - ICON_WIDTH, ROW_HEIGHT * m_options.size() };
|
||||
m_pScroller->put_Area( &szArea );
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cChoice::SchemaLoad(IView *pView, IUnknown *pSchema)
|
||||
{
|
||||
// Load the data from the schema
|
||||
|
||||
MSXML::IXMLDOMElementPtr pElement = pSchema;
|
||||
|
||||
MSXML::IXMLDOMElementPtr pRow;
|
||||
for( MSXML::IXMLDOMNodeListPtr pRows = pElement->selectNodes( _T( "option" ) );
|
||||
( pRow = pRows->nextNode() ).GetInterfacePtr() != NULL; )
|
||||
{
|
||||
_variant_t vRow = pRow->getAttribute( _T( "text" ) ),
|
||||
vData = pRow->getAttribute( _T( "data" ) );
|
||||
_ASSERTE( vRow.vt == VT_BSTR );
|
||||
|
||||
cOption o;
|
||||
o.m_strText = vRow;
|
||||
o.m_value = vData;
|
||||
|
||||
m_options.push_back( o );
|
||||
}
|
||||
|
||||
_variant_t vDropRows = pElement->getAttribute( "droplines" ),
|
||||
vSelected = pElement->getAttribute( "selected" );
|
||||
|
||||
if( vDropRows.vt != VT_NULL )
|
||||
{
|
||||
try
|
||||
{
|
||||
m_nDropLines = static_cast< long >( vDropRows );
|
||||
_ASSERTE( m_nDropLines > 0 );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
// Type conversion error
|
||||
_ASSERTE( FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
if( vSelected.vt != VT_NULL )
|
||||
{
|
||||
try
|
||||
{
|
||||
m_nSelected = static_cast< long >( vSelected );
|
||||
_ASSERTE( m_nSelected >= 0 );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
// Type conversion error
|
||||
_ASSERTE( FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cChoice::AddChoice(BSTR strDisplay, VARIANT vData)
|
||||
{
|
||||
cOption o;
|
||||
o.m_strText = strDisplay;
|
||||
o.m_value = vData;
|
||||
|
||||
m_options.push_back( o );
|
||||
m_pSite->Reformat();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cChoice::get_ChoiceCount(long *pVal)
|
||||
{
|
||||
_ASSERTE( pVal != NULL );
|
||||
|
||||
*pVal = m_options.size();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cChoice::get_Data(long nIndex, VARIANT *pVal)
|
||||
{
|
||||
if( pVal == NULL )
|
||||
return E_POINTER;
|
||||
|
||||
if( nIndex < 0 || nIndex > m_options.size() )
|
||||
{
|
||||
pVal->lVal = -1;
|
||||
pVal->vt = VT_I4;
|
||||
}
|
||||
|
||||
else
|
||||
::VariantCopy( pVal, &m_options[ nIndex ].m_value );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cChoice::put_Data(long nIndex, VARIANT newVal)
|
||||
{
|
||||
_ASSERTE( nIndex >= 0 );
|
||||
_ASSERTE( nIndex < m_options.size() );
|
||||
|
||||
::VariantCopy( &m_options[ nIndex ].m_value, &newVal );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cChoice::get_Text(long nIndex, BSTR *pVal)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
|
||||
_ASSERTE( nIndex >= 0 );
|
||||
_ASSERTE( nIndex < m_options.size() );
|
||||
_ASSERTE( pVal != NULL );
|
||||
|
||||
*pVal = OLE2BSTR( m_options[ nIndex ].m_strText );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cChoice::put_Text(long nIndex, BSTR newVal)
|
||||
{
|
||||
_ASSERTE( nIndex >= 0 );
|
||||
_ASSERTE( nIndex < m_options.size() );
|
||||
_ASSERTE( newVal != NULL );
|
||||
|
||||
m_options[ nIndex ].m_strText = newVal;
|
||||
m_pPopup->Invalidate();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cChoice::RemoveChoice(long nIndex)
|
||||
{
|
||||
_ASSERTE( nIndex >= 0 );
|
||||
_ASSERTE( nIndex < m_options.size() );
|
||||
|
||||
m_options.erase( m_options.begin() + nIndex );
|
||||
|
||||
if( m_nSelected >= m_options.size() )
|
||||
m_nSelected = m_options.size() - 1;
|
||||
|
||||
long nID;
|
||||
m_pSite->get_ID( &nID );
|
||||
Fire_Change( nID, m_nSelected );
|
||||
|
||||
// Redraw the concerned
|
||||
m_pSite->Reformat();
|
||||
m_pPopup->Invalidate();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cChoice::get_Dropped(VARIANT_BOOL *pVal)
|
||||
{
|
||||
_ASSERTE( pVal != NULL );
|
||||
|
||||
*pVal = ( m_bPopup ) ? VARIANT_TRUE : VARIANT_FALSE;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cChoice::put_Dropped(VARIANT_BOOL newVal)
|
||||
{
|
||||
if( !!newVal != m_bPopup )
|
||||
setPopup( !!newVal );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cChoice::get_Selected(long *pVal)
|
||||
{
|
||||
_ASSERTE( pVal != NULL );
|
||||
*pVal = m_nSelected;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cChoice::put_Selected(long newVal)
|
||||
{
|
||||
_ASSERTE( newVal >= -1 );
|
||||
//_ASSERTE( newVal < m_options.size() );
|
||||
//back out if out of bounds, don't error to prevent breaking vb plugs
|
||||
//this should fix the crash on display bug
|
||||
if (newVal >= m_options.size())
|
||||
return S_OK;
|
||||
|
||||
if( newVal == m_nSelected )
|
||||
return S_OK;
|
||||
|
||||
m_nSelected = newVal;
|
||||
|
||||
long nID;
|
||||
m_pSite->get_ID( &nID );
|
||||
Fire_Change( nID, m_nSelected );
|
||||
|
||||
// Redraw the concerned
|
||||
m_pSite->Invalidate();
|
||||
m_pPopup->Invalidate();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cChoice::get_DropLines(long *pVal)
|
||||
{
|
||||
_ASSERTE( pVal != NULL );
|
||||
|
||||
*pVal = m_nDropLines;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cChoice::put_DropLines(long newVal)
|
||||
{
|
||||
_ASSERTE( newVal > 0 );
|
||||
|
||||
m_nDropLines = newVal;
|
||||
m_pSite->Reformat();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cChoice::Clear()
|
||||
{
|
||||
m_options.clear();
|
||||
m_nSelected = -1;
|
||||
|
||||
long nID;
|
||||
m_pSite->get_ID( &nID );
|
||||
Fire_Change( nID, m_nSelected );
|
||||
|
||||
m_pSite->Reformat();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue