Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

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

© Александр Фролов, Григорий Фролов
Том 22, М.: Диалог-МИФИ, 1993, 271 стр.

[Назад] [Содеожание] [Дальше]

7.4. Приложение Compact Disk Player

В качестве примера практического использования органов управления Trackbar, Progressbar и Animation мы предлагаем вам приложение Compact Disk Player, предназначенное для проигрывания дорожек звукового компакт-диска.

Попутно мы продемонстрируем использование MCI-интерфейса в операционной системе Microsoft Windows 95. Напомним, что MCI-интерфейс используется для работы с устройствами мультимедиа. Более подробно вы можете об этом узнать из 15 тома "Библиотеки системного программиста".

Вы также узнаете, как создать приложение Win32, не имеющее главное окно, а представляющее из себя обычную диалоговую панель.

Внешний вид приложения Compact Disk Player показан на рис. 7.6.

Рис. 7.6. Приложение Compact Disk Player

В верхней части окна слева находятся органы управления Trackbar и Progressbar. Первый из них используется для перемещения по дорожкам звукового компакт-диска, второй показывает текущую дорожку. По мере проигрывания дорожек полоса Progressbar и движок Trackbar сдвигаются вправо.

Вы можете переключаться на произвольную дорожку компакт-диска, просто передвигая движок органа Trackbar в нужное место или делая щелчки мышью слева или справа от него в окне Trackbar.

Для перехода к следующей дорожке можно использовать клавишу <PgUp>, клавиши перемещения курсора вверх и вправо, а для перехода к предыдущей - клавишу <PgDn> и клавиши перемещения курсора вниз и влево.

Если нажать на клавишу <Home>, приложение начнет проигрывание с первой дорожки, а если <End> - с последней.

Справа вверху в окне нашего приложения расположен орган управления Animation. Когда проигрывание остановлено, в окне этого органа управления изображается неподвижный компакт-диск. Когда же начинается проигрывание, этот диск начинает вращаться.

В нижней части окна находятся кнопки, с помощью которых можно управлять процессом проигрывания:

Кнопка Назначение
>> Переход к проигрыванию следующей дорожки
<< Переход к проигрыванию предыдущей дорожки
Play Запуск проигрывания
Stop Останов проигрывания
Pause Временный останов проигрывания
Resume Продолжение проигрывания после временного останова
Eject Выталкивание компакт-диска (работает не на всех типах устройств чтения компакт-диска)
Exit Завершение работы приложения

При смене компакт-диска количество рисок в окне органа управления Trackbar автоматически устанавливается равным количеству звуковых дорожек.

Еще одно замечание.

Когда вы вставляете музыкальный компакт-диск, операционная система Microsoft Windows 95 автоматически запускает приложение и начинает проигрывание вставленного диска. Для работы с нашим приложением просто остановите проигрывание и завершите приложение CD Player.

Исходные тексты приложения 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

Описание функций

Кратко опишем функции приложения Compact Disk Player, имеющие отношение к органам управления Trackbar, Progressbar и Animation. Особенности использования интерфейса MCI были описаны в 15 томе "Библиотеки системного программиста".

WinMain

После сохранения идентификатора приложения и проверки на повторный запуск функция WinMain вызывает функцию InitCommonControls, выполняющую инициализацию библиотеки стандартных органов управления.

Далее вызывается функция DialogBox, создающая диалоговую панель. Функция этой диалоговой панели DlgProc выполняет всю полезную работу.

DlgProc

Функция DlgProc обрабатывает сообщения WM_INITDIALOG, WM_COMMAND, WM_HSCROLL и WM_TIMER, вызывая для них, соответственно, функции DlgProc_OnInitDialog, DlgProc_OnCommand, DlgProc_OnHScroll и DlgProc_OnTimer.

DlgProc1_OnInitDialog

Функция DlgProc_OnInitDialog определяет идентификаторы органов управления, расположенных в диалоговой панели, и сохраняет их для дальнейшего использования.

После этого она устанавливает диапазон изменения значений и шаг для органа Progressbar, посылая ему сообщения PBM_SETRANGE и PBM_SETSTEP. В качестве максимального используется значение из переменной nTrackCnt. Как только в устройство чтения компакт-дисков будет вставлен звуковой компакт-диск, обработчик сообщения WM_TIMER запишет в эту переменную количество дорожек.

Шаг изменения значений для органа управления Progressbar устанавливается равным единице.

Затем выполняется инициализация органа управления Trackbar. Максимальное значение устанавливается равным содержимому переменной nTrackCnt (как и для органа Progressbar), а шаг изменения - равным единице. Благодаря этому пользователь сможет перемещаться по всем дорожкам компакт-диска.

После этого обработчик сообщения открывает и инициализирует устройство чтения компакт-дисков, вызывая функцию CdInit, и затем запускает таймер с интервалом, равным примерно одной секунде. Таймер нужен для периодического определения состояния компакт-диска и, в частности, для периодического определения номера текущей дорожки.

На последнем шаге инициализации открывается файл с видеоклипом CD.AVI, который должен находится в текущем каталоге. Этот файл открывается макрокомандой Animate_Open.

DlgProc_OnCommand

Функция DlgProc1_OnCommand обрабатывает сообщение WM_COMMAND, поступающее от органов управления диалоговой панели.

Когда пользователь нажимает кнопку Exit или клавишу <Esc> обработчик уничтожает таймер, закрывает устройство чтения компакт-диска при помощи функции CdClose и затем закрывает диалоговую панель, вызывая функцию EndDialog. В результате приложение завершает свою работу.

Обработка остальных кнопок выполняется соответствующими функциями, определенными в файле cdproc.c (листинг 7.2). Действия, которые выполняют эти функции, были описаны нами в 15 томе "Библиотеки системного программиста", поэтому для экономии места мы не будем рассказывать о них еще раз.

DlgProc_OnTimer

Функция DlgProc_OnTimer обрабатывает сообщение WM_TIMER , поступающее примерно один раз в секунду. Если диалоговая панель находится в минимизированном состоянии (что определяется с помощью функции IsIconic), обработчик сразу возвращает управление.

В противном случае вызывается функция CdUpdateState, определяющая текущее состояние устройства чтения компакт-дисков и выполняющая некоторые другие действия, связанные с обновлением состояния органов управления диалоговой панели.

Если в результате вызова этой функции выяснилось, что состояние изменилось, функция DlgProc_OnTimer отображает номер текущей дорожки в статическом органе управления с идентификатором hwndCurTrack. После этого она изменяет положение движка Trackbar, чтобы он указывал на текущую дорожку, а также устанавливает диапазон значений и новое положение полосы Progressbar.

DlgProc_OnHScroll

Функция DlgProc_OnHScroll обрабатывает сообщение WM_HSCROLL , которое вырабатывает орган управления Trackbar.

В ответ на извещения TB_LINEDOWN и TB_PAGEDOWN обработчик вызывает функцию CdPlayNext, которая проигрывает следующую дорожку. При обработке извещений TB_LINEUP и TB_PAGEUP вызывается функция CdPlayPrev, которая проигрывает предыдущую дорожку.

Когда пользователь нажимает клавиши <Home> или <End>, обработчики извещений TB_TOP и TB_BOTTOM запускают проигрывание, соответственно, первой и последней дорожки звукового компакт-диска.

Если пользователь перемещает движок органа управления Trackbar в новое положение, обработчик извещения TB_THUMBPOSITION запускает проигрывание той дорожки, которая была выбрана и номер которой был передан вместе с этим извещением.

[Назад] [Содеожание] [Дальше]