📄 ctrlmediaframe.cpp
字号:
COLORREF crText = RGB( 0xF0, 0xF0, 0xFF );
dc.SelectObject( &m_pFontValue );
int nY = ( rcBar.top + rcBar.bottom ) / 2 - dc.GetTextExtent( _T("Cy") ).cy / 2;
CRect rcPart( &rcBar );
CString str;
CSize sz;
int nState = 0;
if ( m_nState >= smsPlaying ) nState = 2;
else if ( m_nState >= smsPaused ) nState = 1;
ImageList_DrawEx( m_pIcons, nState, dc, rcBar.left + 2,
( rcBar.top + rcBar.bottom ) / 2 - 8, 16, 16,
crBack, CLR_NONE, ILD_NORMAL );
dc.ExcludeClipRect( rcBar.left + 2, ( rcBar.top + rcBar.bottom ) / 2 - 8,
rcBar.left + 18, ( rcBar.top + rcBar.bottom ) / 2 + 8 );
dc.SetBkMode( OPAQUE );
dc.SetBkColor( crBack );
dc.SetTextColor( crText );
if ( CMetaItem* pItem = m_pMetadata.GetFirst() )
{
dc.SelectObject( &m_pFontKey );
sz = dc.GetTextExtent( pItem->m_sKey + ':' );
rcPart.left = rcBar.left + 20;
rcPart.right = rcPart.left + sz.cx + 8;
dc.ExtTextOut( rcPart.left + 4, nY, ETO_CLIPPED|ETO_OPAQUE, &rcPart, pItem->m_sKey + ':', NULL );
dc.ExcludeClipRect( &rcPart );
dc.SelectObject( &m_pFontValue );
sz = dc.GetTextExtent( pItem->m_sValue );
rcPart.left = rcPart.right;
rcPart.right = rcPart.left + sz.cx + 8;
dc.ExtTextOut( rcPart.left + 4, nY, ETO_CLIPPED|ETO_OPAQUE, &rcPart, pItem->m_sValue, NULL );
dc.ExcludeClipRect( &rcPart );
}
else
{
if ( m_nState >= smsOpen )
{
int nSlash = m_sFile.ReverseFind( '\\' );
str = nSlash >= 0 ? m_sFile.Mid( nSlash + 1 ) : m_sFile;
}
else
{
LoadString( str, IDS_MEDIA_EMPTY );
}
sz = dc.GetTextExtent( str );
rcPart.left = rcBar.left + 20;
rcPart.right = rcPart.left + sz.cx + 8;
dc.ExtTextOut( rcPart.left + 4, nY, ETO_CLIPPED|ETO_OPAQUE, &rcPart, str, NULL );
dc.ExcludeClipRect( &rcPart );
}
if ( m_nState >= smsOpen )
{
str.Format( _T("%.2i:%.2i of %.2i:%.2i"),
(int)( ( m_nPosition / ONE_SECOND ) / 60 ),
(int)( ( m_nPosition / ONE_SECOND ) % 60 ),
(int)( ( m_nLength / ONE_SECOND ) / 60 ),
(int)( ( m_nLength / ONE_SECOND ) % 60 ) );
sz = dc.GetTextExtent( str );
rcPart.right = rcBar.right;
rcPart.left = rcPart.right - sz.cx - 8;
dc.ExtTextOut( rcPart.left + 4, nY, ETO_CLIPPED|ETO_OPAQUE, &rcPart, str, NULL );
dc.ExcludeClipRect( &rcPart );
}
dc.FillSolidRect( &rcBar, crBack );
dc.SelectObject( &m_pFontDefault );
}
BOOL CMediaFrame::PaintStatusMicro(CDC& dc, CRect& rcBar)
{
if ( m_nState <= smsOpen ) return FALSE;
CRect rcStatus( &rcBar );
CRect rcPart( &rcBar );
CString str;
CSize sz;
if ( m_nState >= smsOpen )
{
str.Format( _T("%.2i:%.2i of %.2i:%.2i"),
(int)( ( m_nPosition / ONE_SECOND ) / 60 ),
(int)( ( m_nPosition / ONE_SECOND ) % 60 ),
(int)( ( m_nLength / ONE_SECOND ) / 60 ),
(int)( ( m_nLength / ONE_SECOND ) % 60 ) );
sz = dc.GetTextExtent( str );
rcPart.right = rcStatus.right;
rcPart.left = rcPart.right - sz.cx - 2;
rcStatus.right = rcPart.left;
dc.DrawText( str, &rcPart, DT_SINGLELINE|DT_VCENTER|DT_NOPREFIX|DT_RIGHT );
}
if ( CMetaItem* pItem = m_pMetadata.GetFirst() )
{
sz = dc.GetTextExtent( pItem->m_sKey + ':' );
rcPart.left = rcStatus.left;
rcPart.right = rcPart.left + sz.cx + 2;
rcStatus.left = rcPart.right;
dc.DrawText( pItem->m_sKey + ':', &rcPart, DT_SINGLELINE|DT_VCENTER|DT_LEFT|DT_NOPREFIX );
dc.DrawText( pItem->m_sValue, &rcStatus, DT_SINGLELINE|DT_VCENTER|DT_LEFT|DT_NOPREFIX|DT_END_ELLIPSIS );
}
else
{
if ( m_nState >= smsOpen )
{
int nSlash = m_sFile.ReverseFind( '\\' );
str = nSlash >= 0 ? m_sFile.Mid( nSlash + 1 ) : m_sFile;
}
dc.DrawText( str, &rcStatus, DT_SINGLELINE|DT_VCENTER|DT_LEFT|DT_NOPREFIX|DT_END_ELLIPSIS );
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CMediaFrame interaction message handlers
void CMediaFrame::OnContextMenu(CWnd* pWnd, CPoint point)
{
Skin.TrackPopupMenu( _T("CMediaFrame"), point,
m_nState == smsPlaying ? ID_MEDIA_PAUSE : ID_MEDIA_PLAY );
}
void CMediaFrame::OnTimer(UINT nIDEvent)
{
if ( nIDEvent == 1 )
{
DWORD tNow = GetTickCount();
UpdateState();
if ( m_bFullScreen && ! m_bListVisible )
{
CPoint ptCursor;
GetCursorPos( &ptCursor );
if ( ptCursor != m_ptCursor )
{
m_tBarTime = tNow;
m_ptCursor = ptCursor;
SetTimer( 2, 50, NULL );
}
}
if ( tNow - m_tMetadata > META_DELAY )
{
m_tMetadata = tNow;
m_pMetadata.Shuffle();
}
}
else if ( nIDEvent == 2 )
{
OnSize( SIZE_BARSLIDE, 0, 0 );
}
}
void CMediaFrame::OnClose()
{
SetFullScreen( FALSE );
}
BOOL CMediaFrame::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if ( m_bListVisible )
{
CRect rcClient, rc;
CPoint point;
GetCursorPos( &point );
GetClientRect( &rcClient );
ClientToScreen( &rcClient );
rc.SetRect( rcClient.right - m_nListSize - SPLIT_SIZE,
rcClient.top,
rcClient.right - m_nListSize,
rcClient.bottom );
if ( rc.PtInRect( point ) )
{
SetCursor( AfxGetApp()->LoadStandardCursor( IDC_SIZEWE ) );
return TRUE;
}
}
else if ( m_bFullScreen )
{
DWORD tElapse = GetTickCount() - m_tBarTime;
if ( tElapse > TOOLBAR_STICK + TOOLBAR_ANIMATE )
{
SetCursor( NULL );
return TRUE;
}
}
return CWnd::OnSetCursor( pWnd, nHitTest, message );
}
void CMediaFrame::OnLButtonDown(UINT nFlags, CPoint point)
{
CRect rcClient;
GetClientRect( &rcClient );
if ( m_bListVisible )
{
CRect rcBar( rcClient.right - m_nListSize - SPLIT_SIZE,
rcClient.top,
rcClient.right - m_nListSize,
rcClient.bottom );
if ( rcBar.PtInRect( point ) )
{
DoSizeList();
return;
}
}
if ( ( m_bFullScreen && point.y <= STATUS_HEIGHT ) ||
( ! m_bFullScreen && point.y >= rcClient.bottom - STATUS_HEIGHT - TOOLBAR_HEIGHT ) )
{
OnMediaStatus();
return;
}
if ( m_nState == smsPlaying )
OnMediaPause();
else if ( m_nState == smsPaused )
OnMediaPlay();
CWnd::OnLButtonDown( nFlags, point );
}
void CMediaFrame::OnLButtonDblClk(UINT nFlags, CPoint point)
{
OnMediaFullScreen();
if ( m_nState == smsPlaying )
OnMediaPause();
else if ( m_nState == smsPaused )
OnMediaPlay();
CWnd::OnLButtonDblClk( nFlags, point );
}
BOOL CMediaFrame::DoSizeList()
{
MSG* pMsg = &AfxGetThreadState()->m_msgCur;
CRect rcClient;
CPoint point;
GetClientRect( &rcClient );
ClientToScreen( &rcClient );
ClipCursor( &rcClient );
SetCapture();
GetClientRect( &rcClient );
int nOffset = 0xFFFF;
while ( GetAsyncKeyState( VK_LBUTTON ) & 0x8000 )
{
while ( ::PeekMessage( pMsg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE ) );
if ( ! AfxGetThread()->PumpMessage() )
{
AfxPostQuitMessage( 0 );
break;
}
GetCursorPos( &point );
ScreenToClient( &point );
int nSplit = rcClient.right - point.x;
if ( nOffset == 0xFFFF ) nOffset = m_nListSize - nSplit;
nSplit += nOffset;
nSplit = max( nSplit, 0 );
nSplit = min( nSplit, rcClient.right - SPLIT_SIZE );
if ( nSplit < 8 )
nSplit = 0;
if ( nSplit > rcClient.right - SPLIT_SIZE - 8 )
nSplit = rcClient.right - SPLIT_SIZE;
if ( nSplit != m_nListSize )
{
m_nListSize = nSplit;
OnSize( SIZE_INTERNAL, 0, 0 );
Invalidate();
}
}
ReleaseCapture();
ClipCursor( NULL );
return TRUE;
}
LONG CMediaFrame::OnMediaKey(WPARAM wParam, LPARAM lParam)
{
if ( wParam != 1 ) return 0;
switch ( lParam )
{
case 0xB0000:
GetOwner()->PostMessage( WM_COMMAND, ID_MEDIA_NEXT );
return 1;
case 0xC0000:
GetOwner()->PostMessage( WM_COMMAND, ID_MEDIA_PREVIOUS );
return 1;
case 0xD0000:
GetOwner()->PostMessage( WM_COMMAND, ID_MEDIA_STOP );
return 1;
case 0xE0000:
GetOwner()->PostMessage( WM_COMMAND, m_nState == smsPlaying ? ID_MEDIA_PAUSE : ID_MEDIA_PLAY );
return 1;
}
return 0;
}
/////////////////////////////////////////////////////////////////////////////
// CMediaFrame thumb bars
void CMediaFrame::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if ( pScrollBar == (CScrollBar*)&m_wndVolume )
{
double nVolume = (double)m_wndVolume.GetPos() / 100.0f;
if ( nVolume != Settings.MediaPlayer.Volume )
{
Settings.MediaPlayer.Volume = nVolume;
if ( m_pPlayer != NULL ) m_pPlayer->SetVolume( m_bMute ? 0 : Settings.MediaPlayer.Volume );
}
}
if ( m_pPlayer == NULL ) return;
MediaState nState = smsNull;
if ( FAILED( m_pPlayer->GetState( &nState ) ) ) return;
if ( nState < smsOpen ) return;
if ( pScrollBar == (CScrollBar*)&m_wndPosition )
{
LONGLONG nLength = 0;
if ( FAILED( m_pPlayer->GetLength( &nLength ) ) ) return;
nLength /= TIME_FACTOR;
LONGLONG nPosition = 0;
if ( FAILED( m_pPlayer->GetPosition( &nPosition ) ) ) return;
nPosition /= TIME_FACTOR;
switch ( nSBCode )
{
case TB_TOP:
nPosition = 0;
break;
case TB_BOTTOM:
nPosition = nLength;
break;
case TB_LINEUP:
nPosition -= 5;
break;
case TB_LINEDOWN:
nPosition += 5;
break;
case TB_PAGEUP:
case TB_PAGEDOWN:
if ( TRUE )
{
CRect rc1, rc2;
CPoint pt;
GetCursorPos( &pt );
pScrollBar->GetWindowRect( &rc1 );
((CSliderCtrl*)pScrollBar)->GetChannelRect( &rc2 );
if ( rc1.PtInRect( pt ) )
{
rc2.OffsetRect( rc1.left, rc1.top );
if ( pt.x <= rc2.left )
nPosition = 0;
else if ( pt.x >= rc2.right )
nPosition = nLength;
else
nPosition = (LONGLONG)( (double)( pt.x - rc2.left ) / (double)rc2.Width() * (double)nLength );
}
}
break;
case TB_THUMBPOSITION:
case TB_THUMBTRACK:
nPosition = (int)nPos;
break;
}
if ( nState == smsOpen ) nPosition = 0;
if ( nPosition < 0 ) nPosition = 0;
if ( nPosition > nLength ) nPosition = nLength;
if ( nState == smsPlaying )
{
m_pPlayer->Pause();
m_bThumbPlay = TRUE;
}
m_pPlayer->SetPosition( nPosition * TIME_FACTOR );
m_wndPosition.SetPos( (int)nPosition );
if ( m_bThumbPlay && nSBCode == TB_ENDTRACK )
{
m_pPlayer->Play();
m_bThumbPlay = FALSE;
}
UpdateState();
UpdateWindow();
}
else if ( pScrollBar == (CScrollBar*)&m_wndSpeed )
{
double nNewSpeed = (double)m_wndSpeed.GetPos() / 100.0f;
double nOldSpeed;
if ( nSBCode == TB_TOP || nSBCode == TB_BOTTOM )
{
nNewSpeed = 1.0f;
m_wndSpeed.SetPos( 100 );
}
m_pPlayer->GetSpeed( &nOldSpeed );
if ( nNewSpeed != nOldSpeed ) m_pPlayer->SetSpeed( nNewSpeed );
}
}
/////////////////////////////////////////////////////////////////////////////
// CMediaFrame command handlers
void CMediaFrame::OnUpdateMediaClose(CCmdUI* pCmdUI)
{
pCmdUI->Enable( m_wndList.GetItemCount() > 0 );
}
void CMediaFrame::OnMediaClose()
{
Cleanup();
m_wndList.Clear();
}
void CMediaFrame::OnUpdateMediaPlay(CCmdUI* pCmdUI)
{
MediaState nState = m_nState;
if ( m_bThumbPlay && nState == smsPaused ) nState = smsPlaying;
pCmdUI->Enable( m_nState < smsPlaying );
if ( CCoolBarItem* pItem = CCoolBarItem::FromCmdUI( pCmdUI ) )
pItem->Show( nState != smsPlaying );
}
void CMediaFrame::OnMediaPlay()
{
if ( m_nState < smsOpen )
{
PostMessage( WM_COMMAND, ID_MEDIA_OPEN );
}
else
{
if ( m_pPlayer != NULL ) m_pPlayer->Play();
UpdateState();
}
}
void CMediaFrame::OnUpdateMediaPause(CCmdUI* pCmdUI)
{
MediaState nState = m_nState;
if ( m_bThumbPlay && nState == smsPaused ) nState = smsPlaying;
pCmdUI->Enable( nState == smsPlaying );
if ( CCoolBarItem* pItem = CCoolBarItem::FromCmdUI( pCmdUI ) )
pItem->Show( nState == smsPlaying );
}
void CMediaFrame::OnMediaPause()
{
if ( m_pPlayer ) m_pPlayer->Pause();
UpdateState();
}
void CMediaFrame::OnUpdateMediaStop(CCmdUI* pCmdUI)
{
pCmdUI->Enable( m_nState > smsOpen );
}
void CMediaFrame::OnMediaStop()
{
// if ( m_pPlayer ) m_pPlayer->Stop();
m_bAutoPlay = FALSE;
m_wndList.Reset();
m_bAutoPlay = TRUE;
}
void CMediaFrame::OnUpdateMediaFullScreen(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck( m_bFullScreen );
}
void CMediaFrame::OnMediaFullScreen()
{
SetFullScreen( ! m_bFullScreen );
}
void CMediaFrame::OnMediaZoom()
{
CMenu* pMenu = Skin.GetMenu( _T("CMediaFrame.Zoom") );
m_wndToolBar.ThrowMenu( ID_MEDIA_ZOOM, pMenu );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -