// 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 를 반환하는 함수를 선언해 주는 것이다....
"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."