Перейти к содержанию
  • Регистрация

gonzales

Пользователи
  • Публикаций

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

  • Посещение

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

    3

gonzales стал победителем дня 12 августа

gonzales имел наиболее популярный контент!

Информация о gonzales

  • Звание
    Продвинутый пользователь

Посетители профиля

867 просмотров профиля
  1. Отвечу сам себе. Проблема решена. Всего два дня поисков и вот он, случай - краеугольный камень поиска ошибок! Меня аж забомбило, когда я это откопал. Оказалось, что мой грид лежит на лайоуте, у которого hittest = false. Так вот до тех пор, пока я не перевел его в true грид отказывался принимать ondragover. Но как только layout.hittest:=true все заработало. Дальше дело техники.
  2. Чтобы не плодить темы спрошу в этой. Столкнулся с такой же задачей, не пойму как решить. Есть два грида, нужно перетаскивать ячейки из одного в другой. Более менее разобрался с гридом, из которого тяну ячейки 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...
  3. оо, спасибо. вот ее как раз и нет и в основной программе))) конечно, в основной программе именно так. но через синхронизацию в form1 все равно ходить надо)) а вот это не понял???
  4. Так понятно, что можно сделать. Но это лишь пример оторванный от реальности. Хочется понять, почему класс типа TThreat не работает в своем потоке.
  5. ох))) тяжело это))) У меня есть смутные сомнения, что придуманная мною конструкция работает в главном потоке. Вот накидал пример, но он фризит приложение(( Если не трудно, посмотрите пожалуйста 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.
  6. На ней подготавляваются объекты. Но вопрос то не в этом, вопрос, почему я не вижу изменений на сплэше? При чем тут form1?
  7. 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);
  8. Что-то все равно у меня ничего путного не получается. Я создал класс, типа 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. Свободен ли в этот момент главный поток?
  9. аа, точно, спасибо. чего-то затупил. Правильно вот так 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;
  10. продолжаю разбираться. вернулся обратно к коду, предложенному уважаемым 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; Что я делаю не так??)))
  11. Чего Вы привязались к прогрессбару, это никак не связано с потоками, я просто уточнял, нужно ли обращаться к форме, созданной в потоке через синхронизацию. Прочитайте посты выше, вроде как уже больше недели это обсуждаем. У вас очень странное представление о UI. Вы правда считаете, что я демонстрирую пользователю одновременно Сплэш, две формы, и повергающий его в экстаз прогрессбар??
  12. На форуме обсуждал в соседней ветке. Я хочу открыть соединение с сервером и получать в него данные, пока живо приложение. Соответственно, было бы здорово, если бы все эти манипуляции происходили бы в потоке, отдельно от форм. Поэтому рассматриваю вариант, когда поток стартует вместе с приложением, и живет все время. Ну и заодно хочу забросить в него все остальное. А почему не следует так делать?
  13. Тогда как посоветуете поступить. Есть класс (условно TSystem), который содержит кучу свойств и методов для работы приложения (всю логику). Там и все структуры, и работа с XML, и работа с TCP-клиентом. Задача: развязать работу экземпляра этого класса с формой. Как Вы и советовали, логика отдельно, интерфейс отдельно. Я (по наивности наверное) думал, что если этот класс будет типа TThreat, то он автоматом будет работать в новом потоке, но судя по Вашим комментариям - это не так. В методе TSystem.Execute у меня пока зашит пока только прием данных от TCP-клиента. Как правильно организовать работу, чтобы все методы класса TSystem выполнялись в отдельном потоке, и при этом я мог их запускать из основного потока. Например есть метод TSystem.SendMessage, если я обращаюсь к нему с главной формы, в каком потоке он будет выполнен? Извините, что (скорее всего) задаю тупые вопросы, но обратиться больше не к кому))). Заранее спасибо за любые ответы.
  14. Спасибо! Не могли бы Вы прокомментировать еще мой пост выше
×
×
  • Создать...