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

Лидеры

  1. Кривяков Виталий

    Кривяков Виталий

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


    • Баллы

      10

    • Постов

      79


  2. Евгений Корепов

    Евгений Корепов

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


    • Баллы

      2

    • Постов

      738


  3. Pax Beach

    Pax Beach

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


    • Баллы

      2

    • Постов

      414


  4. Brovin Yaroslav

    Brovin Yaroslav

    Администраторы


    • Баллы

      1

    • Постов

      2 124


Популярный контент

Показан контент с высокой репутацией 22.07.2016 во всех областях

  1. Итак, год спустя описываю решение проблемы. Исследования проводил в Берлине, но думаю рецепт подойдет и для младших версий. 1. Ошибка существует в файле FMX.TextLayout.GPU, поэтому копируем его в проект. 2. Убираем мусор при отрисовке кропнутого символа. Ищем в файле следующий фрагмент: ColoredGlyph := TFontGlyphStyle.ColorGlyph in Rec.Glyph.Style; if ColoredGlyph then TCustomCanvasGpu(ACanvas).ModulateColor := $FFFFFFFF; ACanvas.DrawBitmap(Rec.Bitmap, SrcR, R, Opacity); if ColoredGlyph then TCustomCanvasGpu(ACanvas).ModulateColor := LRun.Color; и заменяем его на if not R.IsEmpty then begin // Disable draw empty rect ColoredGlyph := TFontGlyphStyle.ColorGlyph in Rec.Glyph.Style; if ColoredGlyph then TCustomCanvasGpu(ACanvas).ModulateColor := $FFFFFFFF; ACanvas.DrawBitmap(Rec.Bitmap, SrcR, R, Opacity); if ColoredGlyph then TCustomCanvasGpu(ACanvas).ModulateColor := LRun.Color; end; Пояснение: при расчете области отрисовки R символа, мы можем получить "отрицательный размер", где Bottom будет меньше чем Top. Соответсвенно такой же неправильной становиться область источника SrcR и на экран вылазит мусор. 3. От мусора избавились, но если присмотреться к нижней границе текста, то можно увидеть, что отрезка не ровная, одни символы отрезаны больше, другие меньше. Для этого нужно исправить алгоритм расчета области отсечения. Для этого ищем комментарий //Checking for lines lower than bottom border - с него начинается ветка, в которую нужно внести изменения. Чуть далее ищем код Rec := AddOrGetChar(nil, Run.Chars[K], ChDic, Run.Font); X := MaxSize.Y - FFrame.Last.TopLeft.Y - Rec.Glyph.VerticalAdvance * FScaleFactor; и меняем его на Rec := AddOrGetChar(LayoutCanvas, Run.Chars[K], ChDic, Run.Font); X := MaxSize.Y - FFrame.Last.TopLeft.Y - ((Rec.SrcRect.Height + Rec.Glyph.Origin.Y) * FScaleFactor); Здесь пояснения дать сложнее, скажу только, что разработчики проигнорировали тот момент, что символы имеют разные размеры (например . и Ж) и считают отсечение не по размеру глифа символа а по экранному размеру символа, т.е. он будет одинаковый для всей строки, что неправильно, так как в дальнейшем данное отсечение применяется к глифу символа. P.S. А куда переехал CodeCentral, не нашел его в Берлине?
    4 балла
  2. Добрый день, коллеги! Хочу рассказать о выходе нашего нового продукта 1С-Рарус:Мобильное РМК Приложение написано в 10 версии Delphi (Seatlle), предназначено для автоматизации рабочего места кассира. Есть встроенный демо режим. Работа пока возможна только на планшетах, поддержка смартфонов в будущем. Готов воспринять критику, пожелания и ответить на вопросы.
    3 балла
  3. Axbor

    Собственный TListBoxItem на C++

    Очень не хватает примеров на C++. Решил поделится опытом. Рассмотрим создание собственного "ListBoxItem"а на C++. И так начнем. Для начало создадим стиль для нашего "ListItem"а. В моем случае оно выглядит так: Структура выглядеть следующим образом: А вы сразу можете создать собственный стиль. Создадим класс для нашего "Item"а. Я назвал его TMyListBoxItem. Нужно знать следующие вещи: ApplyStyle() вызывается когда стиль загружен. FreeStyle() когда стиль выгружен. GetDefaultStyleLookupName() когда стиль не задано берется названые стиля по умолчанию. FindStyleResource("стиль") ищет в стиле ресурс с заданным названием. ListBox автоматически очищает из невидимых "Item"ов стиль что бы избежать от расходы на память. И заново загружает когда оно видимо. При этом вызывается соответствующие функции приведенные выше я приведу только некоторые кусочки кода. Остальное всё можете посмотреть в прикреплённых файлах. class TMyListBoxItem : public TListBoxItem { private: // Переменные для хранения данных System::UnicodeString FTimeTo; System::UnicodeString FTimeFrom; //.... // Визуальные компоненты TText* FTextTimeTo; TText* FTextTimeFrom; //... // Функции для присваивания данных, это нужно при написании "properties" void __fastcall SetTimeTo(const System::UnicodeString Value); void __fastcall SetTimeFrom(const System::UnicodeString Value); protected: void __fastcall ApplyStyle(); void __fastcall FreeStyle(); System::UnicodeString __fastcall GetDefaultStyleLookupName(); virtual void UpdateStyleData(); __published: __property System::UnicodeString TimeTo = {read=FTimeTo, write=SetTimeTo}; __property System::UnicodeString TimeFrom = {read=FTimeFrom, write=SetTimeFrom}; public: __fastcall TMyListBoxItem(System::Classes::TComponent* AOwner); }; Теперь напишем сами функции. void __fastcall TMyListBoxItem::ApplyStyle() { // Вызов метода предка TListBoxItem::ApplyStyle(); TFmxObject *StyleObject; // Поиск ресурса из стиля. Посмотрите в скрине, там есть ресурс с названием "timeto" типа TText StyleObject = FindStyleResource("timeto"); // dynamic_cast нужен для корректного преобразования типов. Если тип найденного ресурса не является TText то указателю будет присвоен NULL FTextTimeTo = dynamic_cast<TText*>(StyleObject); StyleObject = FindStyleResource("timefrom"); FTextTimeFrom = dynamic_cast<TText*>(StyleObject); UpdateStyleData(); } void __fastcall TMyListBoxItem::FreeStyle() { // Стиль выгружен из памяти. Нужно очистить указатели что бы избежать ошибок FTextTimeTo = NULL; FTextTimeFrom = NULL; TListBoxItem::FreeStyle(); } System::UnicodeString __fastcall TMyListBoxItem::GetDefaultStyleLookupName() { // название стиля для нашего "Item"а по умолчанию return "mylistboxitemstyle"; } void TMyListBoxItem::UpdateStyleData() { if(FTextTimeTo) FTextTimeTo->Text = FTimeTo; if(FTextTimeFrom) FTextTimeFrom->Text = FTimeFrom; } void __fastcall TMyListBoxItem::SetTimeTo(const System::UnicodeString Value) { FTimeTo = Value; if(FTextTimeTo) FTextTimeTo->Text = FTimeTo; } Вот и всё. Остается только добавит в наш проект ListBox и button для проверки. Вот функция создания нашего "Item"а: void __fastcall TForm1::Button1Click(TObject *Sender) { TMyListBoxItem *Item = new TMyListBoxItem(this); Item->Parent = ListBox1; Item->StyleLookup = "customstyle1"; Item->TimeFrom = "11:20"; Item->TimeTo = "12:50"; } Скриншот программы: В архиве мой класс и стиль. Для корректного отображения некоторых символов нужен fontcustom Какие вопросы задавайте. Отдельное спасибо Ярославу за мануал на дельфи: http://blogs.embarcadero.com/yaroslavbrovin/2012/10/15/listboxitem_styling_part2/ Администраторы и модераторы, прошу подкорректировать если что то неправильно. ListBoxItem.zip
    1 балл
  4. На StackOverflow подсказали решение, адаптировал для Delphi (модуль для работы с процессами Android описан здесь): if TOSVersion.Check(5, 0) then begin TAndroidHelper.Activity.finishAndRemoveTask; Log('- finishAndRemoveTask - OK'); end else if TOSVersion.Check(4, 1) then begin TAndroidHelper.Activity.finishAffinity; Log('- finishAffinity - OK'); end else begin TAndroidHelper.Activity.finish; Log('- finish - OK'); end; TJProcess.JavaClass.killProcess(TJProcess.JavaClass.myPid); Log('- killProcess - OK');
    1 балл
  5. sargon

    MapView и Form.FullScreen

    Доброго дня, спасибо за скрины - вроде все как нужно по ним 80% вероятности, что вы не сгенерили ключ для своей IDE (debug.keystore как оказалось разный на разных компах даже если одну и ту же инсталляшку используешь) и не прописали его в Google.console для Google Maps сервиса. Если сгенерили - то переименуйте проект - потому что в моей консоли проект с таким именем уже существует - там у гугла какой-то дивный глюк с именами проектов, даже под разными пользователями. Работает ли у вас апк собранная у меня? Это нужно в дебаге посмотреть, что за ошибка вываливается, идей никаких нет, тут что угодно может быть - какие версии андройдов на устройствах? Возможные причины: не обновлены гугл-сервисы, версия Андройда (я собирал тестовую АПК под 6-ку), интелловский проц - при эмуляции ARM кода MapView не работает, да и много чего еще может быть. Нашел устройство на котором навигационная панель "рисованная" - проверил - да, проблема воспроизводится. Как оказалось, причина в косяках при реализации джавовского NativeLayout - на котором размещается MapView. На нем размещается оно везде, что в FireMonkey, что в Java. На java такая же проблема с картой... но получилось устранить так getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); Это на Java (код скрывает панель) - работает, но карту надо перерисовать invalidate сделать, иначе панелька "как бы" и не убирается - т.е. она отображается на карте как рисунок - в java так решена проблема с размещением чего-то поверх карты я так понимаю. Интерпретация Java на Delphi type TRunner = class(TJavaLocal, JRunnable) private FRunMethod: TThreadProcedure; public constructor Create(RunMethod: TThreadProcedure); overload; procedure run; cdecl; end; var Runner:TRunner; procedure TForm1.Button2Click(Sender: TObject); begin Runner := TRunner.Create( procedure begin TAndroidHelper.Activity.getWindow.getDecorView().setSystemUiVisibility (TJView.JavaClass.SYSTEM_UI_FLAG_HIDE_NAVIGATION); end); TAndroidHelper.Activity.runOnUiThread(Runner); Sleep(400); Form1.Recreate; Map.Repaint; // Вот тут нужно что-то додумать end; { TRunner } constructor TRunner.Create(RunMethod: TThreadProcedure); begin FRunMethod := RunMethod; Create; end; procedure TRunner.run; begin FRunMethod; end; У меня срабатывает, но панелька не исчезает, потому что она рисуется системой на карте как картинка (как и в случае с Java), и пропадает только после касания области панельки на карте, когда она перерисуется (если вы коснетесь панельки она съедет вниз, но Map.repaint нужно закомментить, иначе оно так и висит, repaint немного не так как ожидается работает), точнее не она NativeLayout. map.repaint не срабатывает - как сделать на delphi пока не придумал. Сейчас к сожалению нету времени покапаться и решить вопрос.
    1 балл
  6. Вроде если навести мышку на дату, то в всплывающей подсказке отображается полная дата и время. Но в любом случае предложение хорошее. Добавлю
    1 балл
  7. Кривяков Виталий

    Android 6 и Exception

    Android 6 + XE7 + Exception = Крах приложения
    1 балл
  8. Pax Beach

    Error "Message must be shown in the main UI thread"

    Вызов необходимо осуществлять в UI потоке: CallInUiThread( procedure begin ... show ur banner end);
    1 балл
  9. разобрался работает без проблем проблема была в прошивке стоял андроид 4,4 стоковый обновил до 6 все работает прекрасно
    1 балл
  10. Хорошая идея! Добавил не обязательный параметр output_format, если он равен json, то выводится в json: http://kayfolom.ru/?cmd=read&api_key=7imq4rcq7rcqm7q3&output_format=json { "status": "ok", "logs": [ { "datetime": "2016-06-23 11:19:40", "datetime_unix": "1466669980", "ip": "195.22.104.78", "message": "Я еще живой, не дождетесь!" }, { "datetime": "2016-06-23 11:19:26", "datetime_unix": "1466669966", "ip": "195.22.104.78", "message": "Я еще живой, не дождетесь!" }, { "datetime": "2016-06-23 11:19:25", "datetime_unix": "1466669965", "ip": "195.22.104.78", "message": "Я еще живой, не дождетесь!" }, { "datetime": "2016-06-23 11:19:20", "datetime_unix": "1466669960", "ip": "195.22.104.78", "message": "Я еще живой, не дождетесь!" } ] }
    1 балл
  11. Попробуйте поэкспериментировать с "Project options -- Version info -- persistent=true", как уже сказал уважаемый krapotkin. Сделайте приложение пустышку которое будет раз в N секунд отсылать запрос на сервер. Чем черт не шутит, может этот вариант подойдет. Я вам безвоздмездно предоставляю api на одном из своих хостингов, на одном из не используемом домене: http://kayfolom.ru/?cmd=[write|read]&api_key=[api_key]&message=[message] cmd - write пишем, read читаем api_key - произвольная строка до 40 символов, идентифицирующая проект, к примеру "kasjlqw4q4t784" или "My_test_persistent_project", лучше использовать латинские буквы без спецсимволов и пробелов. message - произвольная строка, на любом языке, в кодировке utf8. Максимальная длина 255 символов. Пример использования: В своем приложении вы делаете так procedure LogToServer(AMessage, AAPIKey : String); Var Query : String; HTTPClient: THTTPClient; begin Query:='http://kayfolom.ru/?cmd=write&api_key='+AAPIKey+'&message='+AMessage; HTTPClient:=THTTPClient.Create; HTTPClient.Get(Query); FreeAndNil(HTTPClient); end; LogToServer('Я еще живой, не дождетесь!', '7imq4rcq7rcqm7q3'); Потом в браузере открываете ссылку http://kayfolom.ru/?cmd=read&api_key=7imq4rcq7rcqm7q3 и видите примерно следующее: 2016-06-23 11:19:40 195.22.104.78 Я еще живой, не дождетесь! 2016-06-23 11:19:26 195.22.104.78 Я еще живой, не дождетесь! 2016-06-23 11:19:25 195.22.104.78 Я еще живой, не дождетесь! 2016-06-23 11:19:20 195.22.104.78 Я еще живой, не дождетесь! { "status" : "ok" } Сможете мониторить время и с какого IP прислано сообщение. Результатами эксперимента поделитесь. У меня вот XE8, сервисы там отсутствуют, а задумки есть интересные. P.S. Если кому нужно, пользуйтесь этой штукой на здоровье. Только не злоупотребляйте. Несколько запросов с секунду это нормально, а тысячи запросов в секунду вынудят меня прикрыть лавочку :-) Если нужно, прикручу команду очистки истории.
    1 балл
Эта таблица лидеров рассчитана в Москва/GMT+03:00
×
×
  • Создать...