⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 blenderdlg.cpp

📁 最近在学习directshow, Directshow实务精选的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        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 + -