📄 xaplayer.cpp
字号:
/*****************************************************************
|
| Xaudio Player for Windows CE
|
| (c) 1996-1998 MpegTV, LLC
| Author: Gilles Boccon-Gibod (gilles@mpegtv.com)
|
****************************************************************/
/*----------------------------------------------------------------------
| includes
+---------------------------------------------------------------------*/
#ifndef STRICT
#define STRICT
#endif
#include "xaplayer.h"
#include <commctrl.h>
#include "xaudio.h"
#include "player.h"
#include "XaudioPlayer.h"
#include "ceutils.h"
#include "xaplayer.h"
#include "listview.h"
#include "trackview.h"
#include "files.h"
#include "options.h"
#include "perf.h"
#include "volume.h"
#include "about.h"
/*----------------------------------------------------------------------
| constants
+---------------------------------------------------------------------*/
const int XA_MAX_FILENAME = 1024;
const int XA_STATUS_WINDOW_ID = 3333;
const int XA_TRACK_SLIDER_X = 46;
const int XA_TRACK_SLIDER_Y = 0;
const int XA_TRACK_SLIDER_HEIGHT = 24;
const int XA_TRACKVIEW_HEIGHT = 45;
const int XA_ID_COMMAND_BANDS = 100;
const int XA_ID_MENU_BAND = 101;
const int XA_ID_CONTROL_BAND = 102;
const int XA_ID_AUX_BAND = 103;
/*----------------------------------------------------------------------
| globals
+---------------------------------------------------------------------*/
TCHAR AppName[128];
TCHAR AppTitle[128];
WCEPlayer *Player;
/*----------------------------------------------------------------------
| SliderProc
+---------------------------------------------------------------------*/
LRESULT CALLBACK
SliderProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
{
WCEPlayer *player = (WCEPlayer *)GetWindowLong(window, GWL_USERDATA);
switch (message) {
case WM_HSCROLL:
switch (LOWORD(wparam)) {
case SB_LINELEFT:
case SB_LINERIGHT:
case SB_PAGELEFT:
case SB_PAGERIGHT:
if (player->m_Scrolling == FALSE) {
player->m_Scrolling = TRUE;
player->Pause();
}
break;
case SB_ENDSCROLL:
player->Seek(SendMessage(player->m_TrackSlider,
TBM_GETPOS, 0, 0),
player->m_TrackSliderRange);
if (player->m_Scrolling) {
player->m_Scrolling = FALSE;
if (player->m_State == XA_PLAYER_STATE_PLAYING) {
player->Play();
}
}
break;
case SB_THUMBTRACK:
if (player->m_Scrolling == FALSE) {
player->m_Scrolling = TRUE;
player->Pause();
}
// fallthrough
case SB_THUMBPOSITION:
player->Seek(HIWORD(wparam), player->m_TrackSliderRange);
break;
}
break;
default:
return CallWindowProc((WNDPROC)player->m_TrackCommandBarOriginalProc,
window, message, wparam, lparam);
}
return 0;
}
/*----------------------------------------------------------------------
| WCEPlayer contructor
+---------------------------------------------------------------------*/
WCEPlayer::WCEPlayer(HINSTANCE instance) :
XaudioPlayer(instance),
m_Instance(instance),
m_State(XA_PLAYER_STATE_STOPPED)
{
m_Track.duration = 0;
m_Track.timecode.h = 0;
m_Track.timecode.m = 0;
m_Track.timecode.s = 0;
m_Track.timecode.f = 0;
m_Scrolling = FALSE;
m_Volume = 0;
}
/*----------------------------------------------------------------------
| WCEPlayer::InitUserInterface
+---------------------------------------------------------------------*/
void
WCEPlayer::InitUserInterface(HWND window)
{
// store window handle
m_MainWindow = window;
// init the window classes
INITCOMMONCONTROLSEX init_info;
init_info.dwSize = sizeof(init_info);
init_info.dwICC =
ICC_BAR_CLASSES |
ICC_COOL_CLASSES |
ICC_BAR_CLASSES |
ICC_LISTVIEW_CLASSES;
InitCommonControlsEx(&init_info);
//InitCommonControls();
// create the command bands
m_CommandBands = CommandBands_Create(m_Instance, m_MainWindow,
XA_ID_COMMAND_BANDS,
RBS_VARHEIGHT | RBS_BANDBORDERS,
NULL);
// create the bands
REBARBANDINFO info[3];
info[0].cbSize = sizeof(REBARBANDINFO);
info[0].fMask = RBBIM_ID | RBBIM_STYLE;
info[0].fStyle = RBBS_NOGRIPPER;
info[0].wID = XA_ID_MENU_BAND;
info[1].cbSize = sizeof(REBARBANDINFO);
info[1].fMask = RBBIM_ID | RBBIM_STYLE;
info[1].fStyle = 0;
info[1].wID = XA_ID_AUX_BAND;
info[2].cbSize = sizeof(REBARBANDINFO);
info[2].fMask = RBBIM_ID | RBBIM_STYLE;
info[2].fStyle = RBBS_BREAK | RBBS_NOGRIPPER;
info[2].wID = XA_ID_CONTROL_BAND;
CommandBands_AddBands(m_CommandBands, m_Instance, sizeof(info)/sizeof(REBARBANDINFO), info);
// setup the first band (menu bar)
m_MenuCommandBar = CommandBands_GetCommandBar(m_CommandBands, 0);
CommandBar_InsertMenubar(m_MenuCommandBar, m_Instance, IDM_MAIN_MENU, 0);
// setup the second band (aux)
TBBUTTON toolbar_buttons[] = {
{0, IDM_VOLUME, TBSTATE_ENABLED, TBSTYLE_BUTTON | TBSTYLE_DROPDOWN , 0, 0, 0},
};
m_TopCommandBar = CommandBands_GetCommandBar(m_CommandBands, 1);
CommandBar_AddBitmap(m_TopCommandBar, m_Instance, IDB_TOOLBAR_BITMAPS, 1, 0, 0);
CommandBar_AddButtons(m_TopCommandBar, sizeof(toolbar_buttons)/sizeof(TBBUTTON), toolbar_buttons);
// setup the third band (track)
TBBUTTON track_buttons[] = {
{0, IDM_PLAY, 0, TBSTYLE_BUTTON, 0, 0, 0},
{1, IDM_STOP, 0, TBSTYLE_BUTTON, 0, 0, 0},
};
m_TrackCommandBar = CommandBands_GetCommandBar(m_CommandBands, 2);
CommandBar_AddBitmap(m_TrackCommandBar, m_Instance, IDB_TRACK_TOOLBAR_BITMAPS, 3, 0, 0);
CommandBar_AddButtons(m_TrackCommandBar, sizeof(track_buttons)/sizeof(TBBUTTON), track_buttons);
// set the command bands parameters
CommandBands_AddAdornments(m_CommandBands, m_Instance, 0, NULL);
// extend the slider to then end of the bar
RECT bounds;
GetWindowRect(m_TrackCommandBar, &bounds);
m_TrackSliderWidth = bounds.right-bounds.left - XA_TRACK_SLIDER_X;
m_TrackSliderRange = m_TrackSliderWidth;
// set notification range
Player->SetInputPositionRange(m_TrackSliderRange);
// subclass the track command bar to trap slider messages
SetWindowLong(m_TrackCommandBar, GWL_USERDATA, (LONG)this);
Player->m_TrackCommandBarOriginalProc =
GetWindowLong(m_TrackCommandBar, GWL_WNDPROC);
SetWindowLong(m_TrackCommandBar, GWL_WNDPROC, (LONG)SliderProc);
// create the track slider
m_TrackSlider = CreateWindow(
TRACKBAR_CLASS,
NULL,
WS_CHILD |
WS_VISIBLE |
WS_DISABLED |
TBS_BOTH |
TBS_NOTICKS,
XA_TRACK_SLIDER_X,
XA_TRACK_SLIDER_Y,
m_TrackSliderWidth,
XA_TRACK_SLIDER_HEIGHT,
m_TrackCommandBar,
NULL,
m_Instance,
NULL);
SendMessage(m_TrackSlider, TBM_SETRANGE, 0, MAKELONG(0, m_TrackSliderRange));
// get client rect for views positionning
RECT client_rect;
GetClientRect(m_MainWindow, &client_rect);
client_rect.top += CommandBands_Height(m_CommandBands);
// create a status window
m_StatusWindow = CreateStatusWindow(
WS_CHILD,
NULL,
m_MainWindow,
XA_STATUS_WINDOW_ID);
int widths[4] = {60, 120, 180, -1};
SendMessage(m_StatusWindow, SB_SETPARTS, 4, (LPARAM)widths);
SendMessage(m_StatusWindow, SB_SETTEXT, 0, (LPARAM)TEXT("STOPPED"));
SendMessage(m_StatusWindow, SB_SETTEXT, 1, (LPARAM)TEXT("00:00:00"));
SendMessage(m_StatusWindow, SB_SETTEXT, 2, (LPARAM)TEXT("00:00:00"));
{
ShowWindow(m_StatusWindow, SW_SHOW);
RECT status_bounds;
GetWindowRect(m_StatusWindow, &status_bounds);
client_rect.bottom = status_bounds.top;
}
// create the track view
m_TrackView = new TrackView(m_MainWindow, this,
0, client_rect.top ,
bounds.right-bounds.left,
XA_TRACKVIEW_HEIGHT);
m_TrackView->Show();
client_rect.top += XA_TRACKVIEW_HEIGHT;
// create the list view
m_ListView = new ListView(m_MainWindow, this,
0, client_rect.top,
bounds.right-bounds.left,
client_rect.bottom - client_rect.top);
}
/*----------------------------------------------------------------------
| WCEPlayer::UpdateViews
+---------------------------------------------------------------------*/
void
WCEPlayer::UpdateViews()
{
// get client rect for views positionning
RECT client_rect;
GetClientRect(m_MainWindow, &client_rect);
client_rect.top += CommandBands_Height(m_CommandBands);
ShowWindow(m_StatusWindow, SW_SHOW);
RECT status_bounds;
GetWindowRect(m_StatusWindow, &status_bounds);
client_rect.bottom = status_bounds.top;
m_TrackView->Show();
// change the size of the list view
m_ListView->SetBounds(0, client_rect.top,
client_rect.right-client_rect.left,
client_rect.bottom - client_rect.top);
}
/*----------------------------------------------------------------------
| WCEPlayer::SetOutputDeviceFromOptions
+---------------------------------------------------------------------*/
void
WCEPlayer::SetOutputDeviceFromOptions()
{
char device_name[] = "/dev/wave/0";
if (m_Options.m_Output.device == 0) {
device_name[10] = '-';
} else {
device_name[10] = '0' + m_Options.m_Output.device - 1;
}
Player->SetOutputName(device_name);
}
/*----------------------------------------------------------------------
| WCEPlayer::SetVolume
+---------------------------------------------------------------------*/
void
WCEPlayer::SetVolume(int volume)
{
if (volume > 100) volume = 100;
if (volume < 0) volume = 0;
Player->SetOutputVolume(XA_OUTPUT_VOLUME_IGNORE_FIELD,
volume,
XA_OUTPUT_VOLUME_IGNORE_FIELD);
OnNotifyOutputPcmLevel(volume);
}
/*----------------------------------------------------------------------
| WCEPlayer::OnNotifyNack
+---------------------------------------------------------------------*/
void
WCEPlayer::OnNotifyNack(XA_NackInfo *info)
{
TCHAR message[256];
const char *xaudio_message_a = xaudio_error_string(info->code);
TCHAR xaudio_message_w[256];
A2WConvert(xaudio_message_w, xaudio_message_a, 256);
/* some errors are not worth showing */
if (info->command == XA_MSG_SET_OUTPUT_VOLUME ||
info->command == XA_MSG_COMMAND_INPUT_CLOSE ||
info->command == XA_MSG_COMMAND_STOP) return;
swprintf(message, TEXT("Command %d failed\n[%s]"),
info->command,
xaudio_message_w);
MessageBox(NULL, message, TEXT("Xaudio Command Failed"),
MB_OK | MB_ICONSTOP);
}
/*----------------------------------------------------------------------
| WCEPlayer::OnNotifyPlayerState
+---------------------------------------------------------------------*/
void
WCEPlayer::OnNotifyPlayerState(XA_PlayerState state)
{
TCHAR *state_text = TEXT("");
// remember the state
if (m_Scrolling && state == XA_PLAYER_STATE_PAUSED) return;
TBBUTTONINFO button;
button.cbSize = sizeof(button);
button.dwMask = TBIF_COMMAND | TBIF_IMAGE;
switch (state) {
case XA_PLAYER_STATE_PLAYING:
// first button shows "pause"
button.idCommand = IDM_PAUSE;
button.iImage = 2;
SendMessage(m_TrackCommandBar,
TB_SETBUTTONINFO,
IDM_PLAY,
(LPARAM)&button);
m_ListView->SetPlaying(true);
state_text = TEXT("PLAYING");
break;
case XA_PLAYER_STATE_STOPPED:
// first button shows "play"
button.idCommand = IDM_PLAY;
button.iImage = 0;
SendMessage(m_TrackCommandBar,
TB_SETBUTTONINFO,
IDM_PAUSE,
(LPARAM)&button);
state_text = TEXT("STOPPED");
m_ListView->SetPlaying(false);
break;
case XA_PLAYER_STATE_PAUSED:
// first button shows "play"
button.idCommand = IDM_PLAY;
button.iImage = 0;
SendMessage(m_TrackCommandBar,
TB_SETBUTTONINFO,
IDM_PAUSE,
(LPARAM)&button);
break;
case XA_PLAYER_STATE_EOS:
// go to the next file
m_ListView->m_PlayList.Next();
// first button shows "play"
button.idCommand = IDM_PLAY;
button.iImage = 0;
SendMessage(m_TrackCommandBar,
TB_SETBUTTONINFO,
IDM_PAUSE,
(LPARAM)&button);
state_text = TEXT("EOF");
break;
}
m_State = state;
SendMessage(m_StatusWindow, SB_SETTEXT, 0, (LPARAM)state_text);
m_TrackView->SetState(state);
}
/*----------------------------------------------------------------------
| WCEPlayer::OnNotifyInputState
+---------------------------------------------------------------------*/
void
WCEPlayer::OnNotifyInputState(XA_InputState state)
{
BOOL enabled;
switch (state) {
case XA_INPUT_STATE_OPEN:
// enable the play and stop buttons, and the slider
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -