Операционная система Windows 95 для программиста

Исходные тексты приложения Compact Disk Player


Приложение Compact Disk Player сделано на базе приложения MCICDPL, которое было описано в 15 томе "Библиотеки системного программиста".

Функции приложения Compact Disk Player определены в файлах cdplay.c (листинг 7.1) и cdproc.c (листинг 7.2).

Листинг 7.1. Файл cdplay\cdplay.c

#define STRICT #include <windows.h> #include <windowsx.h> #include <commctrl.h> #include "resource.h" #include "afxres.h" #include "cdplay.h"

HINSTANCE hInst; char szAppName[] = "CdPlayApp"; char szAppTitle[] = "CD Player"; UINT nTimerID; UINT nCurTrack = 0; UINT nTrackCnt = 0; HWND hwndCurTrack; HWND hProgressBar; HWND hTrackBar;

// ----------------------------------------------------- // Функция WinMain // ----------------------------------------------------- int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HWND hWnd; hInst = hInstance;

// Преверяем, не было ли это приложение запущено ранее hWnd = FindWindow(szAppName, NULL); if(hWnd) { if(IsIconic(hWnd)) ShowWindow(hWnd, SW_RESTORE); SetForegroundWindow(hWnd); return FALSE; }

// Инициализируем библиотеку стандартных органов управления InitCommonControls();

// Отображаем диалоговую панель, которая служит // главным окном приложения DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc);

return FALSE; }

// ----------------------------------------------------- // Функция DlgProc // ----------------------------------------------------- BOOL APIENTRY DlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { HANDLE_MSG(hdlg, WM_INITDIALOG, DlgProc_OnInitDialog); HANDLE_MSG(hdlg, WM_COMMAND, DlgProc_OnCommand); HANDLE_MSG(hdlg, WM_HSCROLL, DlgProc_OnHScroll); HANDLE_MSG(hdlg, WM_TIMER, DlgProc_OnTimer); default: break; } return FALSE; }

// ----------------------------------------------------- // Функция DlgProc_OnInitDialog // ----------------------------------------------------- BOOL DlgProc_OnInitDialog(HWND hdlg, HWND hwndFocus, LPARAM lParam) { // Определяем идентификатор поля, которое используется // для отображения номера текущей дорожки hwndCurTrack = GetDlgItem(hdlg, IDT_CURTRACK);




// Получаем идентификатор органа Progressbar hProgressBar = GetDlgItem(hdlg, IDC_PROGRESSBAR);

// Устанавливаем диапазон изменения значений // и шаг для органа Progressbar SendMessage(hProgressBar, PBM_SETRANGE, 0, MAKELPARAM(0, nTrackCnt)); SendMessage(hProgressBar, PBM_SETSTEP, 1, 0);

// Получаем идентификатор органа Trackbar hTrackBar = GetDlgItem(hdlg, IDC_TRACKBAR);

// Устанавливаем диапазон изменения значений // для органа Trackbar SendMessage(hTrackBar, TBM_SETRANGE, TRUE, MAKELPARAM(1, nTrackCnt));

// Устанавливаем шаг изменений SendMessage(hTrackBar, TBM_SETPAGESIZE, 0, 1); SendMessage(hTrackBar, TBM_SETLINESIZE, 0, 1);

// Инициализируем устройство проигрывания // звуковых компакт-дисков CdInit();

// Создаем таймер для периодического определения // состояния устройства проигрывания nTimerID = SetTimer(hdlg, 1, 1000, NULL);

// Открываем AVI-файл с видеоклипом (вращающийся // компакт-диск) Animate_Open(GetDlgItem(hdlg, IDC_ANIMATE), "CD.AVI");

return TRUE; }

// ----------------------------------------------------- // Функция DlgProc_OnCommand // ----------------------------------------------------- #pragma warning(disable: 4098) void DlgProc_OnCommand(HWND hdlg, int id, HWND hwndCtl, UINT codeNotify) { switch (id) { case IDCANCEL: case IDB_EXIT: { KillTimer(hdlg, nTimerID); // удаляем таймер

CdClose(); // закрываем устройство чтения компакт-диска

EndDialog(hdlg, TRUE); // завершаем работу приложения break; }

// Выполнение команд проигрывания, останова, // паузы, возобновления проигрывания после паузы и т. д. case IDB_PLAY: CdPlay(hdlg, 1); break; case IDB_STOP: CdStop(); break; case IDB_PAUSE: CdPause(); break; case IDB_RESUME: CdResume(hdlg); break; case IDB_NEXT: CdPlayNext(hdlg); break; case IDB_PREV: CdPlayPrev(hdlg); break; case IDB_EJECT: CdEject(); break;

default: return FALSE; } return TRUE; }

// ----------------------------------------------------- // Функция DlgProc_OnTimer // ----------------------------------------------------- void DlgProc_OnTimer(HWND hwnd, UINT id) { BYTE szBuf[20];



// Если окно свернуто в пиктограмму, ничего не делаем, // чтобы не снижать производительность системы if(IsIconic(hwnd)) return;

// Если состояние устройства проигрывания изменилось, // отображаем изменения в диалоговой панели if(CdUpdateState(hwnd)) { // Отображаем номер текущей дорожки if(nCurTrack != 0) { itoa(nCurTrack, szBuf, 10); SetWindowText(hwndCurTrack, szBuf); } else SetWindowText(hwndCurTrack, "");

// Изменяем положение движка Trackbar SendMessage(hTrackBar, TBM_SETPOS, TRUE, nCurTrack);

// Изменяем диапазон значений и положение // полосы Progressbar SendMessage(hProgressBar, PBM_SETRANGE, 0, MAKELPARAM(0, nTrackCnt)); SendMessage(hProgressBar, PBM_SETPOS, nCurTrack, 0); } }

// ----------------------------------------------------- // Функция DlgProc_OnHScroll // ----------------------------------------------------- void DlgProc_OnHScroll(HWND hdlg, HWND hwndCtl, UINT code, int pos) { switch(code) { // Отрабатываем команды, поступающие от органа // управления Trackbar case TB_LINEDOWN: case TB_PAGEDOWN: CdPlayNext(hdlg); break;

case TB_LINEUP: case TB_PAGEUP: CdPlayPrev(hdlg); break;

case TB_BOTTOM: CdPlay(hdlg, nTrackCnt); break;

case TB_TOP: CdPlay(hdlg, 1); break;

case TB_THUMBPOSITION: CdPlay(hdlg, pos); break; default: break; } }

В файле cdproc.c (листинг 7.2) собраны функции управления устройством чтения компакт-диска.

Листинг 7.2. Файл cdplay\cdproc.c

#define STRICT #include <windows.h> #include <windowsx.h> #include <commctrl.h> #include "resource.h" #include "afxres.h" #include "cdplay.h" #include <mmsystem.h>

DWORD dwrc; MCI_OPEN_PARMS MCIOpen; MCI_SET_PARMS MCISet; MCI_STATUS_PARMS MCIStatus; MCI_PLAY_PARMS MCIPlay; BOOL bMediaPresent = FALSE; BOOL bPaused = FALSE; UINT nMode = 0; HWND hwndCurTrack = NULL; extern UINT nCurTrack; extern UINT nTrackCnt; extern HWND hTrackBar;

// ----------------------------------------------------- // Функция CdInit // ----------------------------------------------------- BOOL CdInit(void) { // Открываем устройство чтения компакт-дисков MCIOpen.lpstrDeviceType = (LPSTR)MCI_DEVTYPE_CD_AUDIO; dwrc = mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID, (DWORD)&MCIOpen); if(dwrc) { mciwioError(dwrc); return FALSE; }



// Устанавливаем формат времени MCISet.dwTimeFormat = MCI_FORMAT_TMSF; dwrc = mciSendCommand(MCIOpen.wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD)&MCISet); if(dwrc) { mciwioError(dwrc); return FALSE; } return TRUE; }

// ----------------------------------------------------- // Функция CdClose // ----------------------------------------------------- void CdClose(void) { // Закрываем устройство чтения компакт-дисков dwrc = mciSendCommand(MCIOpen.wDeviceID, MCI_CLOSE, 0, 0); if(dwrc) mciwioError(dwrc); }

//----------------------------------------------------- // mciwioError // Обработка ошибок //----------------------------------------------------- void mciwioError(DWORD dwrc) { BYTE szBuf[MAXERRORLENGTH];

if(mciGetErrorString(dwrc, (LPSTR)szBuf, MAXERRORLENGTH)) MessageBox(NULL, szBuf, "MCIWAVE Error", MB_ICONEXCLAMATION); else MessageBox(NULL, "Неизвестная ошибка", "MCIWAVE Error", MB_ICONEXCLAMATION); }

// ----------------------------------------------------- // Функция CdUpdateState // ----------------------------------------------------- BOOL CdUpdateState(HWND hdlg) { BOOL fNeedUpdate = FALSE; UINT nCurMode;

// Определяем текущее состояние проигрывателя CD MCIStatus.dwItem = MCI_STATUS_MODE; mciSendCommand(MCIOpen.wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD)&MCIStatus);

// Проверяем, готово ли устройство чтения к работе if((MCIStatus.dwReturn == MCI_MODE_NOT_READY) (MCIStatus.dwReturn == MCI_MODE_OPEN)) { // Устройство не готово nCurMode = CD_EMPTY; } else if((MCIStatus.dwReturn == MCI_MODE_STOP) && bPaused) { // Устройство остановлено nCurMode = CD_PAUSED; } else if(MCIStatus.dwReturn == MCI_MODE_PLAY) { // Устройство находится в режиме проигрывания nCurMode = CD_PLAYING; } else { // Устройство готово nCurMode = CD_READY; }

// Если с момента последней проверки произошло // изменение режима, записываем код нового режима if(nMode != nCurMode) { fNeedUpdate = TRUE; nMode = nCurMode;

// Если устройство находится в режиме проигрывания, // запускаем видеоклип. В противном случае // останавливаем видеоклип в его текущей позиции if(nCurMode == CD_PLAYING) Animate_Play(GetDlgItem(hdlg, IDC_ANIMATE), 0, -1, -1); else Animate_Stop(GetDlgItem(hdlg, IDC_ANIMATE)); }



// Проверяем, вставлен ли компакт-диск MCIStatus.dwItem = MCI_STATUS_MEDIA_PRESENT; mciSendCommand(MCIOpen.wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD)&MCIStatus);

// Если компакт-диск вставлен, определяем // количество звуковых дорожек if((!bMediaPresent) && MCIStatus.dwReturn) { bMediaPresent = TRUE; bPaused = FALSE; nCurTrack = 0;

MCIStatus.dwItem = MCI_STATUS_NUMBER_OF_TRACKS; mciSendCommand(MCIOpen.wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD)&MCIStatus);

nTrackCnt = MCIStatus.dwReturn;

// Устанавливаем диапазон изменения значений // для органа управления Trackbar SendMessage(hTrackBar, TBM_SETRANGE, TRUE, MAKELPARAM(1, nTrackCnt)); }

// Если компакт-диск не вставлен, сбрасываем // номер текущей дорожки в поле диалоговой панели else if((bMediaPresent) && !MCIStatus.dwReturn) { bMediaPresent = FALSE; bPaused = FALSE; }

// Если приложение находится в режиме проигрывания, // определяем номер текущей дорожки if(nCurMode == CD_PLAYING) { // Определяем текущую позицию MCIStatus.dwItem = MCI_STATUS_POSITION; mciSendCommand(MCIOpen.wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD)&MCIStatus);

// Если номер дорожки изменился, отображаем новое // значение в соответствующем поле диалоговой панели if(nCurTrack != (UINT)MCI_TMSF_TRACK(MCIStatus.dwReturn)) { nCurTrack = (UINT)MCI_TMSF_TRACK(MCIStatus.dwReturn); fNeedUpdate = TRUE; } } return fNeedUpdate; }

//----------------------------------------------------- // CdPlay // Запуск проигрывания дорожки //----------------------------------------------------- void CdPlay(HWND hwnd, UINT nTrack) { if(bMediaPresent) { bPaused = FALSE;

MCIPlay.dwCallback = (DWORD)hwnd; MCIPlay.dwFrom = MCI_MAKE_TMSF(nTrack, 0, 0, 0);

dwrc = mciSendCommand(MCIOpen.wDeviceID, MCI_PLAY, MCI_FROM | MCI_NOTIFY, (DWORD)&MCIPlay); if(dwrc) mciwioError(dwrc); } }

//----------------------------------------------------- // CdStop // Останов проигрывания дорожки //----------------------------------------------------- void CdStop(void) { if(bMediaPresent) { bPaused = FALSE; nCurTrack = 0; mciSendCommand(MCIOpen.wDeviceID, MCI_STOP, 0, 0); } }



//----------------------------------------------------- // CdPause // Временный останов проигрывания дорожки //----------------------------------------------------- void CdPause(void) { if(bMediaPresent) { if(!bPaused) { bPaused = TRUE; mciSendCommand(MCIOpen.wDeviceID, MCI_PAUSE, 0, 0); } } }

//----------------------------------------------------- // CdResume // Возобновление проигрывания после временного останова //----------------------------------------------------- void CdResume(HWND hwnd) { if(bMediaPresent) { if(bPaused) { bPaused = FALSE; MCIPlay.dwCallback = (DWORD)hwnd; mciSendCommand(MCIOpen.wDeviceID, MCI_PLAY, MCI_NOTIFY, (DWORD)&MCIPlay); } } }

//----------------------------------------------------- // CdPlayNext // Проигрывание следующей дорожки //----------------------------------------------------- void CdPlayNext(HWND hwnd) { UINT nNewTrack;

if(bMediaPresent) { // Если текущая дорожка - последняя, // начинаем проигрывание с первой дорожки. // Если нет - проигрываем следующую дорожку if(nCurTrack == nTrackCnt) nNewTrack = 1; else nNewTrack = nCurTrack + 1;

CdPlay(hwnd, nNewTrack); } }

//----------------------------------------------------- // CdPlayPrev // Проигрывание предыдущей дорожки //----------------------------------------------------- void CdPlayPrev(HWND hwnd) { UINT nNewTrack; if(bMediaPresent) { // Если текущая дорожка - первая, // проигрываем последнюю дорожку if(nCurTrack <= 1) nNewTrack = nTrackCnt; else nNewTrack = nCurTrack - 1;

CdPlay(hwnd, nNewTrack); } }

//----------------------------------------------------- // CdEject // Выталкивание компакт-диска //----------------------------------------------------- void CdEject(void) { mciSendCommand(MCIOpen.wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, 0); }

В файле cdplay.h (листинг 7.3) находятся описания функций, определенных в приложении Compact Disk Player.

Листинг 7.3. Файл cdplay\cdplay.h

BOOL APIENTRY DlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam); BOOL DlgProc_OnInitDialog(HWND hdlg, HWND hwndFocus, LPARAM lParam); void DlgProc_OnCommand(HWND hdlg, int id, HWND hwndCtl, UINT codeNotify); void DlgProc_OnTimer(HWND hwnd, UINT id); void DlgProc_OnHScroll(HWND hwnd,HWND hwndCtl,UINT code, int pos); void UpdateDlgControls(void); BOOL CdInit(void); void CdClose(void); void mciwioError(DWORD dwrc); BOOL CdUpdateState(HWND hdlg); void CdPlay(HWND hwnd, UINT nTrack); void CdStop(void); void CdPause(void); void CdResume(HWND hwnd); void CdPlayNext(HWND hwnd); void CdPlayPrev(HWND hwnd); void CdEject(void);



#define CD_EMPTY 0 #define CD_READY 1 #define CD_PLAYING 2 #define CD_PAUSED 3

В файле resource.h ( создается автоматически системой Microsoft Visual C++) находятся определения констант для работы с ресурсами приложения Compact Disk Player. Этот файл представлен в листинге 7.4.

Листинг 7.4. Файл cdplay\resource.h

//{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by cdplay.rc // #define IDD_DIALOG1 101 #define IDB_NEXT 1000 #define IDB_PREV 1001 #define IDB_PLAY 1002 #define IDB_STOP 1003 #define IDB_PAUSE 1004 #define IDB_RESUME 1005 #define IDB_EJECT 1006 #define IDT_CURTRACK 1008 #define IDB_EXIT 1009 #define IDC_PROGRESSBAR 1012 #define IDC_TRACKBAR 1014 #define IDC_ANIMATE 1015 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 102 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1016 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif

Файл cdplay.rc (листинг 7.5) содержит определение ресурсов приложения Compact Disk Player.

Листинг 7.5. Файл cdplay\cdplay.rc

//Microsoft Visual C++ generated resource script. // #include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS ////////////////////////////////////////////////////////////// // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h"

////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS

////////////////////////////////////////////////////////////// // Dialog //

IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 278, 138 STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Compact disk player, (C) A. Frolov, 1995" FONT 8, "MS Sans Serif" BEGIN PUSHBUTTON ">>",IDB_NEXT,22,89,50,14 PUSHBUTTON "<<",IDB_PREV,76,89,50,14 PUSHBUTTON "Play",IDB_PLAY,129,89,50,14 PUSHBUTTON "Stop",IDB_STOP,22,106,50,14 PUSHBUTTON "Pause",IDB_PAUSE,76,106,50,14 PUSHBUTTON "Resume",IDB_RESUME,129,106,50,14 PUSHBUTTON "Eject",IDB_EJECT,203,89,50,14 PUSHBUTTON "Exit",IDB_EXIT,203,106,50,14 LTEXT "",IDT_CURTRACK,79,20,92,10 GROUPBOX "",IDC_STATIC,11,6,256,75 CONTROL "Generic1",IDC_PROGRESSBAR, "msctls_progress32", 0x3,25,39,184,9 CONTROL "Generic3",IDC_TRACKBAR, "msctls_trackbar32", WS_TABSTOP | 0x21,19,50,195,25 LTEXT "Track number:",IDC_STATIC,25,20,47,8 GROUPBOX "",IDC_STATIC,11,76,181,53 CONTROL "Animate",IDC_ANIMATE,"SysAnimate32", WS_BORDER | WS_TABSTOP | 0x1,219,34,33,33 GROUPBOX "",IDC_STATIC,191,76,76,53 END

#ifdef APSTUDIO_INVOKED ////////////////////////////////////////////////////////////// // TEXTINCLUDE //

1 TEXTINCLUDE DISCARDABLE BEGIN "resource.h\0" END

2 TEXTINCLUDE DISCARDABLE BEGIN "#include ""afxres.h""\r\n" "\0" END

3 TEXTINCLUDE DISCARDABLE BEGIN "\r\n" "\0" END

////////////////////////////////////////////////////////////// #endif // APSTUDIO_INVOKED

#ifndef APSTUDIO_INVOKED ////////////////////////////////////////////////////////////// // Generated from the TEXTINCLUDE 3 resource. ////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED


Содержание раздела