본문 바로가기
IT창고/DirectShow

2005 Directshow 미디어 재생기 만들기..

by 창구창고 2007. 1. 23.

📑 목차

    반응형

    // MediaPlayerView.cpp : CMediaPlayerView 클래스의 구현
    //

    #include "stdafx.h"
    #include "MediaPlayer.h"

    #include "MediaPlayerDoc.h"
    #include "MediaPlayerView.h"
    #include <math.h>

    const int TIMER_ID_TIMECHECK = 102;

    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif


    // CMediaPlayerView

    IMPLEMENT_DYNCREATE(CMediaPlayerView, CFormView)

    BEGIN_MESSAGE_MAP(CMediaPlayerView, CFormView)
     ON_BN_CLICKED(IDC_BTN_OPEN, &CMediaPlayerView::OnBnClickedBtnOpen)
     ON_BN_CLICKED(IDC_BTN_BACK, &CMediaPlayerView::OnBnClickedBtnBack)
     ON_BN_CLICKED(IDC_BTN_PLAY, &CMediaPlayerView::OnBnClickedBtnPlay)
     ON_BN_CLICKED(IDC_BTN_STOP, &CMediaPlayerView::OnBnClickedBtnStop)
     ON_BN_CLICKED(IDC_BTN_PAUSE, &CMediaPlayerView::OnBnClickedBtnPause)
     ON_BN_CLICKED(IDC_BTN_PRE, &CMediaPlayerView::OnBnClickedBtnPre)
     ON_WM_TIMER()
     ON_WM_HSCROLL()
     ON_WM_LBUTTONDBLCLK()
    END_MESSAGE_MAP()

    // CMediaPlayerView 생성/소멸

    CMediaPlayerView::CMediaPlayerView()
     : CFormView(CMediaPlayerView::IDD)
     , strPlayTime(_T(""))
     , strAllTime(_T(""))
     , strFileName(_T(""))
    {
     // TODO: 여기에 생성 코드를 추가합니다.
     CoInitialize(NULL);

    }

    CMediaPlayerView::~CMediaPlayerView()
    {
     CoUninitialize() ;
     m_bFullScreenOn = false;
    }

    void CMediaPlayerView::DoDataExchange(CDataExchange* pDX)
    {
     CFormView::DoDataExchange(pDX);
     DDX_Control(pDX, IDC_SLIDER1, ctrPlaySlider);
     DDX_Text(pDX, IDC_EDIT_TIME2, strPlayTime);
     DDX_Text(pDX, IDC_EDIT_TIME, strAllTime);
     DDX_Control(pDX, IDC_SLIDER2, ctrVolumeSlider);
     DDX_Text(pDX, IDC_EDIT1, strFileName);
    }

    BOOL CMediaPlayerView::PreCreateWindow(CREATESTRUCT& cs)
    {
     // TODO: CREATESTRUCT cs를 수정하여 여기에서
     //  Window 클래스 또는 스타일을 수정합니다.

     return CFormView::PreCreateWindow(cs);
    }

    void CMediaPlayerView::OnInitialUpdate()
    {
     CFormView::OnInitialUpdate();
     GetParentFrame()->RecalcLayout();
     ResizeParentToFit();

     ctrVolumeSlider.SetRange(0, 100);
     ctrPlaySlider.SetRange(0, 100);
     ctrVolumeSlider.SetPos(50);
     m_POS = 0 ;


     ctrVolumeSlider.ShowWindow(SW_HIDE);
     ctrPlaySlider.ShowWindow(SW_HIDE);

     
    }


    // CMediaPlayerView 진단

    #ifdef _DEBUG
    void CMediaPlayerView::AssertValid() const
    {
     CFormView::AssertValid();
    }

    void CMediaPlayerView::Dump(CDumpContext& dc) const
    {
     CFormView::Dump(dc);
    }

    CMediaPlayerDoc* CMediaPlayerView::GetDocument() const // 디버그되지 않은 버전은 인라인으로 지정됩니다.
    {
     ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMediaPlayerDoc)));
     return (CMediaPlayerDoc*)m_pDocument;
    }
    #endif //_DEBUG


    // CMediaPlayerView 메시지 처리기

    void CMediaPlayerView::OnBnClickedBtnOpen()
    {
     // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
     OnOpenRun();
     ctrVolumeSlider.ShowWindow(SW_SHOW);
     ctrPlaySlider.ShowWindow(SW_SHOW);

    }

    void CMediaPlayerView::OnBnClickedBtnBack()
    {
     // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
     OnBackRun();
    }

    void CMediaPlayerView::OnBnClickedBtnPlay()
    {
     // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
     OnPlayRun();
    }

    void CMediaPlayerView::OnBnClickedBtnStop()
    {
     // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
     OnStopRun();
    }

    void CMediaPlayerView::OnBnClickedBtnPause()
    {
     // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
     OnPauseRun();
    }

    void CMediaPlayerView::OnBnClickedBtnPre()
    {
     // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
     OnPreRun();
    }

    HRESULT CMediaPlayerView::OnOpenRun()
    {


     HRESULT hr ;

     // 필터그래프매니저를 제거하여 필터그래프의 누적 방지!
     if (m_pGB != NULL)
     {
    //  JIF(OnFileClose()) ;
     }

     CString strPath;
     CFileDialog dlg(TRUE);
     if( dlg.DoModal() == IDOK)
     {
      strPath  = dlg.GetPathName();
      strFileName = dlg.GetFileName();
    //  UpadateData(false);
     }

     lstrcpy(m_szFileName, strPath); // ANSI...

     // Retrieve the name of the selected file
     WCHAR wFileName[MAX_PATH] ;

    #ifndef UNICODE
      MultiByteToWideChar(CP_ACP, 0, m_szFileName, -1, wFileName, MAX_PATH) ;
    #else
      lstrcpy(wFileName, m_szFileName);
    #endif


        // Clear open dialog remnants before calling RenderFile()
     AfxGetMainWnd()->SetWindowText(m_szFileName) ;

    /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    이부분은 동영상 재싱 시간을 출력 하기 위해서 정의해 놓은 함수 이다.
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/

     KillTimer( TIMER_ID_TIMECHECK );
     SetTimer( TIMER_ID_TIMECHECK, 1000, NULL );

    /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/
     // 필터그래프매니저 생성 (멤버 변수로 보관)
        // Get the interface for DirectShow's GraphBuilder
        JIF(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&m_pGB)) ;


     /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/
     /* 이부분은 다이얼로그 베이스로 만들었을때... 원하는 부분에.. 동영상을
     재생하기 위해서 정의해 놓은 코드 이다.*/
     /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/
     
     GetDlgItem(IDC_PLAY_VIEW, &playView);

     /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/
     
     // Render File ...
     // Have the graph construct its the appropriate graph automatically
     // 필터 그래프 매니져 : NULL Rendering...
     JIF(m_pGB->RenderFile(wFileName, NULL)) ;
     
     // 비디오창 인터페이스 요청
     // Query for video interfaces
     IVideoWindow * pVW ;
     JIF(m_pGB->QueryInterface(IID_IVideoWindow, (void **)&pVW)) ;
     if (pVW != NULL)
     {
      /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/
      /* 동영상 출력을 원하는 부분의 핸들 값을 넘겨 준다....*/
      /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/
     
      LIF(pVW->put_Owner((OAHWND)playView)) ;

      /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/
     
      LIF(pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)) ;

      // resizing
      LIF(OnSizeRun());
     }

     // Release a interface
     SAFE_RELEASE(pVW) ;
     

    #ifdef REGISTER_FILTERGRAPH
        hr = AddGraphToRot(m_pGB, &m_dwGraphRegister) ;
        if (FAILED(hr))
        {
            TRACE(TEXT("Failed to register filter graph with ROT!  hr=0x%x"), hr) ;
            m_dwGraphRegister = 0 ;
        }
    #endif

     return S_OK ;

    }

    HRESULT CMediaPlayerView::OnBackRun()
    {
     HRESULT hr ;

     // 필터그래프매니저가 생성되지 않은 경우
     if (m_pGB == NULL)
      JIF(OnOpenRun()) ;

     // Query for media seeking interfaces
     IMediaSeeking * pMS ;
     JIF(m_pGB->QueryInterface(IID_IMediaSeeking, (void **)&pMS)) ;
     if (pMS != NULL)
     {
      // Rewind the graph to rewind the media file
      LONGLONG pos;
      LIF(pMS->GetPositions(&pos, NULL)) ;

      pos -= ONE_SECOND;
     
      LIF(pMS->SetPositions(&pos, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning)) ;
     }

     // Release a interface
     SAFE_RELEASE(pMS) ;

     return hr ;

    }

    HRESULT CMediaPlayerView::OnPlayRun()
    {
     HRESULT hr ;

     // 필터그래프매니저가 생성되지 않은 경우
     if (m_pGB == NULL)
      JIF(OnOpenRun()) ;

     // Query for media control interfaces

     //--------------- 컴포넌트 인터페이스 얻기  -----------------------
     IMediaControl * pMC ;
     JIF(m_pGB->QueryInterface(IID_IMediaControl, (void **)&pMC)) ;
     if (pMC != NULL)
     {
      // Run the graph to play the media file
      LIF(pMC->Run()) ;
     }
     // Release a interface
     SAFE_RELEASE(pMC) ;
     //-------------------------------------------------------------------


     return hr ;

    }

    HRESULT CMediaPlayerView::OnStopRun()
    {

     HRESULT hr ;

     // 필터그래프매니저가 생성되지 않은 경우
     if (m_pGB == NULL)
      JIF(OnOpenRun()) ;

     // Query for media control interfaces
     IMediaControl * pMC ;
     JIF(m_pGB->QueryInterface(IID_IMediaControl, (void **)&pMC)) ;
     if (pMC != NULL)
     {
      // Stop the graph to stop the media file
      LIF(pMC->Stop()) ;
     }

     // Query for media seeking interfaces
     IMediaSeeking * pMS ;
     JIF(m_pGB->QueryInterface(IID_IMediaSeeking, (void **)&pMS)) ;
     if (pMS != NULL)
     {
      // Go to the previous of the graph, usually the very first.
      LONGLONG pos = 0 ;
      LIF(pMS->SetPositions(&pos, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning)) ;

      // Display the first frame to indicate the reset condition
      LIF(pMC->Pause()) ;
     }

     ctrVolumeSlider.ShowWindow(SW_SHOW);
     ctrPlaySlider.ShowWindow(SW_SHOW);


     // Release a interface
     SAFE_RELEASE(pMS) ;
     // Release a interface
     SAFE_RELEASE(pMC) ;

     return hr ;
    }

    HRESULT CMediaPlayerView::OnPauseRun()
    {

     HRESULT hr ;

     // 필터그래프매니저가 생성되지 않은 경우
     if (m_pGB == NULL)
      JIF(OnOpenRun()) ;

     // Query for media control interfaces
     IMediaControl * pMC ;
     JIF(m_pGB->QueryInterface(IID_IMediaControl, (void **)&pMC)) ;
     if (pMC != NULL)
     {
      // Pause the graph to pause the media file
      LIF(pMC->Pause()) ;
     }
     // Release a interface
     SAFE_RELEASE(pMC) ;

     return hr ;
    }

    HRESULT CMediaPlayerView::OnPreRun()
    {

     HRESULT hr ;

     // 필터그래프매니저가 생성되지 않은 경우
     if (m_pGB == NULL)
      JIF(OnOpenRun()) ;

     // Query for media seeking interfaces
     IMediaSeeking * pMS ;
     JIF(m_pGB->QueryInterface(IID_IMediaSeeking, (void **)&pMS)) ;
     if (pMS != NULL)
     {
      // Fastforward the graph to fastforward the media file
      LONGLONG pos;
      LIF(pMS->GetPositions(&pos, NULL)) ;

      pos += ONE_SECOND;
      LIF(pMS->SetPositions(&pos, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning)) ;
     }
     // Release a interface
     SAFE_RELEASE(pMS) ;

     return hr ;
    }


    //------------------------------------------------------------------------------
    // Name: CWindowmovieApp::OnSize()
    // Desc: This method manipulate WM_SIZE events
    //------------------------------------------------------------------------------

    HRESULT CMediaPlayerView::OnSizeRun()
    {
     if (m_pGB == NULL)
      return E_ABORT ;

     HRESULT hr ;

     IVideoWindow * pVW;
     JIF(m_pGB->QueryInterface(IID_IVideoWindow, (void **)&pVW));
     if (pVW != NULL)
     {
      // Track the movement of the container window and resize as needed
     // RECT rcToolbar;
     // GetWindowRect(&rcToolbar);
     // int nToolbarHeight = rcToolbar.bottom - rcToolbar.top;

      RECT rect;
      ::GetClientRect(playView, &rect);
      LIF(pVW->SetWindowPosition(rect.left, rect.top,
       rect.right - rect.left, rect.bottom -rect.top));
     }


     // Release a interface
     SAFE_RELEASE(pVW);

     return hr;
    }


    //------------------------------------------------------------------------------
    // Name: CWindowmovieApp::XXXFullScreen()
    // Desc: This method will enter and exit fullscreen mode depending on the bool
    //       value.  We don't use IVideoWindow->putFullScreenMode because
    //       it won't handle the mouse correctly.
    //------------------------------------------------------------------------------

    HRESULT CMediaPlayerView::ToggleFullScreen()
    {
        return false == m_bFullScreenOn ? StartFullScreen() : StopFullScreen() ;
    }

    HRESULT CMediaPlayerView::StartFullScreen()
    {
     if (m_pGB == NULL)
      return E_ABORT ;

     HRESULT hr ;

     // Query for video interfaces
     IVideoWindow * pVW ;
     JIF(m_pGB->QueryInterface(IID_IVideoWindow, (void **)&pVW)) ;
     if (!pVW)
      return E_FAIL ;

     // store the original window position
     long lLeft, lTop, lWidth, lHeight ;
     JIF(pVW->GetWindowPosition(&lLeft, &lTop, &lWidth, &lHeight)) ;
     SetRect(&m_rectOrgVideo, lLeft, lTop, lLeft + lWidth, lTop + lHeight) ;

     // save the original window style
     JIF(pVW->get_WindowStyle(&m_lOrgStyle)) ;
     JIF(pVW->get_WindowStyleEx(&m_lOrgStyleEx)) ;

     // the window can't be a child while it is full screen
     // or it can't be stretched beyond the parent window's borders
     JIF(pVW->put_Owner(NULL)) ;
     JIF(pVW->put_MessageDrain((OAHWND)playView)) ;

     // modify the window's style
     // ... remove these styles
     JIF(pVW->put_WindowStyle(m_lOrgStyle & ~(WS_BORDER|WS_CAPTION|WS_THICKFRAME))) ;
     // ... remove these extended styles
     JIF(pVW->put_WindowStyleEx(m_lOrgStyleEx \
      & ~(WS_EX_CLIENTEDGE|WS_EX_STATICEDGE|WS_EX_WINDOWEDGE|WS_EX_DLGMODALFRAME) \
      | WS_EX_TOPMOST)) ;

     // stretch the window to the full size of the screen
     long lScrnWidth = GetSystemMetrics(SM_CXSCREEN) ;
     long lScrnHeight = GetSystemMetrics(SM_CYSCREEN) ;
     JIF(pVW->SetWindowPosition(0, 0, lScrnWidth, lScrnHeight)) ;

     ::ShowCursor(FALSE) ; // make sure to show mouse now
     m_bFullScreenOn = true;

     // Release a interface
     SAFE_RELEASE(pVW) ;

     return true ;
    }

    HRESULT CMediaPlayerView::StopFullScreen()
    {

     if (m_pGB == NULL)
      return E_ABORT ;

     HRESULT hr ;

     // Query for video interfaces
     IVideoWindow * pVW ;
     JIF(m_pGB->QueryInterface(IID_IVideoWindow, (void **)&pVW)) ;
     if (!(pVW != NULL))
      return E_FAIL ;

     // Track the movement of the container window and resize as needed
    // RECT rcToolbar;
    // GetWindowRect(m_hwndToolBar, &rcToolbar);
    // int nToolbarHeight = rcToolbar.bottom - rcToolbar.top ;

     // restore the window's position
     RECT rect;
     ::GetClientRect(playView, &rect);
     JIF(pVW->SetWindowPosition(0, 0, rect.right, rect.bottom)) ;

     // make it a child window again
     JIF(pVW->put_Owner(reinterpret_cast<OAHWND>(playView))) ;

     // restore the window's styles
     // ... restore the styles
     JIF(pVW->put_WindowStyle(m_lOrgStyle)) ;
     // ... restore the extended styles
     JIF(pVW->put_WindowStyleEx(m_lOrgStyleEx)) ;

     ::ShowCursor(TRUE) ;  // make sure to show mouse now
     m_bFullScreenOn = false;

     AfxGetMainWnd()->SetForegroundWindow() ;
     AfxGetMainWnd()->SetFocus() ;

     /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/
     /*풀스크린 모드에서 다시 돌아올 경우.. 동영상 출력을 하지 못하는 경우가
     생기는데... 그 문제를 해결하기 위해서 정의된 코드 이다.*/
     /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/
     SendMessage(VK_ESCAPE, VK_ESCAPE);
     // Release a interface
     
     UpdateWindow();

     /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/
     SAFE_RELEASE(pVW) ;

     return true ;
    }

    BOOL CMediaPlayerView::PreTranslateMessage(MSG* pMsg)
    {
     // TODO: 여기에 특수화된 코드를 추가 및/또는 기본 클래스를 호출합니다.

     switch(pMsg->wParam)
     {
     case VK_F:
      StartFullScreen();
      break;
     case VK_ESCAPE:
      StopFullScreen();
      break;
     case VK_DOWN:
      m_POS -= 10;
      ctrVolumeSlider.SetPos(m_POS);
      OnVolume(false);
      break ;
     case VK_UP:
      m_POS += 10;
      ctrVolumeSlider.SetPos(m_POS);
      OnVolume(true);
      break ;

     }
     
     return CFormView::PreTranslateMessage(pMsg);
    }

    HRESULT CMediaPlayerView::OnVolume(bool bUp)
    {
     if (m_pGB == NULL)
      return E_ABORT;

     HRESULT hr ;

     // Query audio interface
     IBasicAudio * pBA;
     JIF(m_pGB->QueryInterface(IID_IBasicAudio, (void **)&pBA)) ;
     if (!pBA)
      return E_FAIL ;

     //----------------------------------
     // fPos Range: (0 ~ 1)
     // lfVolume Range: (-10,000 ~ 0)
     //----------------------------------
     float& fPos = m_fVolumePos ;
     double lfVolume ;

     fPos += (bUp ? 0.1f : -0.1f) ;

     // Saturation
     if (fPos < 0)
      fPos = 0 ;
     else if (fPos > 1)
      fPos = 1 ;
       
     // 단순 처리의 경우
     // lfVolume = (fPos - 1) * 10000 ;

     // Scaling (fPos => lfVolume)
     double lfPower10 = pow((double)10, (double)-10) ; // 10 ^ (-10)
     lfVolume = (1 - lfPower10) * fPos + lfPower10 ;
     
     lfVolume = 10 * log10(lfVolume) ; // decibel (-100dB ~ 0dB)
     lfVolume *= 100 ;     // DirectShow resolution (-10,000 ~ 0)

     // Set volume
     JIF(pBA->put_Volume((long)lfVolume)) ;

     // Release a interface
     SAFE_RELEASE(pBA);

     return hr ;
    }

    void CMediaPlayerView::OnTimer(UINT_PTR nIDEvent)
    {
     // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.

     if( nIDEvent == TIMER_ID_TIMECHECK )
     {
      OnTimerRun();
     }

     CFormView::OnTimer(nIDEvent);
    }

    /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/
    /*동영상 총 재생시간 과 현재 재생되고 있는 시간을 표시 하기위해서
    정의해 놓은 함수 이다.*/
    /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/
    HRESULT CMediaPlayerView::OnTimerRun()
    {
     if (m_pGB == NULL)
      return E_ABORT;

     HRESULT hr ;

     IMediaPosition * pMS ;
     double lCur =0 , lTotal = 0;

     JIF(m_pGB->QueryInterface(IID_IMediaPosition, (void **)&pMS)) ;

     pMS->get_CurrentPosition(&lCur);
     pMS->get_Duration(&lTotal);

     int nPos = 0;
     if( lTotal > 0 )
      nPos = int( lCur * 100 / lTotal );

     ctrPlaySlider.SetPos( nPos );
     
     CTimeSpan  m_tTotal, m_tCur;

     CTimeSpan  t0(1,1,1,(int)lTotal);
     CTimeSpan  t1(1,1,1,(int)lCur);
     CTimeSpan  t2(1,1,1,0);

     m_tTotal = t0 - t2;
     m_tCur  = t1 - t2;

     strAllTime = m_tCur.Format("%H:%M:%S");
     strPlayTime = m_tTotal.Format("%H:%M:%S");

     UpdateData(false);

     SAFE_RELEASE(pMS);

     return hr ;
    }
    /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/


    /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/
    /*동영상 재생 스크롤 바인지.. 볼륨 스크롤 바인지 구분해서...
    각각 수행하는 함수를 불러 준다.*/
    /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/
    void CMediaPlayerView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
    {
     // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.

     if((CWnd*)pScrollBar == (CWnd*)&ctrPlaySlider)
     {
      OnHScrollRun(nSBCode, nPos, pScrollBar);
     }

     else if((CWnd*)pScrollBar == (CWnd*)&ctrVolumeSlider)
     {
      OnHScrollVolume(nSBCode, nPos, pScrollBar);
     }
     CFormView::OnHScroll(nSBCode, nPos, pScrollBar);
    }
    /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/


    /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/
    /* 재생 스크롤 바를 끌었을 경우 해당 위치의 동영상을 재생하기 위한
    함수 이다.*/
    /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/
    HRESULT CMediaPlayerView::OnHScrollRun(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
    {
     if (m_pGB == NULL)
      return E_ABORT;

     HRESULT hr ;

     IMediaPosition * pMS ;
     
     JIF(m_pGB->QueryInterface(IID_IMediaPosition, (void **)&pMS)) ;

     if((CWnd*)pScrollBar == (CWnd*)&ctrPlaySlider)
     {
      if(nSBCode == SB_PAGELEFT ||nSBCode == SB_PAGERIGHT || SB_THUMBTRACK == nSBCode)
      {
       REFTIME lCur, lTotal;

       pMS->get_Duration(&lTotal);

       int nPos = ctrPlaySlider.GetPos();

       lCur = nPos * lTotal / 100;

       pMS->put_CurrentPosition(lCur);
      }
     }

     return hr ;
    }
    /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/


    /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/
    /*볼륨에 따라서 스크롤 바를 움직이기 위한 함수 이다.*/
    /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/
    HRESULT CMediaPlayerView::OnHScrollVolume(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
    {
     if (m_pGB == NULL)
      return E_ABORT;

     HRESULT hr ;

     IMediaPosition * pMS ;
     
     JIF(m_pGB->QueryInterface(IID_IMediaPosition, (void **)&pMS)) ;

     if((CWnd*)pScrollBar == (CWnd*)&ctrVolumeSlider)
     {
     
      int curPos,lastPos;
      if(m_POS>0)
      {
       curPos= ctrVolumeSlider.GetPos();

       lastPos=curPos - m_POS; //과거의 위치와 서로 빼준다

       if(lastPos>0){
        for(int upvol=0;upvol<lastPos;upvol++)
         OnVolume(TRUE);
       }
       else if(lastPos<0){
        for(int downvol=0;downvol>lastPos;downvol--)
         OnVolume(FALSE);
       }
       m_POS=curPos;
      }
      else{
       m_POS++;
      }

     }
     return hr ;
    }


    void CMediaPlayerView::OnLButtonDblClk(UINT nFlags, CPoint point)
    {
     // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.

     static int ndx;

     if(ndx == 0){
      StartFullScreen();
      ndx++;
     }
     else{
      StopFullScreen();
      ndx--;
     }

     CFormView::OnLButtonDblClk(nFlags, point);
    }



    위와 같이 각 버튼들을 클릭했을때 실행 함수를 만든다.....


    버튼을 클릭했을때.. 바로 수행 하지 않고... 함수를 호출하는 까닭은....

    vc6.0 에서는 버튼 함수에 void 타입일 HRESULT 로 바꾸어 주어도..

    아무 상관없이 돌아가지만... 2005 버전에서....

    버튼 이벤트 함수를 void 에서 HRESULT 로 바꿀 경우에는...

    에러 메시지를 발생 시킨다...

    때문에... 버튼에서 HRESULT 를 반환하는 함수를 선언해 주는 것이다....

    반응형

    "이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."