source-engine-2018-hl2_src/utils/smp/CWMPHost.cpp
FluorescentCIAAfricanAmerican 3bf9df6b27 1
2020-04-22 12:56:21 -04:00

604 lines
13 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
// CWMPHost.cpp : Implementation of the CWMPHost
//
#include "stdafx.h"
#include "CWMPHost.h"
#include <cstdio>
#include <assert.h>
#include <string>
extern HWND g_hBlackFadingWindow;
extern CWMPHost*g_pFrame;
extern LPTSTR g_lpCommandLine;
extern bool g_bFrameCreated;
extern double g_timeAtFadeStart;
extern bool g_bFadeIn;
extern bool g_bFadeWindowTriggered;
extern std::string g_URL;
bool ShowFadeWindow( bool bShow );
void LogPlayerEvent( EventType_t e, float pos );
CComPtr<IWMPPlayer> g_spWMPPlayer;
bool g_bWantToBeFullscreen = false;
bool g_bPlayOnRestore = false;
int g_desiredVideoScaleMode = ID_STRETCH_TO_FIT;
#define MAX_STRING 1024
bool FAILMSG(HRESULT hr)
{
if (FAILED(hr))
{
TCHAR szError[MAX_STRING];
::wsprintf(szError, _T("Error code = %08X"), hr);
::MessageBox(NULL, szError, _T("Error"), MB_OK | MB_ICONERROR);
}
return FAILED(hr);
}
void LogPlayerEvent( EventType_t e )
{
double dpos = 0.0f;
CComPtr<IWMPControls> spWMPControls;
if ( g_spWMPPlayer )
{
g_spWMPPlayer->get_controls(&spWMPControls);
if ( spWMPControls )
{
spWMPControls->get_currentPosition( &dpos );
}
}
LogPlayerEvent( e, ( float )dpos );
}
bool IsStretchedToFit()
{
if ( !g_spWMPPlayer )
return false;
CComPtr< IWMPPlayer2 > spWMPPlayer2;
g_spWMPPlayer.QueryInterface( &spWMPPlayer2 );
if ( !spWMPPlayer2 )
return false;
VARIANT_BOOL vbStretchToFit = VARIANT_FALSE;
spWMPPlayer2->get_stretchToFit( &vbStretchToFit );
return vbStretchToFit == VARIANT_TRUE;
}
bool SetVideoScaleMode( int videoScaleMode )
{
g_desiredVideoScaleMode = videoScaleMode;
if ( !g_spWMPPlayer )
return false;
long width = 0, height = 0;
CComPtr<IWMPMedia> spWMPMedia;
g_spWMPPlayer->get_currentMedia( &spWMPMedia );
if ( spWMPMedia )
{
spWMPMedia->get_imageSourceWidth ( &width );
spWMPMedia->get_imageSourceHeight( &height );
}
VARIANT_BOOL vbStretchToFit = VARIANT_FALSE;
switch ( videoScaleMode )
{
case ID_HALF_SIZE:
// TODO - set video player size
break;
case ID_FULL_SIZE:
// TODO - set video player size
break;
case ID_DOUBLE_SIZE:
// TODO - set video player size
break;
case ID_STRETCH_TO_FIT:
vbStretchToFit = VARIANT_TRUE;
break;
default:
return false;
}
CComPtr< IWMPPlayer2 > spWMPPlayer2;
g_spWMPPlayer.QueryInterface( &spWMPPlayer2 );
if ( !spWMPPlayer2 )
return false;
bool bStretchToFit = vbStretchToFit == VARIANT_TRUE;
if ( bStretchToFit == IsStretchedToFit() )
return true;
spWMPPlayer2->put_stretchToFit( vbStretchToFit );
return bStretchToFit == IsStretchedToFit();
}
bool IsFullScreen()
{
if ( !g_spWMPPlayer )
return false;
VARIANT_BOOL vbFullscreen = VARIANT_TRUE;
g_spWMPPlayer->get_fullScreen( &vbFullscreen );
return vbFullscreen == VARIANT_TRUE;
}
bool SetFullScreen( bool bWantToBeFullscreen )
{
g_bWantToBeFullscreen = bWantToBeFullscreen;
if ( !g_spWMPPlayer )
return false;
LogPlayerEvent( bWantToBeFullscreen ? ET_MAXIMIZE : ET_RESTORE );
bool bIsFullscreen = IsFullScreen();
CComPtr<IWMPPlayer2> spWMPPlayer2;
HRESULT hr = g_spWMPPlayer.QueryInterface(&spWMPPlayer2);
if ( hr != S_OK )
{
assert( spWMPPlayer2 == NULL ); // the MS documentation claims this shouldn't happen, but it does...
spWMPPlayer2 = NULL;
}
if ( spWMPPlayer2 )
{
VARIANT_BOOL vbStretch = VARIANT_TRUE;
spWMPPlayer2->get_stretchToFit( &vbStretch );
bool bStretch = vbStretch == VARIANT_TRUE;
if ( bStretch != g_bWantToBeFullscreen )
{
bIsFullscreen = !g_bWantToBeFullscreen;
}
}
if ( g_bWantToBeFullscreen == bIsFullscreen )
return true;
if ( g_bWantToBeFullscreen )
{
g_spWMPPlayer->put_uiMode(L"none");
g_spWMPPlayer->put_fullScreen(VARIANT_TRUE);
if ( spWMPPlayer2 )
{
spWMPPlayer2->put_stretchToFit( VARIANT_TRUE );
}
while ( ShowCursor( FALSE ) >= 0 )
;
}
else
{
g_spWMPPlayer->put_fullScreen(VARIANT_FALSE);
g_spWMPPlayer->put_uiMode(L"full");
if ( spWMPPlayer2 )
{
spWMPPlayer2->put_stretchToFit( g_desiredVideoScaleMode == ID_STRETCH_TO_FIT ? VARIANT_TRUE : VARIANT_FALSE );
}
g_pFrame->ShowWindow( SW_RESTORE );
while ( ShowCursor( TRUE ) < 0 )
;
}
bIsFullscreen = IsFullScreen();
if ( bIsFullscreen != g_bWantToBeFullscreen )
{
g_bWantToBeFullscreen = bIsFullscreen;
OutputDebugString( "SetFullScreen FAILED!\n" );
return false;
}
if ( spWMPPlayer2 )
{
if ( g_bWantToBeFullscreen )
{
VARIANT_BOOL vbStretch = VARIANT_TRUE;
spWMPPlayer2->get_stretchToFit( &vbStretch );
if ( vbStretch != VARIANT_TRUE )
{
OutputDebugString( "SetFullScreen FAILED to set stretchToFit!\n" );
return false;
}
}
}
return true;
}
bool IsVideoPlaying()
{
WMPPlayState playState;
g_spWMPPlayer->get_playState(&playState);
return playState == wmppsPlaying;
}
void PlayVideo( bool bPlay )
{
CComPtr<IWMPControls> spWMPControls;
g_spWMPPlayer->get_controls(&spWMPControls);
if ( spWMPControls )
{
if ( bPlay )
{
spWMPControls->play();
}
else
{
spWMPControls->pause();
}
}
}
/////////////////////////////////////////////////////////////////////////////
// CWMPHost
LRESULT CWMPHost::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
AtlAxWinInit();
CComPtr<IAxWinHostWindow> spHost;
CComPtr<IConnectionPointContainer> spConnectionContainer;
CComWMPEventDispatch *pEventListener = NULL;
CComPtr<IWMPEvents> spEventListener;
HRESULT hr;
RECT rcClient;
m_dwAdviseCookie = 0;
m_hPopupMenu = 0;
// create window
GetClientRect(&rcClient);
m_wndView.Create(m_hWnd, rcClient, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN, WS_EX_CLIENTEDGE);
if (NULL == m_wndView.m_hWnd)
goto FAILURE;
// load OCX in window
hr = m_wndView.QueryHost(&spHost);
if (FAILMSG(hr))
goto FAILURE;
hr = spHost->CreateControl(CComBSTR(_T("{6BF52A52-394A-11d3-B153-00C04F79FAA6}")), m_wndView, 0);
if (FAILMSG(hr))
goto FAILURE;
hr = m_wndView.QueryControl(&g_spWMPPlayer);
if (FAILMSG(hr))
goto FAILURE;
// start listening to events
hr = CComWMPEventDispatch::CreateInstance(&pEventListener);
spEventListener = pEventListener;
if (FAILMSG(hr))
goto FAILURE;
hr = g_spWMPPlayer->QueryInterface(&spConnectionContainer);
if (FAILMSG(hr))
goto FAILURE;
// See if OCX supports the IWMPEvents interface
hr = spConnectionContainer->FindConnectionPoint(__uuidof(IWMPEvents), &m_spConnectionPoint);
if (FAILED(hr))
{
// If not, try the _WMPOCXEvents interface, which will use IDispatch
hr = spConnectionContainer->FindConnectionPoint(__uuidof(_WMPOCXEvents), &m_spConnectionPoint);
if (FAILMSG(hr))
goto FAILURE;
}
hr = m_spConnectionPoint->Advise(spEventListener, &m_dwAdviseCookie);
if (FAILMSG(hr))
goto FAILURE;
IWMPSettings *spWMPSettings;
g_spWMPPlayer->get_settings( &spWMPSettings );
if ( spWMPSettings )
{
spWMPSettings->put_volume( 100 );
}
g_spWMPPlayer->put_enableContextMenu( VARIANT_FALSE );
// set the url of the movie
hr = g_spWMPPlayer->put_URL( CT2W( g_URL.c_str() ) );
if (FAILED(hr))
OutputDebugString( "put_URL failed\n" );
return 0;
FAILURE:
OutputDebugString( "CWMPHost::OnCreate FAILED!\n" );
DestroyWindow();
if ( g_hBlackFadingWindow )
{
::DestroyWindow( g_hBlackFadingWindow );
}
// ::PostQuitMessage(0);
return 0;
}
LRESULT CWMPHost::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
LogPlayerEvent( ET_CLOSE );
DestroyWindow();
if ( g_hBlackFadingWindow )
{
::DestroyWindow( g_hBlackFadingWindow );
}
return 0;
}
LRESULT CWMPHost::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
// stop listening to events
if (m_spConnectionPoint)
{
if (0 != m_dwAdviseCookie)
m_spConnectionPoint->Unadvise(m_dwAdviseCookie);
m_spConnectionPoint.Release();
}
// close the OCX
if (g_spWMPPlayer)
{
g_spWMPPlayer->close();
g_spWMPPlayer.Release();
}
m_hWnd = NULL;
g_bFrameCreated = false;
bHandled = FALSE;
return 1;
}
LRESULT CWMPHost::OnErase(UINT /* uMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& bHandled)
{
if ( g_bWantToBeFullscreen && !IsFullScreen() )
{
g_pFrame->BringWindowToTop();
SetFullScreen( false );
}
bHandled = TRUE;
return 0;
}
LRESULT CWMPHost::OnSize(UINT /* uMsg */, WPARAM wParam, LPARAM lParam, BOOL& /* lResult */)
{
if ( wParam == SIZE_MAXIMIZED )
{
SetFullScreen( true );
}
else
{
if ( wParam == SIZE_MINIMIZED )
{
LogPlayerEvent( ET_MINIMIZE );
if ( IsVideoPlaying() )
{
g_bPlayOnRestore = true;
PlayVideo( false );
}
}
else if ( wParam == SIZE_RESTORED )
{
LogPlayerEvent( ET_RESTORE );
}
RECT rcClient;
GetClientRect(&rcClient);
m_wndView.MoveWindow(rcClient.left, rcClient.top, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top);
}
return 0;
}
LRESULT CWMPHost::OnContextMenu(UINT /* uMsg */, WPARAM /* wParam */, LPARAM lParam, BOOL& /* lResult */)
{
if ( !m_hPopupMenu )
{
m_hPopupMenu = CreatePopupMenu();
// AppendMenu( m_hPopupMenu, MF_STRING, ID_HALF_SIZE, "Zoom 50%" );
AppendMenu( m_hPopupMenu, MF_STRING, ID_FULL_SIZE, "Zoom 100%" );
// AppendMenu( m_hPopupMenu, MF_STRING, ID_DOUBLE_SIZE, "Zoom 200%" );
AppendMenu( m_hPopupMenu, MF_STRING, ID_STRETCH_TO_FIT, "Stretch to fit window" );
}
int x = GET_X_LPARAM( lParam );
int y = GET_Y_LPARAM( lParam );
TrackPopupMenu( m_hPopupMenu, TPM_LEFTALIGN | TPM_TOPALIGN, x, y, 0, m_hWnd, NULL );
return 0;
}
LRESULT CWMPHost::OnClick(UINT /* uMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& /* lResult */)
{
if ( IsFullScreen() )
{
SetFullScreen( false );
}
return 1;
}
LRESULT CWMPHost::OnLeftDoubleClick(UINT /* uMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& /* lResult */)
{
SetFullScreen( !IsFullScreen() );
return 1;
}
LRESULT CWMPHost::OnSysKeyDown(UINT /* uMsg */, WPARAM wParam, LPARAM /* lParam */, BOOL& /* lResult */)
{
switch ( wParam )
{
case VK_RETURN:
SetFullScreen( !IsFullScreen() );
break;
}
return 1;
}
LRESULT CWMPHost::OnKeyDown(UINT /* uMsg */, WPARAM wParam, LPARAM /* lParam */, BOOL& /* lResult */)
{
switch ( wParam )
{
case VK_SPACE:
PlayVideo( !IsVideoPlaying() );
break;
case VK_LEFT:
case VK_RIGHT:
{
CComPtr<IWMPControls> spWMPControls;
g_spWMPPlayer->get_controls(&spWMPControls);
if ( !spWMPControls )
break;
CComPtr<IWMPControls2> spWMPControls2;
spWMPControls.QueryInterface(&spWMPControls2);
if ( !spWMPControls2 )
break;
spWMPControls2->step( wParam == VK_LEFT ? -1 : 1 );
LogPlayerEvent( wParam == VK_LEFT ? ET_STEPBCK : ET_STEPFWD );
}
break;
case VK_UP:
case VK_DOWN:
{
CComPtr<IWMPControls> spWMPControls;
g_spWMPPlayer->get_controls(&spWMPControls);
if ( !spWMPControls )
break;
double curpos = 0.0f;
if ( spWMPControls->get_currentPosition( &curpos ) != S_OK )
break;
curpos += wParam == VK_UP ? -5.0f : 5.0f;
spWMPControls->put_currentPosition( curpos );
if ( !IsVideoPlaying() )
{
spWMPControls->play();
spWMPControls->pause();
}
LogPlayerEvent( wParam == VK_UP ? ET_JUMPBCK : ET_JUMPFWD );
}
break;
case VK_HOME:
{
CComPtr<IWMPControls> spWMPControls;
g_spWMPPlayer->get_controls(&spWMPControls);
if ( !spWMPControls )
break;
spWMPControls->put_currentPosition( 0.0f );
if ( !IsVideoPlaying() )
{
spWMPControls->play();
spWMPControls->pause();
}
LogPlayerEvent( ET_JUMPHOME );
}
break;
case VK_END:
{
CComPtr<IWMPMedia> spWMPMedia;
g_spWMPPlayer->get_currentMedia( &spWMPMedia );
if ( !spWMPMedia )
break;
CComPtr<IWMPControls> spWMPControls;
g_spWMPPlayer->get_controls(&spWMPControls);
if ( !spWMPControls )
break;
double duration = 0.0f;
if ( spWMPMedia->get_duration( &duration ) != S_OK )
break;
spWMPControls->put_currentPosition( duration - 0.050 ); // back a little more than a frame - this avoids triggering the end fade
spWMPControls->play();
spWMPControls->pause();
LogPlayerEvent( ET_JUMPEND );
}
break;
case VK_ESCAPE:
if ( IsFullScreen() && !g_bFadeWindowTriggered )
{
CComPtr<IWMPControls> spWMPControls;
g_spWMPPlayer->get_controls(&spWMPControls);
if ( spWMPControls )
{
spWMPControls->stop();
}
LogPlayerEvent( ET_FADEOUT );
g_bFadeWindowTriggered = true;
ShowFadeWindow( true );
}
break;
}
return 0;
}
LRESULT CWMPHost::OnNCActivate(UINT /* uMsg */, WPARAM wParam, LPARAM /* lParam */, BOOL& /* lResult */ )
{
if ( wParam )
{
if ( g_bWantToBeFullscreen )
{
SetFullScreen( true );
}
if ( g_bPlayOnRestore )
{
g_bPlayOnRestore = false;
PlayVideo( true );
}
}
return 1;
}
LRESULT CWMPHost::OnVideoScale(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
SetVideoScaleMode( wID );
return 0;
}