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

Rusland

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

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

  • Посещение

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

    26

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

  1. Like
    Rusland отреагировална Alexander в передача сообщений по локальной сети   
    А если решитесь писать свой, то присмотретьсь к App Tethering 
     
  2. Like
    Rusland отреагировална ENERGY в Выбор файла через диалог   
    На мобильных платформах обычно не принято указывать пути, хотя есть конечно исключения.
    На Android нет стандартного диалога, на iOS есть, но Apple не рекомендует использовать его. 
    Important: An iOS app should never use an Open or Save panel to prompt the 
    user for the location of a file within the app’s sandbox. iOS apps should 
    always save files to known locations inside their sandbox, and apps should 
    use a custom interface when presenting those documents to the user. iOS apps 
    can, however, use a UIDocumentPickerViewController to prompt the user to 
    import, export, open, or move files to or from some areas outside the app’s 
    sandbox. For more information, see the Document Picker Programming Guide.
    https://developer.apple.com/library/ios/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/UsingtheOpenandSavePanels/UsingtheOpenandSavePanels.html
     
    unit frmSelect; 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.Edit, FMX.Layouts, FMX.ListBox, FMX.Controls.Presentation; type TCallback = procedure (ASelected: String) of object; TfmSelect = class(TForm) Panel1: TPanel; btnRefresh: TButton; lstItems: TListBox; edtCurrentFolder: TEdit; pnlDirectoryNotExist: TPanel; lblDirectoryNotExist: TLabel; btnSelect: TButton; procedure btnRefreshClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure lstItemsClick(Sender: TObject); procedure btnSelectClick(Sender: TObject); private { Private declarations } public const CONST_STRING_PARENT = '..'; CONST_X = '/'; { I know is function for this } var Callback: TCallback; { Public declarations } function CD(AFolder: String): Boolean; end; var fmSelect: TfmSelect; implementation {$R *.fmx} uses System.IOUtils; procedure TfmSelect.btnSelectClick(Sender: TObject); var LResult: String; begin if Assigned(Callback) then begin if lstItems.ItemIndex = -1 then LResult := EmptyStr else LResult := lstItems.Items[lstItems.ItemIndex]; Callback(LResult); end; Close; end; function TfmSelect.CD(AFolder: String): Boolean; var LParent: String; LDirs, LFiles: TStringDynArray; s: String; begin lstItems.Clear; pnlDirectoryNotExist.Visible := False; if (AFolder <> EmptyStr) and (AFolder <> CONST_X) and (AFolder[AFolder.Length - 1] <> CONST_X) then AFolder := AFolder + CONST_X; edtCurrentFolder.Text := AFolder; { http://stackoverflow.com/questions/20318875/how-to-show-the-availble-files-in-android-memory-with-firemonkey } if not TDirectory.Exists(AFolder, True) then begin lblDirectoryNotExist.Text := 'Directory ' + AFolder + ' does not exist.'; pnlDirectoryNotExist.Visible := True; Exit(False); end; { } LParent := TDirectory.GetParent(AFolder); { } if LParent <> AFolder then lstItems.Items.Add(CONST_STRING_PARENT); { } LDirs := TDirectory.GetDirectories(AFolder, '*'); // Get all files. Non-Windows systems don't typically care about // extensions, so we just use a single '*' as a mask. LFiles := TDirectory.GetFiles(AFolder, '*'); for s in LDirs do lstItems.Items.Add(s + CONST_X); for s in LFiles do lstItems.Items.Add(s); Result := True; end; procedure TfmSelect.FormCreate(Sender: TObject); begin pnlDirectoryNotExist.Visible := False; end; procedure TfmSelect.lstItemsClick(Sender: TObject); var s: String; begin if lstItems.ItemIndex = -1 then Exit; if SameText(lstItems.Items[lstItems.ItemIndex], CONST_STRING_PARENT) then { Or we need to use global var for Parent } CD(TDirectory.GetParent(edtCurrentFolder.Text)) else begin s := lstItems.Items[lstItems.ItemIndex]; if s = EmptyStr then Exit; if s[s.Length - 1] = CONST_X then CD(s); end; end; procedure TfmSelect.btnRefreshClick(Sender: TObject); begin if edtCurrentFolder.Text <> EmptyStr then CD(edtCurrentFolder.Text) else CD(TPath.GetDocumentsPath); end; end.  
    Использование
    if fmSelect = nil then begin Application.CreateForm(TfmSelect, fmSelect); fmSelect.Callback := Yahoo; end; fmSelect.Show; fmSelect.CD(TPath.GetDocumentsPath); procedure TFormXX.Yahoo(ASelectedItem: String); begin ShowMessage(ASelectedItem); // end;
  3. Like
    Rusland отреагировална ENERGY в [Статья] Ищем самый быстрый парсер JSON в Delphi   
    Друзья, нашел тут интересную статью, где тестируются разные jSON парсеры.
     
    Ссылка: http://www.webdelphi.ru/2016/10/ishhem-samyj-bystryj-parser-json-v-delphi/
    Автор: Владислав Баженов
    Описание (26/10/2016):
     
  4. Like
    Rusland отреагировална kami в передача сообщений по локальной сети   
    В описании русским по экрану написано: " Классы-обертки над TClient|TServerSocket, работоспособны Delphi 2009 и выше "
  5. Like
    Rusland отреагировална kami в передача сообщений по локальной сети   
    Ну, из всех вопросов - важен только первый. Остальное уже есть неоднократно. Пропиарю себя: https://github.com/kami-soft/SimpleTCPComponents
  6. Like
    Rusland отреагировална Евгений Корепов в Прежде чем опубликовать APK-файл в Google Play, запретите его отладку   
    Как уже выше сказали нужно установить Билд конфигурацию - Release, и конфигурацию платформы - Application Store.
    Assertions не влияет, его можно оставить в любом состоянии, хотя среда по умолчанию его включает для релизной конфигурации:
    Assertions - Enables or disables the generation of code for assertions in a Delphi source file. The option is enabled (equivalent to {$C+}) by default. Since assertions are not usually used at run time in shipping versions of a product, compiler directives that disable the generation of code for assertions are provided. Deselect this option to disable assertions.
    Ошибка возникает когда в конфигурации платформы выставить "Development". На картинке выделено жирным

  7. Like
    Rusland отреагировална Равиль Зарипов (ZuBy) в Как узнать оригинальный размер картинки?   
    обратиться к Bitmap
    TImage.Bitmap.Width/Height
  8. Like
    Rusland отреагировална ENERGY в Проблема в реализации PBKDF2-SHA1 средствами INDY(TIdHMACSHA1)   
    Попробуйте  THashSHA1.GetHMACAsBytes из System.Hash.pas 
    Вообще мне больше нравятся System.Net компоненты вместо Indy.
     
     
    Ну и вдогонку 
    function OAuthEncryptHMACSha1(const aValue, aKey: string): string; begin   Result :=  TNetEncoding.Base64.EncodeBytesToString( THashSHA1.GetHMACAsBytes(aValue, aKey) ); end;  
  9. Like
    Rusland отреагировална Вадим Смоленский в ReplaceOpaqueColor   
    Похоже, никто не знает, что с этим делать. Пришлось мне опять прибегнуть к лобовому решению - попиксельно менять черный цвет на синий. Не очень элегантно, но надежно.
    Отмечу, что в случаях, когда монохромный битмэп не задействован, ReplaceOpaqueColor работает исправно и очень выручает.
  10. Like
    Rusland отреагировална Pax Beach в Убить поток TThread?   
    Посмотрите класс, реализующий альтернативный Sleep (под катом).
    соль в следующем:
    создаем потомка TThread, запускаем, ждем завершения:
    class function TDelays.Delay(aDuration: integer): TDelay; begin if not Assigned(FList) then FList := TList<TDelay>.Create; Result := TDelay.Create(aDuration); FList.Add(Result); Result.FreeOnTerminate := false; Result.OnTerminate := OnTerminateItem; Result.Start; Result.WaitFor; end; Работаем с ним нежно
    procedure TDelay.Execute; begin inherited; while (not Terminated) and (MilliSecondsBetween(now, FStart) < FDelay) do begin sleep(100); end; end; По завершении работы убиваем:
    class procedure TDelays.OnTerminateItem(Sender: TObject); begin TTask.Run( procedure begin try if Assigned((Sender as TDelay)) then begin (Sender as TDelay).Free; FList.Remove((Sender as TDelay)); end; except end; end); end; А можем убить и досрочно:
    (TObject as TDelay).Free; потому что в деструкторе стоит такой код:
    destructor TDelay.Destroy; begin Terminate; if (not Suspended) then WaitFor; inherited; end;  
    uDelays.zip
  11. Like
    Rusland отреагировална bigjorj в FastReport с поддержкой Tokyo и без кнопки печати   
    Знаете что действительно смешно? 
    То что мой тикет #415831 в вашей поддержке висит с 25 января 2017, 13:00
    И ни одна душа даже не попыталась на него среагировать. На кой черт я покупал спрашивается FMX версию.
    FMX версия вообще не работает со встроенными в отчет FDQuery. Не возможно указать параметры запроса, нельзя связать запросы. 
  12. Like
    Rusland отреагировална krapotkin в Полноэкранный режим редактора   
    ))
    ПКМ в окне редактора
    New Edit Window
    ?
  13. Like
    Rusland отреагировална Евгений Корепов в Полноэкранный режим редактора   
    Тоже не хватает такой функции, давно смирился... Сейчас модно использовать гей-дизайнерский подход - рабочая область не должна превышать по размерам пачку сигарет. Прошу прощения за резкие высказывания - бросаю курить и не люблю дизайнеров ;-)
  14. Like
    Rusland отреагировална Равиль Зарипов (ZuBy) в ItemAppearance Button click   
    вот так это делается
    LV_ClickEx.zip
  15. Like
    Rusland отреагировална Евгений Корепов в Пример с 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;  
  16. Like
    Rusland отреагировална Maximus в NetHTTPClient передача файла и OnReceiveData   
    В общем, я бы исправил так: добавил локальную переменную
    Abort: Boolean;  
    в TWinHTTPClient.DoExecuteRequest, до цикла передачи данных вызвал бы коллбек с объёмом файла, так же как происходит при загрузке файла на ПК - первый коллбек вызывается с нулевым объёмом переданных данных.
    LRequest.DoReceiveDataProgress(0, DataLength, 0, Abort);  
    В цикл добавил бы проверку на прекращение загрузки
    while (LRequest.FSourceStream.Position < LRequest.FSourceStream.Size) and (not Abort) do  
    В конце цикла вызывал бы коллбек с объёмом файла и количеством переданных байт.
    Первый параметр коллбека - StatusCode получить на данном этапе скорее всего нельзя, или я не понял как, поэтому передаю ноль.
    LRequest.DoReceiveDataProgress(0, DataLength, LRequest.FSourceStream.Position, Abort);  
    Полный текст исправленной функции.
     
  17. Like
    Rusland отреагировална Vitaldj в [FGX] Будет ли релиз FGX под Tokyo?   
    Ярослав! HTMLPanel в студию!!!!
  18. Like
    Rusland отреагировална Равиль Зарипов (ZuBy) в Почему в Берлине нет кнопки Apply   
    В Токио снова появилась кнопка Apply
  19. Like
    Rusland отреагировална Andrey Efimov в XE10.2 Tokyo есть запись вебинара от 28.03.2017?   
    Запись вебинара
  20. Like
    Rusland получил реакцию от ENERGY в Смещается заголовок формы на Android Intel   
    Мы все еще ждем рассказа )
  21. Like
    Rusland отреагировална Alex7wrt в [Статья][AdMob] Добавляем рекламный блок в приложение   
    http://www.tahribat.com/forum/android---delphi-xe7-firemonkey-admob-interstitial-204528
  22. Like
    Rusland отреагировална Brovin Yaroslav в [Форум]Последние сообщения - проблемы   
    Починил
  23. Like
    Rusland отреагировална kami в [Форум]Последние сообщения - проблемы   
    То, что "жирность" шрифта в этом блоке скачет как хочет - это, по большому счету, ерунда.
    Но вот то, что "последнее сообщение" в теме не соответствует реальному - это уже плохо.
    В качестве примера:
    1 - скрин главной страницы после нажатия Ctrl+F5 (полное обновление, минуя кеш)

    2 - скрин темы. Самое интересное - что цифра 4 на главной странице действительно соответствует количеству ответов в теме. Вот только последний - не от того пользователя.

  24. Like
    Rusland отреагировална Brovin Yaroslav в [TMultiView] Починили TMultiView.Enable в Tokyo   
    Моя работа  По просьбе трудящихся на этом форуме сделал эту задачу. А еще добавил настройки, чтобы можно было линию убирать.
  25. Like
    Rusland отреагировална Евгений Корепов в Окончательная точка в вопросе расчета высоты TListViewItem (TListItemText)   
    Наткнулся на еще один нюанс - подсчет высоты текста будет неверным для невидимого ListView. Т.е. если ListView еще не разу не был показан на экране (находится на другой форме, в другом табе), то AFontObject:=(AListView.FindStyleResource('font') as TFontObject) вернет хрен знает что. Для того чтоб заработало для еще невидимого ListView, необходимо перед добавлением Item, вернее перед AItem.Adapter.ResetView(AItem), выполнить ListView.ApplyStyleLookup;
    Добавлю в первую тему.
×
×
  • Создать...