Sources
Delphi Russian Knowledge Base
DRKB - это самая большая и удобная в использовании база знаний по Дельфи в рунете, составленная Виталием Невзоровым

Работа с казахскими шрифтами

01.01.2007

Работа с КАЗАХСКИМИ ШРИФТАМИ.
Здравствуйте Уважаемые Господа Програмисты.
Моя небольшая статья будет, скорее всего, интересна програмистам из региона - КАЗАХСТАН.
Так как програмисты проживающиее и работающие в этом регионе чаще всего встречаются
с проблемой вывода нестандартных КАЗАХСКИХ ШРИФТОВ.
 
Вместо введения...
Как всегда, передо мною, выросла проблема и, как всегда, я решил приложить максимум усилий
чтобы разобраться самому. (Вы меня простите но я не любитель напрягать форумы своими проблемами).
 
Программисты Казахстана знают какая это довольно таки
серьезная проблема "Нестандартные казахские символы".
Так как я сейчас активно занимаюсь "писаниной" пишу прогу которая должна "понимать"
КАЗАХСКИЙ ЯЗЫК от и до(Если так можно сказать). Писал, писал, и вдруг случилось...
Окызывается не один элемент управления не хочить не "писать" , не "читать" по КАЗАХСКИ.
 
Решил перелопатить инфу которая была и локальную и "ИНЕТСКУЮ".
Как выяснилось инфы типа "КАК СДЕЛАТЬ СУПЕР _TButton_" огромное количество.
А по шрифтам... "увольте".
 
Приступим.
 
Первое что надо сделать чтобы работать с казахскими шрифтами это...
Разместить их в системной таблице шрифтов.
Есть два способа закидываете файл со шрифтом в каталог \Windows\Fonts\/
Или же, ложите файл рядом с программой и вызываете AddFontResource('you_font.xxx');
Я пошел по первому пути(Так проще, хотя второй я тоже практиковал).
 
Ну предположим что мы разобрались с методом регистрации шрифта в системе.
Я использовал шрифт "Times/Kazakh" и вам советую. (Во всяком случае все примеры основанны именно на этом шрифте).
Но при определенном навыке, или же когда освоитесь с этим шрифтом. Вы сможете перейти на любой другой шрифт.
 
/*ВАЖНО*/
Второе, в чем часто путаются программеры, это - чтобы работать со шрифтами
по принципу "ОТ ОКНА К ОКНУ" надо чтобы на всех окнах, в которых подразумевается использование
казахского шрифта, было установленно одинаковое имя шрифта (Times/Kazakh). Тогда вы спокойно сможете
пользоваться буфером обмена и оператором присваивания (EditX.Text:=EditY.text;).
Это же относится и ко всем TCanvas на которых подразумевается вывод КАЗ_ШРИФТА.
 
Основная проблема заключается в том что даже после усановки казахской раскладки и казахского шрифта
Окна (даже окна редактирования TEdit. Tmemo) все равно не хотят выводить текст, даже с клавиатуры.
И тут приходиться "хитрить" дело в том что нестандартные КАЗАХСКИЕ СИМВОЛЫ(CHAR)
лежат в диапазоне 176-191(Большие и маленькие).
Поэтому я сделал так - Во время ввода, если выбранна КАЗАХСКАЯ раскладка клавиатуры,
перехватывать VIRT_KEY в событии OnKeyDown. И транслировать их в Казахские ЧАР'ы.
 
Уже готовый текст вы можете сохранить в файл и потом открыть.
Без всяких излишеств. Либо скопировать в буфер обмена.
Но учтите при вставке в другое окно или приложение(NOTEPAD), обязательно убедитесь в том что

там установлен такой же шрифт как и у вас в программе.

//Дополнительные Переменные и функции
 
Const KZ_KBRD = $043f043f;//Дескриптор Казахской раскладки 
                                               //В системе
 
//Функция Определяющая какой регистр использовать
//Данные обрабатываются в соответствии
//С состояниями клавиш от  клавиатуры
Function IsLow:Boolean;
var SHF,CPS_L : Boolean;
begin
REsult:=false;
SHF:= HiWord(GetAsyncKeyState(VK_SHIFT))>0;       //Зажат ли ШИФТ
CPS_L:=  0 <> (GetKeyState(VK_CAPITAL) and $01);   //Состояние CAPS_LOCK
if (SHF and CPS_L) then Result:=true;                        //пропись если ЗАЖАТЫ ОБЕ КЛАВИШИ
if (not SHF and  not CPS_L) then Result :=true;        //Или наоборт
end;
 
//Функция конвертирующая КЛАВИШУ в СИМВОЛ
Function KeyToKZChar(Key:Integer;lowKey:boolean):Char;
Begin
result:=#0;             {Мальнькие }          {Большие}
case key of           {Символы}             {Символы}
50:  if LowKey then result:=chr(184) else Result:= chr(176);
51:  if lowkey then result:=chr(105) else Result:= chr(73);
52:  if lowkey then result:=chr(187) else Result:= Chr(179);
53:  if lowkey then Result:=chr(185) else Result:= Chr(177);
54:  if lowkey then result:=chr(190) else Result:= Chr(182);
55:  if lowkey then result:=chr(189) else Result:= Chr(181);
48:  if lowkey then result:=chr(186) else Result:= Chr(178);
189:if lowkey then result:=chr(188) else Result:= Chr(180);
187:if lowkey then result:=chr(191) else Result:= Chr(183);
end;
end;
 
 
{XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}
{XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}
 
var LastKey :integer;             //Для хранения Последней клавиши
      LowKey :Boolean = true; //Верхний или нижний регистр.
 
 
//Проверяем как прога пишет на Казахском языке
 
//Вылавливаем клавишу для дальнейшей обработки
procedure TForm1.Edit3KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
LastKey := Key;
LowKey:=IsLow; //Сразу (на месте) определяем и сохраняем  регистр.
end;
 
 
procedure TForm1.Edit3KeyPress(Sender: TObject; var Key: Char);
Var tmpKey :char;
begin
if GetKeyboardLayout(0)=KZ_KBRD then //Если казахская раскладка то..
  Begin
     tmpKey:=KeyToKZChar(LastKey,LowKey);// Получаем нужный символ
     if not(tmpKey = #0) then //Если  не стандартный символ то...
      Begin  
       Key:=tmpKey;   // Указываем окну наш символ
       exit;   
   end;
  end;
end;
 
//Дальше тоже самое только для компонента TMEMO
 
procedure TForm1.Memo1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
   LastKey:=key;
   LowKey:=IsLow;
end;
 
procedure TForm1.Memo1KeyPress(Sender: TObject; var Key: Char);
var tmpKey : char;
begin
 if GetKeyboardLayout(0)=KZ_KBRD then
  Begin
     tmpKey:=KeyToKZChar(LastKey,LowKey);
     if not(tmpKey = #0) then
      Begin
      Key:=tmpKey;
      exit;
      end;
  end;
end;
 
 
//Можем сохранить наше творение в файл.
procedure TForm1.Button4Click(Sender: TObject);
begin
Memo1.Lines.SaveToFile('A.txt');
end;
 
//Или же наоборот загрузить из файла.
procedure TForm1.Button5Click(Sender: TObject);
begin
Memo1.Lines.LoadFromFile('A.txt');
end;
 
//Проба вывода на канвас разными методами.
procedure TForm1.Button3Click(Sender: TObject);
begin
pb.Canvas.Font.Name:='Times/Kazakh';
pb.Canvas.Font.Color:=clRed;
pb.Canvas.Font.Size:=14;
pb.Canvas.TextOut(10,10,Edit1.Text);
TextOut(PB.Canvas.Handle,30,30,Pchar(Edit1.Text),10);
end;
 
//Текст На компоненты
Edit3.Text:=Memo1.Text; 
Button2.Caption:=Edit3.Text;

На этом моя задача исчерпала сама себя. Конечно в приведенном примере еще много белых пятен.
К примеру возникают сложности при вставке текста скопированном в другом приложении (Блокнот).
Но это уже другие проблемы, другие вопросы, другие задачи. Даже на основе этого "скилета".
Можно приступать к "написанию" программ на "Казахском языке" либо же разрабатывать
на его основе свои "скилеты".
Буду очень признателен если кто нибудь оттранслирует статью под С++(С сылкой на автора)
Если будут какие нибудь вопросы то...
Я всегда буду рад на них ответить.
 
aster_x@inbox.ru

Из за того что фичь есть но юзать его простым смертным не дано....

С ГЛУБОКИМ УВАЖЕНИЕМ ASTER_X

Взято из https://forum.sources.ru

Автор: ASTER_X