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

Maximus

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

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

  • Посещение

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

    9

Сообщения, опубликованные Maximus

  1. Доброго всем времени суток. Хочу снова поднять вопрос про отрисовку линий на канве, обсуждавшейся здесь

    С горизонтальными и вертикальными линиями проблем нет, при смещении на половину от толщины линии всё прекрасно выглядит. Однако при отрисовке линий под различными углами такой финт не проходит: слева VCL, справа FMX

    VCL.jpgFMX.jpg

    Линия всё так же размазывается, в итоге визуально утолщается и становится не такой чёткой.

    Как всё же добиться такого же результата как на VCL? Интересует только Windows.

    const
      OFFSET_LINE = 0.5;
    ...
      Image.Bitmap.Canvas.BeginScene;
      Image.Bitmap.Canvas.Stroke.Kind := TBrushKind.Solid;
      Image.Bitmap.Canvas.Stroke.Thickness := 1.0;
      Image.Bitmap.Canvas.DrawLine(
            PointF(10.0 - OFFSET_LINE, 10.0 - OFFSET_LINE),
            PointF(500.0 - OFFSET_LINE, 10.0 - OFFSET_LINE), 1.0);
      Image.Bitmap.Canvas.DrawLine(
            PointF(10.0 - OFFSET_LINE, 10.0 - OFFSET_LINE),
            PointF(10.0 - OFFSET_LINE, 500.0 - OFFSET_LINE), 1.0);
      Image.Bitmap.Canvas.DrawLine(
            PointF(10.0 - OFFSET_LINE, 10.0 - OFFSET_LINE),
            PointF(500.0 - OFFSET_LINE, 500.0 - OFFSET_LINE), 1.0);
      Image.Bitmap.Canvas.EndScene;

     

  2. В общем оказалось, что и ITask можно использовать, главное следовать тем же правилам что и при работе с TThread. Если ставим саморазрушение в объект, то извне его разрушать нельзя. А если это всё же необходимо, то придётся убрать саморазрушение после отработки и подождать завершения задачи, в которой можно поставить проверки Task.Status = Canceled для преждевременной остановки задачи.

  3. Доброго времени суток. Надеюсь многие пользуются новым средством распараллеливания ITask, подскажите что я делаю с ним не так.

    Для теста создал простенький класс

    unit ThreadTask;
    
    interface
    
    uses
      System.SysUtils, System.Threading, System.Classes;
    
    type
      TOnCollback = procedure(ID: Integer) of object;
    
      TThreadTask = class
        private
          Task: ITask;
    
          procedure Execute;
          procedure Print;
          procedure Close;
        public
          OnDestroy: TOnCollback;
          OnPrint: TOnCollback;
    
          Destructor Destroy; override;
    
          procedure Start;
          procedure Stop;
      end;
    
    implementation
    
    { TThreadTask }
    
    procedure TThreadTask.Close;
    begin
      if Assigned(OnDestroy) then
        OnDestroy(Task.Id);
    end;
    
    destructor TThreadTask.Destroy;
    begin
      Stop;
      TThread.Synchronize(TThread.CurrentThread, Close);
    
      inherited;
    end;
    
    procedure TThreadTask.Execute;
    begin
      TThread.Sleep(3000);
      TThread.Synchronize(TThread.CurrentThread, Print);
      TThread.Sleep(3000);
      TThread.Synchronize(TThread.CurrentThread, Print);
    
      Free;
    end;
    
    procedure TThreadTask.Print;
    begin
      if Assigned(OnPrint) then
        OnPrint(Task.Id);
    end;
    
    procedure TThreadTask.Start;
    begin
      Task := TTask.Run(Execute);
    end;
    
    procedure TThreadTask.Stop;
    begin
      if Assigned(Task) and (Task.Status = TTaskStatus.Running) then
        Task.Cancel;
    end;
    
    end.

     

    Класс включает в себя интерфейс ITask и после создания и вызова метода Start должен в потоке выполнять какие-то вычисления, в данном случае это просто задержка и вызов коллбека. После отработки класс вызывает коллбек для уведомления о завершении работы и самостоятельно разрушается.

    Код использования класса:

    unit Unit1;
    
    interface
    
    uses
      ..., ThreadTask;
    
    type
      TForm1 = class(TForm)
        Memo: TMemo;
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        ThreadTask: TThreadTask;
    
        procedure TreadDestroy(ID: Integer);
        procedure TreadPrint(ID: Integer);
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.fmx}
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      if Assigned(ThreadTask) then
        FreeAndNil(ThreadTask);
    
      ThreadTask := TThreadTask.Create;
      ThreadTask.OnDestroy := TreadDestroy;
      ThreadTask.OnPrint := TreadPrint;
      ThreadTask.Start;
    end;
    
    procedure TForm1.TreadDestroy(ID: Integer);
    begin
      Memo.Lines.Add(Format('ThreadTask №%d уничтожен', [ID]));
      ThreadTask := nil;
    end;
    
    procedure TForm1.TreadPrint(ID: Integer);
    begin
      Memo.Lines.Add(Format('Я Task №%d', [ID]));
    end;
    
    end.

    По нажатию на кнопку проверяем не существует ли предыдущий экземпляр класса, если существует уничтожаем его, создаём новый и запускаем его. Приходящие сообщения от класса выводим в Memo.

    Если запустить и дождаться полной отработки потоком, то всё ожидаемо, в Memo видим:

    Я Task №1
    Я Task №1
    ThreadTask №1 уничтожен

    Однако если не дождавшись окончания работы первого потока ещё раз нажать на кнопку, то вывод получается совсем не тем, что ожидалось:

    ThreadTask №1 уничтожен
    Я Task №2
    Я Task №2
    Я Task №2
    ThreadTask №2 уничтожен

    Первый класс разрушается, но задача не снимается и кроме того она вызывает лишний раз коллбек от имени второй задачи. Казалось бы можно переписать код кнопки и "занулить" коллбеки:

    procedure TForm1.Button1Click(Sender: TObject);
    begin
      if Assigned(ThreadTask) then
        begin
          ThreadTask.OnDestroy := nil;
          ThreadTask.OnPrint := nil;
          FreeAndNil(ThreadTask);
        end;
    
      ThreadTask := TThreadTask.Create;
      ThreadTask.OnDestroy := TreadDestroy;
      ThreadTask.OnPrint := TreadPrint;
      ThreadTask.Start;
    end;

    Но это не даёт нужного результата, вывод в Memo практически аналогичен предыдущему:

    Я Task №1
    Я Task №1
    Я Task №1
    ThreadTask №1 уничтожен

    Может быть Task нельзя так использовать или я что-то делаю не так?

  4. Добрый день. Возникла проблема при декодировании HTML страницы. При попытке декодировать символ

    THTMLEncoding.HTML.Decode(' ');

    получаю ошибку

    Снимок1.jpg

    Не хотелось использовать обычную замену, думал использовать специальную функцию для этого, но не вышло... Это очередной баг или перед декодированием текст ещё как-то нужно подготовить?

  5. Доброго всем времени суток. Подскажите, есть ли в FireMonkey возможность отслеживать сетевую активность в целом. Чтобы впоследствии можно было бы отобразить сколько байт передано/получено в секуну. Если в Windows это можно реализовать через WinAPI, то что делать с Android и IOS? Универсального средства нет?

  6. На семёрке

    TOSVersion.Major = 6

    TOSVersion.Minor = 1

    TOSVersion.Build = 7601

     

    На десятке

    TOSVersion.Major = 10

    TOSVersion.Minor = 0

    TOSVersion.Build= 0

     

    Про Minor погорячился, он и должен быть 0. У вас на скрине как раз Major и Minor. Но почему Build равен нулю, когда по идее должен быть 10586 на последней версии.

  7.  

    Неполный пример - Integer, как и pointer укладывается в регистр EAX/EBX или какие_там_сейчас_у_процессоров.

    С учетом модели вызовов register, используемой в Delphi, для integer выигрыша в передаче по ссылке/по значению нет. Ну, разве что при передаче по ссылке в винде будет PageFault и процессору придется подгружать страничку. Но это крайне маловероятно, с учетом того, что реальное значение было доступно в вызывающем коде.

    Поэтому и передается по значению.

     

    Корректнее было бы сравнить string, record и array, ибо

    Using const allows the compiler to optimize code for structured - and string-type parameters.

     

     

    Да, вы правы. Со string и class получилось также как и с integer, а вот record и array передались по ссылке и в var, и в const. В любом случае ничего не изменилось в этом плане, в последней версии всё аналогично, а значит править ничего не нужно.

  8.  

     

    да уж ссылочка, почитал, кошмар...теперь ведь все проекты при переходе перелопачивать под "const [Ref]"...жескачь 

    т.е. везде в новых проектов писать эти 11 знаков? мдя...ладно 5 ну 11 уже слишком да и код не айс становиться

     

     

    Вообще-то модификатор const никогда не передавал переменную по ссылке, всегда было по значению, ничего не изменилось в этом плане. Наоборот добавили новую возможность передать по ссылке с использованием модификатора const.

     

    наверно вы правы...люди же для красоты или забавы писали const ))

    если ваша правда, то значит что указать const что не указать все всегда было одно и тоже...просто делать нечего было...вот и писали const )

     

     

    Может люди писали его для блокирования возможности изменения переданного параметра? Именно внутри процедуры. Вот вам элементарная проверка, Delphi 7.

    procedure TForm1.check_const(const b: integer);
    begin
      Label2.Caption := Format('%p', [@b]);
    end;
    
    procedure TForm1.check_var(var c: integer);
    begin
      Label3.Caption := Format('%p', [@c]);
    end;
    
    procedure TForm1.check(d: integer);
    begin
      Label4.Caption := Format('%p', [@d]);
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      a: integer;
    begin
      a := 1;
      Label1.Caption := Format('%p', [@a]);
    
      check_const(a);
      check_var(a);
      check(a);
    end;
    

    779ae5d469438cc326c1454a2c9dd2cc.jpg

     

    Только при передаче через var адрес остаётся неизменным, а значит передача идёт по ссылке.

  9. да уж ссылочка, почитал, кошмар...теперь ведь все проекты при переходе перелопачивать под "const [Ref]"...жескачь 

    т.е. везде в новых проектов писать эти 11 знаков? мдя...ладно 5 ну 11 уже слишком да и код не айс становиться

     

     

    Вообще-то модификатор const никогда не передавал переменную по ссылке, всегда было по значению, ничего не изменилось в этом плане. Наоборот добавили новую возможность передать по ссылке с использованием модификатора const.

  10. Поддержу вопрос, но немного его перефразирую. У меня вообще какой то затык с этим Hint-ом! Как приложение я пишу уже полгода (начал с DelphiEX7), бинт появился только сейчас, то я его добавил только сейчас, но не тут то было! Он вообще не отображается нигде ни при каких обстоятельствах!!!! Что делать? С кем то конфликтует?

    В пустом проекте хоть отображается?

×
×
  • Создать...