Работа с КАЗАХСКИМИ ШРИФТАМИ

Материал из DRKB

Работа с КАЗАХСКИМИ ШРИФТАМИ[править | править код]

Работа с КАЗАХСКИМИ ШРИФТАМИ. Здравствуйте Уважаемые Господа Программисты. Моя небольшая статья будет, скорее всего, интересна программистам из региона - КАЗАХСТАН. Так как программисты проживающие и работающие в этом регионе чаще всего встречаются с проблемой вывода нестандартных КАЗАХСКИХ ШРИФТОВ.

Вместо введения...[править | править код]

Как всегда, передо мною, выросла проблема и, как всегда, я решил приложить максимум усилий чтобы разобраться самому. (Вы меня простите но я не любитель напрягать форумы своими проблемами). Программисты Казахстана знают, какая это, довольно таки серьезная проблема, "Нестандартные казахские символы". Так как я сейчас активно занимаюсь "писаниной" - пишу прогу, которая должна "понимать" КАЗАХСКИЙ ЯЗЫК от и до (Если так можно сказать). Писал, писал, и вдруг случилось... Оказывается, не один элемент управления не хочет ни "писать", ни "читать" по-КАЗАХСКИ. Решил перелопатить инфу, которая была и локальную и "ИНЕТСКУЮ". Как выяснилось, инфы типа "КАК СДЕЛАТЬ СУПЕР _TButton_" огромное количество. А по шрифтам... "увольте".

Приступим.[править | править код]

Первое что надо сделать чтобы работать с казахскими шрифтами это... Разместить их в системной таблице шрифтов. Есть два способа - закидываете файл со шрифтом в каталог \Windows\Fonts\ Или же, ложите файл рядом с программой и вызываете AddFontResource('you_font.xxx');

Я пошел по первому пути (Так проще, хотя второй я тоже практиковал). Ну предположим, что мы разобрались с методом регистрации шрифта в системе. Я использовал шрифт "Times/Kazakh" и вам советую. (Во всяком случае все примеры основаны именно на этом шрифте). Но при определенном навыке, или же когда освоитесь с этим шрифтом, Вы сможете перейти на любой другой шрифт.

ВАЖНО[править | править код]

Второе, в чем часто путаются программеры, это - чтобы работать со шрифтами по принципу "ОТ ОКНА К ОКНУ" надо чтобы на всех окнах, в которых подразумевается использование казахского шрифта, было установлено одинаковое имя шрифта (Times/Kazakh). Тогда вы спокойно сможете пользоваться буфером обмена и оператором присваивания (EditX.Text := EditY.text;). Это же относится и ко всем TCanvas на которых подразумевается вывод КАЗ_ШРИФТА. Основная проблема заключается в том, что даже после установки казахской раскладки и казахского шрифта, окна (даже окна редактирования TEdit. Tmemo) все равно не хотят выводить текст, даже с клавиатуры. И тут приходиться "хитрить" - дело в том, что нестандартные КАЗАХСКИЕ СИМВОЛЫ (CHAR) лежат в диапазоне 176-191 (Большие и маленькие). Поэтому я сделал так - во время ввода, если выбрана КАЗАХСКАЯ раскладка клавиатуры, перехватывать VIRT_KEY в событии OnKeyDown. И транслировать их в Казахские CHAR'ы. Уже готовый текст вы можете сохранить в файл и потом открыть. Без всяких излишеств. Либо скопировать в буфер обмена. Но учтите, при вставке в другое окно или приложение (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


Author: ASTER_X
Source: Взято из http://forum.sources.ru
ID: 01931