// 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; }