Перейти к содержанию
Fire Monkey от А до Я

DirtyBorov

Пользователи
  • Постов

    71
  • Зарегистрирован

  • Посещение

  • Победитель дней

    6

Весь контент DirtyBorov

  1. Еще пару вариантов. 1. Можно немного сократить, не указывая Items (почему - ищите в "корнях" property) for i:=0 to List.Count-1 do List[i].Position.Y := List[i].Position.Y+0.5; 2. Можно использовать такой вариант var c: TCircle; begin for c in List do c.Position.Y := c.Position.Y + 0.5; end;
  2. Все же более правильный вариант будет такой: with TStringList.Create do try Text := 'ТЕКСТ'; SaveToFile('c:\file.txt'); finally Free; end; Иначе, если при каких то проблемах с файлом, Free не будет вызван и мы получим утечку.
  3. Да не ужели? Ни когда бы не догадался... я же всего то 20 лет программирую. Это сарказм. еще могу показать пару вариантов. Например: Label1->Caption = 15 / 3; или так double x = 15, y = 3; Label1->Caption = x / y; Улавливаете ход мысли?
  4. Это я уже понял, немного поигравшись с разными вариантами. void __fastcall TForm1::Button1Click(TObject *Sender) { int x = 3.2; Label1->Caption = x; // выведет 3 } Просто я уже очень давно не писал на С++. Не пойму когда и для чего это сделали. В чем профит? Ведь С++ строго типизированый язык. На мой взгляд это только добавит неявных ошибок. Или я не прав?
  5. DirtyBorov

    Вопрос по С++

    Сегодня один товарищ сломал мне мозг вот таким кодом: void __fastcall TForm1::Button1Click(TObject *Sender) { int x = 2; Label1->Caption = x; } И компилятор это схавал! Как?! Может мне кто нибудь подсказать почему целое, без преобразования присвоилось в лейбу? код проверялся на XE10.1
  6. Похоже проблема с прем-стилями. Причем проблема давняя, я ее обнаружил очень давно.
  7. Очень интересная идея. Спасибо! Буду пробовать
  8. Был бы весьма признателен. Куда уж без костылей )
  9. При любых звонках, в memo падает только Phone is IDLE и Phone is OFFHOOK. Других сообщений нет. На сколько я понял, факт установки соединения под Android не отловить. Или я не прав? В идеале, хотелось бы отследить состояние исходящего звонка. Т.е. набор, соединение, отбой.
  10. Конечно же я его смотрел. И он даже работает. Частично правда. Но все же.. разбираюсь. Спасибо
  11. Допили для себя: /// AHex - строка вида "A1,B2,C3" /// Del - резделитель function HexToBytes(const AHex: string; const Del: string = ','): TBytes; var i: Integer; S: TStringDynArray; begin S := SplitString(Trim(AHex),Del); SetLength(Result, Length(S)); for i := Low(S) to High(S) do Result[i] := StrToIntDef('$'+S[i],0); end; function BytesToStr(const ABytes: TBytes): string; var i: integer; begin Result := EmptyStr; for I := Length(ABytes)-1 Downto 0 do Result := Chr(ABytes[I] + 48) + Result; end;
  12. Доброго времени. Delphi Berlin. Попробовал воспроизвести пример http://docwiki.embarcadero.com/RADStudio/Seattle/en/Mobile_Tutorial:_Using_the_Phone_Dialer_on_Mobile_Devices_(iOS_and_Android) Выяснилось что событие OnCallStateChanged не вызывается (Android). Пробовал пример из поставки. Просмотрел как описано в разных книгах - везде одно и тоже. Но не работает. Как же получить статус звонка?
  13. Из своего опыта (не про Delphi конкретно), приведу реальный пример. Доводилось работать на удаленке в одной международной компании. Уверен все о ней знают и пользуются ее продуктами (без названия, ок?). Так вот в нашей интранете мелкого городского провайдера, лежала подборка их крякнутого софта. Я конечно "стуканул" руководителю и предложил "наехать" на местную контору что бы убрали пиратский софт. Но неожиданно получил от "самого главного боса" нагоняй: "Не вздумай им писать! Пусть софт лежит! Пусть люди им пользуются! Да, именно пиратским. Финансовые потери не сопоставимы с прибылью от популяризации. Пиратство - гарантированная, бесплатная реклама. Тот, кому действительно наш софт нужен - заплатит. Кто не готов платить (например школьники) - не заставишь. По этому оставь маркетинг профессионалам, а сам занимайся поставленными задачами." С тех пор я не лезу в маркетинг.
  14. Именно. Возможно в расчетах что то дергается что приводи к повторному событию. А вообще прав ZuBy, без исходников можно долго гадать и предлагать самые фантастические решения. А на деле все может оказаться просто.
  15. Событие OnResize может происходить несколько раз подряд. Код в этом событии должен быть как можно короче. Расчет большого количества динамических объектов в этом событии - плохая идея. Лучше действительно воспользоваться отдельным потоком (а для ускорения можно несколько). На вскидку, алгоритм примерно такой: в событии OnResize запускаете поток, в который передаете размеры фрейма. В потоке делает расчеты и генерируете свое событие, которое обрабатывает фрейм - отображает эти самые объекты или их данные. Конечно конкретная реализация зависит от задачи
  16. На вскидку TAnonymousThread выглядит неплохо. Но пока я не понял смысла дженериков. Надо попробовать в деле
  17. FMX еще довольно молодой фремворк. Тут порой не хватает самых элементарных вещей. Как вариант вы можете создать на Github нужную вам либу, наверняка это может еще кому то пригодится. Совместными усилиями можно создать отличную вещь. Ну а что бы не быть зависимым от версии - пишите абстрактный код. Не надо привязываться к конкретному компоненту.
  18. Да, я в курсе - это всего лишь уточнение. Тут тоже можно использовать например так: var LTask: IAsyncTask; LTask := AsyncTask; LTask.Run (...); ... LTask.Terminate; // досрочно завершаем поток В ITask exception глушится, что не всегда хорошо. Тут его можно обработать очень просто, если есть нужда. Процедуры тут изначально синхронизированны и в подавляющем большинстве это как раз то что нужно - не нужно постоянно писать код синхронизации (хотя он и тривиален). Сам же модуль был написан еще до появления ITask, так что я как то исторически привык использовать именно его. Однако у ITask есть свои преимущества и они неоспоримы. Это всего лишь альтернатива для некоторых случаев.
  19. Хочу поделится своим модулем, некой альтернативой TTask, которой я пользуюсь уже довольно продолжительное время. Возможно кому то будет полезно. AsyncTask это глобальная функция в модуле, которая возвращает интерфейс IAsyncTask. По этой причине нет нужды специально создавать объект и заботится о его удалении. Пример использования: procedure GetAsyncRequest(const aUrl: string); var LResult: string; begin AsyncTask.Run( procedure begin // это основной метод потока, он не синхронизирован. От сюда нельзя обращатся к визуальным компонентам // или переменным вне функции без синхронизации (если необходимо) LResult := HttpRequest.Get(aUrl); end, procedure begin // Эта процедура выполнится при успешном завершении потока (без exception). // Процедура синхронизированна, по этому тут можно обращатся к любым визуальным компонентам ShowMessage(LResult); end, procedure(E: Exception) begin // Эта процедура выполнится только если во время работы потока произошла ошибка ShowException(E); end, procedure begin // Эта процедура выполнится в любом случае (после завершения потока), в не зависимости была ошибка или нет ShowMessage(LResult); end ); // обратите внимание, что обязательно задать только первую процедуру, остальные можно не указывать или передать вместо них nil. Например так: AsyncTask.Run( procedure begin ... end, nil, procedure(E: Exception) begin ShowException(E); end); Async.Task.pas.zip
  20. Думаю так не получится. Как правило "что бы оно само работало" это типовые, универсальные решения, которые в целом работают, но в силу универсальности работают не очень хорошо. Именно потому чаще всего для конкретной задачи приходится брать "напильник" и затачивать под свои нужды.
  21. Совершенно согласен - динамическое создание фреймов на мой взгляд намного лучше (как и форм). К тому же, если используется модель данных вне формы (фрейма), то тогда вообще нет ни каких проблем. И чаще всего, при использовании моделей типа MVC, MVP и .т.п - код значительно упрощается! Главное становится более надежным, понятным и коротким. Можно легко и не напряженно менять или добавлять формы без вмешательства в логику. Особенно хорошо это проявляется в командной работе, когда не опытный разработчик (или новый человек в команде), может не вдаваясь в код сложной бизнес логики за пару часов прикрутить например отчет или новый view. К тому же, понятие такого подхода абстрагирует разработчика от конкретного языка. В дальнейшем такой подход можно использовать на любом языке. К сожалению архитектура Delphi часто подталкивает к "формошлепству", что в общем то не плохо работает в небольших приложениях. Но когда программа становится несколько сложней чем "Hello world", это становится проблемой. Самое печальное то, что в массе книг по Delphi как раз таки и учат формошлепству. В духе "щелкните два раза по кнопке и получите готовый обработчик события". Я не встречал ни одной книги (кроме нескольких уже довольно устаревших статей), где бы показывалось как использовать MVC или MVP в Delphi. Если не прав - ткните носом. Да, код полностью идентичный приведенный топикастером, за исключением использования дженериков. Но я и не стремился доказать что мой код лучше. Всего лишь показал как делаю я. Этот намеренно простейший шаблон приложения. Не самый лучший. Но на мой взгляд он все таки отделяет "мух от котлет" (данные от форм) и возможно кому то поможет понять что на Delphi тоже можно и нужно использовать MVC. Конечно в реальном приложении обычно все на много сложней. Хотя лично у меня есть парочка довольно мудреных приложений которые используют именно такую архитектуру и прекрасно работают, периодически претерпевая изменения без каких либо серьезных проблем. Часто слышу высказывания в духе "зачем мне усложнять? Я быстро накидаю форму с логикой и получу деньги". По своему опыту скажу - вы ошибаетесь. Да, вы быстро и легко накидаете форму, которая что то будет делать и даже как то работать. Но если вы в дальнейшем будете сопровождать свое творение, то очень скоро убедитесь в том что это полный отстой. Особенно если программа будет продолжать наращивать функционал. Не питайте иллюзий. Пишите сразу правильно - это в дальнейшем сэкономит вам время и нервы. Как говорится в одном знаменитом мульте: "лучше сейчас час потерять, зато потом за пять минут долететь" ))
  22. Разумеется. Типы данных характерные для Delphi не должны использоваться. Об этом так же написано много. Но лично я не вижу в этом проблем. Гораздо чаще, почему то путают другие вещи: прочитав что объекты передавать нельзя, народ пытается передать указатель! т.е. вместо TObject, делают что то вроде Pointer(Object). Или даже integer(Object). Очень странно. Это ведь то же самое что и передача объекта. Такое чувство что народ совершенно не понимает что такое указатель.
  23. Можно попробовать через TMemoryStream. В FMX я не пробовал грид копировать (да и в VCL с большими данными тоже). Но вообще с компонентами попроще такой трюк работает. Например я частенько использую его для сохранения настроек в базе данных (в BLOB). Алгоритм примерно такой: в первой форме делаем var MS: TMemoryStream; MS.WriteComponent(Grid); Потом передаем этот stream во вторую форму, а там делаем MS.Position := 0; MS.ReadComponent(Grid). При этом гриды в обоих формах должны существовать. Просто все свойства и данные из первой, скопируются во вторую. Но вообще, как уже заметили, 1000 строк это уже как то много. Тут либо надо кеширование придумать, что бы одновременно в таблице было не больше строк чем помещается на экран, а остальные подгружались по мере прокрутки. Либо, что намного проще, использовать базу данных.
  24. Сначала попытался объяснить как я переключаю фреймы, но потом подумал и решил что проще будет сделать пример (см. приложенный архив). Мне не очень нравится идея создавать все фреймы сразу. На мой взгляд ( и не только на мой, существует понятие MVC, MVP, MVVP), фреймы это только отображение данных, а сами данные лучше контролировать в другом месте. По этому в моем примере, есть контроллер данных (TDataModule), в котором (в реальной программе) прописана вся бизнес-логика. Во фреймах же и в формах, только код, который относится непосредственно к этому фрейму (форме). Еще небольшой совет: контроллер совсем не обязательно должен быть TDataModule, это может быть обычный класс - синглтон. Но я традиционно использую его, потому что в реальной программе он может служить контейнером для каких то невизуальных компонентов. Например в него я помещаю компонент TfgApplicationEvents из набора FGX(http://fire-monkey.ru/forum/177-fgx/) от Ярослава Бровина. Если в программе используется база данных, то я не помещаю в контроллер компоненты доступа к данным. Для этого я делаю отдельный модуль. Так же, рекомендую посмотреть в сторону компонента TFrameStand (его можно найти в GetIt). FrameSelector.zip
  25. Похоже вы действительно чего то не понимаете. Объекты нельзя предавать. Про это написано тонны статей. Если хотите передавать именно объекты, тогда вам нужно использовать Package (BPL), вместо обычных dll. Но в этом случае вы будете привязаны к конкретной версии Delphi, а про другие языки можно будет забыть (Ни кто кроме Dlphi не умеет делать BPL). Обычный способ передачи либо Handle, либо через interface
×
×
  • Создать...