-
Постов
394 -
Зарегистрирован
-
Посещение
-
Победитель дней
45
Весь контент AngryOwl
-
Друзья! Я тут в одной теме выложил юнит для локализации приложений и демо-пример к нему, а также приложение облегчающее создание и редактирование ресурсов для локализации (файлов с переводами на разные языки). Потом подумал - может стоит вынести это в отдельную тему? Данная проблема (локализации приложений) возникла уже давно. На заре XE2. Потом были все версии, вплоть до текущей. Но лично меня текущие решения так и не устраивали. Мне нужно было простое и удобное редактирование сразу всех языков приложения, и чтобы быстро работало. Тогда и были созданы этот юнит и приложения, с которыми я решил с вами поделиться. Создано это было для себя, для упрощения локализации собственных приложений. Поэтому никакой "красоты" кода прошу не искать - ее там нет. Местами вообще кому-то покажется "кривым"... ) Очень жаль, что у меня критически мало времени для общения на данном ресурсе, а потому я в некотором смысле извиняюсь - мог бы выложить этот код давно. Тем-более, что он очень простой. Все что в нем используется, и как используется, думаю, всем будет доступно и понятно. Итак. Приложение Test_Translator - это дело пример с, непосредственно, самим юнитом uTranslatorFM.pas В uTranslatorFM.pas вы увидите, что локализация осуществлена за счет использования INI-файлов, а сам "перевод" осуществляется простым перебором компонент на форме. Стоит отметить, что перевод осуществляется использованием свойства компонент HelpContext (integer), а у компонент, что не имеют этого свойства - используется свойство Tag. На первый взгляд может показаться неудобным. А если приложение большое - что-то может забыться. Однако, лично я очень быстро привык к такому использованию. И поверьте - приложение, в котором я использую этот юнит, очень большое! ))) Кроме того, если есть компоненты, которые не имеют этих свойств, или которые могут менять значение перевода самостоятельно, либо могут быть динамическими - можно использовать нулевой HelpContext, но при этом придавать им значения "вручную". Например: если требуется у компонента TLabel динамически менять значение в ходе выполнения программы, подставляя нужные "подстроки" (грубо - используя, например, Format(...)), то можно написать в программе Label1.Text := Format( AppTranslator.GetValue(_код_, _значение_по_умолчанию_), [_подставляемое_значение_]); где _код_ - это значение, которое будет считываться из INI-файла (например 100) _значение_по_умолчанию_ - значение строки по умолчанию, на тот случай, если данный текст отсутствует в INI-файле, или файла с таким переводом не существует (этот параметр не обязателен) _подставляемое_значение_ - в данном случае это просто пример, допустим - ход выполнения процесса (например 85%) А строка в INI-файле может быть такая: (файл lang.ru) 100=Процесс выполнения %d%% (файл lang.en) 100=The progress %d%% и также другие языки. Думаю тут, в примере, все элементарно и понятно. Все работает на любой платформе! Как вы будете подключать файлы к приложению - ваше дело. Можно скачивать с инета, можно встроить в качестве ресурсов, задеплоить в проект и т.д. Лично я встраиваю в качестве ресурсов (Win) и деплою (Mac и Android). У меня свои причины и аргументы. Файлы: Lang.ru Lang.en и другие, это INI-файлы соответствующих переводов где строки с переводами имеют одинаковые индексы LangList.ini - вспомогательный файл (разберетесь)) language.rc - файл для создания ресурса (Win) С приложением SLLanguage все немного и сложнее и проще, одновременно... Не вижу смысла его описывать - оно просто позволяет редактировать описанные выше ресурсы (файлы языков). Часть его кода откуда-то позаимствовано (не помню уже). Для чего все это я отдельно решил написать, в отдельную тему? Предлагаю всем пользоваться данным кодом - кому как заблагорассудится! Исправлять, дополнять и делится мыслями и идеями. Возможно кто-то решит создать компонент. Ну вот вроде все, друзья! Если что - спрашивайте! Отвечу по мере возможности. P.S. К модераторам - поправьте, если что, - вдруг не в ту тему закинул. SLLanguage.zip Test_Translator.zip P.P.S. Забыл уточнить - дело-пример делал под XE10, а приложение для создания ресурсов под XE7. Не сложно поправить - кому под что нужно.
-
И еще, друзья! Делалось это все для себя, для личного пользования, а не для "распространения") Так-что не обессудьте - если где "говнокод") Сами поправите кому как нравится) Заодно может поделитесь интересными мыслями и идеями. Если кому что не понятно - подскажу.
-
Как обещал - приложение для создания, редактирования, автоматического перевода и сохранения Ini-файлов с переводами для локализации своих приложений. Для примера есть два файлики (Lang.en и Lang.ru) и другие файлы, содержание которых всем будет понятно) Все, вроде, просто) P.S. Все желающие могут использовать как хотят. Можете что-то добавлять, исправлять и т.д. Ну и не забываем делиться с другими...)) P.P.S. - делалось уже давно, под XE7. Кто захочет под XE10 - думаю все будет крайне просто переделать. SLLanguage.zip
-
В общем я тупо вырезал часть из своего проекта. И создал маленький демо-проект. Работает везде! Хоть на Винде, хоть на Маке, хоть на Андроиде. Думаю - разберетесь. Тем-более, что там все очень просто. В демке сделал только два языка (в моем проекте их 11). Все в Ini-файлах, работает очень быстро. P.S. Все желающие могут использовать как хотят. Можете что-то добавлять, исправлять и т.д. Ну и не забываем делиться с другими... P.P.S. Позже выложу приложение (GUI) для редактирования файлов языков. С автоматическим переводчиком и прочими мелочами, упрощающими редактирование. Test_Translator.zip
-
Попробуйте использовать PreloadContent (если, конечно, Вы его уже не используете) З.Ы. Это в смысле - по поводу первого появления и прочих лагов "в первый раз"
-
Не за что! А благодарить будете, если получится с компонентами, - Ярослава)
- 19 ответов
-
- Delphi XE10
- Android 5.1
-
(и ещё 1 )
C тегом:
-
В конкретном случае - речь идет о Android. Тут, в некотором смысле, проще - воспользуйтесь замечательными компонентами FGX от автора данного форума. У компонента TfgApplicationEvents есть все события, которые Вам необходимы. А именно - событие ДО отображения формы (и куча других). Ну если Вам не хватает отладчика - тупо натыкайте в нужных местах "тостов" (Toast), и смотрите - что будет "последним" событием... З.Ы. А зависание программы происходит однозначно из-за того, что Вы пытаетесь что-то изменить в интерфейсе, до момента пока форма еще не стала активной. Решить можно не только синхронизацией, но и каким-нибудь Splash.
- 19 ответов
-
- Delphi XE10
- Android 5.1
-
(и ещё 1 )
C тегом:
-
Попробуйте загрузку ваших картинок оформить в: TThread.Synchronize(TThread.CurrentThread, procedure begin // тут загрузка ваших картинок end);
- 19 ответов
-
- Delphi XE10
- Android 5.1
-
(и ещё 1 )
C тегом:
-
В общем можно сделать, конечно, установку шрифта в инсталлере программы. И это будет оптимальным решением. Но можно обойтись и без него. Не буду расписывать детали, просто закину приложение и фрагменты кода. Думаю разберетесь. Естественно изменив на свои шрифты и т.п. Все нижеперечисленное - в файл проекта DPR, перед Application.Initialize; const CKey = '\Software\Microsoft\Windows NT\CurrentVersion\Fonts'; CFontFileName = 'spherelive.ttf'; CFontName = 'spherelive (TrueType)'; procedure ExecuteWait(const sProgramm: string; const sParams: string = ''; fHide: Boolean = false); var ShExecInfo: TShellExecuteInfo; begin FillChar(ShExecInfo, sizeof(ShExecInfo), 0); with ShExecInfo do begin cbSize := sizeof(ShExecInfo); fMask := SEE_MASK_NOCLOSEPROCESS; lpFile := PChar(sProgramm); lpParameters := PChar(sParams); lpVerb := 'open'; if (not fHide) then nShow := SW_SHOW else nShow := SW_HIDE end; try if (ShellExecuteEx(@ShExecInfo) and (ShExecInfo.hProcess <> 0)) then try WaitForSingleObject(ShExecInfo.hProcess, INFINITE) finally CloseHandle(ShExecInfo.hProcess); end; except On E : Exception do ShowMessage('font install Exception: ' + E.Message); end; end; if not IsFontRegistered(TPath.Combine(ExtractFilePath(ParamStr(0)), CFontFileName), CFontName) then if FileExists(TPath.Combine(ExtractFilePath(ParamStr(0)), 'RegFontC.exe')) then ExecuteWait(TPath.Combine(ExtractFilePath(ParamStr(0)), 'RegFontC.exe')); Application.Initialize; Где будет лежать файл со шрифтом - это уже ваше дело. Можно его куда угодно поместить. Хоть в ресурсы, хоть файлом просто, хоть с инета скачать. P.S. Ну и конечно - это все именно под винду... RegFont.zip
-
Возможно я не прав, но мой личный опыт показывает, что кол-во "задеплоенных" файлов никак не влияет на скорость запуска приложения. А вот что очень сильно влияет - кол-во визуальных компонентов на форме(ах). И чем их больше - тем, соответственно, дольше запускается приложение. И это независимо от того - видимы они на главной форме или нет. Ну и, конечно, инициализация различных переменных, невизуальных компонентов, инициализации БД и прочего, - это тоже существенно влияет. P.S. Ну и сори - что не в тему (какую именно БД использовать)...
-
Согласен, виноват, на счет процедуры. Но в данном случае я никак не могу увидеть эти две кнопки... Может у меня что-то не так? Или с версией андроида что-то не так, либо еще что-то. У меня отображается список в виде RadioButtons, где выбор осуществляется просто выбором пункта из списка. А отмена - просто нажатие кнопки "назад". Может Вам стоит обрабатывать событие OnKeyDown? Ну или детальнее опишите, желательно со скрином примера...
-
Как отловить событие изменения размера клавиатуры?
AngryOwl опубликовал вопрос в Виртуальная клавиатура
Подобный вопрос уже задавался тут, но ответа так не последовало. А вопрос достаточно актуальный, так как решения не удалось найти. Как отловить событие изменения размера клавиатуры, когда после первого отображения клавиатуры и попытки набора текста появляется некий дополнительный прямоугольник с подсказками по набору текста? Последовательность следующая: 1. без клавиатуры 2. появляется клавиатура при получении фокуса компонентом ввода текста (все ОК) 3. при первом же введенном символе появляется дополнительная область клавиатуры с предлагаемыми вариантами набора текста (баг - клавиатура перекрывает поле ввода) 4. при последующих вызовах клавиатуры (все ок) -
Насколько я понимаю - проблемы не только у Вас. Посмотрите тут.
-
Сорри, конечно, но может я чего-то не догоняю... Откуда у TComboEdit событие OnDropDown?
-
Уточните детали - что Вы хотите получить? Еще лучше - скрин того, чего хотите добиться. Можете просто нарисовать. Если Вам нужно, чтобы на фоне (одного цвета) был расположен TListView другого цвета, и у этого TListView были "скругленные углы", то этого добиться очень просто. Разместите TLayout, на нем TListView, у которого выравнивание Client, а по углам TLayout поместите TImage с соответствующими PNG. Разумеется, нужно установить свойство TListView в Send to back ("под" этими TImage)
-
type TForm2 = class(TForm) SizeGrip1: TSizeGrip; procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override; private { Private declarations } public { Public declarations } end; ........... procedure TForm2.SetBounds(ALeft, ATop, AWidth, AHeight: Integer); begin if AWidth > 800 then AWidth := 800; if AWidth < 300 then AWidth := 300; if AHeight > 600 then AHeight := 600; if AHeight < 200 then AHeight := 200; inherited SetBounds(ALeft, ATop, AWidth, AHeight); end; Пример проекта прилагаю SetBounds.zip P.S. И старайтесь пользоваться поиском. Здесь это уже обсуждалось.
-
Именно так и делал. Один раз написал - все прекрасно работает, стабильно и быстро, на всех платформах. Весь юнит 650 строк, с учетом особенностей проекта.
-
TLang - самый кривой компонент! Да простят меня эмбаркадеровцы... Я писал свое.
-
Среда не открывает форму. Якобы там свойство неведомое.
AngryOwl ответил POV вопрос в Прочие вопросы
Попробуйте следующий вариант: - открываете проект (важно чтобы первой открытой формой в проекте была главная форма) - IDE выдает описанную вами ошибку (жмете Ignore All) - закрываете проект без сохранения (не закрывая среду) - тут же, снова открывате проект - проект должен открыться уже нормально. напомню, что первой должна быть главная форма. если не она, то открываете главную форму (игнорируя все предупреждения) и повторяете снова. Это не ошибка проекта. Это баг IDE. З.Ы. И связано это, скорее-всего, с использованием сторонних компонент, которые используются в вашем стиле. -
Если не ошибаюсь - никак... А если точнее - то только "ручками", отрисовывая текст самостоятельно, в переопределенных процедурах отрисовки ячеек.
-
И [brunnengi] и [ZuBy] оба правы. В первом случае у TLayout нужно выключить свойсвто HitTest, чтобы сам TLayout не "перекрывал" клики мышь (или тапы) (TLayout позволит "выравнивать" несколько "кнопок" относительно друг друга проще) Во втором случае - все проще (любой лишний компонент на форме, не важно - в составе чего он, - это дополнительная память, а главное - расходы на отрисовку. Порой нам кажется, что вроде на форме и "нет ничего", а если копнуть поглубже - там окажется море того, чего мы не видим, а отрисовывать то их прийдется!). Простой TImage, на мой взгляд, лучше. Но, как мне кажется, в данном случае вовсе не обязательно обрабатывать выравнивание в событии OnResize. Достаточно в DesignTime разместить TImage (все) где нужно и установить его (их) свойство Anchors = [akRight, akBottom] (для Вашего случая)
-
Что же касается самой функции, кажется можно чуть проще (где-то на форуме уже вроде был такой код) и он прекрасно работает: function GetTextHeight(AText: string; AMaxWidth: Single; AFont: TFont; ATextAlign: TTextAlign): Single; var txt: TText; begin txt := TText.Create(nil); try txt.Align := TAlignLayout.None; txt.VertTextAlign := ATextAlign; txt.HorzTextAlign := TTextAlign.Leading; txt.Font := AFont; txt.WordWrap := True; txt.Width := AMaxWidth; txt.BeginUpdate; txt.Text := AText; txt.EndUpdate; txt.AutoSize := True; Result := txt.Height; finally FreeAndNil(txt); end; end;