Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.11.11;
Скачать: [xml.tar.bz2];

Вниз

Какой вариант использования форм наиболее оптимален?   Найти похожие ветки 

 
lipskiy   (2002-11-01 01:24) [0]

Мне известны три варианта использования форм со своими контролами. Первый - создать все в дизайн-тайме и не париться. Но при этом вся форма (а мне нужна форма настроек программы - с кучей контролов) всегда сидит в памяти и кушает ресурсы. Второй вариант - также создать форму в дизайн-тайме, но отменить автокрейт и крейтить при вызове, а при гашении освобождать. При этом в ехешник будут скомпилированы все свойства контролов со значениями по умолчанию, даже если я их не использую, получается лишний объем ехе-файла. Третий вариант - создавать форму полностью динамически, ничего не рисуя в дизайн-тайме. Это, имхо, наиболее экономично но жутко неудобно.

Как же все-таки ПРАВИЛЬНО создавать изобилующие контролами формы, которые редко вызываются при работе?
Плюс к этому я хочу на форме настроек переключать множество вкладок с группами настроек, и при этом чтобы в памяти в данный момент сидели только те контролы, которые отображаются, а контролы других вкладок не существовали бы (самих вкладок не видно, это стиль формы настроек с выбором групп посредством TreeView).

И вот еще. Не могу понять, в чем ошибка при создании формы.
В отдельном юните описано:

type
TFormTunes = class (TForm)
end;

var FormTunes : TFormTunes;


В главном юните по кнопке вызываю:
Application.CreateForm(TFormTunes, FormTunes);
Или так:
FormTunes:= TFormTunes.Create(nil);

Вылетает эксепшен - типа ресурс TFormTunes не найден.
Чего я не верно сделал-то?


 
Dr_Mike   (2002-11-01 02:29) [1]

Описания класса и обявление переменной класса должны быть в интерфейсном разделе подчиненного модуля.

Во-вторых, просто не стоит забывать в главном модуле в uses указывать имя используемого модуля.


 
Aleks1   (2002-11-01 02:49) [2]

> Как же все-таки ПРАВИЛЬНО создавать изобилующие контролами >формы, которые редко вызываются при работе?

Правильно - это так, чтоб выбранный способ давал наименьшее количество ошибок для конкретного автора. Все разговоры о размерах занимаемой памяти и ресурсах - это либо разговоры о программах на чистом API, либо о "дурацком" использовании ресурсов. ИМХО, однако.


 
evgeg   (2002-11-01 08:18) [3]

> Все разговоры о размерах занимаемой памяти и ресурсах - это либо разговоры о программах на чистом API, либо о "дурацком" использовании ресурсов.

Ничего подобного. Программа с десятком статичных форм может запросто отказаться запускаться под Windows 98.


 
Alex4444444444   (2002-11-01 10:07) [4]

TForm.Create pytaetsya najti ressursy formy. Esli ih net, nuzhno ispol"zovat" CreateNew (kazhetsya).


 
Dr_Mike   (2002-11-01 10:20) [5]

Хм...действительно, Alex4444444444 правильно акцентировал внимание :)))

Есть ли утебя вообще .DFM файл для FormTunes???


 
lipskiy   (2002-11-01 13:09) [6]

Нет dfm файла. Я чисто руками хочу сделать форму целиком. Так мне кажется наиболее оптимально.

> Описания класса и обявление переменной класса должны быть
> в интерфейсном разделе подчиненного модуля.

Так и сделано.

> Во-вторых, просто не стоит забывать в главном модуле в uses
> указывать имя используемого модуля.

Естественно, иначе бы и компилятор не пропустил.

> Программа с десятком статичных форм может запросто отказаться
> запускаться под Windows 98.

Именно эту цель я и преследую - обеспечить нормальную работу под 98-ой, а НТишные осы имеют нормальные менеджеры графических ресурсов.

> TForm.Create pytaetsya najti ressursy formy. Esli ih net,
> nuzhno ispol"zovat" CreateNew (kazhetsya).

А почему это он не находит ресурсы? Главная-то форрма создается как обычно автоматом. Почему я не могу так же создать новую форму? Какжется просто у меня тупняк какой-то, где-то что-то упустил, но не могу найти...


 
reonid   (2002-11-01 13:41) [7]

Если без дфм - то действительно надо пользоваться CreateNew.
Потому что Create пытается загрузить одноимённый ресурс.
А насчёт главной формы - она обычно создана в дизайнере и имеет дфм.
(И в её модуле стоит {$R *.DFM} - попробуй, убери :-Р )

Если у тебя много форм похожего внешнего облика и функциональности -
то ты можешь сделать одну заготовку
и специальный объект - менеджер внешнего облика(и поведения),
который будет настраивать форму для конкретного применения,
создавать при необходимости доп. контролы и устанавливать
обработчики.

Насчёт вкладок и тривью - ты можешь сделать каждую
вкладку на отдельной форме, по нажатию на соответствующий
узел создавать нужную форму (уничтожив предыдущую),
загружать в эту форму соответствующие данные и делать её парентом основную форму (на которой лежит тривью).


 
Андрей Прокофьев   (2002-11-01 13:47) [8]

2 lipskiy © (01.11.02 01:24)
Есть еще один вариант - запихать эту форму в DLL или package


 
NailS   (2002-11-01 15:14) [9]

Господа, а из-за чего собственно сыр-бор разгорелся?

Если я понял, то lipskiy © имеет желание сэкономить GUI-ресурсы пользователя. Желание похвальное, но, честно говоря, я не понимаю каким образом этому начинанию может помочь создание всех компонентов формы в run-time. Ведь оттого что компоненты создались в run-time они меньше ресурсов жрать не станут. Т.е. для экономии GUI-ресурсы достаточно динамически создавать и удалять форму использовав при этом все прелести визуального построения формы и не замарачиваться с созданием руками всей формы.

Если я что-то неправильно понял и(или) вы преследуете еще какие-то цели, объясните пожалуста.


 
han_malign   (2002-11-01 15:30) [10]

> При этом в ехешник будут скомпилированы все свойства контролов со значениями по умолчанию, даже если я их не использую, получается лишний объем ехе-файла. Третий вариант - создавать форму полностью динамически...

Полностью согласен с NailS т.к. при третьем подходе в ехешник будут скомпилированны не только все свойста, но и код их занесения в контролы, и код создания контролов, и etc, тогда как "загрузчик свойств"(методы TPersistent) никуда не денутся.

З.Ы. А чтобы не искался ресурс у формы не должно быть ни одного published поля и пропертей(наследоваться от TCustomForm), и все контролы опять таки создавать ручками в конструкторе формы, потому как без DFM никто их за вас не создаст.


 
Andre V.   (2002-11-01 17:02) [11]

А. Прокофьеву! Те же я..ца, только сбоку. ДЛЛ всё равно ведь надо грузить в память. Если это делать прямо перед вызовом нужной формы, то сколько времени такое удовольствие займет.
С другой стороны, сколько стоит та же память и надо ли себе портить жизнь. У меня в программе около 30 форм, штук 5 имеют по несколько страниц и всё это работает (включая МДИ-окна с данными


 
KSergey   (2002-11-01 17:10) [12]

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

> lipskiy © (01.11.02 01:24)
> Мне известны три варианта использования форм со своими контролами.

Так, вначале с терминами определимся. Не претендую на абсолютную истину, просто пусть в этом посте это будет так. Под созданием будам понимать создание формы в запущеном приложении. Что мы в этот момент имеем? Съедается память на хранение компонентов-контрлов (1), съедаются ресурсы GDI (2). Теперь смотрим на это и понимаем, что как бы форма не создавалась, эти ресурсы отъедятся неизменно и в любом случае, и отъедены они будут на все время существования формы в полном объеме. Не зависимо ни от установленных/не установленных значений внутренних полей компонент на форме и самой формы, ни от их начальных значений. Это будет съедено всегда, пока форма существует. При этом существование формы и ее видимость - не оджно и тоже. Невидимая форма может существовать, несуществующая форма не может быть видимой ;)
Где что у нас еще вылезает? Ага, есть код создания формы и код заполнения полей значениями по умолчанию (3) (память под код, оно же место в exe-файле), есть возможно некое описание формы в данных (тут видимо оно же всегда является ресурсами; имеется в виду конкретный случай) (4).
А теперь давайте рассмотрим различия в предлоенных вами "методах создания".

> Первый - создать все в дизайн-тайме и не париться. Но при
> этом вся форма (а мне нужна форма настроек программы - с
> кучей контролов) всегда сидит в памяти и кушает ресурсы.

Так, какую память мы тут кушаем? 1+2+3+4, причем на протяжении выполнения всего прилжения. Если форм несколько и все автокрейтные - эта память отъедается для всех форм всегда. Ну немного может будет отъедаться разные ресурся GDI при видимой/невидимой форме, но все компоненты присутствуют всегда.

> Второй вариант - также создать форму в дизайн-тайме, но
> отменить автокрейт и крейтить при вызове, а при гашении
> освобождать.

Так, что мы тут меем? А опять же 1+2+3+4. Разница лишь в том, что составляющие 1 и 2 будут захватываться/освобождаться при создании/уничтожении формы.

>При этом в ехешник будут скомпилированы все
> свойства контролов со значениями по умолчанию, даже если
> я их не использую, получается лишний объем ехе-файла.

А вот это будет всегда, что при первом, что при врором варианте. Т.е. составляющие 3 и 4 в обоих вариантах будут отъедаться абсолютно одинаковые!
При этом есть еще нюанс: код заполнения св-ств формы значениями по умолчанию (и настроенными в Object Manager"е) будет храниться в exe один раз (он из библиотеки VCL) и он будет читать данные из ресурсов. В ресурсах - код для каждой формы, код ее создания - один (метод Create класса TForm и родительских).


 
KSergey   (2002-11-01 17:10) [13]

>Третий
> вариант - создавать форму полностью динамически, ничего
> не рисуя в дизайн-тайме. Это, имхо, наиболее экономично
> но жутко неудобно.

Так, а в этом варианте что мы имеем после того, когда форма создана и показана? Компоненты создаются - да. Форма видна, т.е от GDI мы откусили? Да. Какие-то значения полям формы и контрлов на ней мы присвоить хотим (размер, местоположение, цвет, надписи и т.д.)? Да. Ну разве что в ресурсах ничего нет. Но очевидно, что код присваивания значений полям класса формы и контрлов будет весьма велик, причем рискну утверждать, что он превысит составляющую 4. (из чего состоит код присвоения значений полей в первом и втором случае? циклик, считавает из ресурсов попарно элементы имя поля-значение, имя поля-значение. Циклик сам по себе не большой, согласитесь и записанный один раз на абсолютно все случаи жизни (почему это можно сделать так? не забываем, что все, что можно настроить в Object Inspektor"е - это published поля; если мы настраиваем кроме того и не published поля, то этот код будет вообще константным для всех трех вариантов) [все что тут есть про циклик - это мои личные выдумки, я не знаю как имено это сделано в VCL, но сильно подозреваю что именно так. Во всяком случае я бы сделал так.]. Из чего состоият сами эти значения? Да свалено в кучу в памяти имя=значение и т.д. [опять же мои выдумки; базируются на аргументах выше и на том, что в ресурсах дельфи-приложения нет стандартного описания жиндовских диалогов, следовательно формы создаются, думаю, каким-то таким методом, т.е. динамически а не на основе API-шаблона в ресурсах]). Отвлекся, вспомним про вариант три и составляющую 3 и увиидм, что в случае третьего варианта она явно больше выше описанной в скобках методы (т.к. тут конструкции исходного текста вида поле=значение скомпилируются в команду запихивания значения в поле класса). Впрочем, возможно я зря драматизирую, но уверен, что во всяком случае как минимум составляющие 3 4 первых двух вариантов буду эквивалентны составляющей 3 третьего варианта.

Таким образом получаем, что при созданной форме мы имеем одинаковое расходование ресурсов во всех трех вариантах!

А значит если ставить вопрос

> Как же все-таки ПРАВИЛЬНО создавать изобилующие контролами
> формы, которые редко вызываются при работе?

то - сиренево!

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


> Плюс к этому я хочу на форме настроек переключать множество
> вкладок с группами настроек, и при этом чтобы в памяти в
> данный момент сидели только те контролы, которые отображаются,
> а контролы других вкладок не существовали бы (самих вкладок
> не видно, это стиль формы настроек с выбором групп посредством
> TreeView).

И теперь представьте что это за геморой? Вкладка не видима - уничтожили контролы с нее, но при этом (заметьте!) надо где-то сохранить состояние их, т.к. ползователь там возможно что-то понастраивал, на что память уйдет, верно? Теперь перешли на вкладку - создали контролы, восстановили их значения, контролы с предыдущей удалили, сохранив и их значение. Где тут выигрыш?! Такое впечатление, что процессор у вас пентиум 6, а памяти - 640 килобайт (котрой, по идее, должно хватить на все, согласно известному утверждению Билла Гейтса;) и которую вы упорно экономите. Тут пожалуй действительно тот случай, когда ползователю можно смело сказать: извини, но мое окно настроек не запускается на твоей машине, давай увеличивай ее ресурсы (ну я имею в виду, когда все сделано грамотно;) поберегие помидоры;). Ведь никого же не возмущает необходимость 3D-ускорителей для игр? Причем именно необходимость.

Уфф... Сразу видно, что сегодня я еще ничего не постил... ;)

Надеюсь, что теперь вы поняли, что нет разницы между вашими методами никакой. Ну кроме того, что не надо держать в автокрейте те формы (и даже вредно!), которые не используются постоянно и одновременно. А сэкономить что-то при активной форме - невозможно.


 
NailS   (2002-11-01 17:21) [14]


> KSergey ©


> Где тут выигрыш?!

Ну вообще-то выигрыш на мой взгляд вполне очевиден. Визуальные контролы нужны только для ОТОБРАЖЕНИЯ и ИЗМЕНЕНИЯ значения параметров, но никак не для хранения их значений.

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

Я бы реализовывал это при помощи фреймов, просто и удобно. Перешел по дереву - убил один фрейм - создал другой - отобразил параметры. И TPageControle сэкономил ;)


 
KSergey   (2002-11-01 17:23) [15]

Поправочки ;) и дополнения

KSergey © (01.11.02 17:10)

В ресурсах - код для каждой формы, код ее создания - один (метод Create класса TForm и родительских).

Читать:

В ресурсах - значения полей, а код ее создания храниться один раз (метод Create класса TForm и родительских).

KSergey © (01.11.02 17:10)

жиндовских диалогов = виндовских диалогов

Отвлекся, вспомним про вариант три и составляющую 3 и увиидм, что в случае третьего варианта она явно больше выше описанной в скобках методы

Читать:

Отвлекся, вспомним про вариант три и составляющую 3 и увиидм, что (на основании описанного выше в скобках крупного куска) в случае третьего варианта она явно больше для вариантов первых двух вариантов

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

Уточнение:

при этом под динамикой понимается как второй, так и третий вариант, т.к. они абсолютно идентичны, более того - еще не известно какой из них "легче" по пожирательству. А потому не понятно есть ли смысл выпендриваться, создавая форму ручками, если ее вид полностью известен на этапе создания приложения.


 
KSergey   (2002-11-01 17:29) [16]

> NailS © (01.11.02 17:21)
>
> > KSergey ©
> > Где тут выигрыш?!
>
> Ну вообще-то выигрыш на мой взгляд вполне очевиден. Визуальные
> контролы нужны только для ОТОБРАЖЕНИЯ и ИЗМЕНЕНИЯ значения
> параметров, но никак не для хранения их значений.


Ага, а проваливание скорости при простой операции смены вкладок? Впрочем, я могу согласиться, что иногда это может и нужно (динамическое изменение вида вкладок в зависимости от значений полей ввода на других, например), но при полной статичности вида - нет уж, увольте. Если некуда девать энергию - лучше побегать по стадиону ;) Для здоровъя всяко полезнее. (еще раз скажу: все, конечно же, зависит от конкретной ситуации; когда это необходимо - это надо длать, когде необходимости нет - и не надо).


> > и при этом чтобы в памяти в
> > данный момент сидели только те контролы, которые
> >отображаются, а контролы других вкладок не существовали
> бы
>
> Я бы реализовывал это при помощи фреймов, просто и удобно.
> Перешел по дереву - убил один фрейм - создал другой - отобразил
> параметры. И TPageControle сэкономил ;)

Ну а это уже просто детали реализации, при этом никакой экономии памяти (о которой так печется автор вопроса) тут не произойдет, верно?


 
reonid   (2002-11-01 17:38) [17]

KSergey © (01.11.02 17:29)
>Ну а это уже просто детали реализации, при этом никакой >экономии памяти (о которой так печется автор вопроса) тут не >произойдет, верно?

Это то есть как же?
Наоборот, в каждый конкретный момент времени в
памяти будет находиться только один фрейм,
а не все 25.

Объём экзешника, конечно, это не уменьшит, но
экономия оп. памяти и объектов ГДИ может быть велика.


 
NailS   (2002-11-01 17:44) [18]


> Ну а это уже просто детали реализации, при этом никакой
> экономии памяти (о которой так печется автор вопроса) тут
> не произойдет, верно?

Автор беспокоился в первую очередь о GUI-ресурсах, если я его правильно понял, и при этом он их реально сбережет пользователю.


 
han_malign   (2002-11-01 17:44) [19]

Кстати насчет отжирания памяти - все равно долго не использующуюся память VMM выгружает на диск, освобождая физическую, скорость подкачи страниц сравнима со скоростью создания контролов(если не быстрее т.к. на нулевом кольце)


 
NailS   (2002-11-01 17:46) [20]

[off]Начинает отдавать пятничным флеймом ;))) Пожалуй пора завязывать ;)[/off]


 
Юрий Зотов   (2002-11-01 18:47) [21]

Да... уж... проблема... выеденного яйца...

1. Если форма требует N ресурсов - то она их отожрет, и никуда от этого не денешься. Как уменьшить N - это уже другой вопрос.

2. Чтобы она не отжирала их постоянно, создавайте ее ручками, непосредственно перед тем, как она становится нужна (но не с нуля, а просто вызовом конструктора). И убивайте сразу, же как только она становится не нужна. И так с КАЖДОЙ формой, кроме главной.

3. Чтобы не "париться", спокойно проектируйте любую форму в design-time. Только не забудьте убрать ее из AutoCreate (кроме главной). Хороший стиль - сразу же удалить из модуля формы объявление глобальной ссылки на нее (кроме главной).

4. Для настройки формы перед ее показом существуют события. Вот там и пишите нужный код.


 
evgeg   (2002-11-01 19:06) [22]

Когда форма загружается из dfm, dfm прилинковывается к исп. файлу, что увеличивает его размер. Будет ли экономия размера исп. файла, если присваивать сво-ва кодом, а не читать из dfm? Да, будет и вот почему:
В dfm-е сво-ва храняться грубо говоря в формате:
имя_свойства: значение_свойства.
Причем имя свойства -- это строка. И если класс имеет свойство:
MyVeryImpotentProperty, то в dfm-е будет храниться строка "MyVeryImpotentProperty". В этом легко убедится, открыв двоичный dfm в текстовом редакторе. Таким образом имя свойства занимает довольно приличный размер в исп. файле, зачастую гораздо больше, чем значение.

Но экономится только размер файла, а не ресурсы системы. А для поставленной задачи: запускать под W98, важна именно экономия ресурсов.

> lipskiy

Ссылка по теме: http://www.delphikingdom.com/stones/stone_21.htm


 
Дмитрий Баранов   (2002-11-01 19:55) [23]

Кстати, про PageControl -


совершенно случайно полазил Spy++ по окнам своей поделки - так вот, например, PageControl, содержащий, к примеру, 4 закладки, при запуске программы явно создает только одно дочернее окно - окно ВИДИМОЙ закладки, остальные же - динамически, по мере того, как юзер по ним щелкает. Это еще один плюс в пользу того, насколько грамотно написана VCL. Так что в Борланде тоже любят на ресурсах поэкономить, и в данном случае, польза явная.


 
lipskiy   (2002-11-01 21:14) [24]

Ого! Не ожидал, спасибо всем за обилие полезной инфы, в особенности KSergey.

> Надеюсь, что теперь вы поняли, что нет разницы между вашими
> методами никакой

Да, практически понял все.
Подчеркну лишь, что я действительно желаю сэкономить именно GDI ресурсы (а не просто память), и размер ехешника менее важен. Даже больше скажу - мне кажется (но я не уверен), что нужно экономить GDI ресурсы, чтобы обеспечить устойчивую работу под 98-ой. Может нужно и что-то иное делать.

Насчет хранения настроек.
Я начал с того, что хранил их именно в свойствах контролов, которые существовали у меня всегда. Это довольно удобно.
Теперь, если я убираю форму из AutoCreate, то мне необходимо создавать массив настроек. Думаю, что это все же лучше, так как массив настроек все же не ест графических ресурсов.

> Да... уж... проблема... выеденного яйца...

Юрий! Я снимаю шляпу перед вашим опытом и знаниями, но для моего уровня эта проблема чуть ли не высшего порядка :)
Ваши комментарии понятны (и полезны), так и буду делать.

> Это еще один плюс в пользу того, насколько грамотно написана
> VCL

ТАК ПОЧЕМУ ЖЕ ОНО ТАК ГЛЮЧИТ ПОД 98-МИ-ТО?????? Тудыть их. Забыть давно пора эти 98-е к черту. Но ведь юзвери всегда наровят программерам проблемы устроить :)


 
lipskiy   (2002-11-01 21:27) [25]


> evgeg © (01.11.02 19:06)

Спасибо за ссылку. Коротковато конечно, но полезно.


 
Dr_Mike   (2002-11-02 00:39) [26]

>Дмитрий Баранов © (01.11.02 19:55)

Здесь дело совсем не в грамотности написания VCL ! :-))))

Просто все видимые элементы в VCL создаются путем вызова соответствующих функций WinAPI, а так как в винде нет такого элемента, как PageControl (то есть чего-то с закладками поверху и соответствующим им страницами) - то это все так и реализовывается, как вы сами увидели - сверху лежит TabControl, а так называемая "страница" всего одна.


 
Юрий Зотов   (2002-11-02 10:22) [27]

Еще об экономии ресурсов (наверное, это и есть самое главное).

5. Продумать юзерский интерфейс программы так, чтобы на любом этапе ее работы количество одновременно показанных окон было сведено к минимуму.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2002.11.11;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.007 c
1-34087
brestmarket
2002-10-25 22:06
2002.11.11
Может есть способ сделать XP-совместимым SpeedButton в Delphi6 ?


14-34176
Anatoly Podgorestky
2002-10-20 20:59
2002.11.11
Именинники 21 октября


6-34149
Freeze
2002-09-13 09:53
2002.11.11
Помогите!!! ПЛИЗЗЗ!!!


1-34020
Salvator
2002-11-02 16:41
2002.11.11
Работа с Word через Delphi


3-33872
NeyroSpace
2002-10-21 14:38
2002.11.11
Если 2а IBQuery вешаются на одну IBTransaction1, какой из них





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский