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

Mazzay

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

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

  • Посещение

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

  1. В 24.01.2019 в 13:08, krapotkin сказал:

    если создавать TButton.Create(Self) то нужно больше движений.

    Кстати, в TComponent Owner объявлен как «unsafe». Почему тогда Create(Self) увеличивает счётчик ссылок дополнительно ещё на единицу?

    class PASCALIMPLEMENTATION TComponent : public TPersistent
    {
    ...
    private:
    	__unsafe TComponent* FOwner;
    ...  
    public:
    	__property TComponent* Owner = {read=FOwner};
    ...
    };

     

  2. 1 час назад, krapotkin сказал:

    если создавать TButton.Create(Self) то нужно больше движений. Просто не нужно так делать ))))

    Я и писал:

    В 20.01.2019 в 19:31, Mazzay сказал:

    Помогает, только если ещё и в конструкторе не указывать владельца «TPanel(NULL)», что не считаю нормальным:

    
    __fastcall TBoxItem::TBoxItem(TComponent* Owner, String fText) : TPanel(NULL)

     

     

     

    21 час назад, Mazzay сказал:

    Можно сделать Owner = NULL, но это как-то, ИМХО, неправильно.

    Почему не нужно передавать указатель на себя потомку?

  3. 2 часа назад, krapotkin сказал:

    может, доки прочесть?

    в мобильных платформах используется ARC 

    поэтому, пока есть хоть одна ссылка на объект, он не уничтожается

    зато, когда ссылок нет, он уничтожается самостоятельно

    вызов Delete для компонента нужен для сохранения кросс-платформенной совместимости

    в Windows он работает, в ARC - пустой

    а принудительный вызов деструктора скорее всего только навредит, ибо архитектурный косяк прикрывается костылем...

    Выходит, без условной компиляции не обойтись?

    В деструкторах у меня уничтожаются все дочерние объекты, что в свою очередь должно убирать их с экрана, например. Писать вместо деструкторов функции типа «Hide», а память пусть остаётся занятой?

  4. bi->Parent = NULL;

    Если это вставить перед delete, как здесь описано, не помогает. Помогает, только если ещё и в конструкторе не указывать владельца «TPanel(NULL)», что не считаю нормальным:

    __fastcall TBoxItem::TBoxItem(TComponent* Owner, String fText) : TPanel(NULL)

    //////////////////

    В результате остановился на таком варианте, но он мне тоже не нравится:

    bi->Parent = NULL;
    #if defined(__ANDROID__) || defined(__APPLE__)
    bi->DisposeOf();
    #endif
    delete bi;
    bi = NULL;

     

  5. bi->Parent = NULL;

    Если это вставить перед delete, как здесь описано, не помогает. Помогает, только если ещё и в конструкторе не указывать владельца «TPanel(NULL)», что не считаю нормальным:

    __fastcall TBoxItem::TBoxItem(TComponent* Owner, String fText) : TPanel(NULL)

     

  6. Ничего не приходит на ум! Что я делаю не так?

    Под Windows delete вызывает деструктор, под Android — нет.

    Unit1.h

    #ifndef Unit1H
    #define Unit1H
    //---------------------------------------------------------------------------
    #include <System.Classes.hpp>
    #include <FMX.Controls.hpp>
    #include <FMX.Forms.hpp>
    #include <FMX.Controls.Presentation.hpp>
    #include <FMX.StdCtrls.hpp>
    #include <FMX.Types.hpp>
    //---------------------------------------------------------------------------
    class TBoxItem : public TPanel
    {
    private:
    	TLabel* tInfo;
    public:
    	__fastcall TBoxItem(TComponent* Owner, String fText);
    	__fastcall ~TBoxItem();
    };
    
    //---------------------------------------------------------------------------
    class TForm1 : public TForm
    {
    __published:	// IDE-managed Components
      TButton *ButtonNew;
      TButton *ButtonDelete;
      TLabel *LabelConstructor;
      TLabel *LabelDestructor;
      void __fastcall ButtonNewClick(TObject *Sender);
      void __fastcall ButtonDeleteClick(TObject *Sender);
    private:	// User declarations
      TBoxItem *bi;
    public:		// User declarations
      __fastcall TForm1(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
    
    extern PACKAGE TForm1 *Form1;
    //---------------------------------------------------------------------------
    #endif

    Unit1.cpp

    #include <fmx.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.fmx"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
      : TForm(Owner)
    {
      bi = NULL;
    }
    //---------------------------------------------------------------------------
    __fastcall TBoxItem::TBoxItem(TComponent* Owner, String fText) : TPanel(Owner)
    {
      Form1->LabelConstructor->Text = Form1->LabelConstructor->Text + " OK";
    	Parent = (TFmxObject*)Owner;
    	tInfo = new TLabel(this);
    	tInfo->Parent = this;
      tInfo->TextSettings->HorzAlign = TTextAlign::Center;
      tInfo->Align = TAlignLayout::Center;
      tInfo->Text = fText;
      Height = 32;
      Align = TAlignLayout::Bottom;
    }
    //---------------------------------------------------------------------------
    __fastcall TBoxItem::~TBoxItem()
    {
      Form1->LabelDestructor->Text = Form1->LabelDestructor->Text + " OK";
      delete tInfo;
    }
    
    void __fastcall TForm1::ButtonNewClick(TObject *Sender)
    {
      if(!bi)
      {
        bi = new TBoxItem(this, "BoxItem");
        ButtonNew->Enabled = false;
        ButtonDelete->Enabled = true;
      }
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::ButtonDeleteClick(TObject *Sender)
    {
      if(bi)
      {
        delete bi; // под Android деструктор не вызывается, объект не уничтожается ((
        bi = NULL;
        ButtonNew->Enabled = true;
        ButtonDelete->Enabled = false;
      }
    }
    //---------------------------------------------------------------------------

    Windows (жму кнопку «new» — получаю «Constructor OK» и панель внизу экрана, жму «delete» — получаю «Destructor OK», панель удаляется)

    2019-01-20_15-00-50.png.7b36a33f22b12d869f4da32dd9b80212.png

    Android (жму кнопку «new» — получаю «Constructor OK» и панель внизу экрана, жму «delete» — «Destructor OK» не получаю, панель НЕ удаляется)

    Screenshot_2019-01-20-14-57-02.jpeg.df516efd2c26ccd07cb235eb0af44e47.jpeg

    C++Builder 10.2.3 Tokyo

    delete bi; не вызывает деструктор. ((

  7. 18 часов назад, Mazzay сказал:

    А ещё есть какие-нибудь варианты? C++Builder не поддерживает helper.

    Собственно:

    for(int i = 0; i < ListView1->ControlsCount; ++i)
    	if(dynamic_cast<TControl*>(ListView1->Controls->Items[i])->ClassNameIs("TSearchBox"))
    	{
    		dynamic_cast<TSearchBox*>(ListView1->Controls->Items[i])->Text = EmptyStr;
    		break;
    	}
    

     

  8. Сделал выбор числа месяца скроллингом (как это реализовано на устройствах Apple). Для наглядности вот рабочий пример: https://youtu.be/F73fCMSlL7I.

    Но для красоты картины не хватает вывода заворачивающихся чисел в перспективе:

    2017-05-04_08-25-46.png.2de5496b4d68ea6d4124b5bf3d54462c.png

    Как сие реализовать?

  9. Многократное щёлканье получилось вот так.

    В объявлении класса:

    #ifdef __ANDROID__
    	_di_JAudioTrack audioTrack;
    	TJavaArray__1<short>* samples;
    #endif

    В конструкторе:

    #ifdef __ANDROID__
    	samples = new TJavaArray__1<short>(1);
    	samples->Items[0] = 0x0FFF;
    	audioTrack = TJAudioTrack::JavaClass->init(TJAudioManager::JavaClass->STREAM_MUSIC,
    		11025, TJAudioFormat::JavaClass->CHANNEL_OUT_MONO,
    		TJAudioFormat::JavaClass->ENCODING_PCM_16BIT,
    		TJAudioTrack::JavaClass->getMinBufferSize(11025, TJAudioFormat::JavaClass->CHANNEL_OUT_MONO, TJAudioFormat::JavaClass->ENCODING_PCM_16BIT),
    		TJAudioTrack::JavaClass->MODE_STREAM);
    #endif
    

    На событие:

    #ifdef __ANDROID__
    	audioTrack->write(samples, 0, 1);
    	audioTrack->play();
    	audioTrack->stop();
    #endif
    

    В деструкторе:

    #ifdef __ANDROID__
    	delete samples;
    #endif
    

     

  10. Спасибо большое!

    На Билдере получилось так:

    #include <AndroidApi.JNI.Media.hpp>
    
    void AndroidSound(double freqHz, int durationMs)
    {
    	double Pi = 3.14159265358979323846;
    	int count = (int)(44100.0 * 2.0 * (durationMs / 1000.0)) & ~1;
    	TJavaArray__1<short>* samples = new TJavaArray__1<short>(count);
    	for(int i = 0; i < count; i += 2)
    	{
    		short sample = (short)(Sin(2 * Pi * i / (44100.0 / freqHz)) * 0x7FFF);
    		samples->Items[i + 0] = sample;
    		samples->Items[i + 1] = sample;
    	}
    
    	_di_JAudioTrack audioTrack;
    	audioTrack = TJAudioTrack::JavaClass->init(TJAudioManager::JavaClass->STREAM_MUSIC,
    		44100, TJAudioFormat::JavaClass->CHANNEL_CONFIGURATION_MONO,
    		TJAudioFormat::JavaClass->ENCODING_PCM_16BIT, count * (sizeof(TJavaArray__1<short>) / 8),
    		TJAudioTrack::JavaClass->MODE_STATIC);
    	if(audioTrack->write((TJavaArray__1<short>*)samples, 0, count)) audioTrack->play();
    	delete samples;
    }
    

    Только при многократном вызове (у меня при прокрутке щёлкает звуком ScrollBox) получаю ошибку:

    Цитата

    java.lang.illegalStateException: play() called on uninitialized AudioTrack.

    Не пойму, почему. :( Сдаётся мне, переменную audioTrack надо как-то уничтожать. Хотя, это интерфейс…

  11. Приведённый здесь пример почему-то не обрезает выбираемые варианты звуков по длительности ADuration. :(

    uses 
      AndroidApi.JNI.Media;
    
    procedure MakeSound(ADuration: Integer);
    var
      Volume: Integer;
      StreamType: Integer;
      ToneType: Integer;
      ToneGenerator: JToneGenerator;
    begin
      Volume := TJToneGenerator.JavaClass.MAX_VOLUME; // задаем громкость
      StreamType := TJAudioManager.JavaClass.STREAM_ALARM; 
      ToneType := TJToneGenerator.JavaClass.TONE_DTMF_0; // тип звука
      ToneGenerator := TJToneGenerator.JavaClass.init(StreamType, Volume);
      ToneGenerator.startTone(ToneType, ADuration);
    end;

    Задаваемая длительность может только увеличить время воспроизведения, но не может уменьшить. Может есть какие-нибудь способы обрезать воспроизводимое?

  12. Не хочу добавлять компоненты и аудио-файлы  в проект ради обычного воспроизведения коротенького щелчка.

    Никак не могу найти. Android API позволяет воспроизвести просто звук нужной длительности и частоты?

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