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