В Extended стилях окна можно указать, будет ли оно отображаться слева направо (Left-To-Right - LTR) или справа налево (Right To Left - RTL). Раскладка справа налево используется в языках с написанием справа налево - из которых сегодня наиболее широко используются, вероятно, арабский и иврит. Вы можете попросить Windows сделать окно с ориентацией RTL, установив Extended-стиль
WS_ EX_ LAYOUTRTL.Если вы не укажете Extended-стиль
WS_ EX_ LAYOUTRTL, система всё равно может применить этот стиль автоматически на основе следующих правил:| Сценарий | Правило | |
|---|---|---|
| Дочернее окно (child window) |
Родитель не указывает WS_ |
Наследует WS_ от родителя. |
Родитель указывает WS_ |
Остаётся LTR. | |
| Окно верхнего уровня (top-level window) |
Есть владелец (owned) | Остаётся LTR. |
| Нет владельца | Согласно GetProcessDefaultLayout. |
|
В случае окна верхнего уровня без владельца Extended-стиль
WS_ EX_ LAYOUTRTL устанавливается автоматически, если в настройках по умолчанию процесса установлен бит LAYOUT_ RTL.Как я заметил некоторое время назад, если процесс ни разу не вызывает функцию
SetProcessDefaultLayout, то начальные настройки процесса определяются путём проверки свойства версии FileDescription основного исполняемого файла: если оно начинается с двух меток LRM (Left-To-Right Mark, это кодовая точка Unicode U+200E), то в настройки процесса добавляется LAYOUT_ RTL.Ранее я также отметил, что вы можете запросить у
GetLocaleInfoEx свойство LOCALE_ IREADINGLAYOUT, чтобы определить, является ли какой-либо конкретный язык LTR или RTL.// Направление:
// 0 = слева направо (например, английский, русский и т.п.)
// 1 = справаналево (например, арабский)
// 2 = сверху вниз, справа налево (например, классический китайский)
// 3 = свурху вниз, слева направо (например, монгольский)
function GetLanguageReadingLayout(const ALanguageName: String): Integer;
begin
Win32Check(Boolean(
GetLocaleInfoEx(ALanguageName,
LOCALE_IREADINGLAYOUT or LOCALE_RETURN_NUMBER,
PWideChar(@Result),
SizeOf(Result) div SizeOf(Char))));
end;
function GetSystemDefaultLanguageReadingLayout: Integer;
begin
Result := GetLanguageReadingLayout(LOCALE_NAME_SYSTEM_DEFAULT);
end;
function GetUserDefaultLanguageReadingLayout: Integer;
begin
Result := GetLanguageReadingLayout(LOCALE_NAME_USER_DEFAULT);
end;
Но обычно вас интересует основной язык для текущего потока, так как именно он больше всего влияет на языковые ресурсы, используемые вашей программой. Вы можете использовать GetThreadPreferredUILanguages, чтобы получить все языки, применимые к текущему потоку, а затем передать первый язык в нашу вспомогательную функцию GetLanguageReadingLayout. Вызов функции GetThreadPreferredUILanguages немного разочаровывает, потому что список применимых языков может меняться асинхронно (если другой поток вызывает SetProcessPreferredUILanguages). Это вдвойне раздражает, потому что вспомогательная функция AdaptFixedSizeToAllocatedResult работает с нуль-терминированными строками и не поддерживает строки, заканчивающиеся двойным нулём, поэтому придётся писать цикл вручную:// Возвращает строку вида
// 'ru-RU'#0'ru'#0'en-US'#0'en'#0#0
function GetThreadPreferredUILanguages(const AFlags: DWORD): String;
var
Count, BufferSize: Integer;
Error: Cardinal;
begin
Count := 0;
BufferSize := 0;
SetLastError(0);
Win32Check(WinAPI.Windows.GetThreadPreferredUILanguages(AFlags, @Count, nil, @BufferSize));
repeat
SetLength(Result, BufferSize);
if WinAPI.Windows.GetThreadPreferredUILanguages(AFlags, @Count, PChar(Result), @BufferSize) then
Error := 0
else
Error := GetLastError;
until Error <> ERROR_INSUFFICIENT_BUFFER;
Win32Check(Error = 0);
end;
Теперь мы можем подключить это к нашей существующей функции:function GetDefaultThreadLanguageReadingLayout: Integer; begin Result := GetLanguageReadingLayout(PChar(GetThreadPreferredUILanguages(MUI_LANGUAGE_NAME or MUI_UI_FALLBACK))); end;Извините, что получилось так сложно.
Бонусная болтовня: вся эта логика предполагает, что ваша программа изначально была переведена на язык RTL. Если ваша программа предназначена только для английского/русского языка, не отображайте английские/русские строки в RTL. Как я отметил в этой статье, вы можете добавлять метки в строковые ресурсы, чтобы указать в каком направлении ресурсы ожидают чтения строк.
Комментариев нет:
Отправить комментарий
Можно использовать некоторые HTML-теги, например:
<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>
Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку.
Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.
Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.
Примечание. Отправлять комментарии могут только участники этого блога.