(***********************************************)
(*                                             *)
(* TMT Multimedia Player                       *)
(* Copyright (c) 1999 by TMT Development Corp. *)
(* Author: Vadim Bodrov, TMT Development Corp. *)
(*                                             *)
(* Targets:                                    *)
(*   WIN32 GUI application                     *)
(*                                             *)
(***********************************************)

program TMTMPlay;

{$ifndef __WIN32__}
{$define INVALID_TARGET}
{$endif}
{$ifndef __GUI__}
{$define INVALID_TARGET}
{$endif}
{$ifdef INVALID_TARGET}
  This program must be compiled as Win32 GUI application only
{$endif}

uses Windows, Messages, CommDlg, CommCtrl, Strings, Math, MMSystem, ShellAPI, MMedia;

{$r tmtmplay.res}

const
  TIMER_ID            = 9999;
  IDM_STATUSBAR       = 3000;
  MAIN_ICON           = 0100;
  CD_ICON             = 0101;
  MAIN_DIALOG         = 0100;
  MAIN_MENU           = 0101;
  ABOUT_DIALOG        = 0102;

  PLAY_BUTTON         = 1000;
  STOP_BUTTON         = 1001;
  BACK_BUTTON         = 1002;
  FORWARD_BUTTON      = 1003;
  BSTEP_BUTTON        = 1004;
  FSTEP_BUTTON        = 1005;
  EJECT_BUTTON        = 1006;
  SLIDER              = 1007;
  HOME_PAGE_ITEM      = 1008;
  ABOUT_ITEM          = 1010;
  EXIT_ITEM           = 1011;
  OPEN_FILE_ITEM      = 1012;
  CLOSE_FILE_ITEM     = 1013;
  MMEDIA_ITEM         = 1014;
  CDAUDIO_ITEM        = 1015;
  FULLSCREEN_ITEM     = 1016;
  AUTOREPEAT_ITEM     = 1017;
  ICON_BOX            = 2101;

  PLAY_IMAGE          = 2000;
  PAUSE_IMAGE         = 2001;
  STOP_IMAGE          = 2002;
  BACK_IMAGE          = 2003;
  FORWARD_IMAGE       = 2004;
  BSTEP_IMAGE         = 2005;
  FSTEP_IMAGE         = 2006;
  EJECT_IMAGE         = 2007;

var
  mainDlg, hTimer:    THandle := 0;
  Msg:                TMsg;
  hWndStatusbar:      THandle;
  Menu:               hMenu;
  MainIcon, CDIcon:   hIcon;

  MediaFile:          String := '';
  MMediaObj:          TMMedia;
  Track:              DWORD;
  AutoRepeat:         Boolean := FALSE;
  FileLoaded:         Boolean := FALSE;
  UseTimer:           Boolean := FALSE;
  Ejected:            Boolean := FALSE;
  Plays:              Boolean := FALSE;

  hPlay:              THandle;
  hPause:             THandle;
  hStop:              THandle;
  hBack:              THandle;
  hForward:           THandle;
  hBStep:             THandle;
  hFStep:             THandle;
  hEject:             THandle;

{$i routines.inc}

procedure MyMCIErrorProc(ErrorCode: UINT);
begin
  FileLoaded := FALSE;
end;

// Loads and set button images
procedure SetButtonImages;
begin
  hPause := LoadImage(hInstance, MAKEINTRESOURCE(PAUSE_IMAGE), IMAGE_ICON, 16, 16, 0);
  hPlay := LoadImage(hInstance, MAKEINTRESOURCE(PLAY_IMAGE), IMAGE_ICON, 16, 16, 0);
  SendDlgItemMessage(mainDlg, PLAY_BUTTON,  BM_SETIMAGE, IMAGE_ICON, hPlay);

  hStop := LoadImage(hInstance, MAKEINTRESOURCE(STOP_IMAGE), IMAGE_ICON, 16, 16, 0);
  SendDlgItemMessage(mainDlg, STOP_BUTTON,  BM_SETIMAGE, IMAGE_ICON, hStop);

  hBack := LoadImage(hInstance, MAKEINTRESOURCE(BACK_IMAGE), IMAGE_ICON, 16, 16, 0);
  SendDlgItemMessage(mainDlg, BACK_BUTTON,  BM_SETIMAGE, IMAGE_ICON, hBack);

  hForward := LoadImage(hInstance, MAKEINTRESOURCE(FORWARD_IMAGE), IMAGE_ICON, 16, 16, 0);
  SendDlgItemMessage(mainDlg, FORWARD_BUTTON,  BM_SETIMAGE, IMAGE_ICON, hForward);

  hBStep := LoadImage(hInstance, MAKEINTRESOURCE(BSTEP_IMAGE), IMAGE_ICON, 16, 16, 0);
  SendDlgItemMessage(mainDlg, BSTEP_BUTTON,  BM_SETIMAGE, IMAGE_ICON, hBStep);

  hFStep := LoadImage(hInstance, MAKEINTRESOURCE(FSTEP_IMAGE), IMAGE_ICON, 16, 16, 0);
  SendDlgItemMessage(mainDlg, FSTEP_BUTTON,  BM_SETIMAGE, IMAGE_ICON, hFStep);

  hEject := LoadImage(hInstance, MAKEINTRESOURCE(EJECT_IMAGE), IMAGE_ICON, 16, 16, 0);
  SendDlgItemMessage(mainDlg, EJECT_BUTTON,  BM_SETIMAGE, IMAGE_ICON, hEject);
end;

// Enables/disables GUI controls
procedure RefreshControls;
var
  Pos: DWORD;
  id:  Word;
  Temp: array [0..MAX_PATH] of Char;
  Icon: hIcon;
begin
  if (FileLoaded and (MMediaObj.GetDevice <> MCI_CDAudio)) or MMediaObj.GotoFirstAudioTrack then
  begin
    EnableWindow(GetDlgItem(mainDlg, PLAY_BUTTON),    TRUE);
    EnableWindow(GetDlgItem(mainDlg, STOP_BUTTON),    TRUE);
    EnableWindow(GetDlgItem(mainDlg, BACK_BUTTON),    TRUE);
    EnableWindow(GetDlgItem(mainDlg, FORWARD_BUTTON), TRUE);
    EnableWindow(GetDlgItem(mainDlg, BSTEP_BUTTON),   TRUE);
    EnableWindow(GetDlgItem(mainDlg, FSTEP_BUTTON),   TRUE);
    EnableWindow(GetDlgItem(mainDlg, SLIDER),         TRUE);
    Icon := ExtractAssociatedIcon(hInstance, StrPCopy(Temp, MediaFile), id);
    if Icon = 0 then Icon := MainIcon;
    if MMediaObj.GetDevice = MCI_CDAudio then Icon := CDIcon;
  end else
  begin
    EnableWindow(GetDlgItem(mainDlg, PLAY_BUTTON),    FALSE);
    EnableWindow(GetDlgItem(mainDlg, STOP_BUTTON),    FALSE);
    EnableWindow(GetDlgItem(mainDlg, BACK_BUTTON),    FALSE);
    EnableWindow(GetDlgItem(mainDlg, FORWARD_BUTTON), FALSE);
    EnableWindow(GetDlgItem(mainDlg, BSTEP_BUTTON),   FALSE);
    EnableWindow(GetDlgItem(mainDlg, FSTEP_BUTTON),   FALSE);
    EnableWindow(GetDlgItem(mainDlg, SLIDER),         FALSE);
    Icon := MainIcon;
  end;
  SendDlgItemMessage(mainDlg, ICON_BOX, STM_SETIMAGE, IMAGE_ICON, Icon);
  if MMediaObj.GetDevice = MCI_CDAudio then
  begin
    Pos := mci_MSFtoSeconds(MMediaObj.GetTrackLength(mci_TMSF_Track(MMediaObj.GetPos)));
    EnableWindow(GetDlgItem(mainDlg, EJECT_BUTTON), TRUE);
    EnableMenuItem(Menu, OPEN_FILE_ITEM, MF_GRAYED);
    EnableMenuItem(Menu, CLOSE_FILE_ITEM, MF_GRAYED);
  end else
  begin
    Pos := MMediaObj.GetLength;
    EnableWindow(GetDlgItem(mainDlg, EJECT_BUTTON), FALSE);
    EnableMenuItem(Menu, OPEN_FILE_ITEM, MF_ENABLED);
    EnableMenuItem(Menu, CLOSE_FILE_ITEM, MF_ENABLED);
  end;
  SendDlgItemMessage(mainDlg, SLIDER, TBM_SETRANGEMAX, LONGTRUE, Pos);
end;

// Updates the SLIDER and STATUSBAR controls
procedure RefreshStatus(RefreshSlider: Boolean);
var
  S: String;
  CurrentTrack: DWORD;
  CurrentPos: DWORD;
  CurrentLength: DWORD;
begin
  if (not FileLoaded) or ((MMediaObj.GetDevice = MCI_CDAudio) and
     (not MMediaObj.CDMediaIsPresent)) then
  begin
    SendDlgItemMessage(mainDlg, SLIDER, TBM_SETPOS, LONGTRUE, 0);
    UpdateStatusBar('Ready', 0, 0);
    UpdateStatusBar('', 1, 0);
    UseTimer := FALSE;
    RefreshControls;
  end else
  begin
    if (MMediaObj.GetStatus = MCI_MODE_STOP) and (MMediaObj.GetPos = MMediaObj.GetLength) then
    begin
      UpdateStatusBar('Ready', 0, 0);
      UpdateStatusBar('', 1, 0);
      if AutoRepeat then
      begin
        if MMediaObj.GetDevice = MCI_CDAudio then MMediaObj.GotoFirstAudioTrack;
        if Plays then MMediaObj.Play;
      end else
      begin
        RefreshSlider := TRUE;
        Plays := FALSE;
        UseTimer := FALSE;
        SendDlgItemMessage(mainDlg, PLAY_BUTTON, BM_SETIMAGE, IMAGE_ICON, hPlay);
      end;
    end;
    CurrentPos := MMediaObj.GetPos;
    if MMediaObj.GetDevice = MCI_CDAudio then
    begin
      CurrentTrack := mci_TMSF_Track(CurrentPos);
      CurrentLength := MMediaObj.GetTrackLength(CurrentTrack);
      if Track <> CurrentTrack then
      begin
        RefreshControls;
        Track := CurrentTrack;
      end;
      S := ' Total: ' + LZ(mci_MSF_minute(CurrentLength)) + ':' +
           LZ(mci_MSF_second(CurrentLength)) + ' min.' + #0;
      UpdateStatusBar(@S[1], 0, 0);
      S := ' Track: #' + IntToStr(Track) + ' / Time: ' +  LZ(mci_TMSF_minute(CurrentPos)) +
           ':' + LZ(mci_TMSF_second(CurrentPos)) + ' min.' + #0;
      UpdateStatusBar(@S[1], 1, 0);
      if (Plays) or (RefreshSlider) then
        SendDlgItemMessage(mainDlg, SLIDER, TBM_SETPOS, LONGTRUE, mci_TMSFtoSeconds(CurrentPos));
    end else
    begin
      CurrentLength := MMediaObj.GetLength;
      S := ' Total: ' + GetTime(CurrentLength, CurrentLength < 60000) + #0;
      UpdateStatusBar(@S[1], 0, 0);
      S := ' Time: ' + GetTime(CurrentPos, CurrentLength < 60000) + #0;
      UpdateStatusBar(@S[1], 1, 0);
      if (Plays) or (RefreshSlider) then
        SendDlgItemMessage(mainDlg, SLIDER, TBM_SETPOS, LONGTRUE, CurrentPos);
    end;
  end;
end;

// Use timer to refresh status
procedure TimerProc conv arg_stdcall (hwnd: HWND;  uMsg, idEvent: UInt; dwTime: DWord);
begin
  if UseTimer then RefreshStatus(FALSE);
end;

// About box
function AboutDlgProc conv arg_stdcall (Dialog: HWND; Mess: UINT; WParam: WParam; LParam: LParam): LongInt;
const
  MEM_AVAIL_CAPTION = 1000;
  MEM_INUSE_CAPTION = 1001;
var
  Txt: String;
  MS: TMemoryStatus;
begin
  case Mess of
    WM_INITDIALOG:
      begin
        GlobalMemoryStatus(MS);
        Txt := IntToStr(MS.dwTotalPhys div 1024) + ' KB' + #0;
        SendDlgItemMessage(Dialog, MEM_AVAIL_CAPTION, WM_SETTEXT, 0, DWORD(@Txt[1]));
        Txt := IntToStr(MS.dwMemoryLoad) + ' %' + #0;
        SendDlgItemMessage(Dialog, MEM_INUSE_CAPTION, WM_SETTEXT, 0, DWORD(@Txt[1]));
      end;

    WM_CLOSE:
      EndDialog(Dialog, 0);

    WM_COMMAND:
      begin
        if LoWord(WParam) = IDOK then SendMessage(Dialog, WM_CLOSE, 0, 0);
      end;
  end; {case Mess of}
  Result := 0;
end;

// Main dialog
function MainDlgProc conv arg_stdcall (Dialog: HWND; Mess: UINT; WParam: WParam; LParam: LParam): LongInt;
var
  Pos: Longint;
  DeviceCaps: TMCIDeviceCaps;
begin
  case Mess of
    WM_INITDIALOG:
      begin
        MMediaObj.Create(Dialog);
        MMediaObj.StopAtClose := TRUE;
        MMediaObj.AutoRewind := TRUE;
        MMediaObj.MCIErrorProc := MyMCIErrorProc;
      end;

    WM_COMMAND:
      begin
        case LoWord(WParam) of
          EJECT_BUTTON:
            begin
              MMediaObj.GetDeviceCaps(DeviceCaps);
              if (MMediaObj.GetDevice = MCI_CDAudio) and (DeviceCaps.CanEject) then
              begin
                if Ejected then
                  MMediaObj.SetDoorClosed
                else
                  MMediaObj.SetDoorOpen;
                Ejected := not Ejected
              end;
            end;

          HOME_PAGE_ITEM:
            ShellExecute(mainDlg, 'open', 'http://www.tmt.com', nil, nil, SW_SHOWDEFAULT);

          FULLSCREEN_ITEM:
            begin
              MMediaObj.PlayFullScreen := not MMediaObj.PlayFullScreen;
              if MMediaObj.PlayFullScreen then
                CheckMenuItem(Menu, FULLSCREEN_ITEM, MF_CHECKED)
              else
                CheckMenuItem(Menu, FULLSCREEN_ITEM, MF_UNCHECKED);
            end;

          AUTOREPEAT_ITEM:
            begin
              AutoRepeat := not AutoRepeat;
              if AutoRepeat then
                CheckMenuItem(Menu, AUTOREPEAT_ITEM, MF_CHECKED)
              else
                CheckMenuItem(Menu, AUTOREPEAT_ITEM, MF_UNCHECKED);
            end;

          MMEDIA_ITEM:
            begin
              if MMediaObj.GetDevice <> MCI_CDAudio then exit;
              MMediaObj.Stop;
              CheckMenuItem(Menu, MMEDIA_ITEM, MF_CHECKED);
              CheckMenuItem(Menu, CDAUDIO_ITEM, MF_UNCHECKED);
              if MMediaObj.GetStatus = MCI_MODE_PLAY then MMediaObj.Stop;
              MMediaObj.SetDevice(MCI_AutoSelect);
              MMediaObj.SetTimeFormat(MCI_FORMAT_MILLISECONDS);
              FileLoaded := FALSE;
              RefreshStatus(TRUE);
              SendDlgItemMessage(mainDlg, PLAY_BUTTON, BM_SETIMAGE, IMAGE_ICON, hPlay);
              KillTimer(mainDlg, TIMER_ID);
              SetTimer(mainDlg, TIMER_ID, 400, @TimerProc);
              RefreshControls;
            end;

          CDAUDIO_ITEM:
            begin
              if MMediaObj.GetDevice = MCI_CDAudio then exit;
              MMediaObj.Stop;
              CheckMenuItem(Menu, MMEDIA_ITEM, MF_UNCHECKED);
              CheckMenuItem(Menu, CDAUDIO_ITEM, MF_CHECKED);
              if MMediaObj.GetStatus = MCI_MODE_PLAY then MMediaObj.Stop;
              MMediaObj.SetDevice(MCI_CDAudio);
              MMediaObj.Open('1');
              MMediaObj.Rewind;
              MMediaObj.SetTimeFormat(MCI_FORMAT_TMSF);
              FileLoaded := TRUE;
              RefreshStatus(TRUE);
              SendDlgItemMessage(mainDlg, PLAY_BUTTON, BM_SETIMAGE, IMAGE_ICON, hPlay);
              KillTimer(mainDlg, TIMER_ID);
              SetTimer(mainDlg, TIMER_ID, 200, @TimerProc);
              RefreshControls;
            end;

          ABOUT_ITEM:
            begin
              DialogBoxParam(hInstance, MAKEINTRESOURCE(ABOUT_DIALOG), mainDlg, @AboutDlgProc, 0);
            end;

          EXIT_ITEM:
            DestroyWindow(Dialog);

          OPEN_FILE_ITEM:
            begin
              if OpenFile then
              begin
                FileLoaded := TRUE;
                if not FileLoaded then exit;
                if MediaFile <> '' then
                begin
                  MMediaObj.Open(MediaFile);
                  MMediaObj.Rewind;
                  SendDlgItemMessage(mainDlg, PLAY_BUTTON, BM_SETIMAGE, IMAGE_ICON, hPlay);
                  declare
                  var
                    Temp: array [0..MAX_PATH] of Char;
                    SetWindowText(mainDlg, StrPCopy(Temp, 'TMT Multimedia Player - ' + ExtractFileName(MediaFile)));
                end;
                MMediaObj.SetTimeFormat(MCI_FORMAT_MILLISECONDS);
                RefreshStatus(FALSE);
                RefreshControls;
              end;
            end;

          CLOSE_FILE_ITEM:
            begin
              MMediaObj.Stop;
              FileLoaded := FALSE;
              RefreshStatus(FALSE);
              RefreshControls;
            end;

          PLAY_BUTTON:
            begin
              if (not FileLoaded) or ((MMediaObj.GetDevice = MCI_CDAudio) and
                 (not MMediaObj.CDMediaIsPresent)) then exit;
              if MMediaObj.GetStatus = MCI_MODE_PLAY then
              begin
                MMediaObj.Pause;
                UseTimer := FALSE;
                SendDlgItemMessage(mainDlg, PLAY_BUTTON,  BM_SETIMAGE, IMAGE_ICON, hPlay);
                Plays := FALSE;
              end else
              begin
                MMediaObj.Play;
                MMediaObj.Resume;
                SendDlgItemMessage(mainDlg, PLAY_BUTTON,  BM_SETIMAGE, IMAGE_ICON, hPause);
                Plays := TRUE;
                UseTimer := TRUE;
              end;
              RefreshControls;
            end;

          STOP_BUTTON:
            begin
              if not FileLoaded then exit;
              MMediaObj.Stop;
              MMediaObj.Rewind;
              SendDlgItemMessage(mainDlg, SLIDER, TBM_SETPOS, LONGTRUE, 0);
              SendDlgItemMessage(mainDlg, PLAY_BUTTON,  BM_SETIMAGE, IMAGE_ICON, hPlay);
              Plays := FALSE;
              RefreshControls;
            end;

          BACK_BUTTON:
            begin
              if not FileLoaded then exit;
              if MMediaObj.GetDevice <> MCI_CDAudio then
              begin
                Pos := MMediaObj.GetPos - MMediaObj.GetLength div 20;
                if Pos < 0 then Pos := 0;
              end else
              begin
                Pos := Max(Longint(mci_TMSFtoSeconds(MMediaObj.GetPos) -
                       mci_MSFtoSeconds(MMediaObj.GetTrackLength(mci_TMSF_Track(MMediaObj.GetPos))) div 20), 0);
                Pos := mci_SecondsToTMSF(Pos, MMediaObj.GetPos);
              end;
              if MMediaObj.GetStatus = MCI_MODE_PLAY then
              begin
                MMediaObj.Pause;
                MMediaObj.SetPos(Pos);
                if MMediaObj.GetDevice = MCI_CDAudio then
                  MMediaObj.Resume
                else
                  MMediaObj.Play;
                UseTimer := TRUE;
              end else
                MMediaObj.SetPos(Pos);
              RefreshStatus(TRUE);
            end;

          FORWARD_BUTTON:
            begin
              if not FileLoaded then exit;
              if MMediaObj.GetDevice <> MCI_CDAudio then
              begin
                Pos := MMediaObj.GetPos + MMediaObj.GetLength div 20;
                if Pos > MMediaObj.GetLength then Pos := MMediaObj.GetLength;
              end else
              begin
                Pos := Min(Longint(mci_TMSFtoSeconds(MMediaObj.GetPos) +
                       mci_MSFtoSeconds(MMediaObj.GetTrackLength(mci_TMSF_Track(MMediaObj.GetPos))) div 20),
                       mci_MSFtoSeconds(MMediaObj.GetTrackLength(mci_TMSF_Track(MMediaObj.GetPos))));
                Pos := mci_SecondsToTMSF(Pos, MMediaObj.GetPos);
              end;
              if MMediaObj.GetStatus = MCI_MODE_PLAY then
              begin
                MMediaObj.Pause;
                MMediaObj.SetPos(Pos);
                if MMediaObj.GetDevice = MCI_CDAudio then
                  MMediaObj.Resume
                else
                  MMediaObj.Play;
                UseTimer := TRUE;
              end else
                MMediaObj.SetPos(Pos);
              RefreshStatus(TRUE);
            end;

          BSTEP_BUTTON:
            begin
              if not FileLoaded then exit;
              if MMediaObj.GetDevice = MCI_CDAudio then
              begin
                if mci_TMSF_Track(MMediaObj.GetPos) = 1 then
                  MMediaObj.SetPos(MMediaObj.GetTrackPos(MMediaObj.GetTracksCount))
                else
                  MMediaObj.Previous;
              end else
                MMediaObj.SetPos(0);
              RefreshStatus(TRUE);
            end;

          FSTEP_BUTTON:
            begin
              if not FileLoaded then exit;
              if MMediaObj.GetDevice = MCI_CDAudio then
              begin
                if mci_TMSF_Track(MMediaObj.GetPos) = MMediaObj.GetTracksCount then
                  MMediaObj.SetPos(MMediaObj.GetTrackPos(1))
                else
                  MMediaObj.Next
              end else
                MMediaObj.SetPos(MMediaObj.GetLength);
              RefreshStatus(TRUE);
            end;

          end; {case LoWord(WParam) of}
        end; {WM_COMMAND}

    WM_HSCROLL:
      begin
        if not FileLoaded then exit;
        UseTimer := FALSE;
        if LoWord(wParam) = SB_ENDSCROLL then
        begin
          Pos := SendDlgItemMessage(mainDlg, SLIDER, TBM_GETPOS, 0, 0);
          if MMediaObj.GetDevice = MCI_CDAudio then
            Pos := mci_SecondsToTMSF(Pos, MMediaObj.GetPos);
          if MMediaObj.GetStatus = MCI_MODE_PLAY then
          begin
            MMediaObj.Pause;
            MMediaObj.SetPos(Pos);
            if MMediaObj.GetDevice = MCI_CDAudio then
              MMediaObj.Resume
            else
              MMediaObj.Play;
          end else
            MMediaObj.SetPos(Pos);
          UseTimer := TRUE;
          RefreshStatus(FALSE);
        end;
      end; {WM_HSCROLL}

    WM_CLOSE:
      DestroyWindow(Dialog);

    WM_DESTROY:
      PostQuitMessage(0);
  end; {case Mess of}

  Result := 0;
end;

begin
  InitCommonControls;
  mainDlg := CreateDialog(hInstance, MakeIntResource(MAIN_DIALOG), 0, @MainDlgProc);
  CreateSBar(mainDlg);
  UpdateStatusBar('Ready', 0, 0);
  Menu := GetMenu(mainDlg);

  MainIcon := LoadIcon(hInstance, MAKEINTRESOURCE(MAIN_ICON));
  CDIcon   := LoadIcon(hInstance, MAKEINTRESOURCE(CD_ICON));

  SendMessage(mainDlg, WM_SETICON, 1, MainIcon);
  SetButtonImages;
  ShowWindow(mainDlg, SW_SHOW);
  SetTimer(mainDlg, TIMER_ID, 200, @TimerProc);

  if ParamCount > 0 then
  begin
    FileLoaded := TRUE;
    MediaFile := ParamStr(1);
    MMediaObj.Open(MediaFile);
    MMediaObj.Play;
    UseTimer := TRUE;
    SendDlgItemMessage(mainDlg, PLAY_BUTTON,  BM_SETIMAGE, IMAGE_ICON, hPause);
    declare
    var
      Temp: array [0..MAX_PATH] of Char;
      SetWindowText(mainDlg, StrPCopy(Temp, 'TMT Multimedia Player - ' + ExtractFileName(MediaFile)));
  end;

  RefreshControls;

  while GetMessage(Msg, 0, 0, 0) do
  begin
    TranslateMessage(Msg);
    DispatchMessage(Msg);
  end;

  KillTimer(mainDlg, TIMER_ID);

  MMediaObj.Close;
end.