Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

603 lines
13 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. // CWMPHost.cpp : Implementation of the CWMPHost
  3. //
  4. #include "stdafx.h"
  5. #include "CWMPHost.h"
  6. #include <cstdio>
  7. #include <assert.h>
  8. #include <string>
  9. extern HWND g_hBlackFadingWindow;
  10. extern CWMPHost*g_pFrame;
  11. extern LPTSTR g_lpCommandLine;
  12. extern bool g_bFrameCreated;
  13. extern double g_timeAtFadeStart;
  14. extern bool g_bFadeIn;
  15. extern bool g_bFadeWindowTriggered;
  16. extern std::string g_URL;
  17. bool ShowFadeWindow( bool bShow );
  18. void LogPlayerEvent( EventType_t e, float pos );
  19. CComPtr<IWMPPlayer> g_spWMPPlayer;
  20. bool g_bWantToBeFullscreen = false;
  21. bool g_bPlayOnRestore = false;
  22. int g_desiredVideoScaleMode = ID_STRETCH_TO_FIT;
  23. #define MAX_STRING 1024
  24. bool FAILMSG(HRESULT hr)
  25. {
  26. if (FAILED(hr))
  27. {
  28. TCHAR szError[MAX_STRING];
  29. ::wsprintf(szError, _T("Error code = %08X"), hr);
  30. ::MessageBox(NULL, szError, _T("Error"), MB_OK | MB_ICONERROR);
  31. }
  32. return FAILED(hr);
  33. }
  34. void LogPlayerEvent( EventType_t e )
  35. {
  36. double dpos = 0.0f;
  37. CComPtr<IWMPControls> spWMPControls;
  38. if ( g_spWMPPlayer )
  39. {
  40. g_spWMPPlayer->get_controls(&spWMPControls);
  41. if ( spWMPControls )
  42. {
  43. spWMPControls->get_currentPosition( &dpos );
  44. }
  45. }
  46. LogPlayerEvent( e, ( float )dpos );
  47. }
  48. bool IsStretchedToFit()
  49. {
  50. if ( !g_spWMPPlayer )
  51. return false;
  52. CComPtr< IWMPPlayer2 > spWMPPlayer2;
  53. g_spWMPPlayer.QueryInterface( &spWMPPlayer2 );
  54. if ( !spWMPPlayer2 )
  55. return false;
  56. VARIANT_BOOL vbStretchToFit = VARIANT_FALSE;
  57. spWMPPlayer2->get_stretchToFit( &vbStretchToFit );
  58. return vbStretchToFit == VARIANT_TRUE;
  59. }
  60. bool SetVideoScaleMode( int videoScaleMode )
  61. {
  62. g_desiredVideoScaleMode = videoScaleMode;
  63. if ( !g_spWMPPlayer )
  64. return false;
  65. long width = 0, height = 0;
  66. CComPtr<IWMPMedia> spWMPMedia;
  67. g_spWMPPlayer->get_currentMedia( &spWMPMedia );
  68. if ( spWMPMedia )
  69. {
  70. spWMPMedia->get_imageSourceWidth ( &width );
  71. spWMPMedia->get_imageSourceHeight( &height );
  72. }
  73. VARIANT_BOOL vbStretchToFit = VARIANT_FALSE;
  74. switch ( videoScaleMode )
  75. {
  76. case ID_HALF_SIZE:
  77. // TODO - set video player size
  78. break;
  79. case ID_FULL_SIZE:
  80. // TODO - set video player size
  81. break;
  82. case ID_DOUBLE_SIZE:
  83. // TODO - set video player size
  84. break;
  85. case ID_STRETCH_TO_FIT:
  86. vbStretchToFit = VARIANT_TRUE;
  87. break;
  88. default:
  89. return false;
  90. }
  91. CComPtr< IWMPPlayer2 > spWMPPlayer2;
  92. g_spWMPPlayer.QueryInterface( &spWMPPlayer2 );
  93. if ( !spWMPPlayer2 )
  94. return false;
  95. bool bStretchToFit = vbStretchToFit == VARIANT_TRUE;
  96. if ( bStretchToFit == IsStretchedToFit() )
  97. return true;
  98. spWMPPlayer2->put_stretchToFit( vbStretchToFit );
  99. return bStretchToFit == IsStretchedToFit();
  100. }
  101. bool IsFullScreen()
  102. {
  103. if ( !g_spWMPPlayer )
  104. return false;
  105. VARIANT_BOOL vbFullscreen = VARIANT_TRUE;
  106. g_spWMPPlayer->get_fullScreen( &vbFullscreen );
  107. return vbFullscreen == VARIANT_TRUE;
  108. }
  109. bool SetFullScreen( bool bWantToBeFullscreen )
  110. {
  111. g_bWantToBeFullscreen = bWantToBeFullscreen;
  112. if ( !g_spWMPPlayer )
  113. return false;
  114. LogPlayerEvent( bWantToBeFullscreen ? ET_MAXIMIZE : ET_RESTORE );
  115. bool bIsFullscreen = IsFullScreen();
  116. CComPtr<IWMPPlayer2> spWMPPlayer2;
  117. HRESULT hr = g_spWMPPlayer.QueryInterface(&spWMPPlayer2);
  118. if ( hr != S_OK )
  119. {
  120. assert( spWMPPlayer2 == NULL ); // the MS documentation claims this shouldn't happen, but it does...
  121. spWMPPlayer2 = NULL;
  122. }
  123. if ( spWMPPlayer2 )
  124. {
  125. VARIANT_BOOL vbStretch = VARIANT_TRUE;
  126. spWMPPlayer2->get_stretchToFit( &vbStretch );
  127. bool bStretch = vbStretch == VARIANT_TRUE;
  128. if ( bStretch != g_bWantToBeFullscreen )
  129. {
  130. bIsFullscreen = !g_bWantToBeFullscreen;
  131. }
  132. }
  133. if ( g_bWantToBeFullscreen == bIsFullscreen )
  134. return true;
  135. if ( g_bWantToBeFullscreen )
  136. {
  137. g_spWMPPlayer->put_uiMode(L"none");
  138. g_spWMPPlayer->put_fullScreen(VARIANT_TRUE);
  139. if ( spWMPPlayer2 )
  140. {
  141. spWMPPlayer2->put_stretchToFit( VARIANT_TRUE );
  142. }
  143. while ( ShowCursor( FALSE ) >= 0 )
  144. ;
  145. }
  146. else
  147. {
  148. g_spWMPPlayer->put_fullScreen(VARIANT_FALSE);
  149. g_spWMPPlayer->put_uiMode(L"full");
  150. if ( spWMPPlayer2 )
  151. {
  152. spWMPPlayer2->put_stretchToFit( g_desiredVideoScaleMode == ID_STRETCH_TO_FIT ? VARIANT_TRUE : VARIANT_FALSE );
  153. }
  154. g_pFrame->ShowWindow( SW_RESTORE );
  155. while ( ShowCursor( TRUE ) < 0 )
  156. ;
  157. }
  158. bIsFullscreen = IsFullScreen();
  159. if ( bIsFullscreen != g_bWantToBeFullscreen )
  160. {
  161. g_bWantToBeFullscreen = bIsFullscreen;
  162. OutputDebugString( "SetFullScreen FAILED!\n" );
  163. return false;
  164. }
  165. if ( spWMPPlayer2 )
  166. {
  167. if ( g_bWantToBeFullscreen )
  168. {
  169. VARIANT_BOOL vbStretch = VARIANT_TRUE;
  170. spWMPPlayer2->get_stretchToFit( &vbStretch );
  171. if ( vbStretch != VARIANT_TRUE )
  172. {
  173. OutputDebugString( "SetFullScreen FAILED to set stretchToFit!\n" );
  174. return false;
  175. }
  176. }
  177. }
  178. return true;
  179. }
  180. bool IsVideoPlaying()
  181. {
  182. WMPPlayState playState;
  183. g_spWMPPlayer->get_playState(&playState);
  184. return playState == wmppsPlaying;
  185. }
  186. void PlayVideo( bool bPlay )
  187. {
  188. CComPtr<IWMPControls> spWMPControls;
  189. g_spWMPPlayer->get_controls(&spWMPControls);
  190. if ( spWMPControls )
  191. {
  192. if ( bPlay )
  193. {
  194. spWMPControls->play();
  195. }
  196. else
  197. {
  198. spWMPControls->pause();
  199. }
  200. }
  201. }
  202. /////////////////////////////////////////////////////////////////////////////
  203. // CWMPHost
  204. LRESULT CWMPHost::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  205. {
  206. AtlAxWinInit();
  207. CComPtr<IAxWinHostWindow> spHost;
  208. CComPtr<IConnectionPointContainer> spConnectionContainer;
  209. CComWMPEventDispatch *pEventListener = NULL;
  210. CComPtr<IWMPEvents> spEventListener;
  211. HRESULT hr;
  212. RECT rcClient;
  213. m_dwAdviseCookie = 0;
  214. m_hPopupMenu = 0;
  215. // create window
  216. GetClientRect(&rcClient);
  217. m_wndView.Create(m_hWnd, rcClient, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN, WS_EX_CLIENTEDGE);
  218. if (NULL == m_wndView.m_hWnd)
  219. goto FAILURE;
  220. // load OCX in window
  221. hr = m_wndView.QueryHost(&spHost);
  222. if (FAILMSG(hr))
  223. goto FAILURE;
  224. hr = spHost->CreateControl(CComBSTR(_T("{6BF52A52-394A-11d3-B153-00C04F79FAA6}")), m_wndView, 0);
  225. if (FAILMSG(hr))
  226. goto FAILURE;
  227. hr = m_wndView.QueryControl(&g_spWMPPlayer);
  228. if (FAILMSG(hr))
  229. goto FAILURE;
  230. // start listening to events
  231. hr = CComWMPEventDispatch::CreateInstance(&pEventListener);
  232. spEventListener = pEventListener;
  233. if (FAILMSG(hr))
  234. goto FAILURE;
  235. hr = g_spWMPPlayer->QueryInterface(&spConnectionContainer);
  236. if (FAILMSG(hr))
  237. goto FAILURE;
  238. // See if OCX supports the IWMPEvents interface
  239. hr = spConnectionContainer->FindConnectionPoint(__uuidof(IWMPEvents), &m_spConnectionPoint);
  240. if (FAILED(hr))
  241. {
  242. // If not, try the _WMPOCXEvents interface, which will use IDispatch
  243. hr = spConnectionContainer->FindConnectionPoint(__uuidof(_WMPOCXEvents), &m_spConnectionPoint);
  244. if (FAILMSG(hr))
  245. goto FAILURE;
  246. }
  247. hr = m_spConnectionPoint->Advise(spEventListener, &m_dwAdviseCookie);
  248. if (FAILMSG(hr))
  249. goto FAILURE;
  250. IWMPSettings *spWMPSettings;
  251. g_spWMPPlayer->get_settings( &spWMPSettings );
  252. if ( spWMPSettings )
  253. {
  254. spWMPSettings->put_volume( 100 );
  255. }
  256. g_spWMPPlayer->put_enableContextMenu( VARIANT_FALSE );
  257. // set the url of the movie
  258. hr = g_spWMPPlayer->put_URL( CT2W( g_URL.c_str() ) );
  259. if (FAILED(hr))
  260. OutputDebugString( "put_URL failed\n" );
  261. return 0;
  262. FAILURE:
  263. OutputDebugString( "CWMPHost::OnCreate FAILED!\n" );
  264. DestroyWindow();
  265. if ( g_hBlackFadingWindow )
  266. {
  267. ::DestroyWindow( g_hBlackFadingWindow );
  268. }
  269. // ::PostQuitMessage(0);
  270. return 0;
  271. }
  272. LRESULT CWMPHost::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  273. {
  274. LogPlayerEvent( ET_CLOSE );
  275. DestroyWindow();
  276. if ( g_hBlackFadingWindow )
  277. {
  278. ::DestroyWindow( g_hBlackFadingWindow );
  279. }
  280. return 0;
  281. }
  282. LRESULT CWMPHost::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  283. {
  284. // stop listening to events
  285. if (m_spConnectionPoint)
  286. {
  287. if (0 != m_dwAdviseCookie)
  288. m_spConnectionPoint->Unadvise(m_dwAdviseCookie);
  289. m_spConnectionPoint.Release();
  290. }
  291. // close the OCX
  292. if (g_spWMPPlayer)
  293. {
  294. g_spWMPPlayer->close();
  295. g_spWMPPlayer.Release();
  296. }
  297. m_hWnd = NULL;
  298. g_bFrameCreated = false;
  299. bHandled = FALSE;
  300. return 1;
  301. }
  302. LRESULT CWMPHost::OnErase(UINT /* uMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& bHandled)
  303. {
  304. if ( g_bWantToBeFullscreen && !IsFullScreen() )
  305. {
  306. g_pFrame->BringWindowToTop();
  307. SetFullScreen( false );
  308. }
  309. bHandled = TRUE;
  310. return 0;
  311. }
  312. LRESULT CWMPHost::OnSize(UINT /* uMsg */, WPARAM wParam, LPARAM lParam, BOOL& /* lResult */)
  313. {
  314. if ( wParam == SIZE_MAXIMIZED )
  315. {
  316. SetFullScreen( true );
  317. }
  318. else
  319. {
  320. if ( wParam == SIZE_MINIMIZED )
  321. {
  322. LogPlayerEvent( ET_MINIMIZE );
  323. if ( IsVideoPlaying() )
  324. {
  325. g_bPlayOnRestore = true;
  326. PlayVideo( false );
  327. }
  328. }
  329. else if ( wParam == SIZE_RESTORED )
  330. {
  331. LogPlayerEvent( ET_RESTORE );
  332. }
  333. RECT rcClient;
  334. GetClientRect(&rcClient);
  335. m_wndView.MoveWindow(rcClient.left, rcClient.top, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top);
  336. }
  337. return 0;
  338. }
  339. LRESULT CWMPHost::OnContextMenu(UINT /* uMsg */, WPARAM /* wParam */, LPARAM lParam, BOOL& /* lResult */)
  340. {
  341. if ( !m_hPopupMenu )
  342. {
  343. m_hPopupMenu = CreatePopupMenu();
  344. // AppendMenu( m_hPopupMenu, MF_STRING, ID_HALF_SIZE, "Zoom 50%" );
  345. AppendMenu( m_hPopupMenu, MF_STRING, ID_FULL_SIZE, "Zoom 100%" );
  346. // AppendMenu( m_hPopupMenu, MF_STRING, ID_DOUBLE_SIZE, "Zoom 200%" );
  347. AppendMenu( m_hPopupMenu, MF_STRING, ID_STRETCH_TO_FIT, "Stretch to fit window" );
  348. }
  349. int x = GET_X_LPARAM( lParam );
  350. int y = GET_Y_LPARAM( lParam );
  351. TrackPopupMenu( m_hPopupMenu, TPM_LEFTALIGN | TPM_TOPALIGN, x, y, 0, m_hWnd, NULL );
  352. return 0;
  353. }
  354. LRESULT CWMPHost::OnClick(UINT /* uMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& /* lResult */)
  355. {
  356. if ( IsFullScreen() )
  357. {
  358. SetFullScreen( false );
  359. }
  360. return 1;
  361. }
  362. LRESULT CWMPHost::OnLeftDoubleClick(UINT /* uMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& /* lResult */)
  363. {
  364. SetFullScreen( !IsFullScreen() );
  365. return 1;
  366. }
  367. LRESULT CWMPHost::OnSysKeyDown(UINT /* uMsg */, WPARAM wParam, LPARAM /* lParam */, BOOL& /* lResult */)
  368. {
  369. switch ( wParam )
  370. {
  371. case VK_RETURN:
  372. SetFullScreen( !IsFullScreen() );
  373. break;
  374. }
  375. return 1;
  376. }
  377. LRESULT CWMPHost::OnKeyDown(UINT /* uMsg */, WPARAM wParam, LPARAM /* lParam */, BOOL& /* lResult */)
  378. {
  379. switch ( wParam )
  380. {
  381. case VK_SPACE:
  382. PlayVideo( !IsVideoPlaying() );
  383. break;
  384. case VK_LEFT:
  385. case VK_RIGHT:
  386. {
  387. CComPtr<IWMPControls> spWMPControls;
  388. g_spWMPPlayer->get_controls(&spWMPControls);
  389. if ( !spWMPControls )
  390. break;
  391. CComPtr<IWMPControls2> spWMPControls2;
  392. spWMPControls.QueryInterface(&spWMPControls2);
  393. if ( !spWMPControls2 )
  394. break;
  395. spWMPControls2->step( wParam == VK_LEFT ? -1 : 1 );
  396. LogPlayerEvent( wParam == VK_LEFT ? ET_STEPBCK : ET_STEPFWD );
  397. }
  398. break;
  399. case VK_UP:
  400. case VK_DOWN:
  401. {
  402. CComPtr<IWMPControls> spWMPControls;
  403. g_spWMPPlayer->get_controls(&spWMPControls);
  404. if ( !spWMPControls )
  405. break;
  406. double curpos = 0.0f;
  407. if ( spWMPControls->get_currentPosition( &curpos ) != S_OK )
  408. break;
  409. curpos += wParam == VK_UP ? -5.0f : 5.0f;
  410. spWMPControls->put_currentPosition( curpos );
  411. if ( !IsVideoPlaying() )
  412. {
  413. spWMPControls->play();
  414. spWMPControls->pause();
  415. }
  416. LogPlayerEvent( wParam == VK_UP ? ET_JUMPBCK : ET_JUMPFWD );
  417. }
  418. break;
  419. case VK_HOME:
  420. {
  421. CComPtr<IWMPControls> spWMPControls;
  422. g_spWMPPlayer->get_controls(&spWMPControls);
  423. if ( !spWMPControls )
  424. break;
  425. spWMPControls->put_currentPosition( 0.0f );
  426. if ( !IsVideoPlaying() )
  427. {
  428. spWMPControls->play();
  429. spWMPControls->pause();
  430. }
  431. LogPlayerEvent( ET_JUMPHOME );
  432. }
  433. break;
  434. case VK_END:
  435. {
  436. CComPtr<IWMPMedia> spWMPMedia;
  437. g_spWMPPlayer->get_currentMedia( &spWMPMedia );
  438. if ( !spWMPMedia )
  439. break;
  440. CComPtr<IWMPControls> spWMPControls;
  441. g_spWMPPlayer->get_controls(&spWMPControls);
  442. if ( !spWMPControls )
  443. break;
  444. double duration = 0.0f;
  445. if ( spWMPMedia->get_duration( &duration ) != S_OK )
  446. break;
  447. spWMPControls->put_currentPosition( duration - 0.050 ); // back a little more than a frame - this avoids triggering the end fade
  448. spWMPControls->play();
  449. spWMPControls->pause();
  450. LogPlayerEvent( ET_JUMPEND );
  451. }
  452. break;
  453. case VK_ESCAPE:
  454. if ( IsFullScreen() && !g_bFadeWindowTriggered )
  455. {
  456. CComPtr<IWMPControls> spWMPControls;
  457. g_spWMPPlayer->get_controls(&spWMPControls);
  458. if ( spWMPControls )
  459. {
  460. spWMPControls->stop();
  461. }
  462. LogPlayerEvent( ET_FADEOUT );
  463. g_bFadeWindowTriggered = true;
  464. ShowFadeWindow( true );
  465. }
  466. break;
  467. }
  468. return 0;
  469. }
  470. LRESULT CWMPHost::OnNCActivate(UINT /* uMsg */, WPARAM wParam, LPARAM /* lParam */, BOOL& /* lResult */ )
  471. {
  472. if ( wParam )
  473. {
  474. if ( g_bWantToBeFullscreen )
  475. {
  476. SetFullScreen( true );
  477. }
  478. if ( g_bPlayOnRestore )
  479. {
  480. g_bPlayOnRestore = false;
  481. PlayVideo( true );
  482. }
  483. }
  484. return 1;
  485. }
  486. LRESULT CWMPHost::OnVideoScale(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  487. {
  488. SetVideoScaleMode( wID );
  489. return 0;
  490. }