В 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 можно просто не указывать.
Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.
Примечание. Отправлять комментарии могут только участники этого блога.