📄 playwnd.cpp
字号:
HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker);
if (SUCCEEDED(hr))
{
hr = pROT->Register(0, pUnkGraph, pMoniker, pdwRegister);
pMoniker->Release();
}
pROT->Release();
return hr;
}
//-----------------------------------------------------------------------------
void CDXPlayer::RemoveGraphFromRot(DWORD pdwRegister)
{
IRunningObjectTable *pROT;
if (SUCCEEDED(GetRunningObjectTable(0, &pROT)))
{
pROT->Revoke(pdwRegister);
pROT->Release();
}
}
//-----------------------------------------------------------------------------
#endif
//-----------------------------------------------------------------------------
void CDXPlayer::Msg(TCHAR *szFormat, ...)
{
TCHAR szBuffer[512]; // Large buffer for very long filenames (like HTTP)
// Format the input string
va_list pArgs;
va_start(pArgs, szFormat);
_vstprintf(szBuffer, szFormat, pArgs);
va_end(pArgs);
// Display a message box with the formatted string
MessageBox(NULL, szBuffer, TEXT("PlayWnd Sample"), MB_OK);
}
//-----------------------------------------------------------------------------
HRESULT CDXPlayer::ToggleMute(void)
{
HRESULT hr=S_OK;
if ((!m_pGraphBuilder) || (!m_pBaseAudio))
return S_OK;
// Read current volume
hr = m_pBaseAudio->get_Volume(&m_lVolume);
if (hr == E_NOTIMPL)
{
// Fail quietly if this is a video-only media file
return S_OK;
}
else if (FAILED(hr))
{
Msg(TEXT("Failed to read audio volume! hr=0x%x\r\n"), hr);
return hr;
}
// Switch volume levels
if (m_lVolume == VOLUME_FULL)
m_lVolume = VOLUME_SILENCE;
else
m_lVolume = VOLUME_FULL;
// Set new volume
JIF(m_pBaseAudio->put_Volume(m_lVolume));
UpdateMainTitle();
return hr;
}
//-----------------------------------------------------------------------------
void CDXPlayer::UpdateMainTitle(void)
{
/*
TCHAR szTitle[MAX_PATH]={0}, szFile[MAX_PATH]={0};
// If no file is loaded, just show the application title
if (m_szFileName[0] == L'\0')
{
wsprintf(szTitle, TEXT("%s"), APPLICATIONNAME);
}
// Otherwise, show useful information
else
{
// Get file name without full path
GetFilename(m_szFileName, szFile);
char szPlaybackRate[16];
if (m_PlaybackRate == 1.0)
szPlaybackRate[0] = '\0';
else
sprintf(szPlaybackRate, "(Rate:%2.2f)", m_PlaybackRate);
TCHAR szRate[20];
#ifdef UNICODE
MultiByteToWideChar(CP_ACP, 0, szPlaybackRate, -1, szRate, 20);
#else
lstrcpy(szRate, szPlaybackRate);
#endif
// Update the window title to show filename and play state
wsprintf(szTitle, TEXT("%s [%s] %s%s%s\0\0"),
szFile,
m_bAudioOnly ? TEXT("Audio\0") : TEXT("Video\0"),
(m_lVolume == VOLUME_SILENCE) ? TEXT("(Muted)\0") : TEXT("\0"),
(m_psCurrent == Paused) ? TEXT("(Paused)\0") : TEXT("\0"),
szRate);
}
SetWindowText(ghApp, szTitle);
*/
}
//-----------------------------------------------------------------------------
void CDXPlayer::GetFilename(TCHAR *pszFull, TCHAR *pszFile)
{
int nLength;
TCHAR szPath[MAX_PATH]={0};
BOOL bSetFilename=FALSE;
// Strip path and return just the file's name
_tcscpy(szPath, pszFull);
nLength = (int) _tcslen(szPath);
for (int i=nLength-1; i>=0; i--)
{
if ((szPath[i] == '\\') || (szPath[i] == '/'))
{
szPath[i] = '\0';
lstrcpy(pszFile, &szPath[i+1]);
bSetFilename = TRUE;
break;
}
}
// If there was no path given (just a file name), then
// just copy the full path to the target path.
if (!bSetFilename)
_tcscpy(pszFile, pszFull);
}
//-----------------------------------------------------------------------------
HRESULT CDXPlayer::ToggleFullScreen(HWND hWnd)
{
HRESULT hr=S_OK;
/*
LONG lMode;
static HWND hDrain=0;
// Don't bother with full-screen for audio-only files
if ((m_bAudioOnly) || (!m_pVideoWindow))
return S_OK;
// Read current state
JIF(m_pVideoWindow->get_FullScreenMode(&lMode));
if (lMode == OAFALSE)
{
// Save current message drain
LIF(m_pVideoWindow->get_MessageDrain((OAHWND *) &hDrain));
// Set message drain to application main window
LIF(m_pVideoWindow->put_MessageDrain((OAHWND) hWnd));
// Switch to full-screen mode
lMode = OATRUE;
JIF(m_pVideoWindow->put_FullScreenMode(lMode));
m_bFullscreen = TRUE;
}
else
{
// Switch back to windowed mode
lMode = OAFALSE;
JIF(m_pVideoWindow->put_FullScreenMode(lMode));
// Undo change of message drain
LIF(m_pVideoWindow->put_MessageDrain((OAHWND) hDrain));
// Reset video window
LIF(m_pVideoWindow->SetWindowForeground(-1));
// Reclaim keyboard focus for player application
UpdateWindow(ghApp);
SetForegroundWindow(ghApp);
SetFocus(ghApp);
m_bFullscreen = FALSE;
}
*/
return hr;
}
//-----------------------------------------------------------------------------
//
// Some video renderers support stepping media frame by frame with the
// IVideoFrameStep interface. See the interface documentation for more
// details on frame stepping.
//
//-----------------------------------------------------------------------------
BOOL CDXPlayer::GetFrameStepInterface(void)
{
HRESULT hr;
IVideoFrameStep *pFSTest = NULL;
// Get the frame step interface, if supported
hr = m_pGraphBuilder->QueryInterface(__uuidof(IVideoFrameStep), (PVOID *)&pFSTest);
if (FAILED(hr))
return FALSE;
// Check if this decoder can step
hr = pFSTest->CanStep(0L, NULL);
if (hr == S_OK)
{
m_pVideoFrameStep = pFSTest; // Save interface to global variable for later use
return TRUE;
}
else
{
pFSTest->Release();
return FALSE;
}
}
//-----------------------------------------------------------------------------
HRESULT CDXPlayer::StepOneFrame(void)
{
HRESULT hr=S_OK;
// If the Frame Stepping interface exists, use it to step one frame
if (m_pVideoFrameStep)
{
// The graph must be paused for frame stepping to work
if (m_psCurrent != State_Paused)
PauseClip();
// Step the requested number of frames, if supported
hr = m_pVideoFrameStep->Step(1, NULL);
}
return hr;
}
//-----------------------------------------------------------------------------
HRESULT CDXPlayer::StepFrames(int nFramesToStep)
{
HRESULT hr=S_OK;
// If the Frame Stepping interface exists, use it to step frames
if (m_pVideoFrameStep)
{
// The renderer may not support frame stepping for more than one
// frame at a time, so check for support. S_OK indicates that the
// renderer can step nFramesToStep successfully.
if ((hr = m_pVideoFrameStep->CanStep(nFramesToStep, NULL)) == S_OK)
{
// The graph must be paused for frame stepping to work
if (m_psCurrent != State_Paused)
PauseClip();
// Step the requested number of frames, if supported
hr = m_pVideoFrameStep->Step(nFramesToStep, NULL);
}
}
return hr;
}
//-----------------------------------------------------------------------------
HRESULT CDXPlayer::ModifyRate(double dRateAdjust)
{
HRESULT hr=S_OK;
double dRate;
// If the IMediaPosition interface exists, use it to set rate
if ((m_pMediaPosition) && (dRateAdjust != 0))
{
if ((hr = m_pMediaPosition->get_Rate(&dRate)) == S_OK)
{
// Add current rate to adjustment value
double dNewRate = dRate + dRateAdjust;
hr = m_pMediaPosition->put_Rate(dNewRate);
// Save global rate
if (SUCCEEDED(hr))
{
m_PlaybackRate = dNewRate;
UpdateMainTitle();
}
}
}
return hr;
}
//-----------------------------------------------------------------------------
HRESULT CDXPlayer::SetRate(double dRate)
{
HRESULT hr=S_OK;
// If the IMediaPosition interface exists, use it to set rate
if (m_pMediaPosition)
{
hr = m_pMediaPosition->put_Rate(dRate);
// Save global rate
if (SUCCEEDED(hr))
{
m_PlaybackRate = dRate;
UpdateMainTitle();
}
}
return hr;
}
//-----------------------------------------------------------------------------
HRESULT CDXPlayer::HandleGraphEvent(void)
{
LONG evCode, evParam1, evParam2;
HRESULT hr=S_OK;
// Make sure that we don't access the media event interface
// after it has already been released.
if (!m_pMediaEventEx)
return S_OK;
// Process all queued events
while(SUCCEEDED(m_pMediaEventEx->GetEvent(&evCode, (LONG_PTR *) &evParam1,
(LONG_PTR *) &evParam2, 0)))
{
// Free memory associated with callback, since we're not using it
hr = m_pMediaEventEx->FreeEventParams(evCode, evParam1, evParam2);
// If this is the end of the clip, reset to beginning
if(EC_COMPLETE == evCode)
{
LONGLONG pos=0;
// Reset to first frame of movie
hr = m_pMediaSeeking->SetPositions(&pos, AM_SEEKING_AbsolutePositioning ,
NULL, AM_SEEKING_NoPositioning);
if (FAILED(hr))
{
// Some custom filters (like the Windows CE MIDI filter)
// may not implement seeking interfaces (IMediaSeeking)
// to allow seeking to the start. In that case, just stop
// and restart for the same effect. This should not be
// necessary in most cases.
if (FAILED(hr = m_pMediaControl->Stop()))
{
Msg(TEXT("Failed(0x%08lx) to stop media clip!\r\n"), hr);
break;
}
if (FAILED(hr = m_pMediaControl->Run()))
{
Msg(TEXT("Failed(0x%08lx) to reset media clip!\r\n"), hr);
break;
}
}
}
}
return hr;
}
//-----------------------------------------------------------------------------
void CDXPlayer::SetPlayerWindow(HWND hWnd)
{
m_hWnd = hWnd;
}
//-----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -