//
// Программа - "Тестер электронных дикторов". Версия 1.0.1  от 20 сентября 2003 г. (Open Sourse)
// File Name: e-Speech.exe
// Рабочее имя проекта: FreeFrm
// Информационная поддержка: http://www.native-speech.by.ru.
// Зеркало: http://www.native-speech.invitation.ru.
// Автор и разработчик: Бочаров Николай Викторович.
// E-mail для обсуждений: ns@invitation.ru
//
// Программа была написана в Delphi 6 и тестировалась под Windows 2000
//
// В программе реалирзовано:
// 1) подключение голосовых модулей для речевых движков (синтеза речи) версий 4.0 и 5.1
// 2) масштабируемые полигоны формы окна программы
//
// Для полноценного использования речевых движков необходимо импортирование
// ActiveX Controls (Что и откуда необходимо скачать из интернета,
// можно посмотреть на http://www.native-speech.invitation.ru):
// 1) Microsoft Direct Text-to-Speech (Version 1.0) (Class names: TTextToSpeech)
// 2) Microsoft Voice Text (Version 1.0)      (Class names: TDirectSS)
// 3) Wizzard's SAPI Controls (Version 5.1) ;
//    Wizzard's Type Library (Version 1.0)  (Class names: TTTS)
//
//  P.S. для полноценной работы с речевыми технологиями достаточно обойтись
// движком Microsoft Voice Text
//
// На форму окна программы не сброшены визуальные компоненты речевых движков,
// а инициируются в теле программы в целях исключения ошибки их инициализации.
// Ошибка проявляется до события OnCreate, если речевые движки не установлены
// в системе.
//
// Недостатки текущей версии с функциональной точки зрения не замечены.
// Возможность возникновения ошибок обрабатывается конструкцией вида:
{
try // выделение ресурса
// блок операторов, в котором может произойти ошибка
except
// блок операторов, обрабатывающий ошибку исполнения предыдущих операторов
end; // освобождение ресурса
}
//
// В текущем исполненеии предпринята попытка выжать всю доступную информацию
// из речевых движков о голосовых модулях воспроизведения речи.
//
// На текущий момент остались не рассмотренными следующие вопросы:
//1. Каким образом реализуется подключение к движку словарей произношений?
//   (Form1.DirectSS1.Phonemes(X,Y,Z) - ?)
//2. Как управлять системным контекстом: обычный текст, аббревиатура, web-адрес?
//3. Как управлять стилями чтения: автоматизация процесса узнавания структуры текста,
//   управление паузами и т.д.?
//
// Пологаю, что при ответах на эти вопросы возможно обнаружить различия
// в голосовых модулях от различных разработчиков, что затруднит программирование
// управлением этих параметров
//
//

unit FreeForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, ExtCtrls, OleCtrls, Spin, ComCtrls, Menus, Clipbrd,
//
  WIZTTSLib_TLB, ACTIVEVOICEPROJECTLib_TLB, HTTSLib_TLB;
//

type
  TForm1 = class(TForm)
    Label2: TLabel;
    Panel1: TPanel;
    BitBtn1: TBitBtn;
    BitBtn2: TBitBtn;
    Label1: TLabel;
    BitBtn3: TBitBtn;
    Memo1: TMemo;
    Panel2: TPanel;
    Button1: TBitBtn;
    SpinEdit3: TSpinEdit;
    Label7: TLabel;
    BitBtn5: TBitBtn;
    Label5: TLabel;
    RadioButton1: TRadioButton;
    RadioButton2: TRadioButton;
    Panel3: TPanel;
    Label8: TLabel;
    Label9: TLabel;
    Label10: TLabel;
    Label11: TLabel;
    Label12: TLabel;
    Label13: TLabel;
    Label14: TLabel;
    Label15: TLabel;
    Label16: TLabel;
    Label17: TLabel;
    Label18: TLabel;
    Label19: TLabel;
    Label21: TLabel;
    Label22: TLabel;
    Label23: TLabel;
    Label24: TLabel;
    Label25: TLabel;
    Label26: TLabel;
    Label27: TLabel;
    Label28: TLabel;
    Label29: TLabel;
    Label30: TLabel;
    Label31: TLabel;
    Label32: TLabel;
    Label20: TLabel;
    Label33: TLabel;
    Panel4: TPanel;
    TrackBar2: TTrackBar;
    Label6: TLabel;
    TrackBar1: TTrackBar;
    Label34: TLabel;
    TrackBar3: TTrackBar;
    Label35: TLabel;
    Panel5: TPanel;
    Label3: TLabel;
    Label4: TLabel;
    Label36: TLabel;
    Label37: TLabel;
    Label38: TLabel;
    Label39: TLabel;
    Label40: TLabel;
    Label41: TLabel;
    Label42: TLabel;
    Label43: TLabel;
    Label44: TLabel;
    Label45: TLabel;
    Label46: TLabel;
    Label47: TLabel;
    Label48: TLabel;
    Label49: TLabel;
    Label50: TLabel;
    Label51: TLabel;
    Label52: TLabel;
    Label53: TLabel;
    Label54: TLabel;
    Label55: TLabel;
    Label56: TLabel;
    Label57: TLabel;
    Label58: TLabel;
    Label59: TLabel;
    Label60: TLabel;
    Label61: TLabel;
    Panel6: TPanel;
    Label62: TLabel;
    Label63: TLabel;
    Label64: TLabel;
    TrackBar4: TTrackBar;
    TrackBar5: TTrackBar;
    TrackBar6: TTrackBar;
    Label65: TLabel;
    BitBtn4: TBitBtn;
    RadioButton3: TRadioButton;
    Label68: TLabel;
    Panel7: TPanel;
    Label69: TLabel;
    Label70: TLabel;
    Panel8: TPanel;
    Label95: TLabel;
    Label96: TLabel;
    Label97: TLabel;
    TrackBar7: TTrackBar;
    TrackBar8: TTrackBar;
    TrackBar9: TTrackBar;
    SpeedButton1: TSpeedButton;
    BitBtn6: TBitBtn;
    Label66: TLabel;
    Label67: TLabel;
    Label71: TLabel;
    Label72: TLabel;
    Label73: TLabel;
    Label74: TLabel;
    Label75: TLabel;
    SpeedButton2: TSpeedButton;
    BitBtn7: TBitBtn;
    OpenDialog1: TOpenDialog;
    ColorDialog1: TColorDialog;
    BitBtn8: TBitBtn;
    PopupMenu1: TPopupMenu;
    N1: TMenuItem;
    N2: TMenuItem;
    N3: TMenuItem;
    N4: TMenuItem;
    N5: TMenuItem;
    SpeedButton3: TSpeedButton;
    N6: TMenuItem;
    N7: TMenuItem;
    N8: TMenuItem;
    N9: TMenuItem;
    procedure FormResize(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Label1Click(Sender: TObject);
    procedure Label2Click(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure BitBtn1Click(Sender: TObject);
    procedure BitBtn2Click(Sender: TObject);
    procedure BitBtn3Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure BitBtn5Click(Sender: TObject);
    procedure SpinEdit4Change(Sender: TObject);
    procedure TrackBar1Change(Sender: TObject);
    procedure TrackBar2Change(Sender: TObject);
    procedure TrackBar3Change(Sender: TObject);
    procedure RadioButton1Click(Sender: TObject);
    procedure RadioButton2Click(Sender: TObject);
    procedure TrackBar6Change(Sender: TObject);
    procedure BitBtn4Click(Sender: TObject);
    procedure TrackBar9Change(Sender: TObject);
    procedure TrackBar8Change(Sender: TObject);
    procedure RadioButton3Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure SpeedButton1Click(Sender: TObject);
    procedure BitBtn6Click(Sender: TObject);
    procedure SpeedButton2Click(Sender: TObject);
    procedure BitBtn7Click(Sender: TObject);
    procedure Memo1KeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure BitBtn8Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure N6Click(Sender: TObject);
  private
    { Private declarations }
  TTS1: TTTS;
  DirectSS1:  TDirectSS;
  TextToSpeech1: TTextToSpeech;

  public
    { Public declarations }
    procedure RebuildWindowRgn;
    procedure WMNCHitTest(var M: TWMNCHitTest);

  protected
    procedure hotykey(var msg:TMessage); message WM_HOTKEY;
    
  end;


var
  Form1: TForm1;
  Move: Boolean;
  xpos,ypos: Integer;
  Mouse: TMouse;
  ShiftX, ShiftY: Integer;//Сдвиг по X и по Y
  EllipseWidth, EllipseHigth: Integer;
  KoeffEllipseWidth, KoeffEllipseHigth:Real;
  StyleRebuildWindow:Byte;   //  форма окна программы
  TTS1MaxValue: Integer; // число зарегистированных голосовых модулей для речевого движка пятой версии
  iKey01, iKey02:Integer;
  MainCaptionProgram: String;
  AutoStart: Boolean;


LeftFrmPos: Integer;
TopFrmPos: Integer;
WidthFrmPos: Integer;
HeightFrmPos: Integer;
Form1WindowState: Integer;
CustomColor01: Integer;
OldFile:TextFile;
Announcer:Byte; // Движок
ModuleAn:Integer; // голосовой модуль
  AnVolume:Integer;  // громкость
  AnPitch:Integer;   // тон
  AnSpeed:Integer;   // скорость


implementation

uses AboutFrm;


{$R *.dfm}

procedure SaveCFG;
// Сохраняем конфигурацию программы
begin
//
AssignFile(OldFile,'e-s.cfg');
Rewrite(OldFile);
//
writeln(OldFile,LeftFrmPos);
writeln(OldFile,TopFrmPos);
writeln(OldFile,WidthFrmPos);
writeln(OldFile,HeightFrmPos);
writeln(OldFile, EllipseWidth );
writeln(OldFile, EllipseHigth );
writeln(OldFile, StyleRebuildWindow );
writeln(OldFile, Form1WindowState );
writeln(OldFile, CustomColor01 );
writeln(OldFile, Announcer );
writeln(OldFile, Form1.SpinEdit3.Value );  // ModuleAn
if Announcer=1 then  begin
AnVolume:=Form1.TrackBar1.Position;
AnPitch:=Form1.TrackBar2.Position;
AnSpeed:=Form1.TrackBar3.Position;
writeln(OldFile, AnVolume );
writeln(OldFile, AnPitch );
writeln(OldFile, AnSpeed );
                     end;
if Announcer=2 then  begin
AnVolume:=0;
AnPitch:=0;
AnSpeed:=Form1.TrackBar6.Position;
writeln(OldFile, AnVolume );
writeln(OldFile, AnPitch );
writeln(OldFile, AnSpeed );
                     end;
if Announcer=3 then  begin
AnVolume:=Form1.TrackBar8.Position;
AnPitch:=0;
AnSpeed:=Form1.TrackBar9.Position;
writeln(OldFile, AnVolume );
writeln(OldFile, AnPitch );
writeln(OldFile, AnSpeed );
                     end;
if Announcer=0 then  begin
AnVolume:=0;
AnPitch:=0;
AnSpeed:=0;
writeln(OldFile, AnVolume );
writeln(OldFile, AnPitch );
writeln(OldFile, AnSpeed );
                     end;
//
CloseFile(OldFile);
//
//
end;

procedure SaySpeech;
//  произносим текст  из буфера обмена
begin
IF Form1.RadioButton1.Checked THEN begin
try // выделение ресурса
Form1.DirectSS1.VolumeLeft:=Form1.TrackBar1.Position;
Form1.DirectSS1.VolumeRight:=Form1.TrackBar1.Position;
Form1.DirectSS1.Pitch:=Form1.TrackBar2.Position;
Form1.DirectSS1.Speed:=Form1.TrackBar3.Position;
Form1.DirectSS1.Speak(Clipboard.AsText);    // озвучиваем текст
Form1.DirectSS1.LipType :=0;
except // блок операторов, обрабатывающий ошибку исполнения предыдущих операторов
//
end; // освобождение ресурса
                             end;
IF Form1.RadioButton2.Checked THEN begin
try // выделение ресурса
Form1.TextToSpeech1.Speak(Clipboard.AsText);    // озвучиваем текст
Form1.TextToSpeech1.LipTension :=246;
Form1.TextToSpeech1.LipType :=0;
except // блок операторов, обрабатывающий ошибку исполнения предыдущих операторов
//
end; // освобождение ресурса
                             end;
IF Form1.RadioButton3.Checked THEN begin
try // выделение ресурса
Form1.TTS1.Speak(Clipboard.AsText,1);    // озвучиваем текст. Внимание! только при flags=1 возможно остановить движок во время его звучания
except // блок операторов, обрабатывающий ошибку исполнения предыдущих операторов
//
end; // освобождение ресурса
                             end;
//
end;

procedure TForm1.hotykey(var msg:TMessage);
// реагируем на горячие клавиши из других приложений
begin
// ловим нажатие клавиши
if (msg.LParamLo=MOD_CONTROL) and (msg.LParamHi=84) then    // Ctrl + T
begin
SaySpeech;
end;  // (msg.LParamLo=MOD_CONTROL) and (msg.LParamHi=84)
//
// ловим нажатие клавиши
if (msg.LParamLo=MOD_CONTROL) and (msg.LParamHi=66) then    // Ctrl + B
begin
Form1.BitBtn5.Click;
end;  // (msg.LParamLo=MOD_CONTROL) and (msg.LParamHi=66)
//
end;

procedure Proc31;
// активизация голосового модуля
// вывод описания к назначенному голосовому модулю
begin
//
if Form1.RadioButton3.Checked then begin
//
//  активируем голосовой движок
//
if Form1.SpinEdit3.Value > TTS1MaxValue then Form1.SpinEdit3.Value := TTS1MaxValue ;
try // выделение ресурса
//
Form1.Label70.Caption := Form1.TTS1.Voices[Form1.SpinEdit3.Value];
//
if not AutoStart then Form1.Repaint;
Form1.TTS1.VoiceSet(Form1.SpinEdit3.Value); // выбор установленного в системе голосового движка
except // блок операторов, обрабатывающий ошибку
// Exit; // вылетаем из процедуры
end; // освобождение ресурса
//
                                   end;    // Form1.RadioButton3.Checked
//
//
if Form1.RadioButton1.Checked then begin
//  активируем голосовой движок
//
try // выделение ресурса
Form1.DirectSS1.Select(Form1.SpinEdit3.Value); // выбор установленного в системе голосового движка
except // блок операторов, обрабатывающий ошибку
// Exit; // вылетаем из процедуры
end; // освобождение ресурса
//
//
// информация о движке к сведению пользователя
//
try // выделение ресурса
Form1.Label8.Caption := Form1.DirectSS1.EngineID(Form1.SpinEdit3.Value);
except // блок операторов, обрабатывающий ошибку
Form1.Label8.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label9.Caption := Form1.DirectSS1.ModeName(Form1.SpinEdit3.Value);
except // блок операторов, обрабатывающий ошибку
Form1.Label9.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label10.Caption := Form1.DirectSS1.MfgName(Form1.SpinEdit3.Value);
except // блок операторов, обрабатывающий ошибку
Form1.Label10.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label11.Caption := Form1.DirectSS1.ProductName(Form1.SpinEdit3.Value);
except // блок операторов, обрабатывающий ошибку
Form1.Label11.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label12.Caption := Form1.DirectSS1.ModeID(Form1.SpinEdit3.Value);
except // блок операторов, обрабатывающий ошибку
Form1.Label12.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label13.Caption := Form1.DirectSS1.Speaker(Form1.SpinEdit3.Value) ;
except // блок операторов, обрабатывающий ошибку
Form1.Label13.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label14.Caption := Form1.DirectSS1.Style(Form1.SpinEdit3.Value);
except // блок операторов, обрабатывающий ошибку
Form1.Label14.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label15.Caption := IntToStr(Form1.DirectSS1.Gender(Form1.SpinEdit3.Value));
except // блок операторов, обрабатывающий ошибку
Form1.Label15.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label16.Caption := IntToStr(Form1.DirectSS1.Age(Form1.SpinEdit3.Value));
except // блок операторов, обрабатывающий ошибку
Form1.Label16.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label17.Caption := IntToStr(Form1.DirectSS1.Features(Form1.SpinEdit3.Value));
except // блок операторов, обрабатывающий ошибку
Form1.Label17.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label18.Caption := IntToStr(Form1.DirectSS1.Interfaces(Form1.SpinEdit3.Value));
except // блок операторов, обрабатывающий ошибку
Form1.Label18.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label19.Caption := IntToStr(Form1.DirectSS1.EngineFeatures(Form1.SpinEdit3.Value));
except // блок операторов, обрабатывающий ошибку
Form1.Label19.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label20.Caption := IntToStr(Form1.DirectSS1.LanguageID(Form1.SpinEdit3.Value));
except // блок операторов, обрабатывающий ошибку
Form1.Label20.Caption := 'Нет данных';
end; // освобождение ресурса
//
if AutoStart then Exit;
// Громкость
//
try // выделение ресурса
Form1.TrackBar1.Position :=Form1.DirectSS1.VolumeRight;
except // блок операторов, обрабатывающий ошибку
Form1.TrackBar1.Position :=Form1.TrackBar1.Max;
end; // освобождение ресурса
//
// Настройка тональности
//
try // выделение ресурса
If  Form1.TrackBar2.Min>Form1.DirectSS1.MaxPitch then begin
Form1.TrackBar2.Min:=Form1.DirectSS1.MinPitch ;
Form1.TrackBar2.Max:=Form1.DirectSS1.MaxPitch ;
                                                end
else begin
Form1.TrackBar2.Max:=Form1.DirectSS1.MaxPitch ;
Form1.TrackBar2.Min:=Form1.DirectSS1.MinPitch ;
     end;
Form1.TrackBar2.Position:=Form1.DirectSS1.Pitch ;
except // блок операторов, обрабатывающий ошибку
// Break;
end; // освобождение ресурса
//
// Настройка скорости
//
try // выделение ресурса
If  Form1.TrackBar3.Min>Form1.DirectSS1.MaxSpeed then begin
Form1.TrackBar3.Min:=Form1.DirectSS1.MinSpeed ;
Form1.TrackBar3.Max:=Form1.DirectSS1.MaxSpeed ;
                                                end
else begin
Form1.TrackBar3.Max:=Form1.DirectSS1.MaxSpeed ;
Form1.TrackBar3.Min:=Form1.DirectSS1.MinSpeed ;
     end;
Form1.TrackBar3.Position:=Form1.DirectSS1.Speed ;
except // блок операторов, обрабатывающий ошибку
// Break;
end; // освобождение ресурса
                             end; // RadioButton1.Checked
//
//
if Form1.RadioButton2.Checked then begin
//  активируем голосовой движок
//
try // выделение ресурса
Form1.TextToSpeech1.Select(Form1.SpinEdit3.Value); // выбор установленного в системе голосового движка
except // блок операторов, обрабатывающий ошибку
// Exit; // вылетаем из процедуры
end; // освобождение ресурса
//
//
// информация о движке к сведению пользователя
//
try // выделение ресурса             EngineID
Form1.Label45.Caption := Form1.TextToSpeech1.dialect(Form1.SpinEdit3.Value);
except // блок операторов, обрабатывающий ошибку
Form1.Label45.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label42.Caption := Form1.TextToSpeech1.ModeName(Form1.SpinEdit3.Value);
except // блок операторов, обрабатывающий ошибку
Form1.Label42.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label46.Caption := Form1.TextToSpeech1.MfgName(Form1.SpinEdit3.Value);
except // блок операторов, обрабатывающий ошибку
Form1.Label46.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label61.Caption := Form1.TextToSpeech1.ProductName(Form1.SpinEdit3.Value);
except // блок операторов, обрабатывающий ошибку
Form1.Label61.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label60.Caption := Form1.TextToSpeech1.ModeID(Form1.SpinEdit3.Value);
except // блок операторов, обрабатывающий ошибку
Form1.Label60.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label37.Caption := Form1.TextToSpeech1.Speaker(Form1.SpinEdit3.Value) ;
except // блок операторов, обрабатывающий ошибку
Form1.Label37.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label59.Caption := Form1.TextToSpeech1.Style(Form1.SpinEdit3.Value);
except // блок операторов, обрабатывающий ошибку
Form1.Label59.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label38.Caption := IntToStr(Form1.TextToSpeech1.Gender(Form1.SpinEdit3.Value));
except // блок операторов, обрабатывающий ошибку
Form1.Label38.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label41.Caption := IntToStr(Form1.TextToSpeech1.Age(Form1.SpinEdit3.Value));
except // блок операторов, обрабатывающий ошибку
Form1.Label41.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label58.Caption := IntToStr(Form1.TextToSpeech1.Features(Form1.SpinEdit3.Value));
except // блок операторов, обрабатывающий ошибку
Form1.Label58.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label57.Caption := IntToStr(Form1.TextToSpeech1.Interfaces(Form1.SpinEdit3.Value));
except // блок операторов, обрабатывающий ошибку
Form1.Label57.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label56.Caption := IntToStr(Form1.TextToSpeech1.EngineFeatures(Form1.SpinEdit3.Value));
except // блок операторов, обрабатывающий ошибку
Form1.Label56.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label55.Caption := IntToStr(Form1.TextToSpeech1.LanguageID(Form1.SpinEdit3.Value));
except // блок операторов, обрабатывающий ошибку
Form1.Label55.Caption := 'Нет данных';
end; // освобождение ресурса
//
if AutoStart then Exit;
// Громкость              - нет
//
// Настройка тональности  - нет
//
//
// Настройка скорости
//
try // выделение ресурса
Form1.TrackBar3.Position:=Form1.TextToSpeech1.Speed ;
except // блок операторов, обрабатывающий ошибку
// Break;
end; // освобождение ресурса
                             end; // RadioButton2.Checked
end;  // Proc31



procedure RB1Click;
// функция для события RadioButton1.Click  - выбор речевого движка версии 4.01
begin
try
// фиксируем число найденных Text-To-Speech движков
Form1.Label7.Caption:= 'Выберите диктора из числа найденных ('+IntToStr(Form1.DirectSS1.CountEngines)+'):';
Form1.SpinEdit3.MaxValue := Form1.DirectSS1.CountEngines;
if Form1.SpinEdit3.MaxValue>0 then begin
Form1.SpinEdit3.MinValue := 1;
if not AutoStart then Form1.SpinEdit3.Value:=1 else Form1.SpinEdit3.Value:=ModuleAn;
//
// добавленная строка здесь необходима для корректного определния предельных знамений у голосового модуля
Form1.DirectSS1.Select(Form1.SpinEdit3.Value); // выбор установленного в системе голосового движка
// потом опять инициализируем этот же голосовой модуль для воспроизведения
//
// Громкость
if not AutoStart then Form1.TrackBar1.Position:=Form1.DirectSS1.VolumeRight else begin
Form1.TrackBar1.Position:=AnVolume;
Form1.DirectSS1.VolumeRight:=Form1.TrackBar1.Position;
Form1.DirectSS1.VolumeLeft:= Form1.TrackBar1.Position;
                                                                                 end;
// Настройка тональности
// настройку предельных значений следовало бы оставить в процедуре Proc31
If  Form1.TrackBar2.Min>Form1.DirectSS1.MaxPitch then begin
Form1.TrackBar2.Min:=Form1.DirectSS1.MinPitch ;
Form1.TrackBar2.Max:=Form1.DirectSS1.MaxPitch ;
                                                end
else begin
Form1.TrackBar2.Max:=Form1.DirectSS1.MaxPitch ;
Form1.TrackBar2.Min:=Form1.DirectSS1.MinPitch ;
     end;
if not AutoStart then Form1.TrackBar2.Position:=Form1.DirectSS1.Pitch else begin
Form1.TrackBar2.Position:=AnPitch;
Form1.DirectSS1.Pitch:=AnPitch;
                                                                           end;
// Настройка скорости
// настройку предельных значений следовало бы оставить в процедуре Proc31
If  Form1.TrackBar3.Min>Form1.DirectSS1.MaxSpeed then begin
Form1.TrackBar3.Min:=Form1.DirectSS1.MinSpeed ;
Form1.TrackBar3.Max:=Form1.DirectSS1.MaxSpeed ;
                                                end
else begin
Form1.TrackBar3.Max:=Form1.DirectSS1.MaxSpeed ;
Form1.TrackBar3.Min:=Form1.DirectSS1.MinSpeed ;
     end;
if not AutoStart then Form1.TrackBar3.Position:=Form1.DirectSS1.Speed else begin
Form1.TrackBar3.Position:=AnSpeed;
Form1.DirectSS1.Speed:=AnSpeed;
                                                                           end;
//
                                    end;
except
Exit;
end;
//
Proc31;
//
Form1.Panel3.Visible:=True ;
Form1.Panel5.Visible:=False ;
Form1.Panel7.Visible:=False;
//
Form1.Label3.Visible:=True;
Form1.Label4.Visible:=True;
Form1.Label65.Visible:=False;
//
Announcer:=1;
SaveCFG;
end;

procedure RB2Click;
// функция для события RadioButton2.Click  - выбор речевого движка версии 4.01
begin
//
try
// число найденных Text-To-Speech движков
Form1.Label7.Caption:= 'Выберите диктора из числа найденных ('+IntToStr(Form1.TextToSpeech1.CountEngines)+'):';
Form1.SpinEdit3.MaxValue := Form1.TextToSpeech1.CountEngines;
if Form1.SpinEdit3.MaxValue>0 then begin
Form1.SpinEdit3.MinValue := 1;
if not AutoStart then Form1.SpinEdit3.Value:=1 else Form1.SpinEdit3.Value:=ModuleAn;
//
// Громкость     - нет
//
// Настройка скорости
Form1.TrackBar3.Max:=500;
Form1.TrackBar3.Min:=1;
if not AutoStart then Form1.TrackBar3.Position:=Form1.TextToSpeech1.Speed else Form1.TrackBar6.Position:=AnSpeed;
//
                                    end;
except
Exit;
end;
//
Proc31;
//
Form1.Panel3.Visible:=False ;
Form1.Panel5.Visible:=True ;
Form1.Panel7.Visible:=False;
//
Form1.Label3.Visible:=False;
Form1.Label4.Visible:=False;
Form1.Label65.Visible:=True;
//
Announcer:=2;
SaveCFG;
end;

procedure RB3Click;
// функция для события RadioButton3.Click  - выбор речевого движка версии 5.1
begin
//
// число найденных Text-To-Speech модулей
Form1.Label7.Caption:= 'Выберите диктора из числа найденных ('+IntToStr(TTS1MaxValue)+'):';
//
Form1.SpinEdit3.MaxValue:=TTS1MaxValue;
//
if Form1.SpinEdit3.MaxValue>0 then begin
//
Form1.SpinEdit3.MinValue:=1   ;
//
if not AutoStart then begin
if Form1.SpinEdit3.Value>TTS1MaxValue then Form1.SpinEdit3.Value:=Form1.SpinEdit3.MaxValue;
                      end
else Form1.SpinEdit3.Value:=ModuleAn;
//
//
try
// Настройка громкости
if not AutoStart then Form1.TrackBar8.Position:=Form1.TTS1.Volume else begin
                           Form1.TrackBar8.Position:=AnVolume;
                           Form1.TTS1.Volume:=AnVolume;
                                                                       end;
// Настройка тональности  - нет
// Настройка скорости
if not AutoStart then Form1.TrackBar9.Position:=Form1.TTS1.Speed else begin
                           Form1.TrackBar9.Position:=AnSpeed;
                           Form1.TTS1.Speed:=AnSpeed;
                                                                       end;
except
Exit;
end;
                                    end;
//
//
//
Proc31;
//
Form1.Panel3.Visible:=False ;
Form1.Panel5.Visible:=False ;
Form1.Panel7.Visible:=True;
//
Form1.Label3.Visible:=True;
Form1.Label4.Visible:=True;
Form1.Label65.Visible:=False;
//
if not AutoStart then Form1.Repaint;
//
Announcer:=3;
SaveCFG;
end;


procedure TForm1.RebuildWindowRgn;
// перестроение региона окна программы
var
FullRgn, Rgn,Rgn10, Rgn20: THandle;
  Points: Array [0..5] of TPoint;
begin
// определяем относительные координаты клиентской части
FullRgn:= CreateRectRgn(0, 0, Width, Height); // создаем регион для всей формы
//
if StyleRebuildWindow=1 then begin
//
//Rgn:=0;
// for ii51:=0 to Height div 2 -1 do begin
Rgn:= CreateRoundRectRgn(0, 0, Width, Height, EllipseWidth, EllipseHigth);
CombineRgn(FullRgn, Rgn, Rgn, rgn_Diff);  // внутренняя часть
// CombineRgn(FullRgn,FullRgn ,Rgn , rgn_Diff); // наружная часть
//
//
// включаем перерисовываемый компонент формы в отрисовываемый регион
with Form1.Button1 do begin
// вычитаем квадрат
Rgn20:= CreateRectRgn(Left, Top, Left+Width, Top+Height);
CombineRgn(Rgn,Rgn ,Rgn20 , rgn_Diff);
//  рисуем круг
//Rgn10:= CreateRoundRectRgn(Left, Top, Left+Height, Top+Height, Height-3, Height-3);
Rgn10:= CreateRoundRectRgn(Left+3, Top+3, Left+Height-2, Top+Height-2, Height-3, Height-3);
CombineRgn(Rgn,Rgn ,Rgn10 , RGN_OR);
Visible:=True;
end;
// в результате получили комбинированный вырез окна программы
//
// SetWindowRgn(Handle, FullRgn, False); // устанавливаем новый регион окна  для наружной его  части
 SetWindowRgn(Handle, Rgn, True); // устанавливаем новый регион окна  для наружной его  части
//
                               end; // StyleRebuildWindow=1
//
//
if StyleRebuildWindow=2 then begin
//
Rgn:= CreateEllipticRgn(0, 0, Width, Height);
CombineRgn(FullRgn,Rgn ,Rgn , rgn_Diff);
SetWindowRgn(Handle, Rgn, True); // устанавливаем новый регион окна
//
                               end; // StyleRebuildWindow=2
//
//
if StyleRebuildWindow=3 then begin
//
  Points[0] := Point(0, Height div 10);
  Points[1] := Point(Width div 20, 0);
  Points[2] := Point(Width div 2, Height div 10);
  Points[3] := Point(Width - (Width div 20), 0);
  Points[4] := Point(Width, Height div 10);
  Points[5] := Point(Width div 2, Height);
Rgn:= CreatePolygonRgn(Points[0], 6, ALTERNATE);
CombineRgn(FullRgn,Rgn ,Rgn , rgn_Diff);
SetWindowRgn(Handle, Rgn, True); // устанавливаем новый регион окна
//
                               end; // StyleRebuildWindow=3
//
end;


procedure Proc32;
//  сохранение новых координат окна программы при наступлении события
//  над формой окна программы
begin
//
Form1.WindowState:=wsNormal;
Form1WindowState:=1 ;
// перестроим форму
Form1.RebuildWindowRgn;
//
//
 LeftFrmPos :=Form1.Left;
 TopFrmPos :=Form1.Top;
 WidthFrmPos :=Form1.Width;
 HeightFrmPos :=Form1.Height;
//
SaveCFG;
//
end;


procedure TForm1.FormResize(Sender: TObject);
// все понятно
begin
if AutoStart=True then Exit; // ничего не делаем, если стартуем
//
EllipseWidth:=Round(KoeffEllipseWidth*Form1.Width);
EllipseHigth:=Round(KoeffEllipseHigth*Form1.Height);
//
RebuildWindowRgn; // строим новый регион
//
Form1.Label1.Left:=(Form1.Width div 2) - (Form1.Label1.Width div 2);
Form1.Label1.Top:=0;
Form1.Label2.Left:=(Form1.Width div 2) - (Form1.Label2.Width div 2);
Form1.Label2.Top:=Form1.Height-Form1.Label2.Height;
//
try
KoeffEllipseWidth:=EllipseWidth/Form1.Width;
KoeffEllipseHigth:=EllipseHigth/Form1.Height;
except
end;
//
 LeftFrmPos :=Form1.Left;
 TopFrmPos :=Form1.Top;
 WidthFrmPos :=Form1.Width;
 HeightFrmPos :=Form1.Height;
//
SaveCFG;
end;

procedure TForm1.WMNCHitTest(var M: TWMNCHitTest);
// к технологии перетаскивания формы окна программы мышью
begin
inherited; // вызов унаследованного обработчика
if M.Result = htClient then // мышь сидит на окне?
M.Result := htCaption; // если Да, то пусть Windows думает, что мышь на caption bar
end;

procedure TForm1.FormCreate(Sender: TObject);
// все понятно
label 10, 20;
var ii96: Integer;
begin
inherited;   // ?
AutoStart:=True;
//
  MainCaptionProgram:='Тестер электронных дикторов' ;
//
// открытие файла конфигуратора
If FileExists('e-s.cfg') then begin
//{$V-}
AssignFile(OldFile,'e-s.cfg');
     {$I-}                  { Выключение проверки ввода-вывода }
Reset(OldFile);
     {$I+}                  { Восстановление проверки ввода-вывода }
     if IOResult<>0         { Если файл не может быть открыт, то   }
        then begin          {                     }
        ShowMessage('Не удается открыть Файл-конфигуратор e-s.cfg');
         goto 10;
             end;
//
     {$I-}                  { Выключение проверки ввода-вывода }
readln(OldFile,LeftFrmPos);
     {$I+}                  { Восстановление проверки ввода-вывода }
     if IOResult<>0         { Если файл не может быть открыт, то   }
        then begin          {                      }
        ShowMessage('Ошибка в Файле-конфигураторе e-s.cfg. Возоблены настройки по умолчанию.');
//        CloseFile(OldFile); // закрыли файл
//        DeleteFile('e-s.cfg');// удалили файл
//        Close;              // функция закрытия программы не работает
//        Application.Terminate; // эта функция закрытия программы тоже не работает
         goto 10;
             end;
     {$I-}                  { Выключение проверки ввода-вывода }
readln(OldFile,TopFrmPos);
     {$I+}                  { Восстановление проверки ввода-вывода }
     if IOResult<>0         { Если файл не может быть открыт, то   }
        then begin          {                     }
        ShowMessage('Ошибка в Файле-конфигураторе e-s.cfg. Возоблены настройки по умолчанию.');
         goto 10;
             end;
     {$I-}                  { Выключение проверки ввода-вывода }
readln(OldFile,WidthFrmPos);
     {$I+}                  { Восстановление проверки ввода-вывода }
     if IOResult<>0         { Если файл не может быть открыт, то   }
        then begin          { ничего не делаем                     }
        ShowMessage('Ошибка в Файле-конфигураторе e-s.cfg. Возоблены настройки по умолчанию.');
         goto 10;
             end;
     {$I-}                  { Выключение проверки ввода-вывода }
readln(OldFile,HeightFrmPos);
     {$I+}                  { Восстановление проверки ввода-вывода }
     if IOResult<>0         { Если файл не может быть открыт, то   }
        then begin          { ничего не делаем                     }
        ShowMessage('Ошибка в Файле-конфигураторе e-s.cfg. Возоблены настройки по умолчанию.');
         goto 10;
             end;
     {$I-}                  { Выключение проверки ввода-вывода }
readln(OldFile, EllipseWidth );
     {$I+}                  { Восстановление проверки ввода-вывода }
     if IOResult<>0         { Если файл не может быть открыт, то   }
        then begin          { ничего не делаем                     }
        ShowMessage('Ошибка в Файле-конфигураторе e-s.cfg. Возоблены настройки по умолчанию.');
         goto 10;
             end;
     {$I-}                  { Выключение проверки ввода-вывода }
readln(OldFile, EllipseHigth );
     {$I+}                  { Восстановление проверки ввода-вывода }
     if IOResult<>0         { Если файл не может быть открыт, то   }
        then begin          { ничего не делаем                     }
        ShowMessage('Ошибка в Файле-конфигураторе e-s.cfg. Возоблены настройки по умолчанию.');
         goto 10;
             end;
     {$I-}                  { Выключение проверки ввода-вывода }
readln(OldFile, StyleRebuildWindow );
     {$I+}                  { Восстановление проверки ввода-вывода }
     if IOResult<>0         { Если файл не может быть открыт, то   }
        then begin          { ничего не делаем                     }
        ShowMessage('Ошибка в Файле-конфигураторе e-s.cfg. Возоблены настройки по умолчанию.');
         goto 10;
             end;
     {$I-}                  { Выключение проверки ввода-вывода }
readln(OldFile, Form1WindowState );
     {$I+}                  { Восстановление проверки ввода-вывода }
     if IOResult<>0         { Если файл не может быть открыт, то   }
        then begin          { ничего не делаем                     }
        ShowMessage('Ошибка в Файле-конфигураторе e-s.cfg. Возоблены настройки по умолчанию.');
         goto 10;
             end;
     {$I-}                  { Выключение проверки ввода-вывода }
readln(OldFile, CustomColor01 );
     {$I+}                  { Восстановление проверки ввода-вывода }
     if IOResult<>0         { Если файл не может быть открыт, то   }
        then begin          { ничего не делаем                     }
        ShowMessage('Ошибка в Файле-конфигураторе e-s.cfg. Возоблены настройки по умолчанию.');
         goto 10;
             end;
     {$I-}                  { Выключение проверки ввода-вывода }
readln(OldFile, Announcer );
     {$I+}                  { Восстановление проверки ввода-вывода }
     if IOResult<>0         { Если файл не может быть открыт, то   }
        then begin          { ничего не делаем                     }
        ShowMessage('Ошибка в Файле-конфигураторе e-s.cfg. Возоблены настройки по умолчанию.');
         goto 10;
             end;
     {$I-}                  { Выключение проверки ввода-вывода }
readln(OldFile, ModuleAn );
     {$I+}                  { Восстановление проверки ввода-вывода }
     if IOResult<>0         { Если файл не может быть открыт, то   }
        then begin          { ничего не делаем                     }
        ShowMessage('Ошибка в Файле-конфигураторе e-s.cfg. Возоблены настройки по умолчанию.');
         goto 10;
             end;
     {$I-}                  { Выключение проверки ввода-вывода }
readln(OldFile, AnVolume );
     {$I+}                  { Восстановление проверки ввода-вывода }
     if IOResult<>0         { Если файл не может быть открыт, то   }
        then begin          { ничего не делаем                     }
        ShowMessage('Ошибка в Файле-конфигураторе e-s.cfg. Возоблены настройки по умолчанию.');
         goto 10;
             end;
     {$I-}                  { Выключение проверки ввода-вывода }
readln(OldFile, AnPitch );
     {$I+}                  { Восстановление проверки ввода-вывода }
     if IOResult<>0         { Если файл не может быть открыт, то   }
        then begin          { ничего не делаем                     }
        ShowMessage('Ошибка в Файле-конфигураторе e-s.cfg. Возоблены настройки по умолчанию.');
         goto 10;
             end;
     {$I-}                  { Выключение проверки ввода-вывода }
readln(OldFile, AnSpeed );
     {$I+}                  { Восстановление проверки ввода-вывода }
     if IOResult<>0         { Если файл не может быть открыт, то   }
        then begin          { ничего не делаем                     }
        ShowMessage('Ошибка в Файле-конфигураторе e-s.cfg. Возоблены настройки по умолчанию.');
         goto 10;
             end;
//
goto 20;
10:
// принимаем значения по-умолчанию
 LeftFrmPos:=Form1.Left;
 TopFrmPos:=Form1.Top;
 WidthFrmPos:=Form1.Width;
 HeightFrmPos:=Form1.Height;
 Form1WindowState:=1 ;
 CustomColor01 := Form1.Color;
// назначаем новые значения
EllipseWidth:=50;  // Form1.Width
EllipseHigth:=50;  // Form1.Height
StyleRebuildWindow:=1;
Form1.Position :=poDesktopCenter;
//
Announcer:=0;
ModuleAn:=0;
AnVolume:=0;
AnPitch:=0;
AnSpeed:=0;
// остальные параметры берем из проектных данных
//
//        Application.Terminate;            // закрыли программу
//
20: CloseFile(OldFile);
//
//{$V+}
// на всякий случай исправляем нулевые данные
if WidthFrmPos<50 then begin WidthFrmPos:=Form1.Width; Form1.Position :=poDesktopCenter; end;
if HeightFrmPos<50 then begin HeightFrmPos:=Form1.Height; Form1.Position :=poDesktopCenter; end;
if CustomColor01=0 then CustomColor01:= 15793151;
//
try
KoeffEllipseWidth:=EllipseWidth/WidthFrmPos;
KoeffEllipseHigth:=EllipseHigth/HeightFrmPos;
except
end;
 Form1.Left:=LeftFrmPos;
 Form1.Top:=TopFrmPos;
 Form1.Width:=WidthFrmPos;   // вызывает процедуру FormResize, хотя Form1.Heigh еще не переопределен, поэтму нам необходимо отключить вызов этой процедуры при старте программы
 Form1.Height:=HeightFrmPos; // вызывает процедуру FormResize, поэтму нам необходимо вычислить KoeffEllipseWidth, KoeffEllipseHigth
If Form1WindowState=0 then Form1.WindowState:=wsMinimized;
If Form1WindowState=1 then Form1.WindowState:=wsNormal ;
If Form1WindowState=2 then Form1.WindowState:=wsMaximized ;
//
  Form1.ColorDialog1.Color:=CustomColor01;
  Form1.Color := Form1.ColorDialog1.Color;
  Form1.Panel3.Color := Form1.ColorDialog1.Color;
  Form1.Panel5.Color := Form1.ColorDialog1.Color;
  Form1.Panel7.Color := Form1.ColorDialog1.Color;
  Form1.Panel4.Color := Form1.ColorDialog1.Color;
  Form1.Panel6.Color := Form1.ColorDialog1.Color;
  Form1.Panel8.Color := Form1.ColorDialog1.Color;
//
//
                              end
else begin
// принимаем значения
 LeftFrmPos:=Form1.Left;
 TopFrmPos:=Form1.Top;
 WidthFrmPos:=Form1.Width;
 HeightFrmPos:=Form1.Height;
 Form1WindowState:=1 ;
 CustomColor01 := Form1.Color;
// назначаем новые значения
EllipseWidth:=50;  // Form1.Width
EllipseHigth:=50;  // Form1.Height
StyleRebuildWindow:=1;
Form1.Position :=poDesktopCenter;
//
Announcer:=0;
ModuleAn:=0;
AnVolume:=0;
AnPitch:=0;
AnSpeed:=0;
// остальные параметры берем из проектных данных
//
     end;
//
// использование клавишных эквивалентов команд    - Том Сван "Основы программирования в ..." 96 г. стр. 109
N1.ShortCut:=ShortCut(vk_F4,[ssAlt]);
N2.ShortCut:=ShortCut(vk_F2,[]);
N3.ShortCut:=ShortCut(vk_F3,[]);
N4.ShortCut:=ShortCut(vk_F4,[]);
N6.ShortCut:=ShortCut(vk_F12,[]);
N7.ShortCut:=ShortCut(vk_F11,[]);
//
// регистрация горячих клавиш в Windows
iKey01:=GlobalAddAtom('hotkey01');
RegisterHotKey(handle,iKey01,mod_control,84);
iKey02:=GlobalAddAtom('hotkey02');
RegisterHotKey(handle,iKey02,mod_control,66);
//
// инициализируем движки четвертой версии
//
// Если на форму сбросить визуальные компоненты DirectSS и TextToSpeech от Microsoft,
// то программа не запуститься под операционкой без предустановленных
// драйверов речевого движка (проверено!)
//
try // выделение ресурса
  DirectSS1 := TDirectSS.Create(Self); // создаем движок
with DirectSS1 do begin
  Parent        := Self;     // указание на отображение компонента (Губы)
  Height        := 25;
  Hint          := 'Движок Direct Speech - SYSTEM\speech\XVoice.dll';
  Left          := 464;
  LipTension    := 255;
  LipType       := 0;
  MouthEnabled  := 1;
  MouthHeight   := 240;
  MouthUpturn   := 50;
  MouthWidth    := 230;
  ShowHint      := True;
  TabOrder      := 4;
  Top           := 146;
  Width         := 41;
  Visible       := True;
  Initialized   := 1; // привязывает к первому голосовому модулю (у меня - к английскому),
//  исключая возможность автонастройки на русский голосовой модуль,
//  а это значит, что при старте программы мы видим данные не к инициированному голосовому движку
//   Initialized   := 0;  // можно стартовать с голосового модуля по-умолчанию
                  end;
//
Form1.Panel3.Visible:=True;
//
except // блок операторов, обрабатывающий ошибку исполнения предыдущих операторов
//
Form1.RadioButton1.Visible:=False;
Form1.DirectSS1.Visible   :=False;
//
end; // освобождение ресурса
//
//
try // выделение ресурса
  TextToSpeech1 := TTextToSpeech.Create(Self); // создаем движок
with TextToSpeech1 do begin
  Parent        := Self;     // указание на отображение компонента (Губы)
  Height        := 25;
  Hint          := 'Движок Text-To-Speech - SYSTEM\speech\Vtext.dll';
  Left          := 552;
  LipTension    := 255;
  LipType       := 0;
  MouthHeight   := 240;
  MouthUpturn   := 50;
  MouthWidth    := 230;
  ShowHint      := True;
  TabOrder      := 6;
  Top           := 146;
  Width         := 41;
  Visible       := True;
  TTSMode       := 'c5c35d60-da44-11d1-B1F1-0000F803E456'; // на всякий случай
// здесь при сбоях в системе возможна ошибка инициализации    ...
  Initialized   := 0;
                  end;
//
Form1.Panel3.Visible:=True;
//
except // блок операторов, обрабатывающий ошибку исполнения предыдущих операторов
//
Form1.RadioButton2.Visible  :=False;
Form1.TextToSpeech1.Visible :=False;  // ... поэтому убрали графический мусор с экрана
//
end; // освобождение ресурса
//
//
//
//
//
//
// инициализируем движок пятой версии
//
// Если на форму сбросить визуальный компонент TTS от IBM (Wizzard's Production),
// то программа может не запуститься под операционкой без предустановленных
// драйверов речевого движка (проверено!)
//
try // выделение ресурса
  TTS1 := TTTS.Create(Self); // создаем движок
  Form1.TTS1.Init;
// компонент не визуален
//
for ii96:=1 to 500 do begin    // цикл по максимально возможному числу голосовых модулей
/// Form1.SpinEdit3.Value:=ii96 ;
// оценка ошибки выполнения программы при текущем значении Form1.SpinEdit3.Value
try // выделение ресурса
/// Form1.Label70.Caption := Form1.TTS1.Voices[Form1.SpinEdit3.Value];
Form1.Label70.Caption := Form1.TTS1.Voices[ii96];
{ в предыдущей строке во время отладочного выполнения выдается следующее предупреждение
---------------------------
Debugger Exception Notification
---------------------------
Project FreeFrm.exe raised exception class EVariantError with message 'Variant array index out of bounds'. Process stopped. Use Step or Run to continue.
---------------------------
OK   Help
---------------------------
эту ошибку мы вызываем искуственно, чтобы определить количество установленных
в системе голосовых модуле к пятому движку:
TTS1MaxValue приравниваем Form1.SpinEdit3.Value;
}
except // блок операторов, обрабатывающий ошибку
/// Form1.SpinEdit3.MaxValue:= Form1.SpinEdit3.Value-1;
/// Form1.SpinEdit3.Value:= Form1.SpinEdit3.MaxValue;
TTS1MaxValue:= ii96-1;
Break;  // ii95:=0 to 500
end; // освобождение ресурса
//
                       end;  // ii95:=0 to 500
/// TTS1MaxValue:= Form1.SpinEdit3.Value;
//
except // блок операторов, обрабатывающий ошибку исполнения предыдущих операторов
//ShowMessage('Движок пятой версии не установлен');  // излишнее мерцание окон
RadioButton3.Visible:=False;
end; // освобождение ресурса
//
try // выделение ресурса
// после всех предварительных настроек отображаем стартовре рабочее состояние
//
// назначаем активный речевой движок и голосовой модуль по умолчанию
// признак необходимости в настройках по-умолчанию - Announcer=0
if (Announcer=0) and  (RadioButton1.Visible) then begin
                                                  Announcer:=1;
                                                   ModuleAn:=1;
      Form1.SpinEdit3.MaxValue := Form1.DirectSS1.CountEngines;
                                      Form1.SpinEdit3.Value:=1;
                                                   end
else if (Announcer=0) and  (RadioButton2.Visible) then begin
                                                  Announcer:=2;
                                                   ModuleAn:=1;
  Form1.SpinEdit3.MaxValue := Form1.TextToSpeech1.CountEngines;
                                      Form1.SpinEdit3.Value:=1;
                                                        end
     else if (Announcer=0) and  (RadioButton3.Visible) then  begin
                                                    Announcer:=3;
                                                     ModuleAn:=1;
                         Form1.SpinEdit3.MaxValue :=TTS1MaxValue;
                                        Form1.SpinEdit3.Value:=1;
                                                             end
//
except // блок операторов, обрабатывающий ошибку
end; // освобождение ресурса
//
//
//
if Announcer=1 then  begin
Form1.RadioButton1.Checked:=True;
RB1Click;
                     end;
if Announcer=2 then  begin
Form1.RadioButton2.Checked:=True;
RB2Click;
                     end;
if Announcer=3 then  begin
Form1.RadioButton3.Checked:=True;
RB3Click;
                     end;
//
//
//
RebuildWindowRgn; // строим регион
//
Form1.Label1.Left:=(Form1.Width div 2) - (Form1.Label1.Width div 2);
Form1.Label2.Left:=(Form1.Width div 2) - (Form1.Label2.Width div 2);
Form1.Label2.Top:=Form1.Height-Form1.Label2.Height;
//
//
try      // контроль деления на ноль
KoeffEllipseWidth:=EllipseWidth/Form1.Width;
KoeffEllipseHigth:=EllipseHigth/Form1.Height;
except
end;
//
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
// к технологии перетаскивания формы окна программы мышью
begin
  xpos:=Mouse.CursorPos.x-ShiftX;
  ypos:=Mouse.CursorPos.y-ShiftY;
  if Move=True then MoveWindow(Form1.Handle,xpos,ypos,Form1.Width,Form1.Height,Move);//Перетаскивание окна формы
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
// к технологии перетаскивания формы окна программы мышью
begin
  if Button=mbLeft then begin
    Move:=True;
    ShiftX:=X+(Form1.Width-Form1.ClientWidth);
    ShiftY:=Y+(Form1.Height-Form1.ClientHeight);
  end;
end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
// к технологии перетаскивания формы окна программы мышью
begin
  Move:=False;
//
 LeftFrmPos :=Form1.Left;
 TopFrmPos :=Form1.Top;
 WidthFrmPos :=Form1.Width;
 HeightFrmPos :=Form1.Height;
//
SaveCFG;
//
end;

procedure TForm1.Label1Click(Sender: TObject);
// хотим Развернуть окно программы
begin
try
KoeffEllipseWidth:=EllipseWidth/Form1.Width;
KoeffEllipseHigth:=EllipseHigth/Form1.Height;
except
end;
//
Form1.WindowState:=wsMaximized;
Form1WindowState:=2 ;
//Form1.Left:=0;
//Form1.Top:=0;
Form1.Label1.Caption:='/\';
//
Form1.Label1.Left:=(Form1.Width div 2) - (Form1.Label1.Width div 2);
Form1.Label1.Top:=0;
Form1.Label2.Left:=(Form1.Width div 2) - (Form1.Label2.Width div 2);
Form1.Label2.Top:=Form1.Height-Form1.Label2.Height;
//
//
{
EllipseWidth:=Round(KoeffEllipseWidth*Form1.Width);
EllipseHigth:=Round(KoeffEllipseHigth*Form1.Height);
RebuildWindowRgn;
}
SaveCFG;
end;


procedure TForm1.Label2Click(Sender: TObject);
// хотим Вернуть окно программы в предыдущее состояние
begin
try
KoeffEllipseWidth:=EllipseWidth/Form1.Width;
KoeffEllipseHigth:=EllipseHigth/Form1.Height;
except
end;
//
Form1.WindowState:=wsNormal;
Form1WindowState:=1 ;
Form1.Label2.Caption:='\/';
// end;
Form1.Label1.Left:=(Form1.Width div 2) - (Form1.Label1.Width div 2);
Form1.Label1.Top:=0;
Form1.Label2.Left:=(Form1.Width div 2) - (Form1.Label2.Width div 2);
Form1.Label2.Top:=Form1.Height-Form1.Label2.Height;
//
//
{
EllipseWidth:=Round(KoeffEllipseWidth*Form1.Width);
EllipseHigth:=Round(KoeffEllipseHigth*Form1.Height);
RebuildWindowRgn;
}
//
SaveCFG;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
// обрабатываем горячие клавиши программы
begin
//
if (Key=112) and not (ssShift in Shift) and not (ssAlt in Shift) and not (ssCtrl in Shift)  then begin       {F1}
Form2.ShowModal;
Exit;
                                                                      end;
//
// Озвучивание текста
if (Key=117) and not (ssShift in Shift) and not (ssAlt in Shift) and not (ssCtrl in Shift)  then begin       {F6}
Form1.BitBtn4.Click;
Exit;
                                                                      end;
// масштабирование полигонов
try
KoeffEllipseWidth:=EllipseWidth/Form1.Width;
KoeffEllipseHigth:=EllipseHigth/Form1.Height;
except
end;
//
if (Key=VK_Left) and not (ssShift in Shift) and (ssCtrl in Shift) and (ssAlt in Shift) then begin
if Form1.Width>50 then Form1.Width:=Form1.Width-30;
if Form1.Width<50 then Form1.Width:=50;
Proc32; // перерисовка формы и сохранение новых данных в файл-конфигуратор
                                                   end;  {Ctrl+Alt+<-}
if (Key=VK_Right) and not (ssShift in Shift) and (ssCtrl in Shift) and (ssAlt in Shift) then begin
Form1.Width:=Form1.Width+30;
Proc32;
                                                   end;  {Ctrl+Alt+->}
if (Key=VK_Down) and not (ssShift in Shift) and (ssCtrl in Shift) and (ssAlt in Shift) then begin
Form1.Height:=Form1.Height+30;
Proc32;
                                                   end;  {Ctrl+Alt+\/}
if (Key=VK_Up) and not (ssShift in Shift) and (ssCtrl in Shift) and (ssAlt in Shift) then begin
if Form1.Height>50 then Form1.Height:=Form1.Height-30;
if Form1.Height<50 then Form1.Height:=50;
Proc32;
                                                   end;  {Ctrl+Alt+/\}
//
if (Key=VK_Left) and (ssShift in Shift) and (ssCtrl in Shift) and (ssAlt in Shift) then begin
if Form1.Width>50 then Form1.Width:=Form1.Width-1;
                                                   end;  {Shift+Ctrl+Alt+<-}
if (Key=VK_Right) and (ssShift in Shift) and (ssCtrl in Shift) and (ssAlt in Shift) then begin
Form1.Width:=Form1.Width+1;
Proc32;
                                                   end;  {Shift+Ctrl+Alt+->}
if (Key=VK_Down) and (ssShift in Shift) and (ssCtrl in Shift) and (ssAlt in Shift) then begin
Form1.Height:=Form1.Height+1;
Proc32;
                                                   end;  {Shift+Ctrl+Alt+\/}
if (Key=VK_Up) and (ssShift in Shift) and (ssCtrl in Shift) and (ssAlt in Shift) then begin
if Form1.Height>50 then Form1.Height:=Form1.Height-1;
Proc32;
                                                   end;  {Shift+Ctrl+Alt+/\}
//
//
//
if (Key=36) and not (ssShift in Shift) and (ssCtrl in Shift) and (ssAlt in Shift) then begin
if EllipseWidth>0 then EllipseWidth:=EllipseWidth-30;
if EllipseWidth<0 then EllipseWidth:=0;
Proc32;
                                                   end;  {Ctrl+Alt+Home}
if (Key=35) and not (ssShift in Shift) and (ssCtrl in Shift) and (ssAlt in Shift) then begin
if EllipseWidth<Form1.Width then EllipseWidth:=EllipseWidth+30;
if EllipseWidth>Form1.Width then EllipseWidth:=EllipseWidth;
Proc32;
                                                   end;  {Ctrl+Alt+End}
if (Key=34) and not (ssShift in Shift) and (ssCtrl in Shift) and (ssAlt in Shift) then begin
if EllipseHigth<Form1.Height then EllipseHigth:=EllipseHigth+30;
if EllipseHigth>Form1.Height then EllipseHigth:=Form1.Height;
Proc32;
                                                   end;  {Ctrl+Alt+PgDn}
if (Key=33) and not (ssShift in Shift) and (ssCtrl in Shift) and (ssAlt in Shift) then begin
if EllipseHigth>0 then EllipseHigth:=EllipseHigth-30;
if EllipseHigth<0 then EllipseHigth:=0;
Proc32;
                                                   end;  {Ctrl+Alt+PgUp}
//
if (Key=36) and (ssShift in Shift) and (ssCtrl in Shift) and (ssAlt in Shift) then begin
if EllipseWidth>0 then EllipseWidth:=EllipseWidth-1;
Proc32;
                                                   end;  {Shift+Ctrl+Alt+Home}
if (Key=35) and (ssShift in Shift) and (ssCtrl in Shift) and (ssAlt in Shift) then begin

if EllipseWidth<Form1.Width then EllipseWidth:=EllipseWidth+1;
Proc32;
                                                   end;  {Shift+Ctrl+Alt+End}
if (Key=34) and (ssShift in Shift) and (ssCtrl in Shift) and (ssAlt in Shift) then begin
if EllipseHigth<Form1.Height then EllipseHigth:=EllipseHigth+1;
Proc32;
                                                   end;  {Shift+Ctrl+Alt+PgDn}
if (Key=33) and (ssShift in Shift) and (ssCtrl in Shift) and (ssAlt in Shift) then begin
if EllipseHigth>0 then EllipseHigth:=EllipseHigth-1;
Proc32;
                                                   end;  {Shift+Ctrl+Alt+PgUp}
//
//
//
if (Key=109) and not (ssShift in Shift) and (ssCtrl in Shift) and (ssAlt in Shift) then begin
if Form1.Left>0 then Form1.Left:=Form1.Left-1;
Proc32;
                                                   end;  {Ctrl+Alt+серый минус}
if (Key=107) and not (ssShift in Shift) and (ssCtrl in Shift) and (ssAlt in Shift) then begin
Form1.Left:=Form1.Left+1;
Proc32;
                                                   end;  {Ctrl+Alt+серый плюс}
if (Key=107) and (ssShift in Shift) and (ssCtrl in Shift) and (ssAlt in Shift) then begin
Form1.Top:=Form1.Top+1;
Proc32;
                                                   end;  {Shift+Ctrl+Alt+серый плюс}
if (Key=109) and (ssShift in Shift) and (ssCtrl in Shift) and (ssAlt in Shift) then begin
if Form1.Top>0 then Form1.Top:=Form1.Top-1;
Proc32;
                                                   end;  {Shift+Ctrl+Alt+серый минус}
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
// хотим видеть прямоугольное окно
begin
StyleRebuildWindow:=1;
RebuildWindowRgn;
SaveCFG;
end;

procedure TForm1.BitBtn2Click(Sender: TObject);
// хотим видеть круглое окно
begin
StyleRebuildWindow:=2;
RebuildWindowRgn;
SaveCFG;
end;

procedure TForm1.BitBtn3Click(Sender: TObject);
// хотим видеть самолетик
begin
StyleRebuildWindow:=3;
RebuildWindowRgn;
SaveCFG;
end;


procedure TForm1.Button1Click(Sender: TObject);
// закрытие программы
begin
Close;
end;

procedure TForm1.BitBtn5Click(Sender: TObject);
// остановить речевой движок
begin
try // выделение ресурса
if Form1.RadioButton1.Checked then Form1.DirectSS1.AudioReset;
if Form1.RadioButton2.Checked then Form1.TextToSpeech1.StopSpeaking;
if Form1.RadioButton3.Checked then Form1.TTS1.Stop;
except // блок операторов, обрабатывающий ошибку
//
end; // освобождение ресурса
end;

procedure TForm1.SpinEdit4Change(Sender: TObject);
// выбор голосового модуля
begin
if AutoStart then Exit;
// без выполнения нижеследующего кода можно бегать по бесконечности
try
if (Form1.SpinEdit3.Value<Form1.SpinEdit3.MinValue) then Form1.SpinEdit3.Value:=Form1.SpinEdit3.MinValue;
if (Form1.SpinEdit3.Value>Form1.SpinEdit3.MaxValue) then Form1.SpinEdit3.Value:=Form1.SpinEdit3.MaxValue
except
end;
//
{
if Form1.SpinEdit3.MaxValue=Form1.SpinEdit3.MinValue then
begin
Form1.SpinEdit3.Value:=Form1.SpinEdit3.MaxValue;
Exit;
end;
}
//
Proc31;
//
SaveCFG;
//
end;

procedure TForm1.TrackBar1Change(Sender: TObject);
// настройка громкости для первого движка
begin
if AutoStart=True then begin Form1.Label73.Caption:=IntToStr(AnVolume); Exit; end ;
//
try // выделение ресурса
Form1.DirectSS1.VolumeLeft:=TrackBar1.Position;
Form1.DirectSS1.VolumeRight:=TrackBar1.Position;
Form1.Label73.Caption:=IntToStr(TrackBar1.Position);
except // блок операторов, обрабатывающий ошибку
//
end; // освобождение ресурса
//
SaveCFG;
//
end;

procedure TForm1.TrackBar2Change(Sender: TObject);
// настройка тона для первого движка
begin
if AutoStart=True then begin Form1.Label74.Caption:=IntToStr(AnPitch); Exit; end ;
//
try // выделение ресурса
Form1.DirectSS1.Pitch:=TrackBar2.Position;
Form1.Label74.Caption:=IntToStr(TrackBar2.Position);
except // блок операторов, обрабатывающий ошибку
//
end; // освобождение ресурса
//
SaveCFG;
//
end;


procedure TForm1.TrackBar3Change(Sender: TObject);
// настройка скорости для первого движка
begin
if AutoStart=True then begin Form1.Label75.Caption:=IntToStr(AnSpeed); Exit; end ;
//
try // выделение ресурса
Form1.DirectSS1.Speed:=TrackBar3.Position;
Form1.Label75.Caption:=IntToStr(TrackBar3.Position);
except // блок операторов, обрабатывающий ошибку
//
end; // освобождение ресурса
//
SaveCFG;
//
end;

procedure TForm1.RadioButton1Click(Sender: TObject);
// выбор первого движка
begin
RB1Click;
end;


procedure TForm1.RadioButton2Click(Sender: TObject);
// выбор второго движка
begin
RB2Click;
end;

procedure TForm1.TrackBar6Change(Sender: TObject);
// настройка скорости для второго движка
begin
if AutoStart=True then begin Form1.Label72.Caption:=IntToStr(AnSpeed); Exit; end ;
//
try // выделение ресурса
Form1.TextToSpeech1.Speed:=TrackBar6.Position;
Form1.Label72.Caption:=IntToStr(TrackBar6.Position);
except // блок операторов, обрабатывающий ошибку
//
end; // освобождение ресурса
//
SaveCFG;
//
end;

procedure TForm1.BitBtn4Click(Sender: TObject);
// активировать речевой движок - воспроизвести речь
 var ii97:Integer;
begin
if Form1.Memo1.SelText='' then begin
   SaySpeech;
   Exit;
                               end;
//
IF RadioButton1.Checked THEN begin
try // выделение ресурса
Form1.DirectSS1.VolumeLeft:=TrackBar1.Position;
Form1.DirectSS1.VolumeRight:=TrackBar1.Position;
Form1.DirectSS1.Pitch:=TrackBar2.Position;
Form1.DirectSS1.Speed:=TrackBar3.Position;
Form1.DirectSS1.Speak(Memo1.SelText);    // говорим
Form1.DirectSS1.LipType :=0;
except // блок операторов, обрабатывающий ошибку исполнения предыдущих операторов
//
end; // освобождение ресурса
                             end;
IF RadioButton2.Checked THEN begin
try // выделение ресурса
Form1.TextToSpeech1.Speak(Memo1.SelText);    // говорим
Form1.TextToSpeech1.LipTension :=246;
Form1.TextToSpeech1.LipType :=0;
except // блок операторов, обрабатывающий ошибку исполнения предыдущих операторов
//
end; // освобождение ресурса
                             end;
IF RadioButton3.Checked THEN begin
try // выделение ресурса
Form1.TTS1.Speak(Memo1.SelText,1);    // говорим  - Внимание! только при flags=1 возможно остановить движок во время его звучания
except // блок операторов, обрабатывающий ошибку исполнения предыдущих операторов
//
end; // освобождение ресурса
                             end;
//
{  Пример перемещаемого компонента со сквозным вырезом }
ii97:=Form1.Button1.Left;
Dec(ii97);
Form1.Button1.Left:=ii97;
RebuildWindowRgn;
//
end;


procedure TForm1.TrackBar9Change(Sender: TObject);
// настройка скорости для третьего движка
begin
if AutoStart=True then begin Form1.Label71.Caption:=IntToStr(AnSpeed); Exit; end ;
//
try
Form1.TTS1.Speed:=Form1.TrackBar9.Position;
Form1.Label71.Caption:=IntToStr(TrackBar9.Position);
except
end;
//
SaveCFG;
//
end;

procedure TForm1.TrackBar8Change(Sender: TObject);
// настройка громкости для третьего движка
begin
if AutoStart=True then begin Form1.Label67.Caption:=IntToStr(AnVolume); Exit; end ;
//
try
Form1.TTS1.Volume:=Form1.TrackBar8.Position;
Form1.Label67.Caption:=IntToStr(TrackBar8.Position);
except
end;
//
SaveCFG;
//
end;

procedure TForm1.RadioButton3Click(Sender: TObject);
// выбор третьего движка
begin
RB3Click;
end;


procedure TForm1.FormDestroy(Sender: TObject);
// снятие регистрации горячих клавиш в Windows
begin
UnRegisterHotKey(handle,iKey01);
UnRegisterHotKey(handle,iKey02);
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
// минимизация окна программы
begin
Application.Minimize;
Form1WindowState:=0;
SaveCFG;
end;

procedure TForm1.BitBtn6Click(Sender: TObject);
// вывод списка голосовых модулей во встроенном текстовом окне
var ii95: Integer;
begin
//
if Form1.RadioButton1.Checked or Form1.RadioButton2.Checked then begin
//  активируем голосовой движок
if Form1.SpinEdit3.MaxValue>0 then
for  ii95:=1 to Form1.SpinEdit3.MaxValue do begin
//
Form1.SpinEdit3.Value:=ii95;
//
try // выделение ресурса
Form1.DirectSS1.Select(Form1.SpinEdit3.Value); // выбор установленного в системе голосового движка
except // блок операторов, обрабатывающий ошибку
//
end; // освобождение ресурса
//
//
// информация о движке к сведению пользователя
//
try // выделение ресурса             EngineID
Form1.Label45.Caption := Form1.TextToSpeech1.dialect(Form1.SpinEdit3.Value);
except // блок операторов, обрабатывающий ошибку
Form1.Label45.Caption := 'Нет данных';
end; // освобождение ресурса
//
//
try // выделение ресурса
Form1.Label8.Caption := Form1.DirectSS1.EngineID(Form1.SpinEdit3.Value);
except // блок операторов, обрабатывающий ошибку
Form1.Label8.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label9.Caption := Form1.DirectSS1.ModeName(Form1.SpinEdit3.Value);
except // блок операторов, обрабатывающий ошибку
Form1.Label9.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label10.Caption := Form1.DirectSS1.MfgName(Form1.SpinEdit3.Value);
except // блок операторов, обрабатывающий ошибку
Form1.Label10.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label11.Caption := Form1.DirectSS1.ProductName(Form1.SpinEdit3.Value);
except // блок операторов, обрабатывающий ошибку
Form1.Label11.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label12.Caption := Form1.DirectSS1.ModeID(Form1.SpinEdit3.Value);
except // блок операторов, обрабатывающий ошибку
Form1.Label12.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label13.Caption := Form1.DirectSS1.Speaker(Form1.SpinEdit3.Value) ;
except // блок операторов, обрабатывающий ошибку
Form1.Label13.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label14.Caption := Form1.DirectSS1.Style(Form1.SpinEdit3.Value);
except // блок операторов, обрабатывающий ошибку
Form1.Label14.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label15.Caption := IntToStr(Form1.DirectSS1.Gender(Form1.SpinEdit3.Value));
except // блок операторов, обрабатывающий ошибку
Form1.Label15.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label16.Caption := IntToStr(Form1.DirectSS1.Age(Form1.SpinEdit3.Value));
except // блок операторов, обрабатывающий ошибку
Form1.Label16.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label17.Caption := IntToStr(Form1.DirectSS1.Features(Form1.SpinEdit3.Value));
except // блок операторов, обрабатывающий ошибку
Form1.Label17.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label18.Caption := IntToStr(Form1.DirectSS1.Interfaces(Form1.SpinEdit3.Value));
except // блок операторов, обрабатывающий ошибку
Form1.Label18.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label19.Caption := IntToStr(Form1.DirectSS1.EngineFeatures(Form1.SpinEdit3.Value));
except // блок операторов, обрабатывающий ошибку
Form1.Label19.Caption := 'Нет данных';
end; // освобождение ресурса
//
try // выделение ресурса
Form1.Label20.Caption := IntToStr(Form1.DirectSS1.LanguageID(Form1.SpinEdit3.Value));
except // блок операторов, обрабатывающий ошибку
Form1.Label20.Caption := 'Нет данных';
end; // освобождение ресурса
//
Form1.Repaint;
//
Form1.Memo1.Lines.Add( IntToStr(ii95)+'.  '+
Form1.Label23.Caption+' - '+Form1.Label10.Caption+';  '+
Form1.Label24.Caption+' - '+Form1.Label11.Caption+';  '+
Form1.Label26.Caption+' - '+Form1.Label13.Caption+';  '+
Form1.Label29.Caption+' - '+Form1.Label16.Caption+';  '+
Form1.Label22.Caption+' - '+Form1.Label9.Caption+';  '+
Form1.Label27.Caption+' - '+Form1.Label14.Caption+';  '+
Form1.Label44.Caption+' - '+Form1.Label45.Caption+'.  '
);
//
                                            end; // Form1.SpinEdit3.Value:=1 to Form1.SpinEdit3.MaxValue
                                                                 end; // Form1.RadioButton1.Checked or Form1.RadioButton2.Checked
//
if Form1.RadioButton3.Checked then begin
// обработка исключительной ситуации на инициализацию компонента TTS1 излишняя,
// так как RadioButton3 уже не может быть инициирована
//
for ii95:=1 to TTS1MaxValue do begin
Form1.SpinEdit3.Value:=ii95 ;
Proc31;
if  Form1.SpinEdit3.Value=ii95 then begin
Form1.Memo1.Lines.Add( IntToStr(ii95) + '.  ' +
Form1.Label69.Caption + ' - ' + Form1.TTS1.Voices[Form1.SpinEdit3.Value] );
                                    end
else begin
Form1.Memo1.Lines.Add('  ');
     end;
                               end;  // ii95:=0 to TTS1MaxValue
//
                                   end; // Form1.RadioButton3.Checked
//
end;


procedure TForm1.SpeedButton2Click(Sender: TObject);
// сворачивание окна программы в иконку
begin
// Последовательность следующих операторов принципиальна
Form1.WindowState:=wsNormal;
Form1WindowState:=1;
Form1.Width:=50;
Form1.Height:=50;
//
if (Form1.Left<0) or (Form1.Top<0) then begin
//  Поправка на новые координаты
if MessageDlg('Спрятать иконку за границей экрана?',mtConfirmation, [mbYes, mbNo], 0) = mrNo then
  begin
if Form1.Left<0 then Form1.Left:=0;
if Form1.Top<0 then Form1.Top:=0;
 LeftFrmPos :=Form1.Left;
 TopFrmPos :=Form1.Top;
  end;
                                        end;
//
SaveCFG;
end;

procedure TForm1.BitBtn7Click(Sender: TObject);
// загрузка файла в текстовое окно
label 10;
Var sizeFile: Integer ;
    openFile: file of Byte;
    filename: String;
    OldFile:  TextFile;
begin
//
10: if Form1.OpenDialog1.Execute then begin
//
filename := Form1.OpenDialog1.FileName;
//
// проверка - Не новый ли файл мы открываем
If not FileExists(filename) then begin
if Application.MessageBox('Файл не существует. Создать его?',PChar(MainCaptionProgram), mb_YesNo+MB_ICONQUESTION)= IDYes then
   begin
   AssignFile(OldFile, filename);
   Rewrite(OldFile);
   Writeln(OldFile,'');
   CloseFile(OldFile);
   end
else goto 10;
                                  end;
//
// проверяем файл на его размер. Больше 2.0 Мб не открываем!
    AssignFile(openFile, OpenDialog1.FileName);
// Проверяем , не занят ли файл?
{$I-}
    Reset(openFile);
{$I+}
if IOResult<>0 then begin
if Application.MessageBox('Файл занят другим приложением.',PChar(MainCaptionProgram), mb_OK+MB_ICONINFORMATION)= IDOK then goto 10;
                    end;
//
// тогда открываем для определения его размера
    try
      sizeFile := FileSize(openFile);    // определяем размер файла
    finally
      CloseFile(openFile);
    end;
//
If sizeFile>2048000 then begin // 2 048 000 байт = 2 Мбайт
if  Application.MessageBox('Файл не должен быть больше 2 Мб.',PChar(MainCaptionProgram), mb_OK+MB_ICONINFORMATION)= IDOK then goto 10;
                         end;
// после всех проверок открываем файл
Form1.Memo1.Lines.LoadFromFile(filename);
//
                                      end; //  Form1.OpenDialog1.Execute
//
end;

procedure TForm1.Memo1KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
// выделение текста по Ctrl+A
begin
if ((ssCtrl in Shift) and (Key=65) and not (ssAlt in Shift) and not (ssShift in Shift) ) then Form1.Memo1.SelectAll;        {Ctrl+'a'} {Ctrl+'ф'}
end;

procedure TForm1.BitBtn8Click(Sender: TObject);
// выбор цвета окна программы из системной палитры 
begin
  if ColorDialog1.Execute then begin
  CustomColor01:=Form1.ColorDialog1.Color;
  Form1.Color := ColorDialog1.Color;
  Form1.Panel3.Color := ColorDialog1.Color;
  Form1.Panel5.Color := ColorDialog1.Color;
  Form1.Panel7.Color := ColorDialog1.Color;
  Form1.Panel4.Color := ColorDialog1.Color;
  Form1.Panel6.Color := ColorDialog1.Color;
  Form1.Panel8.Color := ColorDialog1.Color;
                               end;
SaveCFG;
end;

procedure TForm1.FormShow(Sender: TObject);
// определение состояния окна программы
begin
if Form1.WindowState=wsNormal then Form1WindowState:=1;
if Form1.WindowState=wsMaximized then Form1WindowState:=1;
SaveCFG;
AutoStart:=False;
end;

procedure TForm1.N6Click(Sender: TObject);
// выбор пункта "Нормальный вид" контекстного меню окна программы
begin
// Последовательность следующих операторов принципиальна
Form1.WindowState:=wsNormal;
Form1WindowState:=1;
Form1.Width:=800;
Form1.Height:=480;        
Form1.Position :=poDesktopCenter;
//  Поправка на новые координаты
 LeftFrmPos :=Form1.Left;
 TopFrmPos :=Form1.Top;
//
SaveCFG;
end;


end.
