Евгений Корепов
-
Постов
738 -
Зарегистрирован
-
Посещение
-
Победитель дней
100
Сообщения, опубликованные Евгений Корепов
-
-
'%3D' вместо "=", '%26' вместо "&" - это стандартная методика отправки данных, называется url encoding. Принимающая сторона производит обратный процесс url decoding. Это нормальный процесс экранирования спецсимволов для HTTP протокола.
Если вы не хотите использовать encoding (хотя в ContentType := 'application/x-www-form-urlencoded' вы утверждаете обратное), по используйте опцию poDoNotEncode в опциях параметра (http://docwiki.embarcadero.com/Libraries/Tokyo/en/REST.Types.TRESTRequestParameterOption)
А лучше используйте штатный THTTPClient (System.Net.HTTPClient) и будет счастье, потому как TRest, рожденный в недрах безумия Эмбы, преподнесет вам не мало неприятных сюрпризов.
-
-
4 часа назад, Александр Лукьянов (Filament Extruder 1.75) сказал:
Active возвращается в true
Если tcpserver1 на форму бросить и не создавать компонент то работает пример. Использую 10.1 berlin. Дома попробую 10.1 update 2 и отпишусь
Ну значит точно в биндинге дело, делайте вот так:
FIdTCPServer.Bindings.Clear; with FIdTCPServer.Bindings.Add do begin IP:='0.0.0.0'; Port:=ATCPPort; end;
-
Да, и следующим кодом
idTCPserver1.Bindings.Add.Port:=5000; idTCPserver1.Bindings.Add.IP:='0.0.0.0';
вы создаете серверу два интерфейса для прослушки, один с портом 5000 и не определенным адресом, второй с адресом 0.0.0.0 и не определенным портом.
-
Попробуйте проверять запустился ли сервер. К примеру так
function TForm.CreateTCPServer(Var ATCPPort : Word) : Boolean; begin Result:=False; FIdTCPServer:=TIdTCPServer.Create; FIdTCPServer.OnExecute:=IdTCPServerExecute; FIdTCPServer.OnConnect:=IdTCPServerConnect; FIdTCPServer.Bindings.Clear; with FIdTCPServer.Bindings.Add do begin IP:='0.0.0.0'; Port:=ATCPPort; end; try FIdTCPServer.Active:=True; except Result:=False; end; if FIdTCPServer.Active then Result:=True; end;
-
5 часов назад, Jose Medeiros сказал:
Спокойной ночи,
Где я могу скачать компоненты fgx для delphi tokyo 10.2.3?
признательна.
-
24 минуты назад, Alex7wrt сказал:
Да нет, таймер не походит. Нужен прямой подход.
Этот подход прямее некуда. Думаете как контролы генерируют событие OnMouseLeave (Enter)? Точно не посредством колдовства.
-
29 минут назад, Alex7wrt сказал:
Спасибо за совет, но это смахивает на костыль ))
И в каком событии проверять координаты?
Кстати, есть ли способ узнать координаты курсора мыши в пределах всей формы с учетом дочерних компонентов?
Проверяйте не в событии, а в таймере. Координаты в глобальной переменной Screen.MousePos
-
23 минуты назад, Alex7wrt сказал:
Добрый день
Столкнулся со следующей задачей, и пока не могу ее решить:
Есть заполненный ListBox, в общем случае он с вертикальной полосой прокрутки. Нужно отработать для него событие OnMouseLeave. Точнее говоря, нужно сделать так, чтобы, когда курсор мыши покидает его пределы, то делаем ListBox.Visible:=False.
Но дело в том, что, во-первых, событие OnMouseLeave в общем случае не сработает, так как в заполненном ListBox-е это событие перехватывается его дочерними элементами, а во вторых вертикальная полоса прокрутки не учитывается в событиях мыши ListBox-а. К тому же, даже если я сделаю какую-нибудь внешнюю рамку, и буду обрабатывать OnMouseLeave для нее, то все равно при быстром движении мыши событие не происходит.
Потому прошу подсказать оптимальный и надежный способ, как сделать ListBox невидимым, когда курсор мыши находится за его пределами.
Наверно этот вопрос относится к любому компоненту, который полностью заполнен по площади дочерними компонентами, и в комплекте со скролбоксом.
Таймер, эдак милисекунд на 200. И в нем проверять координаты мыши, дальше уже арифметика.
-
-
22 минуты назад, Barvin сказал:
Евгений Корепов, спасибо. И это всё, что нужно сделать?
Думаю да.
-
3 минуты назад, Barvin сказал:
При сабмите приложения на play market получаю такое сообщение. Подскажите что и где нужно поменять в опциях проекта? Спасибо.
Требования к целевому уровню API с августа 2018 г.
Предупреждение
Целевой уровень API для вашего приложения – 14. Чтобы обеспечить необходимую производительность и безопасность, целевой уровень API должен быть не ниже 26.
С августа 2018 года целевая версия новых приложений должна быть не менее Android 8.0 (API уровня 26).
С ноября 2018 года целевая версия обновляемых приложений должна быть не менее Android 8.0 (API уровня 26).Совет
Измените целевой уровень API для приложения.
Файл AndroidManifest.template.xml в папке проекта (это шаблон манифеста).
Строка:
<uses-sdk android:minSdkVersion="%minSdkVersion%" android:targetSdkVersion="%targetSdkVersion%" />
Если вы откомпилируете проект и посмотрите подготовленный средой файл манифеста в папке
\Android\Debug\AndroidManifest.xml
то увидите что приложение предназначено для API десятилетней давности:
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="14" />
Гугль от вас просит примерно такого
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="26" />
Измените шаблон AndroidManifest.template.xml:
<uses-sdk android:minSdkVersion="%minSdkVersion%" android:targetSdkVersion="26" />
-
Принцип работы такой:
- На форму кладете стандартный TImage
- Создаете экземпляр TGifPlayer
- Задаете свойство FGifPlayer.Image:=Image; где Image это лежащая на форме TImage
- Загружаете гифку FGifPlayer.LoadFromFile('D:\Embarcadero\Projects\ShareCode\FMX.GifUtils\GIF_Example.gif');
- Запускаем проигрывание гифки FGifPlayer.Play;
Вот код:
unit UnitFormMain; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.GifUtils, FMX.Objects; type TFormMain = class(TForm) Image: TImage; procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } FGifPlayer : TGifPlayer; end; var FormMain: TFormMain; implementation {$R *.fmx} procedure TFormMain.FormCreate(Sender: TObject); begin FGifPlayer:=TGifPlayer.Create(Self); FGifPlayer.Image:=Image; FGifPlayer.LoadFromFile('D:\Embarcadero\Projects\ShareCode\FMX.GifUtils\GIF_Example.gif'); FGifPlayer.Play; end; end.
Вот демо проект во вложении:
-
-
15 минут назад, Вадим Шавров сказал:
Вроде бы ошибок нет, а как правильно её вызывать?
ShareFile('storage/emulated/0/Documents/data.db', ???);
aFileName - это полный путь к файлу или только название "data.db'?
aComment - а это я вообще не понимаю для чего
Конечно полный путь, откуда иначе функция узнает какой файл отправлять?
AComment - комментарий, типа "Это файл №199 из такого то приложения, служит для того то". Но никто не заставляет вас его писать.
Перед тем как пробовать запускать, прочтите предупреждения компилятора, некоторые функции устарели или изменилось их местоположение. Исправьте код. После этого вызывайте как указали, но вместо знаков вопроса укажите пустую строку к примеру.
И убедитесь в существовании файла перед его отправкой.
-
Да, конечно. Что то из этих, лишнее уберите:
Androidapi.JNI.Webkit,
FMX.Platform.Android,
Androidapi.Helpers,
Androidapi.JNI.GraphicsContentViewText,
Androidapi.JNIBridge,
Androidapi.JNI.JavaTypes,
Androidapi.JNI.Net,
Androidapi.JNI.Os,
-
Вот так:
procedure ShareFile(aFileName, aComment : String); {$IFDEF ANDROID} var Intent : JIntent; uri : Jnet_Uri; AttachmentFile: JFile; S : String; {$ENDIF ANDROID} begin {$IFDEF ANDROID} Intent := TJIntent.Create; Intent.setAction(TJIntent.JavaClass.ACTION_SEND); Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK); S:=TPath.GetFileName(aFileName); Intent.putExtra(TJIntent.JavaClass.EXTRA_SUBJECT, StringToJString(aComment)); Intent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, StringToJString(aComment)); AttachmentFile := TJFile.JavaClass.init(StringToJString(aFileName)); Uri := TJnet_Uri.JavaClass.fromFile(AttachmentFile); Intent.putExtra(TJIntent.JavaClass.EXTRA_STREAM, TJParcelable.Wrap((Uri as ILocalObject).GetObjectID)); Intent.setType(StringToJString('text/plain')); // Intent.setDataAndType(StrToJURI('file:' + TPath.Combine(TPath.GetSharedDownloadsPath, 'picture.png')), StringToJString ('image/png')); SharedActivity.startActivity(Intent); {$ENDIF ANDROID} end;
Из давнего проекта, возможно нужно будет подправить согласно сообщениям компилятора.
P.S. И файл должен находится в общедоступной папке (к примеру TPath.GetSharedDocumentsPath)
-
10 минут назад, hippocamus сказал:
Добавляю ран-тайм в TVertScrollBox компоненты TLabel со свойством Align = Top
В первый раз всё в порядке, а после очистки контейнера и заливки новых TLabel порядок изменён:
если сначала было 1 2 3 4 5 6 7 8, то начиная со второго раза лейблы идут в таком порядке: 1 8 7 6 5 4 3 2.
Причём в TVertScrollBox.Content.Children они содержатся в правильном порядке. Не важно, добавляю ли я их через AddObject или через InsertObject.
Та же беда с добавлением чекбоксов в TExplorer.Решал удалением родительского компонента и созданием его заново каждый раз. Но хочется нормального решения.
Кроме Align = Top, установите еще свойство Top = 10000, что бы они добавлялись заведомо ниже всех существующий элементов. Если не устанавливать Top, то по умолчанию позиция у всех будет 0 и порядок элементов будет зависеть от погрешности вычислений Single.
-
Накидал вам пример с использование потокобезопасной очереди.
Логика работы такая - поток получает данные и заталкивает их в очередь, в главной форме, в таймере (можно изменить на OnIdle), проверяем очередь на наличие данных, если данные есть, то обрабатываем их.
Обратите внимание на процедуру создания очереди - FQueue:=TThreadedQueue<TRec_Data>.Create(100, 1000, 10); где первый параметр размер очереди (100), второй таймаут заталкивания данных в очередь (1000мс = 1сек), третьй таймаут вытаскивания из очереди (10 мс - маленький, чтоб таймер у нас не подвисал в ожидании).
Вот код проекта целиком
unit Unit1; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, System.Generics.Collections, IdTCPClient, IdGlobal, FMX.Controls.Presentation, FMX.ScrollBox, FMX.Memo; type TRec_Data = record Flag: array[0..20] of char; end; TMyThread = class(TThread) private Progress: string; Client : TIdTCPClient; FQueue : TThreadedQueue<TRec_Data>; protected procedure Execute; override; public constructor Create(const AQueue : TThreadedQueue<TRec_Data>); destructor Destroy; override; end; TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private declarations } FQueue : TThreadedQueue<TRec_Data>; FMyThread : TMyThread; Timer : TTimer; procedure OnTimer(Sender: TObject); public Memo1: TMemo; { Public declarations } end; var Form1: TForm1; implementation {$R *.fmx} procedure TForm1.FormCreate(Sender: TObject); begin FQueue:=TThreadedQueue<TRec_Data>.Create(100, 1000, 10); Timer:=TTimer.Create(Self); Timer.Interval:=100; Timer.OnTimer:=OnTimer; Timer.Enabled:=True; FMyThread:=TMyThread.Create(FQueue); FMyThread.Start; end; procedure TForm1.FormDestroy(Sender: TObject); begin if Assigned(FMyThread) then begin FMyThread.Terminate; FMyThread.WaitFor; FMyThread.Free end; if Assigned(Timer) then Timer.Free; if Assigned(FQueue) then FQueue.Free; end; procedure TForm1.OnTimer(Sender: TObject); Var ARec : TRec_Data; begin // while FQueue.PopItem(ARec) = TWaitResult.wrSignaled do или if FQueue.PopItem(ARec) = TWaitResult.wrSignaled then Form1.Memo1.Lines.Insert(0, ARec.Flag); end; constructor TMyThread.Create(const AQueue : TThreadedQueue<TRec_Data>); var Rec: TRec_Data; Buffer: TIdBytes; begin inherited Create(true); FQueue:=AQueue; Client := TIdTCPClient.Create(nil); Client.Host := '127.0.0.1'; Client.Port := 6000; Client.Connect; // Передаем данные if Client.Connected = True then begin Rec.Flag := 'addUser'; Buffer := RawToBytes(Rec, SizeOf(Rec)); Client.IOHandler.Write(Buffer); end; end; destructor TMyThread.Destroy; begin if Assigned(Client) then Client.Free; inherited; end; procedure TMyThread.Execute; var Rec: TRec_Data; Buffer: TIdBytes; begin while Not Terminated do begin if Client.Connected then begin Client.IOHandler.ReadBytes(Buffer, SizeOf(Rec)); BytesToRaw(Buffer, Rec, SizeOf(Rec)); Progress := Rec.Flag; // Synchronize(SetProgress); FQueue.PushItem(Rec); end else Client.Connect; TThread.Sleep(10); end; end; end.
Так же обратите внимание, я переписал ваш метод Execute на правильный. В вашей реализации, поток завершался при потере соединения.
-
Тут в процессе работы над одним проектом понадобилось узнать IP адрес устройства. Очень не хотелось включать дополнительные разрешения приложению. Думал ограничится одним "Доступ в Интернет".
Вот как это можно сделать:
С помощью TIdUDPServer посылаем широковещательное сообщение, с помощью того же TIdUDPServer сами получаем его и в ABinding узнаем с какого IP оно пришло. Таким образом мы узнаем IP адрес интерфейса с маршрутом по умолчанию.
Вот код, все просто:
unit Unit1; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, IdGlobal, IdSocketHandle, IdBaseComponent, IdComponent, IdUDPBase, IdUDPServer; const ConstUDPSendString = 'dfgb2hd3f6gbf'; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private { Private declarations } FUDPServer : TIdUDPServer; FMyIP : String; procedure OnUDPServerUDPRead(AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle); procedure GetMyIP; public { Public declarations } end; var Form1: TForm1; implementation {$R *.fmx} procedure TForm1.FormCreate(Sender: TObject); begin GetMyIP; end; procedure TForm1.GetMyIP; begin FMyIP:=''; FUDPServer:=TIdUDPServer.Create; FUDPServer.DefaultPort:=46734; FUDPServer.BroadcastEnabled:=True; FUDPServer.OnUDPRead:=OnUDPServerUDPRead; FUDPServer.Active:=True; FUDPServer.Broadcast(ConstUDPSendString, FUDPServer.DefaultPort); end; procedure TForm1.OnUDPServerUDPRead(AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle); begin AThread.Synchronize(AThread, procedure begin if BytesToString(AData).Equals(ConstUDPSendString) and FMyIP.IsEmpty then FMyIP:=ABinding.PeerIP; end ); end; end.
-
В 20.03.2018 в 11:07, kiz35196 сказал:
как включитьт её если у меня компонент не на форме,а создается через THTTPClient.create; ?
Var FIAsyncResult : IAsyncResult; procedure DoEndDownload(const ASyncResult: IAsyncResult); .... FHTTPClient:=THTTPClient.Create; FHTTPClient.ResponseTimeout:=FResponseTimeout; FHTTPClient.ConnectionTimeout:=FConnectionTimeout; FIAsyncResult:=FHTTPClient.BeginGet(DoEndDownload, 'https://.....'); procedure TServiceData.DoEndDownload(const ASyncResult: IAsyncResult); Var LAsyncHTTPResponse : IHTTPResponse; begin try LAsyncHTTPResponse:=THTTPClient.EndAsyncHTTP(AsyncResult); except on E:Exception do AErrorMessage:=E.Message; end; if Assigned(LAsyncHTTPResponse) then begin if LAsyncHTTPResponse.StatusCode = 200 then S:=LAsyncHTTPResponse.ContentAsString; ....
-
4 часа назад, YurMak сказал:
Здравствуйте, Евгений! Еще раз спасибо!
В очередной раз вернулся к разработке своего приложения, посмотрел Ваш пример, и возник целый ряд вопросов.
Не могли бы вы прокомментировать (расписать) Ваш пример. Новичку многое непонятно. Как заполняется ListView (и почему именно ListView, а не ListBox);
как изменить Стиль Item`а (мне, например, не нужно "чекить" его);
как заносятся данные в ItemDetail (мне, например, нужно выводить не дату создания файла, а ID Tag Mp3 файда, не размер его, а длительность в мин.сек (после обработки в соответсвенной процедуре);
в примере есть процедура:
procedure TFormMain.SpeedButton1Click(Sender: TObject);
Var ASelected : TArray<TFileManagerSelectedItem>;
begin
ASelected:=FileManager.GetSelected;
end;отвечающая, как я понял, за заполнение массива данными о содержании директории, но самой SpeedButton на форме я не нашел, начал тупить. Видимо оттого, что я привык работать по-старинке, отдельными методами, процедурами и функциями, а здесь нечтто новое для меня, оттого и непонятное.
Разъясните новичку. Думаю, и другим будет интересно.
С уважением!
Listview против ListBox - листбокс тут не подходит, он проще, но гораздо тяжеловеснее. В некоторые папки вы зайти не сможете, при использовании Листбокса. К примеру C:\Windows\System32, у меня там 4 тысячи файлов, и даже под винду для листбокса это будет тяжело. В TFileManager использование ListView не самое оптимальное (лучше использовать DynamicApperance), но на тот момент мне нужен был работающий менеджер и за пол часа
Все вопросы касаемые ListView - вне этой темы, просто изучите соответствующий раздел этого форума. Очень, очень, очень рекомендую упереться и понять как им пользоваться и как он работает. Владение ListView очень пригодится, особенно в мобильных платформах. Просто прочтите вдумчиво все темы в разделе ListView. Потраченное время окупится многократно.
Процедуру SpeedButton1Click(Sender: TObject) игнорируйте, просто класс TFileManager я писал для какого то своего проекта, и этот пример, в некоторых местах, просто куски бессмысленного кода...
-
3 часа назад, YurMak сказал:
Огромное спасибо!!!
Весьма необычное (для меня) решение, но, главное, работает и решает мою проблему.
Спасибо.
P.S. Можно еще обращаться с вопросами напрямую? (если дадите "координаты" (E-mail, Skype, Viber, Messenger...) куда писать).
Нет, напрямую не надо, форум - лучший способ, мало ли кому пригодится.
-
Держите готовый объект FileManager с демкой. Под все платформы (тестил на вин и андроиде)
AndroidTV
в Android
Опубликовано
Добавлю. Есть ТВ-приставки просто с андроидом, а есть приставки с AndroidTV. В первом случае никаких проблем не возникает. Во втором случае - Андрей Ефимов уже подсказал.
Если решите публиковать приложение для андроид тв, то вот ответ гугля мне: