본문 바로가기
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 를 반환하는 함수를 선언해 주는 것이다....

반응형

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