-
Постов
394 -
Зарегистрирован
-
Посещение
-
Победитель дней
45
Активность репутации
-
AngryOwl отреагировална OnePeople в Рисование на неклиентской часть окна
Или просто сделайте borderstyle формы none. И сами сделайте рамки, кнопки закрыть, свернуть и т.д.
-
AngryOwl отреагировална Martifan в Рисование на неклиентской часть окна
К сожалению, в FireMonkey для Windows нет встроенной поддержки для размещения компонентов или рисования на заголовке окна (title bar).
Однако, есть несколько возможных вариантов для достижения похожего эффекта:
Создать собственный кастомный компонент на основе TControl, который будет перекрывать заголовок окна и имитировать его. Можно нарисовать свой фон, кнопки и т.д. Использовать Windows API функции для настройки и изменения заголовка окна. Например, SetWindowText, SetWindowLong и другие. Это более сложный подход, но дает больше контроля. Рассмотреть сторонние компоненты и библиотеки. Возможно, кто-то уже реализовал похожую функциональность для FireMonkey. Попробовать поместить TControlAboveTarget на TForm и настроить его позицию/размер чтобы перекрывал заголовок. Не идеальный вариант, но может сработать. Так что в целом это возможно реализовать в FireMonkey, но нет встроенного прямого решения как в VCL. Придется поиграться с кастомными компонентами и низкоуровневым API.
-
AngryOwl отреагировална Martifan в Теряются Push уведомления
Firebase Cloud Messaging (FCM) предоставляет возможность установить приоритет сообщения, но это не гарантирует, что все сообщения будут доставлены в определенном порядке или что все сообщения будут доставлены вообще.
Когда устройство находится в режиме отключения от интернета, FCM хранит только последнее сообщение для каждого топика. Это означает, что если вы отправляете три разных уведомления на одно и то же устройство, когда оно отключено от интернета, FCM сохранит только последнее уведомление. Когда устройство снова подключается к интернету, оно получит только это последнее уведомление.
Если вам нужно, чтобы все уведомления были доставлены, вам нужно будет реализовать свою собственную систему очереди на стороне клиента. Это может включать в себя сохранение уведомлений в локальной базе данных на устройстве и отображение их в нужном порядке, когда устройство подключается к интернету.
-
AngryOwl отреагировална krapotkin в Размер компилируемого файла
что за детский сад
на андроиде приложения весят 400К и при этом используют библиотеки Java на 2G
это как - маленькие или большие приложения?
то же с .NET
Приложение с пустой формой тащит за собой весь функционал, который вы можете использовать, при этом не требуя установки дополнительных run-time библиотек, чем, собсн, всегда и хороша была Делфи
mp3 файл весит 8-10 мб. а 5 сек видео "опы - 120. Не видел я чтобы кто-то плакал по этому поводу
-
AngryOwl отреагировална ENERGY в Размер компилируемого файла
Menkos1
Это код для уменьшения размера exe под Windows. Добавляшь в Dpr файл (Project > View Source), выбираешь Release в правой панели, затем Project > Build. Размер еще уменьшиться.
Правда потом нужно протестировать программу. На VCL с этими директивами у меня проблем никогда не было, - в смысле каких то багов в программе. На FMX не пробовал (я FMX пока только под моб. девайсы использую)
-
AngryOwl отреагировална ENERGY в Размер компилируемого файла
Системе не навредит, просто смысла в этом нет. Лучше упаковать архиватором, или инсталлятором.
Упакованные exe распаковываются целиком в память, и остаются там до конца, плюс дольше запускаются.
Не упакованные exe загружаются по сегментам, частично, только то, что нужно. http://api.farmanager.com/ru/articles/packers.html
Я такой обычно код вставляю в dpr файл, для Windows проектов.
uses Windows; {$IFDEF RELEASE} {$SETPEFlAGS IMAGE_FILE_RELOCS_STRIPPED or IMAGE_FILE_DEBUG_STRIPPED or IMAGE_FILE_LINE_NUMS_STRIPPED} {$WEAKLINKRTTI ON} {$RTTI EXPLICIT METHODS([]) FIELDS([]) PROPERTIES([])} {$ENDIF} Конечно же нужно выбрать Release в Build Configurations в правой панели.
Есть смысл упаковывать вирусы итп, чтобы быстрее скачать, чтобы зашифровать и сменить сигнатуру. Или кеиген или что-то подобное.
-
AngryOwl отреагировална Tumaso в Не получается скачать файл по https
Используй TNetHTTPClient вместо инди, проблема с ssl уйдет.
При использовании инди и указании https в URL например в виндах требуется две дополнительные dll-ки (libeay32.dll / ssleay32.dll), для андроида libcrypto.so / libssl.so и т.д. Поэтому проще перейти на TNetHTTPClient
-
AngryOwl отреагировална Hevard в Delphi 11 Transparent StatusBar
Проверено на Александрии. Работает.
-
AngryOwl отреагировална Hevard в Книга. Обучение мобильной разработке не Delphi
Неужели так сложно не ссылки кидать, а приложить файлы? 🙄
Среда разработки Delphi 10.3.pdf Delphi. Программирование для Windows, OS X, iOS и Android [2014].pdf Мобильная разработка в delphi.pdf
Программирование_на_Delphi_для_школ.pdf
-
AngryOwl отреагировална Hevard в Вышла Delphi 11 Community Edition
Для переноса (компилирования) проектов из более ранней версии необходимо провести действия для Android 32-bit и Android 64-bit.
В окне Projects (справа) выбрать Target Platforms -> Правой кнопкой щёлкнуть по Libraries и выбрать Revert System Files to Default.
И не забудьте перенести debug.keystore из c:\Users\<USER>\AppData\Roaming\Embarcadero\BDS\21.0\ в папку ...\22.0\
Delphi: Community Edition - Embarcadero
-
AngryOwl отреагировална Евгений Корепов в IdTCPClient, IdTCPServer и соеденение
Тут все просто - нужно ждать. Ваш код работает корректно только в идеальных условиях. Но если вторая сторона не ответила мгновенно, то вы уже ничего не получите.
Перед отправкой/получением вам надо проверить наличие соединения функцией FTCPClient.IOHandler.CheckForDisconnect() - при отсутствии соединения она сгенерит исключение:
try FTCPClient.IOHandler.CheckForDisconnect(); except on E: EIdException do begin LogError('TUTM5StreamProtocol.Run CheckForDisconnect ERROR ' + E.Message); Reconnect(); end; end; Читать с ожиданием данных можно несколькими способами:
1. Задавать FTCPClient.IOHandler.ReadTimeout в надежде что в отведенное время что то придет.
2. Использовать FTCPClient.IOHandler.ReadLnWait() для чтения строки.
3. Или обрабатывать проверять наличие данных и читать по мере их поступления:
if FTCPClient.IOHandler.CheckForDataOnSource(FConnectParams.Timeouts.TCPReadTimeout) then читаем....
-
AngryOwl отреагировална Pavel Vasilev в Использование OpenGL?
Подготовка GLXcene компонентов на основе OpenGL для FMX (пока только для win32/64) возобновлена по новому адресу
https://github.com/GLScene/GLScene/tree/master/Source/FMX
Синхронизация юнитов и форм почти завершена с помощью BeyondCompare (входит теперь в состав редактора RAD Studio), префиксы классов и компонентов теперь разные, чтобы можно было устанавливать сразу обе сцены: у VCL - TGL.., у FMX - Tgx...
Пока компилируются run-time пакеты GLXcene for Delphi/C++Builder, а для design-time необходимо ещё добавить форму вьюера OpenGL и модуль дизайнера компонентов.
Для разработки графических 3D приложений под OpenGL для Delphi/C++Builder & Lazarus (Win/Linux/iOS/Android) лучше чем графический движок рендеринга GLScene ничего нет - в нём также есть своя физика, вейвлеты, менеджеры подключения сторонних звуковых и физических движков (BASS, OpenAL, Newton). Версия GLXcene объединит возможности Firemonkey для 3д моделирования и визуализации с имеющимися для Vcl версии.
Имеющие опыт создания компонентов под FMX, приглашаются принять участие в дальнейшей разработке графической платформы на гитхаб
https://github.com/GLScene/GLScene
-
AngryOwl получил реакцию от neo в Как убрать клаву по окончанию ввода в TEdit ?
uses
FMX.VirtualKeyboard, FMX.Platform,
...
var
Keyboard: IFMXVirtualKeyboardService;
begin
if TPlatformServices.Current.SupportsPlatformService( IFMXVirtualKeyboardService, IInterface( Keyboard ) ) then
Keyboard.HideVirtualKeyboard;
end;
-
AngryOwl получил реакцию от Ingalime в [ListBox] загрузка картинок
1. Создайте свой стиль для ListBoxItem, например 'listboxitemMystyle', скопировав стандартный и переобозвав его. В своем стиле Итемов просто сделайте невидимым Detail. Или, что еще лучше, - храните Ваши ссылки в TagString Итема.
2. В Style Designer, при редактировании Вашего listboxitemMystyle, вставьте TImage задайте ему необходимые свойства: выравнивание, размеры, отступы и т.д. (не забудьте сделать "растягивание" или что там Вам требуется - просто проверьте в дизайнере). И задайте Вашему TImage имя, например, 'myimagestyle'.
3. При загрузке изображения я бы рекомендовал сначала загрузить изображение в созданный TBitmap, а потом уже грузить его в наш 'myimagestyle'. А самое оптимальное решение - загрузка изображений в "контейнер", в фоновом режиме, а при окончании загрузки, по событию, - отрисовка уже в самом итеме. В любом случае - сначала в битмап, а потом этот битмап в Итем. Иначе, вероятность того что битмап отрисуется в вашем случае - практически нулевая.
4. Далее, при создании итемов:
procedure ContactList_AddItem(Sender: TObject); var newItem : TListBoxItem; newBitmap : TBitmap; begin newItem := TListBoxItem.Create(nil); newItem.StyleLooup := 'listboxitemMystyle'; // хотя будет проще не писать этого, а прописать в ListBox1.DefaultItemStyles.ItemStyle newItem.Text := 'текст'; newItem.TagString := тут может быть Ваша ссылка newBitmap := TBitmap.Create; newBitmap.LoadFrom ....... // грузим картинку newItem.TagObject := newBitmap; newItem.OnApplyStyleLookup := MyItemApplyStyle; ListBox1.AddObject(newItem); end; procedure MyItemApplyStyle(Sender: TObject); var LI : TListBoxItem; tmpBitmap : TBitmap; begin LI := Sender as TListBoxItem; if Assigned(LI) then try LI.BeginUpdate; tmpBitmap := LI.TagObject as TBitmap; if Assigned(tmpBitmap) then LI.StylesData['myimagestyle.bitmap'] := tmpBitmap; // тут вообще можно обновлять все что угодно в этом Итеме finally LI.EndUpdate; end; end; Собственно все.
Сорри если что не понятно - писал "от руки", без проверки. Но вроде все просто.
-
AngryOwl отреагировална Yuriy2606 в Приложение вылетает на Android 9
Решение:
Do any of the following:
1- Update the play-services-maps library to the latest version:
com.google.android.gms:play-services-maps:16.1.0 2- Or include the following declaration within the <application> element of AndroidManifest.xml.
<uses-library android:name="org.apache.http.legacy" android:required="false" /> Закинул сюда, может кому-то пригодится.
Ссылки:
https://stackoverflow.com/questions/50461881/java-lang-noclassdeffounderrorfailed-resolution-of-lorg-apache-http-protocolve
https://www.delphiworlds.com/2019/02/a-fix-for-using-tmapview-on-android-9-devices/
-
AngryOwl получил реакцию от Евгений Корепов в Как выгрузить приложение
procedure TfmMain.DoAppExit;
begin
try
Toast('Shutdown...');
TThread.Synchronize(nil, Do__________); // тут что-то делаем до завершения
finally
KillMe; // из Android.KillMainProcess
end;
end;
android.KillMainProcess.zip
-
AngryOwl получил реакцию от Евгений Корепов в Как при переходе с эдита на эдит очистить предыдущий текст в клавиатуре, что бы он не попал в новый эдит?
Мне помогло следующее:
TThread.Synchronize(nil, procedure begin memoChatMessage.Text := ' '; memoChatMessage.SelectAll; memoChatMessage.DeleteSelection; end);
-
AngryOwl отреагировална Brovin Yaroslav в [FGX Native] [Вебинар] Сравнение возможностей кроссплатформенных мобильных библиотек нативных приложений FMX и FGX Native
Тема: "Сравнение возможностей кроссплатформенных мобильных библиотек нативных приложений FMX и FGX Native" Дата и время: 20 декабря 2018 года в 12:00 (по московскому времени) Участники: @Brovin Yaroslav, Андрей Совцов Регистрация: ссылка Ссылка на официальный телеграмм канал: https://t.me/fgx_native Участие бесплатное Под конец уходящего нового года сравним текущие возможности кроссплатформенной библиотеки мобильной разработки FGX Native и FMX. Поговорим о перспективах развития и ознакомимся с ближайшим планом до выпуска публичной бета версии. Посмотрим в живую на новый функционал библиотеки, разработанный за последнее время. У вас будет возможность задать любые вопросы автору. Не пропусти эту возможность!
-
AngryOwl отреагировална Евгений Корепов в Проигрывание стандартных звуковых эффектов Android
Задался вопросом, нашел ответ, может кому пригодится.
uses Androidapi.JNI.Media, Androidapi.Helpers, Androidapi.JNIBridge, AndroidApi.Jni.JavaTypes, Androidapi.JNI.GraphicsContentViewText; .... procedure TFormMain.PlaySoundEffects(const ASoundID : Integer; AVolume : Single = 1.0); var AudioObj: JObject; Audio: JAudioManager; begin AudioObj:= TAndroidHelper.Context.getSystemService(TJContext.JavaClass.AUDIO_SERVICE); Audio:= TJAudioManager.Wrap((AudioObj as ILocalObject).GetObjectID); Audio.loadSoundEffects; Audio.playSoundEffect(ASoundID, AVolume); end; Константы звуковых эффектов тут https://developer.android.com/reference/android/view/SoundEffectConstants
Правда у меня только звук "чпок" на всех константах. Но мне он и был нужен )
-
AngryOwl отреагировална Rusland в Запуск приложения от PUSH-уведомления
Slava Marchenko подсказал что при закрытом приложении получить сам текст можно так:
procedure TFormMain.FormActivate(Sender: TObject); var CurNotification : TPushServiceNotification; begin if Length(fPushService.StartupNotifications) > 0 then for CurNotification in fPushService.StartupNotifications do if Assigned(CurNotification) then Memo.Lines.Text := CurNotification.Json.ToJSON; end;
-
AngryOwl отреагировална rareMax в Telega π - Библиотека для работы с Telegram Bot API в Delphi
В начале пару новостей:
Репозиторий клонируется также на ГитХаб. Можно устанавливать с помощью Delphinus'a Бот калькулятор для Telegram.
А сейчас мы напишем своего бота, который сможет решать арифметические выражения(и не только).
Что для этого нужно:
Telega π - Библиотека для работы с Telegram Bot API в Delphi TeeBI После установки библиотек свыше - создаем новое консольное приложение. Далее создаем новый модуль(unit) и называем его, например, Telegram.Plugin.Calculator
В этом модуле мы будем писать логику калькулятора, а точнее взаимодействие команд от пользователя и модуля выражений BI.Expression(TeeBI).
Для наглядности, сразу код модуля:
unit Telegram.Plugin.Calculator; interface uses TelegAPI.Bot, TelegAPI.Types, TelegAPI.Utils, TelegAPI.Module; Type TTgCalculatorBot = Class(TTgModule) private FIsCommandWait: Boolean; protected procedure OnUpdate(Sender: TObject; Const Update: TtgUpdate); override; End; implementation uses BI.Expression, System.SysUtils; { TTgWelcomeBot } procedure TTgCalculatorBot.OnUpdate(Sender: TObject; const Update: TtgUpdate); var Cmd: TCommandHelper; Procedure Calculation; var TextExpr: String; Begin FIsCommandWait := False; if Cmd.ParamCount = 0 then TextExpr := Update.Message.Text else TextExpr := Cmd.ParamsToString; try (Sender as TTelegramBot).sendTextMessage(Update.Message.Chat.ID, TExpression.FromString(TextExpr).Value); except on E: Exception do (Sender as TTelegramBot).sendTextMessage(Update.Message.Chat.ID, 'упс, ошибочка вышла: ' + E.ClassName + ' ' + E.Message); end; End; begin Cmd := TCommandHelper.Create(Update.Message.Text); try if Cmd.Command = '/calc' then Begin if Cmd.ParamCount = 0 then Begin FIsCommandWait := true; (Sender as TTelegramBot).sendTextMessage(Update.Message.Chat.ID, 'ожидаю выражение:'); End else Begin Calculation; End; End else if FIsCommandWait then Begin Calculation; End; finally Cmd.Free; end; end; end. Первое на что обращаем внимание - наш класс TTgCalculatorBot будет наследоваться от TTgModule, в котором заложен базовый функционал для расширения функционала бота(на данный момент только получение обновлений от сервера).
В метод OnUpdate будут поставляться обновления, которые приходят от сервера, в нем мы и будем работать.
Насчет поля FIsCommandWait. Уж так сложилось - что, как правило, пользователь сразу отправляет боту команду - а потом параметры. Поэтому, если придет поддерживаемая модулем команда - мы устанавливаем это поле в True. Если это поле - правда - значит нужно обработать текст.
Теперь вернемся к нашему консольному приложению:
program CalculatorBot; {$APPTYPE CONSOLE} {$R *.res} uses TelegaPi.Bot, TelegaPi.Types, System.SysUtils, Telegram.Plugin.Calculator in 'Telegram.Plugin.Calculator.pas'; Const C_PAUSE_UPDATE = 1000; { 1sec. } Var TelegramBot: TTelegramBot; TelegramCalc: TTgCalculatorBot; Procedure InitRecesive; var Offset: Integer; Updates: TArray<TtgUpdate>; Update: TtgUpdate; Begin Offset := 0; while True do begin Sleep(C_PAUSE_UPDATE); // Update pause Updates := TelegramBot.getUpdates(Offset); // Get updates if Length(Updates) = 0 then Continue; Offset := Updates[High(Updates)].ID + 1; end; End; begin WriteLn('Telegram Calculator Sample'); { Here you Api key } TelegramBot := TTelegramBot.Create({$I ..\telegaToken.inc} ); TelegramCalc := TTgCalculatorBot.Create(TelegramBot); try WriteLn('Bot token: ', TelegramBot.getMe.ID <> -1); InitRecesive; except on E: Exception do WriteLn(E.ClassName, ': ', E.Message); end; TelegramBot.Free; TelegramCalc.Free; end. TelegramCalc := TTgCalculatorBot.Create(TelegramBot); - во время создания модуля - происходит подписка на сообщения от сервера. Никаких данных программисту передавать не нужно.
Далее, что бы консоль сразу же не закрылась - нужно зациклить прием данных от сервера. Пример - в процедуре InitRecesive.
Что получаем в итоге:
Так же можете сами протестировать бота(если он конечно будет запущен): @test_delphi_api_bot
Готовый пример: https://bitbucket.org/uasoft/telegapi/src//examples/PluginCalculator/?at=master
-
AngryOwl отреагировална Tumaso в Переход на новую модель разрешений
@Alex7wrt,
устанавливают в том числе и новые пользователи на старых версиях андроида, и у них работает. minSdkVersion для этого.
Что касается targetSDK, то этим значением приложение уведомляет операционку, что возможно будет использовать api вплоть до данной версии. targetSDK 27 пока не использовал, только 26, и все что надо работает.
В самом коде делаю анализ текущей версии SDK, и в зависимости от нее возможно делаю дополнительные действия. Вот например, работа с правами:
{$IFDEF ANDROID} // для Android 6+ требуется дополнительная работа с правами if TJBuild_VERSION.JavaClass.SDK_INT >= 23 then begin if (TAndroidHelper.context.checkSelfPermission( StringToJString(PERMISSION_FILE_READ) ) = TJPackageManager.JavaClass.PERMISSION_DENIED) or (TAndroidHelper.context.checkSelfPermission( StringToJString(PERMISSION_FILE_WRITE) ) = TJPackageManager.JavaClass.PERMISSION_DENIED) then begin // необходимо запросить разрешение на использование галереи LIsWaitPermissions := True; TAndroidHelper.Activity.requestPermissions( CreateJavaStringArray([PERMISSION_FILE_READ, PERMISSION_FILE_WRITE]), BUTTON_FILE ); end; end; {$ENDIF}
-
AngryOwl отреагировална ENERGY в Не оптимизированный TLabel и TText (решение)
Есть такая процедура, function DelAmp(const Text: string): string; в FMX.Types.
Которая 2 раза выделяет память для всей строки, и сканирует все символы в строке, в поисках &.
TLabel.Text := 'Text'; - эта процедура выполнится 2 раза, на любой платформе. Чтобы она выполнилась 1 раз, нужно сделать
TLabel.PrefixStyle := TPrefixStyle.NoPrefix;
TText
TText.Text := 'Text'; Процедура DelAmp выполниться в любом случае на любой платформе
procedure TText.SetText(const Value: string); [..] begin if Text <> Value then begin NewText := ConvertText(DelAmp(Value)); [..] Стили состоят из множества TText элементов. Теперь представьте сколько ресурсов тратиться впустую.
function DelAmp(const Text: string): string; var I, J: Integer; Sb: TCharArray; begin Result := ''; if Text <> '' then begin SetLength(Sb, Text.Length); I := Low(Text); J := 0; while I <= High(Text) do begin if (Text[I] <> '&') then begin Sb[J] := Text[I]; Inc(J); end else begin if ((I < High(Text)) and (Text[I + 1] = '&')) then begin Sb[J] := Text[I]; Inc(J); Inc(I); end; end; Inc(I); end; Result := string.Create(Sb, 0, J); end; end;
Решение - скопировать FMX.Types в папку с проектом, и переделать функцию на:
function DelAmp(const Text: string): string; begin Result := Text; end;
-
AngryOwl получил реакцию от Anatoliy в Как убрать клаву по окончанию ввода в TEdit ?
uses
FMX.VirtualKeyboard, FMX.Platform,
...
var
Keyboard: IFMXVirtualKeyboardService;
begin
if TPlatformServices.Current.SupportsPlatformService( IFMXVirtualKeyboardService, IInterface( Keyboard ) ) then
Keyboard.HideVirtualKeyboard;
end;
-
AngryOwl получил реакцию от Anatoliy в TImage изображение по центру
Если я правильно понял, то Вам достаточно у TImage установить свойство ClipChildren = True.