-
Постов
58 -
Зарегистрирован
-
Посещение
Активность репутации
-
Mazzay отреагировална d7d1cd в Не срабатывает деструктор
Вот код добавления кнопки и ее удаление без условной компиляции, который работает и на Windows и на Android, а так же, когда при создании указывается владелец:
// btn объявлен в описании класса TForm1 __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { btn = 0; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { btn = new TButton(this); btn->Text = L"Created!"; btn->Parent = this; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { if(!btn) return; btn->Parent = 0; RemoveComponent(btn); delete btn; btn = 0; }
-
Mazzay отреагировална d7d1cd в Не срабатывает деструктор
Счётчик увеличивается на 2 потому что одну ссылку хранит владелец, а вторую указатель bi.
Тут я не прав. Есть статья Бровина Ярослава. Там сказано, что каждый компонент с фокусом получает дополнительную ссылку. Я проверил, так происходит только тогда, когда при создании объекта указывается его владелец. Поэтому не указывай владельца при создании объекта.
Владелец нужен только для автоматического удаления того, кем он владеет при удалении его самого. У тебя же не тот случай.
-
Mazzay отреагировална krapotkin в Не срабатывает деструктор
Причем сразу на 2 )) каюсь, я не стал выяснять почему
-
Mazzay отреагировална d7d1cd в Не срабатывает деструктор
Owner объявлен как __unsafe для того, чтобы объекты не увеличивали счетчик ссылок у их владельцев. То есть, это для того, чтобы когда мы пишем, например: TButton *btn = new TButton(Form1), то счетчик ссылок у Form1 не изменился.
Когда мы указываем владельца при создании объекта, то он (создаваемый объект), попадает в список того, чем владеет владелец, поэтому счетчик ссылок создаваемого объекта увеличивается.
-
Mazzay отреагировална krapotkin в Не срабатывает деструктор
может, доки прочесть?
в мобильных платформах используется ARC
поэтому, пока есть хоть одна ссылка на объект, он не уничтожается
зато, когда ссылок нет, он уничтожается самостоятельно
вызов Delete для компонента нужен для сохранения кросс-платформенной совместимости
в Windows он работает, в ARC - пустой
а принудительный вызов деструктора скорее всего только навредит, ибо архитектурный косяк прикрывается костылем...
-
Mazzay отреагировална Dev в MessageDlg — как сделать кнопки с русскими надписями?
Найти примерно по этому пути C:\Program Files\Embarcadero\Studio\19.0\source\fmx файл FMX.Consts.pas, скопировать в папку с проектом, открыть в блокноте, найти строки SMsgDlgYes = 'Yes'; SMsgDlgNo = 'No'; заменить на SMsgDlgYes = 'Да'; SMsgDlgNo = 'Нет'; сохранить. После компиляции на андроиде в диалоге на кнопках должны быть русские «Да» «Нет»
-
Mazzay получил реакцию от Anatoliy в Можно ли программно передать фокус на SearchBox и очистить строку?
Собственно:
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; }
-
-
-
Mazzay получил реакцию от Евгений Корепов в Как вывести текст в перспективе?
Сделал выбор числа месяца скроллингом (как это реализовано на устройствах Apple). Для наглядности вот рабочий пример: https://youtu.be/F73fCMSlL7I.
Но для красоты картины не хватает вывода заворачивающихся чисел в перспективе:
Как сие реализовать?
-
Mazzay получил реакцию от Rusland в Можно ли как-нибудь попроще воспроизвести на Андроиде произвольный звук?
Многократное щёлканье получилось вот так.
В объявлении класса:
#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
-
Mazzay получил реакцию от Kitty в Можно ли как-нибудь попроще воспроизвести на Андроиде произвольный звук?
Спасибо большое!
На Билдере получилось так:
#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) получаю ошибку:
Не пойму, почему. Сдаётся мне, переменную audioTrack надо как-то уничтожать. Хотя, это интерфейс…
-
Mazzay отреагировална krapotkin в Можно ли как-нибудь попроще воспроизвести на Андроиде произвольный звук?
http://stackoverflow.com/questions/2413426/playing-an-arbitrary-tone-with-android
тут формируют буфер синусом и
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, (int)numSamples*2, AudioTrack.MODE_STATIC); audioTrack.write(generatedSnd, 0, generatedSnd.length); // Load the track audioTrack.play(); ну или тут
https://gist.github.com/slightfoot/6330866
-
Mazzay отреагировална Rusland в Звук и вибра при нажатии на кнопку
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; Типы звука можно посмотреть здесь
-
Mazzay отреагировална Egorka64 в Как правильно рисовать на канве?
ну тогда особое уважение: работать и находить время на общение со слепыми котятами типа меня - это ж какая сила воли нужна
-
Mazzay отреагировална dammit в Анимация масштабирования
Друзья, столкнулся с проблемой, описанной в посте
Хочу предложить свое решение (может кому пригодится).
Чтобы центр масштабирования был именно в центре объекта (в моем случае это TImage), необходимо после масштабирования установить свойство Align = TAlignLayout.Center, причем до этого нужно установить его в TAlignLayout.None !
Примерно вот так:
Image1.Scale.X:= 1.3;
Image1.Scale.Y:= 1.3;
Image1.Align:= TAlignLayout.None;
Image1.Align:= TAlignLayout.Center;
В этом случае будет эффект увеличения объекта из центра. Если убрать строчку "Image1.Align:= TAlignLayout.None;" - увеличение будет из левого верхнего угла. На мой взгляд некорректное поведение платформы. Возможно в будущих релизах это поправят.
Embarcadero® Delphi 10.1 Berlin Update 2 Version 24.0.25048.9432
-
Mazzay отреагировална Равиль Зарипов (ZuBy) в Конец анимации
за плавность анимации отвечает TScrollCalculations (TAniCalculations), у него есть событие OnStop.
вот если его переназначить и не сломать сам компонент в этот момент, будет вам счастье
-
Mazzay получил реакцию от Rusland в Загрузка извне apk-пакета и запуск его на установку
Фух! Вот уж воистину. Бьёшься-бьёшься — не получается. Спросишь в интернете — и наведут на решение. Всё, что GetShared… не работает. Android 5.1 без карты памяти не хочет сохранять туда файл. У меня по крайней мере. Но очередной просмотр доступных методов у TPath навёл меня на вот какой: GetPublicPath. Описание от Embarcadero у него следующее:
http://docwiki.embarcadero.com/Libraries/Berlin/en/System.IOUtils.TPath.GetPublicPath
Собственно, судя по описанию, то, что нужно. Пробую. Не работает. На эмуляторе GetPublicPath возвращает пустую строку.
Из описания:
Расстроился. Но на всякий случай попробовал на реальном устройстве под Android 5.1. И о, чудо! GetPublicPath возвращает «/storage/sdcard0/Android/data/com.<ХХХХ.myappname>/files» и установка apk оттуда через Intent замечательно работает. Проводник тоже видит эту папку и файлы в ней.
На Android 4.2 тоже работает.
Всем большое спасибо!
-
Mazzay получил реакцию от Евгений Корепов в Загрузка извне apk-пакета и запуск его на установку
Фух! Вот уж воистину. Бьёшься-бьёшься — не получается. Спросишь в интернете — и наведут на решение. Всё, что GetShared… не работает. Android 5.1 без карты памяти не хочет сохранять туда файл. У меня по крайней мере. Но очередной просмотр доступных методов у TPath навёл меня на вот какой: GetPublicPath. Описание от Embarcadero у него следующее:
http://docwiki.embarcadero.com/Libraries/Berlin/en/System.IOUtils.TPath.GetPublicPath
Собственно, судя по описанию, то, что нужно. Пробую. Не работает. На эмуляторе GetPublicPath возвращает пустую строку.
Из описания:
Расстроился. Но на всякий случай попробовал на реальном устройстве под Android 5.1. И о, чудо! GetPublicPath возвращает «/storage/sdcard0/Android/data/com.<ХХХХ.myappname>/files» и установка apk оттуда через Intent замечательно работает. Проводник тоже видит эту папку и файлы в ней.
На Android 4.2 тоже работает.
Всем большое спасибо!
-
Mazzay отреагировална krapotkin в Загрузка извне apk-пакета и запуск его на установку
Все это касается только частной папки вашего приложения. А общие папки все равно должны быть. Там несколько функций GetShared...Path()
попробуйте другую
-
Mazzay отреагировална Кривяков Виталий в Загрузка извне apk-пакета и запуск его на установку
Рекомендую в коде проверять наличие общих папок. Недавно столкнулся на 6 андроиде с тем, что GetSharedDocumentPath не существовала. Просто создал ее и приложение заработало.
-
Mazzay получил реакцию от Kitty в Загрузка извне apk-пакета и запуск его на установку
Моё приложение при запуске проверяет номер версии и при необходимости обновляется. Обновляется следующим образом: грузит с сервера и сохраняет на устройстве apk-пакет и запускает его на выполнение. Всё замечательно работало до перехода на Android 5.1. Загрузка пакета осуществляется в папку, возвращаемую GetSharedDownloadsPath. Запуск обновления производится следующим кодом:
_di_JIntent Intent; _di_Jnet_Uri oUri; _di_JFile oPath; _di_JFile oFile; oPath = TJFile::JavaClass->init(StringToJString(fPath)); // fPath = System::Ioutils::TPath::GetSharedDownloadsPath(); oFile = TJFile::JavaClass->init(oPath, StringToJString(fFile)); // fFile = L"myapp.apk" oUri = TJnet_Uri::JavaClass->fromFile(oFile); Intent = TJIntent::JavaClass->init(TJIntent::JavaClass->ACTION_VIEW); Intent->setDataAndType(oUri, StringToJString(L"application/vnd.android.package-archive")); Intent->setFlags(TJIntent::JavaClass->FLAG_ACTIVITY_NEW_TASK); SharedActivity()->startActivity(Intent); Application->Terminate(); На Android 5.1 на выполнении этого кода получаю сообщение "... Access denied."
Не помню, где, нарыл следующее:
Как установить для файла режим Readable, чтобы его могло читать другое приложение?
P.S. Внешней карты памяти на устройстве нет. Если её вставить, то работает, ибо с ней GetSharedDownloadsPath возвращает путь именно на внешней карте. Втыкание внешней карты пока рассматривается только как временный костыль, но он не очень интересен, так как устройств, на которых работает приложение 18 штук — не хочется покупать 18 карточек.