📄 blenderdlg.cpp
字号:
r.top = fBottom;
r.bottom = fTop;
}
DisplayCoordinates(nStreamID, r);
// Update the destination rectangle for the selected stream
if(pMix)
hr = pMix->SetOutputRect(nStreamID, &r);
return hr;
}
void CBlenderDlg::DisplayCoordinates(int nStreamID, VMR9NormalizedRect& r)
{
USES_CONVERSION;
int nID[2] = {IDC_STATIC_GROUP1, IDC_STATIC_GROUP2};
// Display composition space coordinates for this stream
char szAnsiLabel[128];
TCHAR szLabel[128];
// The wsprintf method doesn't support floating point, so use the
// ANSI version and convert to UNICODE if necessary.
sprintf(szAnsiLabel, "Stream %d (%02.2f x %02.2f) at (%02.2f, %02.2f)\0",
nStreamID, (float) (r.right - r.left), (float)(r.bottom - r.top),
r.left, r.top);
_tcsncpy(szLabel, A2T(szAnsiLabel), NUMELMS(szLabel)-1);
CWnd *pWnd = GetDlgItem(nID[nStreamID]);
pWnd->SetWindowText(szLabel);
}
void CBlenderDlg::MoveVideoWindow(void)
{
HRESULT hr;
RECT rcDest={0};
// Track the movement of the container window and resize as needed
if (pWC)
{
m_Screen.GetClientRect(&rcDest);
hr = pWC->SetVideoPosition(NULL, &rcDest);
}
}
void CBlenderDlg::InitStreamParams(void)
{
// Set default values for X, Y, Width, Height and Alpha values
// for both streams. These values will be adjusted by the user
// at runtime by manipulating sliders and dialog controls.
CopyMemory(&strParam[0], strParamInit, sizeof(strParamInit));
CopyMemory(&strParam[1], strParamInit, sizeof(strParamInit));
}
HRESULT CBlenderDlg::RepaintVideo(void)
{
HRESULT hr=S_OK;
// Request the VMR to repaint the video. This is especially
// necessary if the graph is paused or stopped, since the VMR
// won't be automatically updating the screen when playing video frames.
if (pWC)
{
HDC hdc;
hdc = ::GetDC(m_hwndScreen);
hr = pWC->RepaintVideo(m_hwndScreen, hdc);
::ReleaseDC(m_hwndScreen, hdc);
}
return hr;
}
LRESULT CBlenderDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// Field notifications from the DirectShow filter graph manager
// and those posted by the application
switch (message)
{
case WM_HSCROLL:
HandleHorizontalTrackbar(wParam, lParam);
break;
case WM_VSCROLL:
HandleVerticalTrackbar(wParam, lParam);
break;
case WM_GRAPHNOTIFY:
HandleGraphEvent();
break;
}
return CDialog::WindowProc(message, wParam, lParam);
}
HRESULT CBlenderDlg::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 (!pME)
return S_OK;
// Process all queued events
while(SUCCEEDED(pME->GetEvent(&evCode, (LONG_PTR *) &evParam1,
(LONG_PTR *) &evParam2, 0)))
{
// Free memory associated with callback, since we're not using it
hr = pME->FreeEventParams(evCode, evParam1, evParam2);
// If this is the end of the clip, reset to beginning
if(EC_COMPLETE == evCode)
{
// Restart from the beginning. The OnStop call
// seeks to the beginning of the clip.
OnStop();
OnPlay();
}
}
return hr;
}
HRESULT CBlenderDlg::WaitForState(OAFilterState fsReq)
{
HRESULT hr=S_OK;
OAFilterState fs;
if (pMC)
{
// Read the current graph state
hr = pMC->GetState(500, &fs);
// Wait for the state to propagate to all filters
while ((SUCCEEDED(hr)) && (fs != fsReq))
hr = pMC->GetState(500, &fs);
}
return hr;
}
void CBlenderDlg::StartTimer()
{
// Cancel any pending timer event
StopTimer();
// Create a new timer
g_wTimerID = SetTimer(TIMERID, TICKLEN, NULL);
}
void CBlenderDlg::StopTimer()
{
// Cancel the timer
if(g_wTimerID)
{
KillTimer(g_wTimerID);
g_wTimerID = 0;
}
}
void CBlenderDlg::OnTimer(UINT nIDEvent)
{
UpdatePosition();
CDialog::OnTimer(nIDEvent);
}
void CBlenderDlg::OnCheckFlip()
{
strParam[0].bFlipped ^= 1;
UpdatePinPos(0);
}
void CBlenderDlg::OnCheckMirror()
{
strParam[0].bMirrored ^= 1;
UpdatePinPos(0);
}
void CBlenderDlg::OnCheckFlip2()
{
strParam[1].bFlipped ^= 1;
UpdatePinPos(1);
}
void CBlenderDlg::OnCheckMirror2()
{
strParam[1].bMirrored ^= 1;
UpdatePinPos(1);
}
void CBlenderDlg::OnButtonAbout()
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
void CBlenderDlg::InitControls(void)
{
int i;
// Initialize and disable all stream sliders and check boxes
for (i=0; i < NUM_SLIDERS; i++)
{
CSliderCtrl *pSlider;
pSlider = (CSliderCtrl *) GetDlgItem(nSliderIDs[i]);
pSlider->SetRange(0, 100, TRUE);
pSlider->SetTicFreq(10);
pSlider->EnableWindow(FALSE);
}
for (i=0; i < NUM_CHECKS; i++)
{
CButton *pButton = (CButton *) GetDlgItem(nCheckIDs[i]);
pButton->SetCheck(0);
pButton->EnableWindow(FALSE);
}
}
void CBlenderDlg::EnableControls(BOOL bEnable)
{
int i;
// Enable/disable all stream sliders and check boxes.
// These controls should be disabled until all streams are loaded
// and the filter graph is fully configured.
for (i=0; i < NUM_SLIDERS; i++)
{
CSliderCtrl *pSlider;
pSlider = (CSliderCtrl *) GetDlgItem(nSliderIDs[i]);
pSlider->EnableWindow(bEnable);
}
for (i=0; i < NUM_CHECKS; i++)
{
CButton *pButton = (CButton *) GetDlgItem(nCheckIDs[i]);
pButton->EnableWindow(bEnable);
}
}
void CBlenderDlg::SetSliders(void)
{
CSliderCtrl *pSlider;
// Set the sliders to reflect the current state of their
// associated streams, using data stored in the global strParam array
// Set X, Y, and Alpha for stream 1
pSlider = (CSliderCtrl *) GetDlgItem(IDC_SLIDER_X);
pSlider->SetPos((int) (100.0 * strParam[0].xPos));
pSlider = (CSliderCtrl *) GetDlgItem(IDC_SLIDER_Y);
pSlider->SetPos((int) (100.0 * strParam[0].yPos));
pSlider = (CSliderCtrl *) GetDlgItem(IDC_SLIDER_ALPHA);
pSlider->SetPos((int) (100.0 * strParam[0].Alpha));
// Set width and height for stream 1
pSlider = (CSliderCtrl *) GetDlgItem(IDC_SLIDER_WIDTH);
pSlider->SetPos((int) (100.0 * (strParam[0].xSize - strParam[0].xPos)));
pSlider = (CSliderCtrl *) GetDlgItem(IDC_SLIDER_HEIGHT);
pSlider->SetPos((int) (100.0 * (strParam[0].ySize - strParam[0].yPos)));
// Set X, Y, and Alpha for stream 2
pSlider = (CSliderCtrl *) GetDlgItem(IDC_SLIDER_X2);
pSlider->SetPos((int) (100.0 * strParam[1].xPos));
pSlider = (CSliderCtrl *) GetDlgItem(IDC_SLIDER_Y2);
pSlider->SetPos((int) (100.0 * strParam[1].yPos));
pSlider = (CSliderCtrl *) GetDlgItem(IDC_SLIDER_ALPHA2);
pSlider->SetPos((int) (100.0 * strParam[1].Alpha));
// Set width and height for stream 2
pSlider = (CSliderCtrl *) GetDlgItem(IDC_SLIDER_WIDTH2);
pSlider->SetPos((int) (100.0 * (strParam[1].xSize - strParam[1].xPos)));
pSlider = (CSliderCtrl *) GetDlgItem(IDC_SLIDER_HEIGHT2);
pSlider->SetPos((int) (100.0 * (strParam[1].ySize - strParam[1].yPos)));
}
void CBlenderDlg::HandleHorizontalTrackbar(WPARAM wParam, LPARAM lParam)
{
if (wParam != SB_ENDSCROLL)
{
// First determine which slider was adjusted
HWND hwnd = (HWND) lParam;
int nID = ::GetWindowLong(hwnd, GWL_ID);
CSliderCtrl *pSlider = (CSliderCtrl *)GetDlgItem(nID);
// Read the current value of the adjusted slider
DWORD dwPosition = pSlider->GetPos();
// Convert the 0-100 decimal value to a 0.0 to 1.0 float value
// to represent position in VMR composition space
FLOAT fPos = (FLOAT) dwPosition * (FLOAT) 0.01;
switch (nID)
{
case IDC_SLIDER_X:
strParam[0].xPos = fPos;
UpdatePinPos(0);
break;
case IDC_SLIDER_X2:
strParam[1].xPos = fPos;
UpdatePinPos(1);
break;
case IDC_SLIDER_WIDTH:
strParam[0].xSize = fPos;
UpdatePinPos(0);
break;
case IDC_SLIDER_WIDTH2:
strParam[1].xSize = fPos;
UpdatePinPos(1);
break;
case IDC_SLIDER_ALPHA:
strParam[0].Alpha = fPos;
UpdatePinAlpha(0);
break;
case IDC_SLIDER_ALPHA2:
strParam[1].Alpha = fPos;
UpdatePinAlpha(1);
break;
}
}
}
void CBlenderDlg::HandleVerticalTrackbar(WPARAM wParam, LPARAM lParam)
{
if (wParam != SB_ENDSCROLL)
{
// First determine which slider was adjusted
HWND hwnd = (HWND) lParam;
int nID = ::GetWindowLong(hwnd, GWL_ID);
CSliderCtrl *pSlider = (CSliderCtrl *)GetDlgItem(nID);
// Read the current value of the adjusted slider
DWORD dwPosition = pSlider->GetPos();
// Convert the 0-100 decimal value to a 0.0 to 1.0 float value
// to represent position in VMR composition space
FLOAT fPos = (FLOAT) dwPosition * (FLOAT) 0.01;
switch (nID)
{
case IDC_SLIDER_Y:
strParam[0].yPos = fPos;
UpdatePinPos(0);
break;
case IDC_SLIDER_Y2:
strParam[1].yPos = fPos;
UpdatePinPos(1);
break;
case IDC_SLIDER_HEIGHT:
strParam[0].ySize = fPos;
UpdatePinPos(0);
break;
case IDC_SLIDER_HEIGHT2:
strParam[1].ySize = fPos;
UpdatePinPos(1);
break;
}
}
}
HRESULT CBlenderDlg::DisplayFileDuration(void)
{
HRESULT hr;
if (!pMS)
return E_NOINTERFACE;
// Initialize the display in case we can't read the duration
m_StrDuration.SetWindowText(TEXT("<00:00.000>"));
// Is media time supported for this file?
if (S_OK != pMS->IsFormatSupported(&TIME_FORMAT_MEDIA_TIME))
return E_NOINTERFACE;
// Read the time format to restore later
GUID guidOriginalFormat;
hr = pMS->GetTimeFormat(&guidOriginalFormat);
if (FAILED(hr))
return hr;
// Ensure media time format for easy display
hr = pMS->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME);
if (FAILED(hr))
return hr;
// Read the file's duration
LONGLONG llDuration;
hr = pMS->GetDuration(&llDuration);
if (FAILED(hr))
return hr;
// Return to the original format
if (guidOriginalFormat != TIME_FORMAT_MEDIA_TIME)
{
hr = pMS->SetTimeFormat(&guidOriginalFormat);
if (FAILED(hr))
return hr;
}
// Convert the LONGLONG duration into human-readable format
unsigned long nTotalMS = (unsigned long) llDuration / 10000; // 100ns -> ms
int nMS = nTotalMS % 1000;
int nSeconds = nTotalMS / 1000;
int nMinutes = nSeconds / 60;
nSeconds %= 60;
// Update the display
TCHAR szDuration[24];
wsprintf(szDuration, _T("%02dm:%02d.%03ds\0"), nMinutes, nSeconds, nMS);
m_StrDuration.SetWindowText(szDuration);
return hr;
}
void CBlenderDlg::UpdatePosition(void)
{
HRESULT hr;
REFERENCE_TIME rtNow;
// Read the current stream position
hr = pMS->GetCurrentPosition(&rtNow);
if (FAILED(hr))
return;
// Convert the LONGLONG duration into human-readable format
unsigned long nTotalMS = (unsigned long) rtNow / 10000; // 100ns -> ms
int nSeconds = nTotalMS / 1000;
int nMinutes = nSeconds / 60;
nSeconds %= 60;
// Update the display
TCHAR szPosition[24], szCurrentString[24];
wsprintf(szPosition, _T("%02dm:%02ds\0"), nMinutes, nSeconds);
// Read current string and compare to the new string. To prevent flicker,
// don't update this label unless the string has changed.
m_StrPosition.GetWindowText(szCurrentString, 24);
if (_tcscmp(szCurrentString, szPosition))
m_StrPosition.SetWindowText(szPosition);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -