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

Вниз

Не получается добавить значек в трей.   Найти похожие ветки 

 
Ego   (2004-12-20 08:37) [0]

Здравствуйте, всем.Я пытаюсь добавить пиктограмму в панель резидентов:

..
const MyTryIcon = WM_USER+1;
..
uses Unit2, Unit3, Unit4, ShellAPI;
var  NID : TNotifyIconData;
..
procedure TForm1.FormCreate(Sender: TObject);
begin
SetWindowRgn(handle,CreateRoundRectRgn(0,0,width,height,30,30),true);
with NID do
 begin
 cbSize:=SizeOf(TNotifyIconData);
 Wnd:=Handle;
 uId:=1;
 uFlags:=NIF_ICON or NIF_MESSAGE or NIF_TIP;
 uCallbackMessage:=MyTryIcon;
 hIcon:=Application.Icon.Handle;
 szTip:="";
 end;
Shell_NotifyIcon(NIM_ADD,@Icon);
end;

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


 
Ego   (2004-12-20 08:42) [1]

Простите, я из старого исходника копировал.Сейчас строка выглядит так:
Shell_NotifyIcon(NIM_ADD,@NID);


 
Ego   (2004-12-20 08:57) [2]

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

 private
   { Public declarations }
   procedure MTIcon( var a: TMessage); message MyTryIcon;

но получаю ошибку:
unsatisfied forward or external declaration :"TForm1.MTIcon"
Признаться, я не очень понимаю, что я делаю, и, просто, как обезьяна, скопировал эти строки из книжки, но там они работают.
Поэтому мне не обязательно, даже, получить ответ на эти вопросы - хотя бы подскажите, где об этом можно прочитать, потому что все что я нашел - это примеры, в точности совпадающие с тем, что у меня в книге есть...


 
Digitman ©   (2004-12-20 09:10) [3]


> получаю ошибку:
> unsatisfied forward or external declaration :"TForm1.MTIcon"


> где об этом можно прочитать


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


 
Ego   (2004-12-20 09:26) [4]

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

const MyTryIcon = WM_USER+1;
type
 TForm1 = class(TForm)
..
 private
   { Private declarations }
   procedure MTIcon( var a: TMessage); message MyTryIcon;
..
 end;


 
Digitman ©   (2004-12-20 10:08) [5]

декларации метода в объявлении класса должна соответствовать обязательная реализация этого метода

у тебя, очевидно, реализация отсутствует, поэтому компилятор и выдает ошибку


> unsatisfied forward or external declaration :"TForm1.MTIcon"


в переводе с хинди это означает : в разделе implementation не могу найти строчку

procedure TForm1.MTIcon( var a: TMessage);


 
Ego   (2004-12-20 10:29) [6]

Большое спасибо.С этим разобрался.А со значком что делать - он же не отображается?


 
Digitman ©   (2004-12-20 11:50) [7]


> Ego


вот пример из BorlandSocketServer

//создание иконки в трее
   with FIconData do
   begin
     cbSize := SizeOf(FIconData);
     Wnd := Self.Handle;
     uID := $DEDB;
     uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
     hIcon := Forms.Application.Icon.Handle;
     uCallbackMessage := WM_MIDASICON;
     StrCopy(szTip, PChar(Caption));
   end;
   Shell_NotifyIcon(NIM_Add, @FIconData);

//удаление иконки из трэя
   Shell_NotifyIcon(NIM_DELETE, @FIconData);


 
tradakad   (2004-12-21 15:35) [8]

у меня есть такая функция
function TaskBarAddIcon( hWindow : THandle; ID  : Cardinal;

ICON : hicon; CallbackMessage : Cardinal; Tip  : String ) : Boolean;
var

NID : TNotifyIconData;
begin

FillChar( NID, SizeOf( TNotifyIconData ), 0 );
with NID do begin
cbSize := SizeOf( TNotifyIconData );
Wnd   := hWindow;
uID    := ID;
uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
uCallbackMessage := CallbackMessage;
hIcon  := Icon;
if Length( Tip ) > 63 then SetLength( Tip, 63 );
StrPCopy( szTip, Tip );
end;
Result := Shell_NotifyIcon( NIM_ADD, @NID );
end;
но типа TNotifyIconData у меня нет и соответсвено она не работает  ((


 
tradakad   (2004-12-21 15:35) [9]

у меня есть такая функция
function TaskBarAddIcon( hWindow : THandle; ID  : Cardinal;

ICON : hicon; CallbackMessage : Cardinal; Tip  : String ) : Boolean;
var

NID : TNotifyIconData;
begin

FillChar( NID, SizeOf( TNotifyIconData ), 0 );
with NID do begin
cbSize := SizeOf( TNotifyIconData );
Wnd   := hWindow;
uID    := ID;
uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
uCallbackMessage := CallbackMessage;
hIcon  := Icon;
if Length( Tip ) > 63 then SetLength( Tip, 63 );
StrPCopy( szTip, Tip );
end;
Result := Shell_NotifyIcon( NIM_ADD, @NID );
end;
но типа TNotifyIconData у меня нет и соответсвено она не работает  ((


 
Piter ©   (2004-12-21 21:46) [10]

Для работы с SysTray"ем (область где часики) в WinApi есть функция - Shell_NotifyIcon. С помощью нее можно добавлять свои иконки в SysTray, модифицировать их и удалять.
Вот ее описание:

function Shell_NotifyIcon(dwMessage: DWORD; lpData: PNotifyIconData): BOOL; stdcall;

Ее заголовок, а также определение типов TNotifyIconData, PNotifyIconData находится в юните shellapi.pas, который надо подключить для использования данной функции:
uses
ShellAPI;


В функции Shell_NotifyIcon первый параметр dwMessage указывает, что вы хотите сделать: добавить иконку, удалить или модифицировать существующую.
Соответственно, может принимать такие значения:

NIM_ADD - добавление иконки
NIM_DELETE - удаление иконки
NIM_MODIFY - модифицирование существующей иконки

Следующий параметр lpData - это указатель на запись TNotifyIconData, которая описана так:
TNotifyIconData = record
   cbSize: DWORD;
   Wnd: HWND;
   uID: UINT;
   uFlags: UINT;
   uCallbackMessage: UINT;
   hIcon: HICON;
   szTip: array [0..63] of AnsiChar;
end;

cbSize - размер этой самой структуры TNotifyIconData. Легко вычисляется с помощью sizeof(TNotifyIconData)

Wnd - номер окна, которое будет принимать сообщения от иконки

uID - уникальный номер иконки в вашем приложении

uFlags - флаги, показывающие какие поля TNotifyIconData должны быть обработаны системой

uCallbackMessage - если в uFlags установлено NIF_MESSAGE, то uCallbackMessage указывает номер сообщения, которое будет послано окну под номером Wnd

hIcon - если в uFlags установлено NIF_ICON, то hIcon показывает номер иконки, которая будет будет отображаться в SysTray"е

szTip - если в uFlags установлено NIF_TIP, то szTip задает всплывающий текст, который отображается при наведении курсора мышки на иконку

Ну вот собственно и все, что нужно знать для того, чтобы "запуздырить" свою иконку в SysTray.
В программе где-то имеет смысл объявить глобальную переменную, например NID типа TNotifyIconData.
var NID: TNotifyIconData;
Глобально - потому что эта переменная понадобится, чтобы удалять иконку и модифицировать ее.
Осталось рассмотреть конкретную реализацию:
предполагается, что где-то в программе объявлена глобальная переменная NID: TNotifyIconData

procedure TForm1.Button1Click(Sender: TObject);
begin
 NID.uID :=0;
 NID.Wnd := Handle;
 NID.uCallbackMessage :=WM_USER;
 NID.hIcon := LoadIcon(HINSTANCE,"ICON1");
 NID.szTip := "Моя иконка";
 NID.uFlags :=NIF_ICON or NIF_MESSAGE or NIF_TIP;
 NID.cbSize :=sizeof(NID);
 Shell_NotifyIcon(NIM_ADD,@NID);
end;


NID.uID :=0;
уникальный номер иконки в приложении. Если у вас несколько иконок в одном приложении, то это позволит вам их различать. У нас иконка одна, так что ставим что угодно. Например, ноль.

NID.Wnd := Handle;
Выбираем окно, которое будет обрабатывать сообщение от иконки. В моем тестовом приложении только одна форма, одно окно, его и выбираю.
Выбираемое окно должно иметь процедуру обработки сообщения.

NID.uCallbackMessage :=WM_USER;
Выбираем номер сообщения, которое будет послано нашему окну, как только с иконкой произведут какие-либо действия.
Для наших личных сообщений Microsoft рекомендует использовать номера от WM_USER до 0x7FFF. Выбираем WM_USER

NID.hIcon := LoadIcon(HINSTANCE,"ICON1");
Тут загружаем изображение, иконку, которая будет отображена в SysTtay. По этому пункту почему-то возникает много вопросов, вроде "а как загрузить-то?".
Это, наверное, тема для очередного вопроса, но кратко расскажу как можно. Запускаете в Delphi "Tools->ImageEditor" и создаете новый "Resource File" или открываете существующий (только не главный ресурсный файл вашего приложения, типа project1.res).
Рисуете иконку под именем ICON1, сохраняете ресурсный файл под именем icon.res, кладете файл в каталог с программой.
В модуле формы, где используется LoadIcon, после {$R *.dfm} пишете {$R icon.RES}, после чего Delphi включит ресурсы вашего icon1.res в создаваемый exe файл. В том числе включит иконку ICON1.
После чего эту иконку можно загрузить как показано выше.

NID.szTip := "Моя иконка";
Просто задаете текст всплывающей подсказки. Так как объявлено:
szTip: array [0..63] of AnsiChar;
то соответственно, подсказка не должна быть длиннее 64 символов.

NID.uFlags :=NIF_ICON or NIF_MESSAGE or NIF_TIP;
задаются флаги, которые показывают, какие поля TNotifyIconData должны учитываться системой. Мы заполнили и hIcon, и uCallbackMessage, и szTip. Соответственно, все они должны учитываться.

NID.cbSize :=sizeof(NID);
просто задается размер TNotifyIconData. Эта строчка всегда будет именно такой.

Shell_NotifyIcon(NIM_ADD,@NID);
собственно говоря, вызывается функция Shell_NotifyIcon с нужными параметрами (так как должен передаваться указатель на структуру, а не сама TNotifyIconData, то поэтому @NID, а не просто NID). Можно анализировать значение, возвращаемое функцией. True в случае успешного добавления иконки и False в случае неуспеха.

Созданную иконку можно удалить. Например, это следует делать при завершении приложения:

procedure TForm1.FormDestroy(Sender: TObject);
begin
 Shell_NotifyIcon(NIM_DELETE,@NID);
end;


Если вы хотите модифицировать текст всплывающей подсказки или отобразить другую иконку вместо прежней, то просто перезаполните нужное поле NID и вызывайте:

Shell_NotifyIcon(NIM_MODIFY,@NID);

Но это не все, иконку мы добавили, но ведь нужно как-то обрабатывать события, такие, например, как клик мышкой по иконке.
Именно для этого окно (на которое указывает параметр Wnd), которое будет получать события от иконки, должно иметь обработчик сообщений. Мы определили сообщение как WM_USER. Соответственно, добавим к нашей форме нужную процедуру:

procedure IconMessage (var Msg: TMessage); message wm_USER;

Теперь, при действиях с иконкой, соответствующие сообщения будут посылаться окну Wnd, что приведет к вызову нашей процедуры IconMessage и передаче ей структуры TMessage, полностью определяющей


 
Piter ©   (2004-12-21 21:46) [11]

возникшее событие.
По параметру lParam можно судить о произошедшем действии, например:

WM_LBUTTONDOWN - клик левой кнопкой мышки по иконке
WM_RBUTTONDOWN - клик правой
WM_MOUSEMOVE - движение курсора мышки над иконкой

и так далее. Подробнее можно посмотреть во встроенной справке Windows SDK (файл WIN32S.HLP) в разделе "Mouse Input Messages".

В соответствии со сказанным реализуем нашу процедуру.
Например, мы хотим, чтобы при клике левой кнопкой по иконке выводился бокс с сообщением, а по клику правой кнопки хотим вывести существующее PopUp меню:

procedure TForm1.IconMessage(var Msg: TMessage);
var
 Pt: TPoint;
begin
case Msg.lParam of
 WM_LBUTTONDOWN : showmessage("По иконке кликнули левой кнопкой мыши!");
 WM_RBUTTONDOWN :
   begin
     GetCursorPos (Pt);
     SetForegroundWindow(Application.MainForm.Handle);
     PopupMenu1.Popup (Pt.x, Pt.y);
   end;
end;

end;


Строчка
SetForegroundWindow(Application.MainForm.Handle);
не просто так. Если при вызове PopUp меню активным будет не наше окно, то это приведет к маленькому глюку - невозможности вызвать другие меню. Можете попробовать - убрать данную строчку, поместить иконку в трей, кликнуть правой кнопкой мыши - появится всплывающее меню. Но не выбирайте там ни одного пункта, а кликнете правой кнопой, например, по панели задач - всплывающее меню не откроется.

Файл проекта с данным примером можно загрузить ЗДЕСЬ

Мы рассмотрели вызов функции Shell_NotifyIcon, которая ссылается на системную WinApi функцию Shell_NotifyIconA, то есть она предназначена для использования с ANSI строками. Точнее, строка там одна - в структуре TNotifyIconData есть поле szTip, которое заполняется ANSI символами. Есть и Unicode версия функции - Shell_NotifyIconW, которая эквивалентна Shell_NotifyIconA, но требует в качестве параметра указатель на запись TNotifyIconDataW в которой поле szTip определено следующим образом:

szTip: array [0..63] of WideChar;

Так что вы можете пользоваться Unicode версией функции для избежания проблем с кодировкой в не русской windows (с не русской локалью). Но помните, что полная поддержка Unicode функцией реализована только в системах, начиная с Windows 2000.

Ну и совсем напоследок хочу предупредить, что иконка автоматически удаляется как только окно Wnd, указанное в TNotifyIconData, удаляется из системы. При это возникает стандартный глюк, выражающийся в том, что иконка хоть и удалена, но она "висит" в SysTray, пока не получит сообщения, например, пока к ней не подведут мышку.
При этом удаление окна может произойти не только при закрытии приложения, а, например, при смене BorderStyle у формы, так как при этом окно уничтожается и создается заново, но с другими параметрами стиля.

Отвечал: Piter


 
GuAV ©   (2004-12-22 02:35) [12]

2 Piter ©

про RegistrewindowMessage("TaskbarCreated") ещё допиши :-)


 
tradakad   (2004-12-22 09:50) [13]

для  Piter - спасибо. очень хоршо и подробно описанно. оди вопрос
NID.Wnd := Handle; - если у программы нет формы - что сюда писать?


 
Piter ©   (2004-12-22 19:48) [14]

tradakad   (22.12.04 9:50) [13]

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

И что это за приложение у которого нет окна?

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


 
tradakad   (2004-12-23 09:57) [15]

>Видимо, ничего. Судя по справке - чтобы получить обратную связь от иконки - нужно чтобы в приложении было окно.
да. теперь я это поня уже. признаться поставленный вопрос был некорректен изначально из-за недостаточности моих знаний ( no one is perfect
Спасибо за помощь еще раз!


 
Garry   (2005-01-08 09:56) [16]

procedure IconMessage (var Msg: TMessage); message wm_USER;
У меня Delphi 7 ругается на "message", говорит ...
Uknown directive "message" ___Из - за чего??
я писал точно так как написано


 
Garry   (2005-01-08 09:56) [17]

procedure IconMessage (var Msg: TMessage); message wm_USER;
У меня Delphi 7 ругается на "message", говорит ...
Uknown directive "message" ___Из - за чего??
я писал точно так как написано


 
VMcL ©   (2005-01-08 10:11) [18]

>>Garry  (08.01.05 09:56) [16]

"message" может использоваться только для методов классов.


 
Garry   (2005-01-08 15:49) [19]

И как мне сделать чтобы заработало ? (изивините за тупые вопросы, но я в этом новичок)


 
Piter ©   (2005-01-08 16:51) [20]

VMcL ©   (08.01.05 10:11) [18]
И как мне сделать чтобы заработало ?


определить процедуру с message у метода класса (у формы, например)?


 
VMcL ©   (2005-01-08 16:55) [21]

>>Piter ©  (08.01.05 16:51) [20]

[offtopic]
Клиент глючит?
[/offtopic]


 
Eraser ©   (2005-01-08 17:00) [22]

В нете полно готовых рабочих компонентов. torry.ru например


 
Piter ©   (2005-01-08 18:15) [23]

VMcL ©   (08.01.05 16:55) [21]
Клиент глючит?


да не туда ткнул просто :)
Есть у него такая особенность...


 
grom   (2005-01-08 18:17) [24]

http://delphimaster.net/view/1-1104563793/


 
Grief ©   (2005-02-12 09:45) [25]

У меня вопрос есть, имитирую: сделал все как надо, а потом... а потом - ничего, в трее появляется еще одна иконка, а когда на нее курсор наводишь - исчезает. В качестве NotifyIconData.WND я использую окно, созданное
MainWnd:=CreateWindowEx(WS_EX_AcceptFiles, "WinMin : Main", "The Launcher", WS_Popup, CW_USEDEFAULT, CW_USEDEFAULT, Display.Width, Display.Height, 0, 0, Hinstance, nil);

Почему так?
P.S. Лучше использовать не WM_USER (может быть конфликт) а RegisterWindiwMessage


 
Eraser ©   (2005-02-12 11:50) [26]

Ego
Всё равно всё закончиться установкой готовых компонентов...имхо.
Так что советую JEDI VCL.


 
Piter ©   (2005-02-12 16:28) [27]

Eraser ©   (12.02.05 11:50) [26]
Всё равно всё закончиться установкой готовых компонентов...имхо.


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

Grief ©   (12.02.05 9:45) [25]
MainWn


Чему равно MainWnd после вызова CreateWindowEx? Не ноль, случайно?


 
Eraser ©   (2005-02-12 20:56) [28]

Piter ©
Написать код для помещения иконки в трей - дело минуты.


Нельзя не согласиться. Но когда необходимо "прикрутить" к этой иконки менюшку, обработку различных кликов различными кнопками, анимацию, baloon hint и т.д. эта задача выливается в немаленнький код с кучей патенциальных дыр.
Так вот, ИМХО, лучше энтузиазм тратить на более полезные вещи, чем на копирование RxLib и JEDI VCL, опять же имхо...


 
Grief ©   (2005-02-12 22:11) [29]

>Чему равно MainWnd после вызова CreateWindowEx? Не ноль, случайно?
Возможно... до меня доходит.... а что сделать можно?


 
sniknik ©   (2005-02-12 22:44) [30]

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

> а что сделать можно?
окно, чей хендл используется, должно существовать все время пока иконка используется.


 
Grief ©   (2005-02-12 23:06) [31]

Существует, см выше, я его не убиваю... оно даже на экране есть.


 
sniknik ©   (2005-02-12 23:37) [32]

значит чтото не то туда пишеш, вот попробуй вышепреведенный пример там где от стандартного окна Form1.Handle вносится, не будет изчезать.

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


 
sniknik ©   (2005-02-13 14:32) [33]

> да мало ли еще что, неохота вникать.
не выдержал, проверил ;о)), сделал на "чистом" winapi форму (вернее переделал имеющийся пример, "усек" его по размеру), передал ее хендл значку... как и ожидалось работает.
у тебя точно чтото не то с созданным окном, показал бы все, как создаеш, а то одна приведенная тобой функция не может быть, она возвращает 0.
в примере (моем) кроме этого регистрится класс окна (т.е. про регистрацию я угадал ;), а вот специальных событий не нужно (стандартный обработчик только). и WS_Popup это случаем не окно для всплываюхих менюшек? вряд ли оно тогда подойдет (хотя, не знаю, может и подойдет, проверять опять ломает ;) просто логически, не для того оно).


 
Piter ©   (2005-02-13 21:42) [34]

sniknik ©   (13.02.05 14:32) [33]
т.е. про регистрацию я угадал


ни фига себе угадал... А как ты еще создащь окно какого-то класса (не стандартного), если не зарегистрируешь его?!
Какое тут блин гадание...


 
Grief ©   (2005-02-13 22:11) [35]

Ой, товарищи мастера, я сожалею, что нагнал здесь всякой пурги, но дело в том, что я просто банально недоглядел... этож надо, вызывать InitializeTray раньше, чем CreateWindowEx, of course handle = 0!!! Ламер я, ой ламер, пора уходить на пенсию))))


 
Piter ©   (2005-02-13 22:16) [36]

О нуле я написал еще в 12.02.05 16:28
И больше дня потребовалось, чтобы проверить это! И только в 13.02.05 22:11 озарение.

Отпадает всякое желание помогать вообще.


 
sniknik ©   (2005-02-14 01:57) [37]

> ни фига себе угадал...
угадал угадал. ;о)) дело в том что я про это вобще не думал при ответе, тем более до этого > [31] было сказано, окно есть и его видно на экране... т.е. все ок.
т.что про нее я сказал наугад, на всякий случай.


 
Grief ©   (2005-02-14 07:26) [38]

Озарение было сразу, но написать ответ пришло не сразу....


 
Piter ©   (2005-02-14 19:32) [39]

sniknik ©   (14.02.05 1:57) [37]
дело в том что я про это вобще не думал при ответе, тем более до этого


подожди. Какая разница о чем ты думал? :)
Ты сказал:

sniknik ©   (12.02.05 23:37) [32]
может дополнительно регистрить окно надо


что значит дополнительно и может? Окно регистрировать надо по любому, а не может!



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

Форум: "WinAPI";
Текущий архив: 2005.03.27;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.61 MB
Время: 0.034 c
4-1108560083
oleg_SYS
2005-02-16 16:21
2005.03.27
Menu средствами Windows API


10-1087305616
Ivanhoe
2004-06-15 17:20
2005.03.27
Выбор распределенной системы


14-1109773013
RDA
2005-03-02 17:16
2005.03.27
Закончились уникальные MAC адреса для сетевух?


1-1110534729
DelphiNew
2005-03-11 12:52
2005.03.27
Как перестроить ветку в Treeview1


14-1110455760
mmms
2005-03-10 14:56
2005.03.27
Холодильник молотит без остановки, есть ли спецы?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский