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

gonzales

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

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

  • Посещение

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

    27

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

  1. И вот настало долгожданное попозже))). Сорри, как-то проглядел вопрос. Я думал, что поменяв в рантайме сами элементы стиля мне не придется возиться с каждым объектом, который создается в рантайме. По сути хотел реализовать что-то типа смены цветовой схемы, например перед созданием объектов прохожу по используемым элементам стиля и меняю везде цвет на определенный. Далее создаю объекты, применяю к ним стиль и вуаля - цвет везде изменен на новый.
  2. Апну тему))) Возникла все-таки необходимость менять цвета объектов в рантайме. Конкретно уперся в TSwitch (переключатель). Проблема в том, что элементы его стиля содержатся в объекте TSwitchObject. Но если сделать так ReleSwitch.StyleLookup := 'switchstyledark'; StyleObject:=ReleSwitch.FindStyleResource('switchstyledark'); if (StyleObject is TSwitchObject) then TSwitchObject(StyleObject).FillOn.Color := TAlphaColorRec.Yellow; то среда ругается, что не знает, что такое TSwitchObject. Попытка загуглить, где содержится TSwitchObject результатов не дала. Вопрос собственно простой, как поменять свойство FillOn у объекта TSwitchObject?
  3. Одобрили приложение до 1-го августа 2020г. Надеюсь к тому времени и компилятор допилят)))
  4. Пока вот такой ответ Hello Alexey, Thanks for your reply. I’ve documented your request and escalated it to our review team. Our team is working to respond to your request as soon as possible. Please note that I can't guarantee your 64-bit extension request will be accepted, and you only need to request this extension once. I appreciate your patience and I’ll let you know the moment I have an update. If you have any other questions in the meantime, please let me know.
  5. Подал заявку, прошло 3 дня, никакого ответа. У кого-нибудь положительно решилась ситуация?
  6. Отвечу сам себе. Проблема решена. Всего два дня поисков и вот он, случай - краеугольный камень поиска ошибок! Меня аж забомбило, когда я это откопал. Оказалось, что мой грид лежит на лайоуте, у которого hittest = false. Так вот до тех пор, пока я не перевел его в true грид отказывался принимать ondragover. Но как только layout.hittest:=true все заработало. Дальше дело техники.
  7. Чтобы не плодить темы спрошу в этой. Столкнулся с такой же задачей, не пойму как решить. Есть два грида, нужно перетаскивать ячейки из одного в другой. Более менее разобрался с гридом, из которого тяну ячейки procedure TForm2.GridMouseDown(Sender: TObject; button: TMouseButton; Shift: TShiftState; X, Y: single); var Svc: IFMXDragDropService; DragData: TDragObject; DragImage: TBitmap; rect:trectf; begin TPlatformServices.Current.SupportsPlatformService(IFMXDragDropService, Svc); with Sender as TStringGrid do begin Grid.CellByPoint(X, Y, SourceCol, SourceRow); DragImage:=TBitmap.Create; DragImage.Width:=round(Grid.Width); DragImage.Height:=round(grid.Height); rect:=rectf(0,(SourceRow+1)*grid.RowHeight,grid.Width,(SourceRow+2)*grid.RowHeight); DragImage.Canvas.BeginScene(); DragImage.Canvas.Fill.Color:=4280444565; //DragImage.Canvas.FillRect(rect,0,0,[],1); DragImage.Canvas.FillText(rect,grid.Cells[SourceCol,SourceRow],false,1.0,[],TTextalign.Leading); DragImage.Canvas.EndScene; form1.currentItem := form1.items.ChildNodes.Nodes[SourceRow]; DragData.Source := Sender; try DragData.Data := SourceRow; Svc.BeginDragDrop(self, DragData, DragImage); finally DragImage.Free; end; end; end; Вижу, что код отрабатывает, появляется изображение с текстом ячейки, которую перетаскиваю. Но вот заставить принять ее второй грид не могу. Более того, даже в droptarget ничего не попадает. Не пойму как гриду сказать, что он может принимать что-то по drag&drop В VCL это было так procedure TForm2.RoomGridDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); begin Accept := (Source = Grid); end; А как это сделать в FireMonkey? procedure TForm2.RoomGridDragOver(Sender: TObject; const Data: TDragObject; const Point: TPointF; var Operation: TDragOperation); begin Operation := TDragOperation.Copy; end; это не помогает... вообще не вызывается dragover...
  8. оо, спасибо. вот ее как раз и нет и в основной программе))) конечно, в основной программе именно так. но через синхронизацию в form1 все равно ходить надо)) а вот это не понял???
  9. Так понятно, что можно сделать. Но это лишь пример оторванный от реальности. Хочется понять, почему класс типа TThreat не работает в своем потоке.
  10. ох))) тяжело это))) У меня есть смутные сомнения, что придуманная мною конструкция работает в главном потоке. Вот накидал пример, но он фризит приложение(( Если не трудно, посмотрите пожалуйста unit Unit1; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls, FMX.Controls.Presentation; type TClient = class(TThread) public procedure Logic; constructor Create; Overload; destructor Destroy; Overload; end; var Client: TClient; type TForm1 = class(TForm) Button1: TButton; ProgressBar1: TProgressBar; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.fmx} constructor TClient.Create; begin inherited Create; end; destructor TClient.Destroy; begin inherited; end; procedure TClient.Logic; var i:integer; a:real; begin for i := 0 to 100000000 do begin a:=i/3; if i mod 1000000 = 0 then begin TThread.Synchronize(nil, procedure begin form1.ProgressBar1.Value:=form1.ProgressBar1.Value+1; end); end; end; end; procedure TForm1.Button1Click(Sender: TObject); begin form1.ProgressBar1.Value := 0; Client.Logic; end; end.
  11. На ней подготавляваются объекты. Но вопрос то не в этом, вопрос, почему я не вижу изменений на сплэше? При чем тут form1?
  12. procedure TSplashForm.FormShow(Sender: TObject); begin {$IFDEF IOS} SplashForm.StartupTimer.Enabled:=true; {$ELSE} SplashForm.LoadProgramm; {$ENDIF} end; Главной будет Form1. После загрузки приложения выполняется код TThread.Synchronize(TThread.CurrentThread, procedure begin SplashForm.StartUpLabel.text := 'Старт программы'; application.MainForm := Form1; Form1.Show; SplashForm.Close; end);
  13. Что-то все равно у меня ничего путного не получается. Я создал класс, типа TThread type TClient = class(TThread) public .... На загрузочной форме создаю экземпляр этого класса procedure TSplashForm.LoadProgramm; begin StartUpLabel.Text := 'Инициализация'; Application.CreateForm(TForm1, Form1); Client:= TClient.Create; label1.Text:=VERSION; end; Соответственно в конструкторе класса провожу загрузку приложения и через синхронизацию обновляю надпись на загрузочной форме ... TThread.Synchronize(TThread.CurrentThread, procedure begin SplashForm.StartUpLabel.text := 'права пользователя'; end); ... но обновления надписей не вижу. Вопросов возникает несколько 1. TClient при такой конструкции работает в отдельном потоке 2. Правильно ли я провожу синхронизацию с главным потоком? 3. Свободен ли в этот момент главный поток?
  14. аа, точно, спасибо. чего-то затупил. Правильно вот так procedure TSplashForm.FormCreate(Sender: TObject); var f: TForm1; begin AniIndicator1.Enabled := True; AniIndicator1.Visible := True; b1.Visible := false; TTask.Run( procedure begin datamodel.ObtainData; TThread.Synchronize(nil, procedure begin AniIndicator1.Enabled := false; AniIndicator1.Visible := false; b1.Visible := True; lbl1.Text := datamodel.data1; lbl2.Text := datamodel.data2; f := TForm1.Create(NIL); f.Show; end) end); end;
  15. продолжаю разбираться. вернулся обратно к коду, предложенному уважаемым krapotkin Хочу внести одно изменение, чтобы форма1 создавалась в процедуре TMyDatamodel.ObtainData procedure TMyDatamodel.ObtainData; var tasks: array of ITask; task: ITask; f: TForm1; procedure CreateTasks; begin tasks := [ TTask.Create(procedure () begin sleep(2000); data1:='data1'; end), TTask.Create(procedure () begin sleep(2000); data2:='data2'; f:=TForm1.Create(NIL); form1.Show; end) ]; end; begin CreateTasks; for task in tasks do task.start; TTask.WaitForAll(tasks); end; В одну из задач воткнул создание формы, при этом приложение отрабатывает не корректно. Получаю AccessViolation на этапе form1.show. Подозреваю, что проблема в том, что форма создана в потоке. Перебросил form1.show в SplashForm.FormCreate, ошибок нет, но и форма не показывается. procedure TSplashForm.FormCreate(Sender: TObject); begin AniIndicator1.Enabled := True; AniIndicator1.Visible := True; b1.Visible := false; TTask.Run( procedure begin datamodel.ObtainData; TThread.Synchronize(nil, procedure begin AniIndicator1.Enabled := false; AniIndicator1.Visible := false; b1.Visible := True; lbl1.Text := datamodel.data1; lbl2.Text := datamodel.data2; form1.Show; end); end); end; Что я делаю не так??)))
  16. Чего Вы привязались к прогрессбару, это никак не связано с потоками, я просто уточнял, нужно ли обращаться к форме, созданной в потоке через синхронизацию. Прочитайте посты выше, вроде как уже больше недели это обсуждаем. У вас очень странное представление о UI. Вы правда считаете, что я демонстрирую пользователю одновременно Сплэш, две формы, и повергающий его в экстаз прогрессбар??
  17. На форуме обсуждал в соседней ветке. Я хочу открыть соединение с сервером и получать в него данные, пока живо приложение. Соответственно, было бы здорово, если бы все эти манипуляции происходили бы в потоке, отдельно от форм. Поэтому рассматриваю вариант, когда поток стартует вместе с приложением, и живет все время. Ну и заодно хочу забросить в него все остальное. А почему не следует так делать?
  18. Тогда как посоветуете поступить. Есть класс (условно TSystem), который содержит кучу свойств и методов для работы приложения (всю логику). Там и все структуры, и работа с XML, и работа с TCP-клиентом. Задача: развязать работу экземпляра этого класса с формой. Как Вы и советовали, логика отдельно, интерфейс отдельно. Я (по наивности наверное) думал, что если этот класс будет типа TThreat, то он автоматом будет работать в новом потоке, но судя по Вашим комментариям - это не так. В методе TSystem.Execute у меня пока зашит пока только прием данных от TCP-клиента. Как правильно организовать работу, чтобы все методы класса TSystem выполнялись в отдельном потоке, и при этом я мог их запускать из основного потока. Например есть метод TSystem.SendMessage, если я обращаюсь к нему с главной формы, в каком потоке он будет выполнен? Извините, что (скорее всего) задаю тупые вопросы, но обратиться больше не к кому))). Заранее спасибо за любые ответы.
  19. Спасибо! Не могли бы Вы прокомментировать еще мой пост выше
  20. И еще, если я в своем классе TThread создаю форму для отображение прогресс бара application.CreateForm(TForm27, Form27); Form27.ProgressBar1.Max := highbyte + 1; Form27.ProgressBar1.value := 0; Form27.StartUpLabel.text := inttostr(filesize); Должен я обращаться к ней через синхронизацию?
  21. Че то я опять запутался))) Допустим я создал свой класс типа Tthreat, в котором у меня крутится вся логика. В частности есть public свойства SettingsXML - XMLDocument и settingsfilename - поле для хранения пути к файлу настроек. Далее я создаю экземпляр этого класса, который находится на form1. form1.SystemClient:= TSystemClient.Create; При этом экземпляр же находится в главном потоке? При вызове вот такого метода, в каком потоке он будет выполняться? form1.SystemClient.SettingsXML.LoadFromFile(form1.SystemClient.settingsfilename);
  22. Да, забыл указать, форме присваиваем FullScreen = true, чтобы стрыть шторку и системные кнопки, если они экранные.
  23. Тоже столкнулся с необходимостью запретить пользователю нажимать на кнопку Домой. Нашел достаточно простое решение (для себя), заставить приложение быть Лаунчером, при этом доступна шторка и кнопка включения. Но основные фишки работают: после перезагрузки автоматически стартует моя программа, она не висит в списке задач, ее нельзя выгрузить, не работает кнопка Домой. Суть в изменении манифеста. В файле AndroidManifest.template.xml находим строки <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> И добавляем <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.HOME" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> Пересобираем приложение, запускаем. На 6-ом Андроиде при нажатии на кнопку Домой система предложит выбрать Лаунчер, выбираем нашу программу и нажимаем Всегда. Чтобы изменить, через шторку входим в настройки - выбор системного интерфейса. На 8-ом Андроиде также через настройки принудительно выставляем лаунчер на нашу программу.
  24. Подскажите еще пожалуйста, если я сделаю свой класс типа TThread, я же могу из него запустить еще один новый поток для каких-то побочных задач?
×
×
  • Создать...