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

Alex7wrt

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

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

  • Посещение

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

    31

Активность репутации

  1. Like
    Alex7wrt получил реакцию от Anatoliy в [Apple Store]нужен совет   
    Заметил, что у вас кнопка "Поделиться с друзьями" имеет Андроидовский дизайн. А у Apple это прямоугольник со стрелкой, направленной вверх.
  2. Like
    Alex7wrt отреагировална Brovin Yaroslav в Описание TfgImageList   
    Первый набросок компонента, позволяющего организовать централизованное хранение графических ресурсов для всех платформ.
    Основные особенности:
    Спроектирован для использования одного экземпляра изображения во многих компонентах. Позволяет хранить все графические ресурсы любых размеров. В будущем не будет грузить картинки в память, если они не используются. А будет подгружать их из файла по мере необходимости. Тем самым будет значительно экономиться память. Хранение именованных графических ресурсов, а не по индексу. Это позволяет отразить в названии назначение картинки. Использование папок. Группировка изображений по смыслу для удобства работы с ними. Возможность загрузки разных картинок для разных устройств, или же загрузить один набор картинок для всех устройств. Удобная и быстрая загрузка изображений путем перетаскивания Хранение отступов изображения.  Наглядное отображение картинки в свойствах компонентах. При изменении имени картинки, в компонентах используемых картинку идет автоматическое обновление имени картинки. В стандартном TImageList, из-за индексной структуру все картинки съезжают и при удалении картинки, компонент начинает отображать уже другую картинку.


  3. Like
    Alex7wrt отреагировална Andrey Efimov в Tokyo, артефакты при отрисовке на канве, Android   
    Рекомендую вернуться на Berlin Upd2.
    Tokyo вышла очень бажная, особенно в плане мобильной разработки. Юзать текущую версию себе дороже выйдет. Нужно дождаться как минимум Upd1, но я думаю лучше сразу Upd2 ждать.
  4. Like
    Alex7wrt получил реакцию от Евгений Корепов в Почему приложение вылетает при смене ориентации?   
    Возможно в файле манифеста нужно дописать
     
    android:configChanges="orientation|keyboard|keyboardHidden|screenSize"
  5. Like
    Alex7wrt отреагировална krapotkin в Команды для переключения мониторов, Windows   
    https://social.msdn.microsoft.com/Forums/vstudio/en-US/7c9fd6d4-cee7-490a-8507-afb9512b3e8b/change-mode-of-multimonitor-setup-programmatically?forum=csharpgeneral
    https://msdn.microsoft.com/en-us/library/dd183554(VS.85).aspx
  6. Like
    Alex7wrt отреагировална Brovin Yaroslav в Как правильно организовать многопоточный алгоритм   
    Пулл потоков вам в помощь. Это о вопросе долго времени создания и удаления инстансов потоков.
  7. Like
    Alex7wrt отреагировална Камышев Александр в Как правильно организовать многопоточный алгоритм   
    имхо, с firemonkey неплохо работает такая схема:
    1. создать две потокозащищенные очереди (структуры), на си для этого подходит std::deque, в fmx можно TList. Защита стандартно TCriticalSection;
    2. создать несколько потоков, с помощью TEvent указать им ссылки на очереди и критические секции;
    3. в потоках:
     3.1 TCriticalSection::Enter лочим очередь задач,
     3.2 забираем крайнюю задачу
     3.3 TCriticalSection::Leave отпускаем очередь задач
     3.4 вычисления
     3.5 по аналогии с очередью задач лочим очередь результатов, выкладываем результаты, отпускаем
     3.6 повтор с пункта 3.1
    4. в основном потоке в очереди (тоже lock unlock) выкладывать задачи и при наличии результатов отрисовывать имеющимися средствами.
    в 4 пункте нужен будет нужен будет какой-нибудь mmtimer.
     
  8. Like
    Alex7wrt отреагировална GASCHE в Как правильно организовать многопоточный алгоритм   
    Если верить интернету, то в Windows создание потоков и синхронизация с основным потоком довольно "трудозатратая" операция. Для Windows я торможу поток dwStatus := WaitForSingleObject( Parms.fvEventUSB, INFINITE ); Когда надо запустить поток устанавливаю Event, данные из потока скидываю в потокобезопасный буффер и сообщаю об окончании обработки данных установкой другого Event.
  9. Like
    Alex7wrt отреагировална kami в Как правильно организовать многопоточный алгоритм   
    А точно нужно дожидаться, пока все потоки отработают? Это не асинхронные задачи?
    В качестве еще одного варианта - воспользуйтесь interlocked-функциями. Главный поток определяет, сколько вторичных потоков он запустит. И выставляет нужное значение в integer-переменной.
    Каждый поток, завершив виток просчета вызывает InterlockedDecrement(ThreadCounter); При достижении нуля - из последнего вторичного потока вызывается TThread.Queue для сообщения главному потоку "все просчеты завершены". Ну и - потоки входят в спячку, например - на ожидании TEvent. А получив очередную порцию данных для просчета - выходят из ожидания события.
    Даже лучше не так: каждый поток при запуске делает InterlockedIncrement(ThreadCounter), не стоит главному потоку выставлять начальное значение, хватит с него и запуска вторичных потоков. А вот всё остальное - да, остается в силе.
     
  10. Like
    Alex7wrt отреагировална kami в Как правильно организовать многопоточный алгоритм   
    Если Windows - то это WaitForMultipleObjects
    в остальных случаях - см. TTask.WaitForAll
  11. Like
    Alex7wrt отреагировална enatechno в Параллельные вычисления, System.Threading   
    Видео (Task, Future, Parallel, WaitForAll etc.) 
    и на русском
  12. Like
    Alex7wrt отреагировална krapotkin в Параллельные вычисления, System.Threading   
    если у вас возникали проблемы с TThread то лучше понять источник проблем. Использование System.Threading ничем не отличается в этом плане. Те же потоки создаются. Та же синхронизация требуется.
    Для меня TTask - это способ в лучшем случае сделать что-то "по-быстрому". Если серьезное что, с отладкой, лучше по-прежнему пользовать TThread.
  13. Like
    Alex7wrt отреагировална Maximus в Параллельные вычисления, System.Threading   
    Вкратце вот здесь можно почитать http://proghouse.ru/programming/36-delphi-xe7-ppl
    Например, если таск организован как бесконечный цикл, то после завершения каждого таска, в главном потоке увеличивать счётчик. Как только он станет равным количеству запущенных, можно будет обновлять информацию на экране и делать повторный запуск. Разумеется доступ к главному потоку должен быть синхронизирован. А если в таске конечная последовательность действий, то можно просто проверять статусы всех тасков.
    Логично. WaitForAll приостанавливает поток в котором был вызван до тех пор, пока не будут завершены все таски.
  14. Like
    Alex7wrt отреагировална Равиль Зарипов (ZuBy) в [Обзор] #3 ModernListView - динамическая подгрузка контента   
    Ссылка: http://blog.rzaripov.kz/2016/12/3-modernlistview.html
    Автор: Зарипов Равиль @ZuBy
    Описание:  Реализация динамической подгрузки контента:
    Бесконечный скроллинг (например как лента в ВК) Паджинация/Пагинация (постраничная загрузка)
  15. Like
    Alex7wrt отреагировална AliZairov в Facebook API под Firemonkey   
    Привет. Alcione
  16. Like
    Alex7wrt отреагировална Brovin Yaroslav в Определение положения экрана   
    Да точно! :-)
  17. Like
    Alex7wrt отреагировална Brovin Yaroslav в Определение положения экрана   
    Самый простой и тупой способ это у формы в OnResize анализировать ширину и высоту. Этот способ будет одинаково работать везде.
    Если хочется более нативного варианта решения задачи, то можно воспользоваться TfgApplicationEvents.OnDeviceOrientationChanged.
  18. Like
    Alex7wrt отреагировална Mars M в Глобальные и локальные координаты позиции курсора   
    Вот тут скорее всего как раз про это 
     
  19. Like
    Alex7wrt получил реакцию от AngryOwl в [Android] Отслеживание сворачивания приложения   
    Добрый день.
    Andrey Yefimov в своем блоге подробно описал получение событий жизненного цикла приложения, в том числе и потерю активности.
    http://delphifmandroid.blogspot.com/2013/10/blog-post.html
    function TForm1.HandleAppEvent(AAppEvent: TApplicationEvent; AContext: TObject): Boolean; begin case AAppEvent of TApplicationEvent.BecameActive: Log('Became Active'); TApplicationEvent.EnteredBackground: Log('Entered Background'); TApplicationEvent.WillBecomeForeground: Log('Will Become Foreground'); end; Result := True; end; procedure TForm1.FormCreate(Sender: TObject); var aFMXApplicationEventService: iFMXApplicationEventService; begin ............ if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationEventService, IInterface(aFMXApplicationEventService)) then aFMXApplicationEventService.SetApplicationEventHandler(HandleAppEvent); ............ end;
  20. Thanks
    Alex7wrt получил реакцию от MrSergei2017 в TPath Как программно указать TPathData   
    Например так:
     
    var path: TPathData; .......... Path:=TPathData.Create; Path.Clear; Path.MoveTo(PointF(x[0],y[0])); for i:=1 to N do Path.LineTo(PointF(x[i],y[i])); Path.ClosePath;  
  21. Like
    Alex7wrt получил реакцию от Kitty в TPath Как программно указать TPathData   
    Например так:
     
    var path: TPathData; .......... Path:=TPathData.Create; Path.Clear; Path.MoveTo(PointF(x[0],y[0])); for i:=1 to N do Path.LineTo(PointF(x[i],y[i])); Path.ClosePath;  
  22. Like
    Alex7wrt получил реакцию от Равиль Зарипов (ZuBy) в Не могу добавить сторонний txt файл в скомпилированый пакет под андроид   
    То есть просто вы раньше не добавляли наклонную черту-разделитель между директорией и именем файла. Вот и вся загвоздка.
  23. Like
    Alex7wrt отреагировална ENERGY в как заставить TTimeEdit работать в режиме 24ч.   
    А если нужно будет указать длительность 24 или 25 часов?
    Сделай обычный TLabel и рядом кнопки + - которые будут прибавлять убавлять единицу, или можно использовать TSpinBox
     
     
  24. Like
    Alex7wrt отреагировална Евгений Корепов в Пример с TInAppPurchase   
    Вот мой юнит для работы с покупками в приложении:
    unit UnitInAppPurchase; interface uses // UnitGetDeviceInfo, FMX.InAppPurchase, System.Classes, System.SysUtils, System.Hash; //const // HashMixer = 'p345mcq34mq'; type TBillingEventPurchased = procedure(ASecretKey : String) of object; TBillingEventNotPurchased = procedure of object; TBillingLog = procedure(AMessage : String) of object; TBilling = class private InAppPurchase: TInAppPurchase; FBillingEventPurchased : TBillingEventPurchased; FBillingEventNotPurchased : TBillingEventNotPurchased; FBillingLog : TBillingLog; FNoAdsID : String; FSecretKey : String; FApplicationLicenseKey : String; procedure InAppPurchaseSetupComplete(Sender: TObject); procedure InAppPurchaseProductsRequestResponse(Sender: TObject; const Products: TIAPProductList; const InvalidProductIDs: TStrings); procedure InAppPurchaseError(Sender: TObject; FailureKind: TFailureKind; const ErrorMessage: string); procedure InAppPurchasePurchaseCompleted(Sender: TObject; const ProductID: string; NewTransaction: Boolean); procedure ConsumeComplete(Sender: TObject; const ProductID: string); procedure ConsumeFailed(Sender: TObject; const ProductID, ErrorMessage: string); function GetSecretKey : String; function CheckSecretKey : Boolean; procedure LogMy(AMessage : String); public // Constructor Create(AApplicationLicenseKey, ANoAdsID, ASecretKey : String); constructor Create(AApplicationLicenseKey, ANoAdsID : String); destructor Destroy; procedure CheckPurchase; procedure Purchase; // published property OnPurchased : TBillingEventPurchased read FBillingEventPurchased write FBillingEventPurchased; property OnNotPurchased : TBillingEventNotPurchased read FBillingEventNotPurchased write FBillingEventNotPurchased; property OnPurchasedError : TBillingEventNotPurchased read FBillingEventNotPurchased write FBillingEventNotPurchased; property OnLog : TBillingLog read FBillingLog write FBillingLog; end; implementation //Constructor TBilling.Create(AApplicationLicenseKey, ANoAdsID, ASecretKey : String); Constructor TBilling.Create(AApplicationLicenseKey, ANoAdsID : String); begin FNoAdsID:=ANoAdsID; FApplicationLicenseKey:=AApplicationLicenseKey; // FSecretKey:=ASecretKey; InAppPurchase:=TInAppPurchase.Create(Nil); InAppPurchase.ApplicationLicenseKey:=FApplicationLicenseKey; InAppPurchase.ProductIDs.Add(FNoAdsID); InAppPurchase.OnSetupComplete := InAppPurchaseSetupComplete; InAppPurchase.OnProductsRequestResponse := InAppPurchaseProductsRequestResponse; InAppPurchase.OnError := InAppPurchaseError; InAppPurchase.OnPurchaseCompleted := InAppPurchasePurchaseCompleted; InAppPurchase.OnConsumeCompleted := ConsumeComplete; InAppPurchase.OnConsumeFailed := ConsumeFailed; end; Destructor TBilling.Destroy; begin if Assigned(InAppPurchase) then FreeAndNil(InAppPurchase); inherited; end; procedure TBilling.Purchase; begin try InAppPurchase.PurchaseProduct(FNoAdsID); except LogMy('PurchaseProduct except'); end; end; procedure TBilling.CheckPurchase; begin if CheckSecretKey Then begin LogMy('CheckSecretKey True - Disable Ads'); FSecretKey:=GetSecretKey; if Assigned(OnPurchased) then OnPurchased(FSecretKey); Exit; end; LogMy('CheckSecretKey False - Check InAppPurchase status'); InAppPurchase.SetupInAppPurchase; end; function TBilling.GetSecretKey : String; Var ADeviceIMEI : String; begin // Это был костыль для хранения флага о покупке локально, не оправдал себя и изъят из обращения // ADeviceIMEI:=GetDeviceIMEI; // Result:=System.Hash.THashSHA1.GetHashString(HashMixer+ADeviceIMEI+FNoAdsID); end; function TBilling.CheckSecretKey : Boolean; begin Result:=False; // Result:=FSecretKey.Equals(GetSecretKey); end; procedure TBilling.InAppPurchaseSetupComplete(Sender: TObject); begin LogMy('InAppPurchaseSetupComplete'); try LogMy('InAppPurchase.QueryProducts'); InAppPurchase.QueryProducts; except on E:Exception do LogMy('QueryProducts Exception: '+e.Message); end; end; procedure TBilling.InAppPurchaseProductsRequestResponse(Sender: TObject; const Products: TIAPProductList; const InvalidProductIDs: TStrings); var Product: TProduct; begin LogMy('TMainForm.InAppPurchaseProductsRequestResponse'); LogMy('Start search '+FNoAdsId); LogMy('Products.Count='+Products.Count.ToString); for Product in Products do begin LogMy('Start search '+FNoAdsId); if Product.ProductID = FNoAdsId then begin LogMy('Founded '+FNoAdsId); if InAppPurchase.IsProductPurchased(FNoAdsId) then begin // КУПЛЕНО!!!! LogMy(FNoAdsID+' Yes ProductPurchased'); FSecretKey:=GetSecretKey; if Assigned(OnPurchased) then OnPurchased(FSecretKey); end Else begin LogMy(FNoAdsID+' Not ProductPurchased'); if Assigned(OnNotPurchased) then OnNotPurchased; end; Exit; end; end; LogMy('Product not found - OnNotPurchased'); if Assigned(OnNotPurchased) then OnNotPurchased; LogMy('TMainForm.InAppPurchaseProductsRequestResponse END'); end; procedure TBilling.InAppPurchaseError(Sender: TObject; FailureKind: TFailureKind; const ErrorMessage: string); Var S: String; begin if FailureKind = TFailureKind.ProductsRequest Then S:='ProductsRequest'; if FailureKind = TFailureKind.Purchase Then S:='Purchase'; if Assigned(OnPurchasedError) then OnPurchasedError; LogMy('Purchasing error ('+S+'):'+ErrorMessage); end; procedure TBilling.InAppPurchasePurchaseCompleted(Sender: TObject; const ProductID: string; NewTransaction: Boolean); begin LogMy('TMainForm.InAppPurchasePurchaseCompleted'); if ProductID = FNoAdsID then begin LogMy('HideAndDestroyAds'); FSecretKey:=GetSecretKey; if Assigned(OnPurchased) then OnPurchased(FSecretKey); end; end; procedure TBilling.ConsumeComplete(Sender: TObject; const ProductID: string); begin LogMy('Consume Complete: ' + ProductID); end; procedure TBilling.ConsumeFailed(Sender: TObject; const ProductID, ErrorMessage: string); begin LogMy('Consume Failed: ' + ProductID); end; procedure TBilling.LogMy(AMessage : String); begin if Assigned(OnLog) then OnLog(AMessage); end; end. Использовать вот так:
    const NoAdsID = 'mysuperapp_remove_ad'; //название товара, тоже что и консоли разработчика ... private Billing : TBilling; procedure BillingEventPurchased(ASecretKey : String); procedure BillingEventNotPurchased; procedure BillingEventPurchasedError; procedure BillingLog(AMessage : String); procedure DisablePurchaseUI; procedure EnablePurchaseUI; ... FormCreate start Var AppLicenseKey : String; ... AppLicenseKey:='MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxim8ZGAIhK/FPhpXT0r6MXHYxYi1qcMfIiKOkiBDHcRYgRLK7'; AppLicenseKey:=AppLicenseKey+'********************************************************************************'; AppLicenseKey:=AppLicenseKey+'******************************************************************************'; AppLicenseKey:=AppLicenseKey+'*******************************************************************************'; AppLicenseKey:=AppLicenseKey+'Mgv7JP8A+qcDV3lm4M9OKBgxBRLaejxHd1iH3tsMR8PLkKUUf3yrMW8QIDAQAB'; Billing:=TBilling.Create(AppLicenseKey, NoAdsID); Billing.OnPurchased:=BillingEventPurchased; Billing.OnNotPurchased:=BillingEventNotPurchased; Billing.OnPurchasedError:=BillingEventPurchasedError; Billing.OnLog:=BillingLog; Billing.CheckPurchase; FormCreate stop ... procedure TFormMain.BillingEventPurchased(ASecretKey : String); begin // LogMy('CheckSecretKey True - Disable Ads'); Setting.Flags.AdsShowFlag:=False; DisablePurchaseUI; // удаляет кнопки и прочую фигню предлагающую купить товар (товар в данном случае - Удаление рекламы) HideAndDestroyAds; // удаление рекламы из приложения, так как товар куплен // Setting.SecretKey:=ASecretKey; // SaveFormState; end; procedure TFormMain.BillingEventNotPurchased; begin Setting.Flags.AdsShowFlag:=True; EnablePurchaseUI; ShowAds; end; procedure TFormMain.BillingEventPurchasedError; begin Setting.Flags.AdsShowFlag:=True; // EnablePurchaseUI; ShowAds; end; procedure TFormMain.BillingLog(AMessage : String); begin // Memo.Lines.Insert(0,AMessage); end; procedure TFormMain.DisablePurchaseUI; begin ButtonRemoveAds.Visible:=False; LayoutRemoveAds.Visible:=False; end; procedure TFormMain.EnablePurchaseUI; begin LayoutRemoveAds.Visible:=True; ButtonRemoveAds.Visible:=True; end;  
  25. Like
    Alex7wrt отреагировална Fedor K в TListView: список в виде CheckBox в ListViewItem   
    У стандартного TListView уже все есть:
     
    //устанавливаем режим редактирования у списка либо в редакторе свойств выставляем ListView1.EditMode := True; //... //Получаем список всех выбранных элементов ListView1.Items.CheckedIndexes(true); //обращаться к свойству текущего элемента так: ListView1.Items.SetChecked(const Index: Integer; const Value: Boolean); ListView1.Items.GetChecked(const Index: Integer): Boolean;  

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