// ------------------------------------------------
// Приложение MCIWNDC
// Использование класса окна MCIWnd для 
// проигрывания и записи файлов Multimedia
// ------------------------------------------------

#define STRICT
#include <windows.h>
#include <windowsx.h>
#include <commdlg.h>
#include <memory.h>
#include <vfw.h>
#include "mciwndc.h"

// Прототипы функций
BOOL    InitApp(HINSTANCE);
LRESULT CALLBACK _export WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL mciwndSelectFile(LPSTR lpszFileName);

// Глобальные переменные
char const szClassName[]   = "MCIWNDCClass";
char const szMovieClass[]  = MCIWND_WINDOW_CLASS;
char const szWindowTitle[] = "MCIWnd Player & Recorder";
HINSTANCE  hInst;
HWND hwndMovie = NULL;

// =====================================
// Функция WinMain
// =====================================
int PASCAL
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
        LPSTR lpszCmdLine, int nCmdShow)
{
  MSG  msg;      // структура для работы с сообщениями
  HWND hwnd;     // идентификатор главного окна приложения
  WORD wVersion; // версия Video for Windows

  if(hPrevInstance)
    return FALSE;

  // Проверяем версию Video for Windows
  wVersion = HIWORD(VideoForWindowsVersion());
  if(wVersion < 0x010a)
  {
    MessageBox(NULL, "Используйте Video for Windows"
        " версии 1.1 или более поздней версии",
        "MCIWnd Error", MB_OK | MB_ICONHAND);
    return FALSE;
  }

  if(!InitApp(hInstance))
    return FALSE;
    
  hInst = hInstance;

  hwnd = CreateWindow(
    szClassName,         // имя класса окна
    szWindowTitle,       // заголовок окна
    WS_OVERLAPPEDWINDOW, // стиль окна
    CW_USEDEFAULT,       // размеры и расположение окна
    CW_USEDEFAULT,       
    400, 350, 0, 0, hInstance, NULL);
                       
  if(!hwnd)
    return FALSE;

  ShowWindow(hwnd, nCmdShow);
  UpdateWindow(hwnd);

  while(GetMessage(&msg, 0, 0, 0))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  return msg.wParam;
}

// =====================================
// Функция InitApp
// Выполняет регистрацию класса окна
// =====================================

BOOL InitApp(HINSTANCE hInstance)
{
  ATOM aWndClass; // атом для кода возврата
  WNDCLASS wc;    // структура для регистрации

  memset(&wc, 0, sizeof(wc));
  wc.lpszMenuName  = "APP_MENU";
  wc.style         = CS_HREDRAW | CS_VREDRAW;
  wc.lpfnWndProc   = (WNDPROC) WndProc;
  wc.cbClsExtra    = 0;
  wc.cbWndExtra    = 0;
  wc.hInstance     = hInstance;
  wc.hIcon         = LoadIcon(hInstance, "APPICON");
  wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  wc.lpszClassName = (LPSTR)szClassName;

  aWndClass = RegisterClass(&wc);
  return (aWndClass != 0);
}

// =====================================
// Функция WndProc
// =====================================

LRESULT CALLBACK _export
WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  switch (msg)
  {
// ------------------------------------------------------------
// WM_INITMENU
// Инициализация меню
// ------------------------------------------------------------
    case WM_INITMENU:
    {                                       
      // Определяем стиль окна MCI  
      WORD wStyles = MCIWndGetStyles(hwndMovie);
      
      // Если окно MCI имеет панель управления,
      // отмечаем строку "Play Bar" меню "Styles"
      CheckMenuItem(GetMenu(hwnd), CM_STPBAR, 
        (wStyles & MCIWNDF_NOPLAYBAR) ? MF_UNCHECKED : MF_CHECKED);
      return 0;
    }

// ------------------------------------------------------------
// WM_COMMAND
// Обработка сообщений от меню
// ------------------------------------------------------------
    case WM_COMMAND:
    {
      switch (wParam)
      {
        // -------------------------------------------------
        // Строка "About" меню "Help"
        // -------------------------------------------------
        case CM_HELPABOUT:
        {
          MessageBox(hwnd,
            "MCIWnd Player & Recorder, v.1.0\n"
            "(C) Frolov A.V., 1994",
            "About MCIWNDC", MB_OK | MB_ICONINFORMATION);
          return 0;
        }

        // -------------------------------------------------
        // Строка "New Waveaudio" меню "File"
        // -------------------------------------------------
        case CM_FILENEW:
        {
          // Если окно MCI уже было создано, удаляем его
          if(hwndMovie)
            MCIWndDestroy(hwndMovie);

          // Создаем новое окно для записи звука,
          // открываем драйвер устройства waveaudio
          hwndMovie = MCIWndCreate(
            hwnd, hInst,
            WS_VISIBLE | WS_CHILD | WS_BORDER |
            MCIWNDF_RECORD, 
            (LPSTR)"waveaudio");
             
          // Создаем новый файл
          MCIWndNew(hwndMovie, "waveaudio");
          return 0;
        }

        // -------------------------------------------------
        // Строка "Save Waveaudio As..." меню "File"
        // -------------------------------------------------
        case CM_FILESAVEAS:
        {
          // Создаем диалоговую панель "Save As..." для
          // сохранения файла
          MCIWndSaveDialog(hwndMovie);
          return 0;
        }

        // -------------------------------------------------
        // Строка "CD Audio" меню "File"
        // -------------------------------------------------
        case CM_FILECDAUDIO:
        {
          // Если окно MCI уже было создано, удаляем его
          if(hwndMovie)
            MCIWndDestroy(hwndMovie);

          // Создаем новое окно для проигрывания CD,
          // открываем драйвер устройства cdaudio
          hwndMovie = MCIWndCreate(
            hwnd, hInst,
            WS_VISIBLE | WS_CHILD | WS_BORDER |
            MCIWNDF_RECORD, 
            (LPSTR)"cdaudio");
          return 0;
        }

        // -------------------------------------------------
        // Строка "Open" меню "File"
        // -------------------------------------------------
        case CM_FILEOPEN:
        {
          char szBuff[256];
          
          // Если окно MCI уже было создано, удаляем его
          if(hwndMovie)
            MCIWndDestroy(hwndMovie);
          
          // Выбираем файл для загрузки в окно MCI
          if(mciwndSelectFile(szBuff))
          {
             // Создаем окно MCI
             hwndMovie = MCIWndCreate(
               hwnd, hInst,
               WS_VISIBLE | WS_CHILD | WS_BORDER |
               MCIWNDF_RECORD,
               (LPSTR)szBuff);
          }
          return 0;
        }

        // -------------------------------------------------
        // Строка "Close" меню "File"
        // -------------------------------------------------
        case CM_FILECLOSE:
        {
          // Удаляем окно MCI
          MCIWndDestroy(hwndMovie);
          hwndMovie = NULL;
          return 0;
        }

        // -------------------------------------------------
        // Меню "Movie"
        // -------------------------------------------------
        case CM_MVIPLAY:    // "Play"
        {
          // Проигрывание
          MCIWndPlay(hwndMovie);
          return 0;
        }

        case CM_MVIRPLAY:   // "Play Reverse"
        {
          // Проигрывание в обратном направлении
          MCIWndPlayReverse(hwndMovie);
          return 0;
        }

        case CM_MVISTOP:    // "Stop"
        {
          // Останов
          MCIWndStop(hwndMovie);
          return 0;
        }

        case CM_MVIRECORD:  // "Record"
        {
          // Запись
          MCIWndRecord(hwndMovie);
          return 0;
        }             
        
        case CM_MVIHOME:    // "Home"
        {
          // Позиционирование в начало
          MCIWndHome(hwndMovie);
          return 0;
        }

        case CM_MVIEND:     // "End"
        {
          // Позиционирование в конец
          MCIWndEnd(hwndMovie);
          return 0;
        }

        case CM_MVISTEP:    // "Step Fwrd"
        {
          // Шаг вперед
          MCIWndStep(hwndMovie, 1);
          return 0;
        }

        case CM_MVIRSTEP:   // "Step Back"
        {
          // Шаг назад
          MCIWndStep(hwndMovie, -1);
          return 0;
        }

        case CM_MVIINFO:    // "Info..."
        {              
          char szBuff[512], szBuff1[256];
          long dwSize;
          
          // Если окно MCI создано, выводим информацию
          // о загруженном в него файле
          if(hwndMovie)
          {
            // Имя устройства
            MCIWndGetDevice(hwndMovie, (LPSTR)szBuff, 512);
            lstrcat(szBuff, (LPSTR)"\n");
          
            // Путь к файлу или имя устройства
            MCIWndGetFileName(hwndMovie, (LPSTR)szBuff1, 256);
            lstrcat(szBuff, (LPSTR)szBuff1);
            lstrcat(szBuff, (LPSTR)"\n");

            // Размер файла
            dwSize = MCIWndGetLength(hwndMovie);
            wsprintf(szBuff1, "Size: %ld ", (long)dwSize);
            lstrcat(szBuff, (LPSTR)szBuff1);

            // Формат времени
            MCIWndGetTimeFormat(hwndMovie, (LPSTR)szBuff1, 256);
            lstrcat(szBuff, (LPSTR)szBuff1);

            MessageBox(hwnd, szBuff,
              "Media Info", MB_OK | MB_ICONINFORMATION);
          }
          return 0;
        }
        // -------------------------------------------------
        // Меню "Styles"
        // -------------------------------------------------
        case CM_STPBAR:     // "Play Bar"
        {
          // Определяем стили окна MCI
          WORD wStyles = MCIWndGetStyles(hwndMovie);
      
          // Инвертируем состояние стиля MCIWNDF_NOPLAYBAR
          MCIWndChangeStyles(hwndMovie, MCIWNDF_NOPLAYBAR, 
            (wStyles & MCIWNDF_NOPLAYBAR) ? 0 : MCIWNDF_NOPLAYBAR);
          return 0;
        }

        // -------------------------------------------------
        // Строка "Exit" меню "File"
        // Завершение работы приложения
        // -------------------------------------------------
        case CM_FILEEXIT:
        {
          DestroyWindow(hwnd);
          return 0;
        }
        default:
          return 0;
      }
    }

    // Отслеживаем изменения в системной палитре
    case WM_PALETTECHANGED:
    {
      SendMessage(hwndMovie, msg, wParam, lParam);
      break;
    }
    case WM_QUERYNEWPALETTE:
    {
      return SendMessage(hwndMovie, msg, wParam, lParam);
    }


// ------------------------------------------------------------
// WM_DESTROY
// Уничтожение главного окна приложения
// ------------------------------------------------------------
    case WM_DESTROY:
    {
      PostQuitMessage(0);
      return 0;
    }
    default:
      break;
  }
  return DefWindowProc(hwnd, msg, wParam, lParam);
}

//-----------------------------------------------------
// mciwndSelectFile
// Выбор файла
//-----------------------------------------------------
BOOL mciwndSelectFile(LPSTR lpszFileName)
{
  OPENFILENAME ofn;

  char szFile[256];
  char szFileTitle[256];
  char szFilter[256] =
     "Video Files\0*.avi\0"
     "Waveaudio Files\0*.wav\0"
     "MIDI Files\0*.mid;*.rmi\0"
     "Any Files\0*.*\0";
  szFile[0] = '\0';
  memset(&ofn, 0, sizeof(OPENFILENAME));

  // Инициализируем нужные нам поля
  ofn.lStructSize       = sizeof(OPENFILENAME);
  ofn.hwndOwner         = NULL;
  ofn.lpstrFilter       = szFilter;
  ofn.nFilterIndex      = 1;
  ofn.lpstrFile         = szFile;
  ofn.nMaxFile          = sizeof(szFile);
  ofn.lpstrFileTitle    = szFileTitle;
  ofn.nMaxFileTitle     = sizeof(szFileTitle);
  ofn.lpstrInitialDir   = NULL;
  ofn.Flags =   OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST
               | OFN_HIDEREADONLY;
  // Выбираем входной файл
  if (GetOpenFileNamePreview(&ofn))
  {
    // Копируем путь к выбранному файлу
    lstrcpy(lpszFileName, (LPSTR)szFile);
    return TRUE;
  }
  else
    return FALSE;
}
