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
863
Native/DecalControls/Scroller.cpp
Normal file
863
Native/DecalControls/Scroller.cpp
Normal file
|
|
@ -0,0 +1,863 @@
|
|||
// Scroller.cpp : Implementation of cScroller
|
||||
#include "stdafx.h"
|
||||
#include "DecalControls.h"
|
||||
#include "Scroller.h"
|
||||
|
||||
enum eScrollChildren
|
||||
{
|
||||
eScrollerUp = 1,
|
||||
eScrollerDown = 2,
|
||||
eScrollerRight = 3,
|
||||
eScrollerLeft = 4,
|
||||
eScrollerPager = 5,
|
||||
eScrollerPageUp = 6,
|
||||
eScrollerPageDown = 7,
|
||||
eScrollerPageLeft = 8,
|
||||
eScrollerPageRight = 9,
|
||||
eScrollerClient = 10,
|
||||
eScrollerHThumb = 11,
|
||||
eScrollerVThumb = 12
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// cScroller
|
||||
|
||||
void cScroller::onCreate()
|
||||
{
|
||||
// Initialize our layout options
|
||||
m_szArea.cx = 0;
|
||||
m_szArea.cy = 0;
|
||||
|
||||
m_szIncrement.cx = 100;
|
||||
m_szIncrement.cy = 20;
|
||||
|
||||
m_ptThumb.x = 0;
|
||||
m_ptThumb.y = 0;
|
||||
|
||||
m_bHScroll = VARIANT_FALSE;
|
||||
m_bVScroll = VARIANT_FALSE;
|
||||
|
||||
CComPtr< ILayer > pLayerPager;
|
||||
HRESULT hRes = ::CoCreateInstance( __uuidof( Pager ), NULL, CLSCTX_INPROC_SERVER, __uuidof( ILayer ),
|
||||
reinterpret_cast< void ** >( &pLayerPager ) );
|
||||
_ASSERTE( SUCCEEDED( hRes ) );
|
||||
|
||||
LayerParams p = { eScrollerPager, { 0, 0, 0, 0 }, eRenderClipped };
|
||||
|
||||
m_pSite->CreateChild( &p, pLayerPager );
|
||||
pLayerPager->QueryInterface( &m_pPager );
|
||||
IPagerEventsImpl< PAGER_CLIENT, cScroller >::advise( m_pPager );
|
||||
|
||||
CComPtr< ILayer > pLayerUp;
|
||||
hRes = ::CoCreateInstance( __uuidof( Button ), NULL, CLSCTX_INPROC_SERVER, __uuidof( ILayer ),
|
||||
reinterpret_cast< void ** >( &pLayerUp ) );
|
||||
_ASSERTE( SUCCEEDED( hRes ) );
|
||||
|
||||
p.ID = eScrollerUp;
|
||||
|
||||
CComPtr< IButton > pUp;
|
||||
m_pSite->CreateChild( &p, pLayerUp );
|
||||
pLayerUp->QueryInterface( &pUp);
|
||||
ICommandEventsImpl< BUTTON_UP, cScroller >::advise( pUp );
|
||||
pUp->SetImages( 0, 0x06001261, 0x06001262 );
|
||||
pUp->put_Matte( RGB( 0, 0, 0 ) );
|
||||
|
||||
CComPtr< ILayer > pLayerDown;
|
||||
hRes = ::CoCreateInstance( __uuidof( Button ), NULL, CLSCTX_INPROC_SERVER, __uuidof( ILayer ),
|
||||
reinterpret_cast< void ** >( &pLayerDown ) );
|
||||
_ASSERTE( SUCCEEDED( hRes ) );
|
||||
|
||||
p.ID = eScrollerDown;
|
||||
|
||||
CComPtr< IButton > pDown;
|
||||
m_pSite->CreateChild( &p, pLayerDown );
|
||||
pLayerDown->QueryInterface( &pDown );
|
||||
ICommandEventsImpl< BUTTON_DOWN, cScroller >::advise( pDown );
|
||||
pDown->SetImages( 0, 0x0600125E, 0x0600125F );
|
||||
pDown->put_Matte( RGB( 0, 0, 0 ) );
|
||||
|
||||
CComPtr< ILayer > pLayerLeft;
|
||||
hRes = ::CoCreateInstance( __uuidof( Button ), NULL, CLSCTX_INPROC_SERVER, __uuidof( ILayer ),
|
||||
reinterpret_cast< void ** >( &pLayerLeft ) );
|
||||
_ASSERTE( SUCCEEDED( hRes ) );
|
||||
|
||||
p.ID = eScrollerLeft;
|
||||
|
||||
CComPtr< IButton > pLeft;
|
||||
m_pSite->CreateChild( &p, pLayerLeft );
|
||||
pLayerLeft->QueryInterface( &pLeft );
|
||||
ICommandEventsImpl< BUTTON_LEFT, cScroller >::advise( pLeft );
|
||||
pLeft->SetImages( 0, 0x06001295, 0x06001296 );
|
||||
pLeft->put_Matte( RGB( 0, 0, 0 ) );
|
||||
|
||||
CComPtr< ILayer > pLayerRight;
|
||||
hRes = ::CoCreateInstance( __uuidof( Button ), NULL, CLSCTX_INPROC_SERVER, __uuidof( ILayer ),
|
||||
reinterpret_cast< void ** >( &pLayerRight ) );
|
||||
_ASSERTE( SUCCEEDED( hRes ) );
|
||||
|
||||
p.ID = eScrollerRight;
|
||||
|
||||
CComPtr< IButton > pRight;
|
||||
m_pSite->CreateChild( &p, pLayerRight );
|
||||
pLayerRight->QueryInterface( &pRight );
|
||||
ICommandEventsImpl< BUTTON_RIGHT, cScroller >::advise( pRight );
|
||||
pRight->SetImages( 0, 0x06001298, 0x06001299 );
|
||||
pRight->put_Matte( RGB( 0, 0, 0 ) );
|
||||
|
||||
// Positioning will occur during Reformat
|
||||
|
||||
// Load the images
|
||||
CComPtr< IPluginSite > pPlugin;
|
||||
m_pSite->get_PluginSite( &pPlugin );
|
||||
|
||||
pPlugin->LoadBitmapPortal( 0x06001260, &m_pVScrollBack );
|
||||
pPlugin->LoadBitmapPortal( 0x06001297, &m_pHScrollBack );
|
||||
}
|
||||
|
||||
void cScroller::onDestroy()
|
||||
{
|
||||
m_pPager.Release();
|
||||
}
|
||||
|
||||
void cScroller::constrainOffset( LPPOINT ppt )
|
||||
{
|
||||
// First check for overflow, furthest scroll should be allowed is less a
|
||||
// page size
|
||||
POINT ptMax = { m_szArea.cx, m_szArea.cy };
|
||||
|
||||
SIZE szViewport;
|
||||
get_Viewport( &szViewport );
|
||||
|
||||
if((szViewport.cx % m_szIncrement.cx)==0)
|
||||
ptMax.x -= szViewport.cx;
|
||||
else
|
||||
ptMax.x -= ( szViewport.cx / m_szIncrement.cx + 1) * m_szIncrement.cx;
|
||||
|
||||
if((szViewport.cy % m_szIncrement.cy)==0)
|
||||
ptMax.y -= szViewport.cy;
|
||||
else
|
||||
ptMax.y -= ( szViewport.cy / m_szIncrement.cy + 1) * m_szIncrement.cy;
|
||||
|
||||
// substract the viewport (rounded up a notch) from the max scroll area
|
||||
// ptMax.x -= ( szViewport.cx / m_szIncrement.cx + 1) * m_szIncrement.cx;
|
||||
// ptMax.y -= ( szViewport.cy / m_szIncrement.cy + 1) * m_szIncrement.cy;
|
||||
|
||||
if( ppt->x > ptMax.x )
|
||||
ppt->x = ptMax.x;
|
||||
if( ppt->y > ptMax.y )
|
||||
ppt->y = ptMax.y;
|
||||
|
||||
// Check for underflow (either because it was assigned too low
|
||||
// or or max is too low)
|
||||
if( ppt->x < 0 )
|
||||
ppt->x = 0;
|
||||
if( ppt->y < 0 )
|
||||
ppt->y = 0;
|
||||
|
||||
}
|
||||
|
||||
#define BTN_SIZE 16
|
||||
|
||||
long cScroller::hitTest( MouseState *pMS )
|
||||
{
|
||||
if( pMS->over != this )
|
||||
return -1;
|
||||
|
||||
SIZE szViewport;
|
||||
|
||||
get_Viewport( &szViewport );
|
||||
|
||||
RECT rcScroll = { BTN_SIZE, BTN_SIZE, szViewport.cx - BTN_SIZE, szViewport.cy - BTN_SIZE };
|
||||
|
||||
// Check if it's on the horizontal bar
|
||||
if( m_bHScroll )
|
||||
{
|
||||
if( pMS->client.x > rcScroll.left && pMS->client.x < rcScroll.right && pMS->client.y > szViewport.cy )
|
||||
{
|
||||
if( m_szArea.cx == szViewport.cx )
|
||||
// Special case, no scrolling if the area is the minimum size
|
||||
return -1;
|
||||
|
||||
// We hit the horizontal bar
|
||||
if( pMS->client.x < ( m_ptThumb.x + BTN_SIZE ) )
|
||||
// Hit before the thumb
|
||||
return eScrollerPageLeft;
|
||||
else if( pMS->client.x > ( m_ptThumb.x + BTN_SIZE * 2 ) )
|
||||
// Hit after the thumb
|
||||
return eScrollerPageRight;
|
||||
|
||||
// Hit the thumb
|
||||
return eScrollerHThumb;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if it's on the vertical bar
|
||||
if( m_bVScroll )
|
||||
{
|
||||
if( pMS->client.y > rcScroll.top && pMS->client.y < rcScroll.bottom && pMS->client.x > szViewport.cx )
|
||||
{
|
||||
if( m_szArea.cy == szViewport.cy )
|
||||
// Special case, no scrolling if the area is the minimum size
|
||||
return -1;
|
||||
|
||||
// We hit the vertical bar
|
||||
if( pMS->client.y < ( m_ptThumb.y + BTN_SIZE ) )
|
||||
// Hit above the thumb
|
||||
return eScrollerPageUp;
|
||||
else if( pMS->client.y > ( m_ptThumb.y + BTN_SIZE * 2 ) )
|
||||
// Hit below thumb
|
||||
return eScrollerPageDown;
|
||||
|
||||
// Hit the v thumb
|
||||
return eScrollerVThumb;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
STDMETHODIMP cScroller::Render(ICanvas *pCanvas)
|
||||
{
|
||||
SIZE szViewport;
|
||||
get_Viewport( &szViewport );
|
||||
|
||||
// Fill in the scrollbars as neccessary
|
||||
static POINT ptOff = { 0, 0 };
|
||||
|
||||
CComPtr< IPluginSite > pPluginSite;
|
||||
m_pSite->get_PluginSite( &pPluginSite );
|
||||
|
||||
SIZE szIcon = { BTN_SIZE, BTN_SIZE };
|
||||
CComPtr< IIconCache > pIconCache;
|
||||
pPluginSite->GetIconCache( &szIcon, &pIconCache );
|
||||
|
||||
if( m_bHScroll )
|
||||
{
|
||||
RECT rcHScroll = { BTN_SIZE, szViewport.cy, szViewport.cx - BTN_SIZE, szViewport.cy + BTN_SIZE };
|
||||
m_pHScrollBack->PatBlt( pCanvas, &rcHScroll, &ptOff );
|
||||
|
||||
if( m_szArea.cx != szViewport.cx )
|
||||
{
|
||||
// Draw the H thumb
|
||||
POINT ptHThumb = { BTN_SIZE + m_ptThumb.x, szViewport.cy };
|
||||
RECT rcThumb = { ptHThumb.x, ptHThumb.y, ptHThumb.x + BTN_SIZE, ptHThumb.y + BTN_SIZE };
|
||||
pCanvas->Fill( &rcThumb, RGB( 0, 0, 0 ) );
|
||||
pIconCache->DrawIcon( &ptHThumb, ( m_nCurrentCommand == eScrollerHThumb ) ? 0x06001264 : 0x06001263, 0, pCanvas );
|
||||
}
|
||||
}
|
||||
|
||||
if( m_bVScroll )
|
||||
{
|
||||
RECT rcVScroll = { szViewport.cx, BTN_SIZE, szViewport.cx + BTN_SIZE, szViewport.cy - BTN_SIZE };
|
||||
m_pVScrollBack->PatBlt( pCanvas, &rcVScroll, &ptOff );
|
||||
|
||||
if( m_szArea.cy != szViewport.cy )
|
||||
{
|
||||
// Draw the V thumb
|
||||
POINT ptVThumb = { szViewport.cx, BTN_SIZE + m_ptThumb.y };
|
||||
RECT rcThumb = { ptVThumb.x, ptVThumb.y, ptVThumb.x + BTN_SIZE, ptVThumb.y + BTN_SIZE };
|
||||
pCanvas->Fill( &rcThumb, RGB( 0, 0, 0 ) );
|
||||
pIconCache->DrawIcon( &ptVThumb, ( m_nCurrentCommand == eScrollerVThumb ) ? 0x06001264 : 0x06001263, 0, pCanvas );
|
||||
}
|
||||
}
|
||||
|
||||
if( m_bHScroll && m_bVScroll )
|
||||
{
|
||||
// Draw the little corner piece
|
||||
RECT rcCorner = { szViewport.cx, szViewport.cy, szViewport.cx + BTN_SIZE, szViewport.cy + BTN_SIZE };
|
||||
pCanvas->Fill( &rcCorner, RGB( 130, 100, 80 ) );
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cScroller::Reformat()
|
||||
{
|
||||
SIZE szViewport;
|
||||
get_Viewport( &szViewport );
|
||||
|
||||
CComPtr< ILayerSite > pPagerSite;
|
||||
HRESULT hRes = m_pSite->get_Child( eScrollerPager, ePositionByID, &pPagerSite );
|
||||
|
||||
RECT rcPager = { 0, 0, szViewport.cx, szViewport.cy };
|
||||
pPagerSite->put_Position( &rcPager );
|
||||
|
||||
CComPtr< ILayerSite > pClientSite;
|
||||
pPagerSite->get_Child( eScrollerClient, ePositionByID, &pClientSite );
|
||||
|
||||
RECT rcClient = { 0, 0, m_szArea.cx, m_szArea.cy };
|
||||
pClientSite->put_Position( &rcClient );
|
||||
|
||||
CComPtr< ILayerSite > pUp, pDown, pLeft, pRight;
|
||||
|
||||
m_pSite->get_Child( eScrollerUp, ePositionByID, &pUp );
|
||||
m_pSite->get_Child( eScrollerDown, ePositionByID, &pDown );
|
||||
m_pSite->get_Child( eScrollerLeft, ePositionByID, &pLeft );
|
||||
m_pSite->get_Child( eScrollerRight, ePositionByID, &pRight );
|
||||
|
||||
static RECT rcHidden = { 0, 0, 0, 0 };
|
||||
|
||||
if( m_bHScroll )
|
||||
{
|
||||
RECT rcLeft = { 0, szViewport.cy, BTN_SIZE, szViewport.cy + BTN_SIZE },
|
||||
rcRight = { szViewport.cx - BTN_SIZE, szViewport.cy, szViewport.cx, szViewport.cy + BTN_SIZE };
|
||||
|
||||
pLeft->put_Position( &rcLeft );
|
||||
pRight->put_Position( &rcRight );
|
||||
}
|
||||
else
|
||||
{
|
||||
pLeft->put_Position( &rcHidden );
|
||||
pRight->put_Position( &rcHidden );
|
||||
}
|
||||
|
||||
if( m_bVScroll )
|
||||
{
|
||||
RECT rcUp = { szViewport.cx, 0, szViewport.cx + BTN_SIZE, BTN_SIZE },
|
||||
rcDown = { szViewport.cx, szViewport.cy - BTN_SIZE, szViewport.cx + BTN_SIZE, szViewport.cy };
|
||||
|
||||
pUp->put_Position( &rcUp );
|
||||
pDown->put_Position( &rcDown );
|
||||
}
|
||||
else
|
||||
{
|
||||
pUp->put_Position( &rcHidden );
|
||||
pDown->put_Position( &rcHidden );
|
||||
}
|
||||
|
||||
// Calculate the size of the page increments
|
||||
m_szPage.cx = ( szViewport.cx / m_szIncrement.cx ) * m_szIncrement.cx;
|
||||
m_szPage.cy = ( szViewport.cy / m_szIncrement.cy ) * m_szIncrement.cy;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void cScroller::onButtonHit(long nID)
|
||||
{
|
||||
m_pPager->put_Command( nID );
|
||||
}
|
||||
|
||||
void cScroller::onButtonUnhit(long)
|
||||
{
|
||||
m_pPager->FinishCommand();
|
||||
}
|
||||
|
||||
VARIANT_BOOL cScroller::onClientGetNextPosition(long nID, long nCommand, long *pnX, long *pnY)
|
||||
{
|
||||
POINT ptDest;
|
||||
m_pPager->get_Offset( &ptDest );
|
||||
|
||||
POINT ptOriginal = ptDest;
|
||||
|
||||
switch( nCommand )
|
||||
{
|
||||
case eScrollerUp:
|
||||
ptDest.y -= m_szIncrement.cy;
|
||||
break;
|
||||
|
||||
case eScrollerDown:
|
||||
ptDest.y += m_szIncrement.cy;
|
||||
break;
|
||||
|
||||
case eScrollerPageUp:
|
||||
ptDest.y -= m_szPage.cy;
|
||||
break;
|
||||
|
||||
case eScrollerPageDown:
|
||||
ptDest.y += m_szPage.cy;
|
||||
break;
|
||||
|
||||
case eScrollerLeft:
|
||||
ptDest.x -= m_szIncrement.cx;
|
||||
break;
|
||||
|
||||
case eScrollerRight:
|
||||
ptDest.x += m_szIncrement.cx;
|
||||
break;
|
||||
|
||||
case eScrollerPageLeft:
|
||||
ptDest.x -= m_szPage.cx;
|
||||
break;
|
||||
|
||||
case eScrollerPageRight:
|
||||
ptDest.x += m_szPage.cx;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Unknown scrolling command
|
||||
_ASSERTE( FALSE );
|
||||
}
|
||||
|
||||
constrainOffset( &ptDest );
|
||||
|
||||
if( ptDest.x == ptOriginal.x && ptDest.y == ptOriginal.y )
|
||||
// We didn't move this cycle - do not continue
|
||||
return VARIANT_FALSE;
|
||||
|
||||
*pnX = ptDest.x;
|
||||
*pnY = ptDest.y;
|
||||
|
||||
return VARIANT_TRUE;
|
||||
}
|
||||
|
||||
void cScroller::onClientChange( long nID, long, long nX, long nY )
|
||||
{
|
||||
_ASSERTE( nID == eScrollerPager );
|
||||
|
||||
// Convert these values to a thumb-like position
|
||||
SIZE szViewport;
|
||||
get_Viewport( &szViewport );
|
||||
|
||||
SIZE szScroll = szViewport;
|
||||
szScroll.cx -= BTN_SIZE * 3;
|
||||
szScroll.cy -= BTN_SIZE * 3;
|
||||
|
||||
// The viewport is now the size of the thumb ranges
|
||||
m_ptThumb.x = static_cast< long >( ( ( m_szArea.cx - szViewport.cx ) != 0 ) ? static_cast< double >( nX * szScroll.cx ) / static_cast< double >( m_szArea.cx - szViewport.cx ) : 0.0 );
|
||||
m_ptThumb.y = static_cast< long >( ( ( m_szArea.cy - szViewport.cy ) != 0 ) ? static_cast< double >( nY * szScroll.cy ) / static_cast< double >( m_szArea.cy - szViewport.cy ) : 0.0 );
|
||||
|
||||
if( m_ptThumb.x > szScroll.cx || nX >= ( m_szArea.cx - szViewport.cx - m_szIncrement.cy ) )
|
||||
m_ptThumb.x = szScroll.cx;
|
||||
if( m_ptThumb.y > szScroll.cy || nY >= ( m_szArea.cy - szViewport.cy - m_szIncrement.cy ) )
|
||||
m_ptThumb.y = szScroll.cy;
|
||||
|
||||
if( m_ptThumb.x < 0 )
|
||||
m_ptThumb.x = 0;
|
||||
if( m_ptThumb.y < 0 )
|
||||
m_ptThumb.y = 0;
|
||||
|
||||
// Check if the thumb moving has canceled a mouse action
|
||||
switch( m_nCurrentCommand )
|
||||
{
|
||||
case eScrollerPageUp:
|
||||
case eScrollerPageDown:
|
||||
case eScrollerPageLeft:
|
||||
case eScrollerPageRight:
|
||||
{
|
||||
MouseState ms = { this, { 0, 0 }, { m_ptMouseLast.x, m_ptMouseLast.y }, VARIANT_FALSE, VARIANT_FALSE };
|
||||
if( hitTest( &ms ) != m_nCurrentCommand )
|
||||
m_pPager->FinishCommand();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Draw next frame
|
||||
m_pSite->Invalidate();
|
||||
|
||||
long nIDThis;
|
||||
m_pSite->get_ID( &nIDThis );
|
||||
Fire_Change( nIDThis, nX, nY );
|
||||
}
|
||||
|
||||
STDMETHODIMP cScroller::get_Viewport(LPSIZE pVal)
|
||||
{
|
||||
_ASSERTE( pVal != NULL );
|
||||
|
||||
RECT rc;
|
||||
m_pSite->get_Position( &rc );
|
||||
|
||||
pVal->cx = ( rc.right - rc.left ) - ( ( m_bVScroll ) ? BTN_SIZE : 0 );
|
||||
pVal->cy = ( rc.bottom - rc.top ) - ( ( m_bHScroll ) ? BTN_SIZE : 0 );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cScroller::get_Area(LPSIZE pVal)
|
||||
{
|
||||
_ASSERTE( pVal != NULL );
|
||||
|
||||
*pVal = m_szArea;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cScroller::put_Area(LPSIZE newVal)
|
||||
{
|
||||
_ASSERTE( newVal != NULL );
|
||||
//_ASSERTE( newVal->cx >= 0 && newVal->cy >= 0 );
|
||||
|
||||
// Now this area will have to be rounded up to an increment or
|
||||
// a page size
|
||||
SIZE szViewport;
|
||||
get_Viewport( &szViewport );
|
||||
|
||||
if( newVal->cx < szViewport.cx )
|
||||
// This view is thinner than the viewport, set it to the minimum
|
||||
newVal->cx = szViewport.cx;
|
||||
else if( m_bHScroll )
|
||||
if((szViewport.cx % m_szIncrement.cx)!=0)
|
||||
newVal->cx += m_szIncrement.cx - ( newVal->cx % m_szIncrement.cx ); // Make sure there is an extra line so we don't scroll off the edge
|
||||
|
||||
// Repeat for y-scoord
|
||||
if( newVal->cy < szViewport.cy )
|
||||
newVal->cy = szViewport.cy;
|
||||
else if( m_bVScroll )
|
||||
if((szViewport.cy % m_szIncrement.cy)!=0)
|
||||
newVal->cy += m_szIncrement.cy - ( newVal->cy % m_szIncrement.cy );
|
||||
|
||||
m_szArea = *newVal;
|
||||
m_pSite->Reformat();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cScroller::get_HorizontalEnabled(VARIANT_BOOL *pVal)
|
||||
{
|
||||
_ASSERTE( pVal != NULL );
|
||||
|
||||
*pVal = m_bHScroll;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cScroller::put_HorizontalEnabled(VARIANT_BOOL newVal)
|
||||
{
|
||||
if( newVal != m_bHScroll )
|
||||
{
|
||||
m_bHScroll = newVal;
|
||||
m_pSite->Reformat();
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cScroller::get_VerticalEnabled(VARIANT_BOOL *pVal)
|
||||
{
|
||||
_ASSERTE( pVal != NULL );
|
||||
|
||||
*pVal = m_bVScroll;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cScroller::put_VerticalEnabled(VARIANT_BOOL newVal)
|
||||
{
|
||||
if( newVal != m_bVScroll )
|
||||
{
|
||||
m_bVScroll = newVal;
|
||||
m_pSite->Reformat();
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cScroller::CreateClient(ILayer *pChild)
|
||||
{
|
||||
CComPtr< ILayerSite > pPagerSite;
|
||||
HRESULT hRes = m_pSite->get_Child( eScrollerPager, ePositionByID, &pPagerSite );
|
||||
|
||||
_ASSERTE( SUCCEEDED( hRes ) );
|
||||
|
||||
LayerParams lp = { eScrollerClient, { 0, 0, 0, 0 }, eRenderClipped };
|
||||
|
||||
return pPagerSite->CreateChild( &lp, pChild );
|
||||
}
|
||||
|
||||
STDMETHODIMP cScroller::get_Offset(LPPOINT pVal)
|
||||
{
|
||||
_ASSERTE( pVal != NULL );
|
||||
|
||||
POINT ptTrueOff;
|
||||
m_pPager->get_Offset( &ptTrueOff );
|
||||
|
||||
pVal->x = ptTrueOff.x / m_szIncrement.cx;
|
||||
pVal->y = ptTrueOff.y / m_szIncrement.cy;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cScroller::put_Offset(LPPOINT newVal)
|
||||
{
|
||||
_ASSERTE( newVal != NULL );
|
||||
_ASSERTE( newVal->x >= 0 && newVal->y >= 0 );
|
||||
|
||||
POINT ptTrueOff = { newVal->x * m_szIncrement.cx, newVal->y * m_szIncrement.cy };
|
||||
|
||||
constrainOffset( &ptTrueOff );
|
||||
m_pPager->put_Offset( &ptTrueOff );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cScroller::ScrollTo(LPPOINT ptOffset)
|
||||
{
|
||||
_ASSERTE( ptOffset != NULL );
|
||||
_ASSERTE( ptOffset->x >= 0 && ptOffset->y >= 0 );
|
||||
|
||||
POINT ptTrueOff = { ptOffset->x * m_szIncrement.cx, ptOffset->y * m_szIncrement.cy };
|
||||
|
||||
constrainOffset( &ptTrueOff );
|
||||
m_pPager->ScrollTo( &ptTrueOff );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cScroller::get_Increments(LPSIZE pVal)
|
||||
{
|
||||
_ASSERTE( pVal != NULL );
|
||||
|
||||
*pVal = m_szIncrement;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cScroller::put_Increments(LPSIZE newVal)
|
||||
{
|
||||
_ASSERTE( newVal != NULL );
|
||||
_ASSERTE( newVal->cx > 0 && newVal->cy > 0 );
|
||||
|
||||
// Assign the new increments
|
||||
m_szIncrement = *newVal;
|
||||
|
||||
// Align the current position to the new position
|
||||
POINT ptCurrent;
|
||||
m_pPager->get_Offset( &ptCurrent );
|
||||
|
||||
ptCurrent.x = ( ptCurrent.x / newVal->cx ) * newVal->cx;
|
||||
ptCurrent.y = ( ptCurrent.y / newVal->cy ) * newVal->cy;
|
||||
|
||||
constrainOffset( &ptCurrent );
|
||||
m_pPager->put_Offset( &ptCurrent );
|
||||
m_pSite->Reformat();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cScroller::MouseDown( MouseState *pMS )
|
||||
{
|
||||
m_nCurrentCommand = hitTest( pMS );
|
||||
|
||||
if( m_nCurrentCommand == -1 )
|
||||
return S_OK;
|
||||
|
||||
switch( m_nCurrentCommand )
|
||||
{
|
||||
case eScrollerHThumb:
|
||||
m_nScreenStart = pMS->screen.x;
|
||||
m_nThumbStart = m_ptThumb.x;
|
||||
break;
|
||||
|
||||
case eScrollerVThumb:
|
||||
m_nScreenStart = pMS->screen.y;
|
||||
m_nThumbStart = m_ptThumb.y;
|
||||
break;
|
||||
|
||||
case eScrollerPageUp:
|
||||
case eScrollerPageDown:
|
||||
case eScrollerPageLeft:
|
||||
case eScrollerPageRight:
|
||||
m_ptMouseLast = pMS->client;
|
||||
m_pPager->put_Command( m_nCurrentCommand );
|
||||
break;
|
||||
}
|
||||
|
||||
m_pSite->Invalidate();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cScroller::MouseUp( MouseState *pMS )
|
||||
{
|
||||
m_nCurrentCommand = -1;
|
||||
|
||||
// Make sure there are no more commands in the pager
|
||||
m_pPager->FinishCommand();
|
||||
|
||||
m_pSite->Invalidate();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cScroller::MouseMove( MouseState *pMS )
|
||||
{
|
||||
if( m_nCurrentCommand == -1 )
|
||||
// No command, so nothgin to do
|
||||
return S_OK;
|
||||
|
||||
SIZE szViewport;
|
||||
get_Viewport( &szViewport );
|
||||
SIZE szScroller = { szViewport.cx - BTN_SIZE * 3, szViewport.cy - BTN_SIZE * 3 };
|
||||
|
||||
POINT ptOffset;
|
||||
m_pPager->get_Offset( &ptOffset );
|
||||
|
||||
switch( m_nCurrentCommand )
|
||||
{
|
||||
case eScrollerPageUp:
|
||||
case eScrollerPageDown:
|
||||
case eScrollerPageLeft:
|
||||
case eScrollerPageRight:
|
||||
{
|
||||
if( hitTest( pMS ) == m_nCurrentCommand )
|
||||
m_pPager->put_Command( m_nCurrentCommand );
|
||||
else
|
||||
m_pPager->FinishCommand();
|
||||
m_ptMouseLast = pMS->client;
|
||||
}
|
||||
break;
|
||||
|
||||
case eScrollerHThumb:
|
||||
{
|
||||
long nPos = m_nThumbStart + ( pMS->screen.x - m_nScreenStart );
|
||||
|
||||
// Make sure it's bigger than 0
|
||||
if( nPos < 0 )
|
||||
nPos = 0;
|
||||
|
||||
// Convert this to an actual position
|
||||
ptOffset.x = nPos * ( m_szArea.cx - szViewport.cx ) / szScroller.cx;
|
||||
|
||||
// Align to the nearest line
|
||||
ptOffset.x -= ptOffset.x % m_szIncrement.cx;
|
||||
|
||||
// Set the position, pager callback will set the thumb position
|
||||
constrainOffset( &ptOffset );
|
||||
m_pPager->put_Offset( &ptOffset );
|
||||
}
|
||||
break;
|
||||
|
||||
case eScrollerVThumb:
|
||||
{
|
||||
long nPos = m_nThumbStart + ( pMS->screen.y - m_nScreenStart );
|
||||
|
||||
// Make sure it's bigger than 0
|
||||
if( nPos < 0 )
|
||||
nPos = 0;
|
||||
|
||||
// Convert this to an actual position
|
||||
ptOffset.y = nPos * ( m_szArea.cy - szViewport.cy ) / szScroller.cy;
|
||||
|
||||
// Align to the nearest line
|
||||
ptOffset.y -= ptOffset.y % m_szIncrement.cy;
|
||||
|
||||
// Set the position, pager callback will set the thumb position
|
||||
constrainOffset( &ptOffset );
|
||||
m_pPager->put_Offset( &ptOffset );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT cScroller::SchemaLoad( IView *pView, IUnknown *pXMLElement )
|
||||
{
|
||||
MSXML::IXMLDOMElementPtr pElement = pXMLElement;
|
||||
|
||||
_variant_t vHScroll = pElement->getAttribute( _T( "hscroll" ) ),
|
||||
vVScroll = pElement->getAttribute( _T( "vscroll" ) ),
|
||||
vAreaWidth = pElement->getAttribute( _T( "areawidth" ) ),
|
||||
vAreaHeight = pElement->getAttribute( _T( "areaheight" ) ),
|
||||
vIncrementX = pElement->getAttribute( _T( "incrementx" ) ),
|
||||
vIncrementY = pElement->getAttribute( _T( "incrementy" ) );
|
||||
|
||||
// Do the client
|
||||
MSXML::IXMLDOMElementPtr pClient = pElement->selectSingleNode( _T( "control" ) );
|
||||
if( pClient.GetInterfacePtr() != NULL )
|
||||
{
|
||||
// Recurse and load the client
|
||||
CComPtr< ILayerSite > pPager;
|
||||
m_pSite->get_Child( eScrollerPager, ePositionByID, &pPager );
|
||||
long nAssigned;
|
||||
pView->LoadControl( pPager, eScrollerClient, pClient, &nAssigned );
|
||||
}
|
||||
|
||||
// First enable the scroll bars
|
||||
if( vHScroll.vt != VT_NULL )
|
||||
{
|
||||
try
|
||||
{
|
||||
m_bHScroll = static_cast< bool >( vHScroll ) ? VARIANT_TRUE : VARIANT_FALSE;
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
// Type conversion error
|
||||
_ASSERTE( FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
if( vVScroll.vt != VT_NULL )
|
||||
{
|
||||
try
|
||||
{
|
||||
m_bVScroll = static_cast< bool >( vVScroll ) ? VARIANT_TRUE : VARIANT_FALSE;
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
// Type conversion error
|
||||
_ASSERTE( FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
// Next set the increment sizes
|
||||
if( vIncrementX.vt != VT_NULL )
|
||||
{
|
||||
try
|
||||
{
|
||||
m_szIncrement.cx = static_cast< long >( vIncrementX );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
// Type conversion error
|
||||
_ASSERTE( FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
if( vIncrementY.vt != VT_NULL )
|
||||
{
|
||||
try
|
||||
{
|
||||
m_szIncrement.cy = static_cast< long >( vIncrementY );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
// Type conversion error
|
||||
_ASSERTE( FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
// Last, set the area
|
||||
SIZE szArea = m_szArea;
|
||||
if( vAreaWidth.vt != VT_NULL )
|
||||
{
|
||||
try
|
||||
{
|
||||
szArea.cx = static_cast< long >( vAreaWidth );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
// Type conversion error
|
||||
_ASSERTE( FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
if( vAreaHeight.vt != VT_NULL )
|
||||
{
|
||||
try
|
||||
{
|
||||
szArea.cy = static_cast< long >( vAreaHeight );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
// Type conversion error
|
||||
_ASSERTE( FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
put_Area( &szArea );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP cScroller::ResetScroller()
|
||||
{
|
||||
|
||||
POINT ptCurrent;
|
||||
ptCurrent.x = 0;
|
||||
ptCurrent.y = 0;
|
||||
constrainOffset( &ptCurrent );
|
||||
m_pPager->put_Offset( &ptCurrent );
|
||||
m_ptThumb.x =0;
|
||||
m_ptThumb.y =0;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue