Доска почета


Popular Content

Showing most liked content since 18.04.2017 Во всех областях

  1. 8 likes
    Для одного проекта писал такое пару месяцев назад, пользуйтесь.Под windows, при клике на сообщение, оно превращается в readonly TMemo - дабы можно было скопировать нужное из сообщения. При наличии URL в сообщении, сбоку появляется кнопка открыть - лучше ничего для открытия ссылок не придумал. Надо бы сделать диалог выбора для открытия одной из нескольких ссылок, но руки пока не доходят. Пощупать чат вживую можно в приложении https://play.google.com/store/apps/details?id=ru.flintnet.InternetAgent , для активации и загрузки примера чата отсканируйте приложением qr-код с страницы http://internetagent.flintnet.ru/ unit ChatBox; interface uses System.SysUtils, System.Classes, FMX.Types, FMX.Controls, FMX.Layouts,System.Types, FMX.StdCtrls,FMX.Edit,FMX.Memo,FMX.TextLayout,System.UITypes,FMX.Graphics,FMX.Objects, FMX.Effects,FMX.Styles.Objects; type TMessagePos = (msgLeft,msgRight); TEventText = procedure(PURL: String) of object; TChatBox = class(TVertScrollBox) private FTextLyout : TTextLayout; FLastMessageId : Integer; FMsgWidthPercentage : Integer; FOnURLButtonClick : TEventText; FCalloutLength : Single; FCalloutXRadius : Single; FCalloutYRadius : Single; FMessageFontSize : Single; FMemo : TMemo; procedure ButtonClick(Sender: TObject); procedure MyMsgContainerOnClick(Sender: TObject); procedure MyMsgContainerOnExit(Sender: TObject); function FCreateMsgBlock(AOwner: TComponent; PMessageId : Integer; PDate, PAutor, PMessage : String; PMessagePos : TMessagePos) : TLayout; function CalculateTextItemHeight(Sender: TObject) : Single; procedure LayoutResize(Sender: TObject); function ExtractURL(pString : String) : String; procedure Memo1ApplyStyleLookup(Sender: TObject); public property LastMessageId : Integer read FLastMessageId; property MsgWidthPercentage : Integer read FMsgWidthPercentage write FMsgWidthPercentage default 80; constructor Create(AOwner: TComponent); override; destructor Destroy; override; Procedure AddMessage(pMessageId : Integer; PDate, PAutor, PMessage : String; PMessagePos : TMessagePos); procedure ClearChildren(AChatBox: TChatBox); procedure ScrollBottomSmoothly; procedure ScrollBottom; published property OnURLButtonClick : TEventText read FonURLButtonClick write FonURLButtonClick; property CalloutLength : Single read FCalloutLength write FCalloutLength; property CalloutXRadius : Single read FCalloutXRadius write FCalloutXRadius; property CalloutYRadius : Single read FCalloutYRadius write FCalloutYRadius; property MessageFontSize : Single read FMessageFontSize write FMessageFontSize; end; TOpenChatBox = class(TChatBox); Procedure Register; implementation procedure Register; begin RegisterComponents('EKorepov', [TChatBox]); end; constructor TChatBox.Create(AOwner: TComponent); begin inherited create(Aowner); FLastMessageId:=-1; FTextLyout := TTextLayoutManager.DefaultTextLayout.Create; FMemo:=TMemo.Create(Aowner); FMemo.TextSettings.WordWrap:=True; FMemo.ReadOnly:=True; FMemo.Align:=TAlignLayout.Client; FMemo.OnExit:=MyMsgContainerOnExit; FMemo.OnApplyStyleLookup:=Memo1ApplyStyleLookup; FMemo.StyledSettings:=FMemo.StyledSettings-[TStyledSetting.Size]; With Self as TVertScrollBox do begin AniCalculations.Animation := True; AniCalculations.BoundsAnimation := True; AniCalculations.TouchTracking := [ttVertical]; end; end; destructor TChatBox.Destroy; begin FreeAndNil(FMemo); FreeAndNil(FTextLyout); inherited Destroy; end; procedure TChatBox.ScrollBottomSmoothly; begin AniCalculations.MouseWheel(0, ContentBounds.Height+5); end; procedure TChatBox.ScrollBottom; begin ScrollBy(0, -ContentBounds.Height); end; procedure TChatBox.ButtonClick(Sender: TObject); Var URL : String; begin URL:=TButton(Sender).HelpKeyword; if Assigned(FonURLButtonClick) then FonURLButtonClick(URL); end; procedure TChatBox.Memo1ApplyStyleLookup(Sender: TObject); begin end; procedure TChatBox.MyMsgContainerOnClick(Sender: TObject); begin FMemo.TextSettings:=TLabel(Sender).TextSettings; FMemo.Lines.Text:=TLabel(Sender).Text; TLabel(Sender).AddObject(FMemo); end; procedure TChatBox.MyMsgContainerOnExit(Sender: TObject); begin if (Sender is TMemo) then if Assigned(TMemo(Sender).Parent) then if (TMemo(Sender).Parent is TLabel) then TLabel(TMemo(Sender).Parent).RemoveObject(TMemo(Sender)); end; procedure TChatBox.ClearChildren(AChatBox: TChatBox); begin Assert(AChatBox <> nil); TOpenChatBox(AChatBox).Content.DeleteChildren; AChatBox.Repaint; end; function TChatBox.CalculateTextItemHeight(Sender: TObject) : Single; var Item: TLabel; begin Result:=0; if (Sender is TLabel) then begin Item := TLabel(Sender); FTextLyout.BeginUpdate; try FTextLyout.Text := Item.Text; FTextLyout.MaxSize := TPointF.Create(Item.Width-Item.Margins.Left-Item.Margins.Right-10, 1000); FTextLyout.Font := Item.Font; FTextLyout.WordWrap:= Item.WordWrap; FTextLyout.HorizontalAlign:= Item.TextSettings.HorzAlign; FTextLyout.VerticalAlign:= Item.TextSettings.VertAlign; finally FTextLyout.EndUpdate; end; Result:= FTextLyout.Height+10; end; end; procedure TChatBox.LayoutResize(Sender: TObject); Var Item : TLabel; CalloutRectangle : TCalloutRectangle; Layout : TLayout; I : Integer; begin Layout:=TLayout(Sender); for I := 0 to Layout.Children.Count-1 do begin If Layout.Children.Items[I] is TCalloutRectangle Then begin CalloutRectangle:=TCalloutRectangle(Layout.Children.Items[I]); Item:=TLabel(CalloutRectangle.Children.Items[0]); CalloutRectangle.Width:=(Layout.Width / 100) * FMsgWidthPercentage; Layout.Height:=CalculateTextItemHeight(Item); end; If Layout.Children.Items[I] is TButton Then begin TButton(Layout.Children.Items[I]).Width:=(Layout.Width / 100) * (100-FMsgWidthPercentage-5); end; end; end; Procedure TChatBox.AddMessage(pMessageId : Integer; PDate, PAutor, PMessage : String; PMessagePos : TMessagePos); Var lcLayout : TLayout; begin PDate:=Trim(PDate); PAutor:=Trim(PAutor); PMessage:=Trim(PMessage); FLastMessageId:=PMessageId; lcLayout:=FCreateMsgBlock((Self as TVertScrollBox), PMessageId, PDate, PAutor, PMessage, PMessagePos); Self.AddObject(lcLayout); end; function TChatBox.FCreateMsgBlock(AOwner: TComponent; PMessageId : Integer; PDate, PAutor, PMessage : String; PMessagePos : TMessagePos) : TLayout; Var lcLayout,lcLayout2 : TLayout; Item : TLabel; Button : TButton; CalloutRectangle : TCalloutRectangle; lcHeight : Single; URL : String; begin lcLayout:=TLayout.Create(AOwner); lcLayout.Tag:=pMessageId; lcLayout.Align:=TAlignLayout.Top; lcLayout.Width:=200; lcLayout.Position.X:=0; lcLayout.Position.Y:= ((AOwner as TVertScrollBox).ContentBounds.Height+10); lcLayout.Margins.Bottom:=10; CalloutRectangle:=TCalloutRectangle.Create(lcLayout); CalloutRectangle.XRadius:=FCalloutXRadius; CalloutRectangle.YRadius:=FCalloutYRadius; CalloutRectangle.CalloutWidth:=10; CalloutRectangle.CalloutOffset:=-3-FCalloutYRadius-CalloutRectangle.CalloutWidth; CalloutRectangle.Width:=((AOwner as TVertScrollBox).Width / 100) * FMsgWidthPercentage; CalloutRectangle.HitTest:=False; case PMessagePos of msgRight : begin CalloutRectangle.Align:=TAlignLayout.Right; CalloutRectangle.CalloutPosition:=TCalloutPosition.Right; CalloutRectangle.Padding.Right:=CalloutRectangle.CalloutLength+CalloutRectangle.XRadius; CalloutRectangle.Padding.Left:=CalloutRectangle.XRadius; end; msgLeft : begin CalloutRectangle.Align:=TAlignLayout.Left; CalloutRectangle.CalloutPosition:=TCalloutPosition.Left; CalloutRectangle.Padding.Left:=CalloutRectangle.CalloutLength+CalloutRectangle.XRadius; CalloutRectangle.Padding.Right:=CalloutRectangle.XRadius; end; end; CalloutRectangle.Padding.Top:=1; CalloutRectangle.Padding.Bottom:=1; lcLayout.AddObject(CalloutRectangle); Item:=TLabel.Create(CalloutRectangle); Item.TextSettings.Font.Size:=MessageFontSize; CalloutRectangle.AddObject(Item); Item.Align:=TAlignLayout.Client; {$IFDEF MSWINDOWS} Item.OnClick:=MyMsgContainerOnClick; {$ENDIF MSWINDOWS} Item.Text:=PDate+' '+PAutor+#10+PMessage; Item.HitTest:=True; Item.WordWrap:=True; lcHeight:=CalculateTextItemHeight(Item); lcLayout.Height:=lcHeight; URL:=ExtractURL(pMessage); Item.StyledSettings:=Item.StyledSettings- [TStyledSetting.Size,TStyledSetting.Style]; if Not URL.IsEmpty then begin lcLayout2:=TLayout.Create(lcLayout); lcLayout2.Align:=TAlignLayout.Client; lcLayout2.Margins.Left:=5; lcLayout2.Margins.Right:=5; lcLayout.AddObject(lcLayout2); Button:=TButton.Create(lcLayout2); Button.Text:='Открыть'; Button.Align:=TAlignLayout.Center; Button.HelpKeyword:=URL; Button.OnClick:=ButtonClick; lcLayout2.AddObject(Button); end; lcLayout.OnResize:=LayoutResize; Result:=lcLayout; end; function TChatBox.ExtractURL(pString : String) : String; Var S : String; begin Result:=''; if Not pString.Contains('http') then Exit; S:=pString.Substring(Pos('http',pString)-1); S:=S.Remove(S.IndexOfAny([' ',','])); Result:=S.TrimRight(['.']); end; end.
  2. 5 likes
    после долгих мучений нашёл проблему. баг в деплойменте. файл не деплоится если в имени файла есть символ подчёркивания _ ! почему я не проверил сразу т.к. почти все файлы аппликации содержат этот символ а то и два. я вообще-то и взял файл для проверки один из стандартных. но они проходят на ура а файлы которые идут в документс не проходят. спасибо всем кто помогал.
  3. 5 likes
    Я поступил проще - на Токио пока даже и не пробовал переходить... Берлин работает, как работает - устраивает. Пока Токио не допилят, пока об этом все не напишут, и пока не появится как минимум первый апдейт - даже и пробовать не буду. Политика Embarcadero мне понятна. Искренне надеюсь, что им хватит ума и бюджета на то, чтобы развивать продукт. Оставался и остаюсь приверженцем Delphi, и во многих случаях ему просто нет объективной замены/альтернативы. Но кидаться "в омут" (на каждую новую версию) - желания нет.
  4. 5 likes
    картинка из примера Загружаем её в BitmapListAnimation настройка BitmapListAnimation ну и не забываем BitmapListAnimation1.Enabled := true;
  5. 4 likes
    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
  6. 4 likes
    Добрый день! Коллеги, хочу озвучить одну из причин, из-за которой может возникать ситуация " Иногда бывает что при вставке пути в TPath, компонент его отображает некорректно" Дело в том, что существуют сокращения в представлении данных и не все из низ TPath понимает, вот с чем столкнулся: Есть команда 'c' - рисование кривой. не буду вдаваться в подробности, можно найти в интернете описание, скажу только то, что данная команда содержит 6 чисел. В идеале должно быть: сX1 X2 X3 X4 X5 X6 Но очень часто (например в иконках Material Design) можно встретить: c-1.1 0-1.99.9-1.99 2 И на этой строчке парсер TPath падает с ошибкой, так как пытается сконвертировать '-1.99.9' в число, что не верно. В реальности данная запись соответствует двум числам -1.99 и 0.9. Для обхода проблемы я загружаю SVG в рантайме, и сроку пропускаю через корректор: function CorrectSVG(const Value: String): String; var SB : TStringBuilder; I: Integer; C : Char; begin SB := TStringBuilder.Create; try I := 0; for C in Value do begin if C='.' then Inc(I) else if not CharInSet(C, ['0'..'9']) then I := 0; if I=2 then begin SB.Append(' 0.'); I := 0; end else SB.Append(C); end; Result := SB.ToString; finally FreeAndNil(SB); end; end;
  7. 4 likes
  8. 4 likes
    Под Android я делаю так. Вставляю изначально файл БД в Deploy. Потом вызываю при необходимости процедуру procedure TForm1.RefreshBD; { TODO -cKod : RefreshBD - обновление БД } var PackageName: JString; zip: TZipFile; begin // Отключаемся от базы FDConnection1.Connected := False; // Получаем имя apk файла PackageName := SharedActivityContext.getPackageResourcePath; if TFile.Exists(JStringToString(PackageName)) then begin // Удаляем старый файл базы TFile.Delete(TPath.GetHomePath + PathDelim + 'DBGK.db'); // Извлекаем новый файл базы zip := TZipFile.Create; zip.Open(JStringToString(PackageName), TZipMode.zmRead); zip.Extract('assets/internal/DBGK.db', TPath.GetDocumentsPath, False); zip.Close; zip.free; end; // Подключаемся к базе FDConnection1.Connected := True; end; Под iOS вставляю в ресурсы, потом вот так procedure TForm1.RefreshBD; { TODO -cKod : RefreshBD - обновление БД } begin // Отключаемся от базы FDConnection1.Connected := False; if FindResource(0, 'res_bd', PChar(RT_RCDATA)) <> 0 then rs_bd := TResourceStream.Create(0,'res_bd',PChar(RT_RCDATA)); if TFile.Exists(TPath.GetHomePath+PathDelim+'Documents'+PathDelim +'dbgkios.db') then begin TFile.Delete(TPath.GetHomePath+PathDelim+'Documents'+PathDelim +'dbgkios.db'); rs_bd.SaveToFile(TPath.GetHomePath+PathDelim+'Documents'+PathDelim +'dbgkios.db'); end else begin rs_bd.SaveToFile(TPath.GetHomePath+PathDelim+'Documents'+PathDelim +'dbgkios.db'); end; FDConnection1.Connected := True; end;
  9. 3 likes
    это не случайные символы. и создаете вы его сами, когда НАСЛЕДУЕТЕ master-форму для конкретных платформ и разрешений http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Using_FireMonkey_Views
  10. 3 likes
    Друзья, столкнулся с проблемой, описанной в посте Хочу предложить свое решение (может кому пригодится). Чтобы центр масштабирования был именно в центре объекта (в моем случае это 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
  11. 3 likes
    Подправил uChatBox.pas под себя, заменил TLabel на TText, теперь проблем с отрисовкой бордюра не наблюдаю. Добавил выделение заголовка и градиент в "облачка". ChatBox.zip
  12. 3 likes
    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; Типы звука можно посмотреть здесь
  13. 2 likes
    картинку желательно не загружать в базу а складывать в папку на сервере (и лучше всего сжать до нужных размеров) и в базу вписать лишь путь до файла вот мануалчик на пхп http://php.net/manual/ru/features.file-upload.post-method.php на delphi это просто составляем POST запрос aURL - путь до скрипта, который будет принимать файлы aFileName - полный путь до файла, который нужно отправить var aData: TMultipartFormData; aHTTP: THTTPClient; aResp: TStringStream; begin aResp := TStringStream.Create('', aEncoding); aData := TMultipartFormData.Create(); aHTTP := THTTPClient.Create; try try aData.AddFile('image', aFileName); // на php считываем по полю image aHTTP.Post(aURL, aData, aResp); Result := aResp.DataString; // тут скрипт должен что-то вернуть о успешном принятии except Result := TmyHTTPClient.ERROR_COMMON; // генерация своей ошибки, если что-то пошло не так end; finally FreeAndNil(aHTTP); FreeAndNil(aData); FreeAndNil(aResp); end;
  14. 2 likes
    Добрый день, Друзья! Помогите, пожалуйста, разобраться - в голове уже каша Как в Delphi можно реализовать обработку поступающих на устройство PUSH-уведомлений при выгруженном или свернутом приложении? При запущеном и активном приложении проблем нет - использую OnReceiveNotificationEvent(Sender: TObject; const ANotification: TPushServiceNotification) в связке с TNotificationCenter. Эта процедура у меня: 1. очищает все активные уведомления; 2. создает в TNotificationCenter последнее пришедшее, которое и отображается пользователю. Его обработчик мной реализован. "Проблемы" есть если приложение выгружено или свернуто... Есть 2 очень похожих сценария: Сценарий №1: Приложение выгружено из памяти. Приходит PUSH. Пользователь нажимает на него. Приложение запускается. OnReceiveNotificationEvent после запуска не отрабатывает. Как обработать событие - не знаю Сценарий №2: Приложение запущено, но свернуто. Приходит PUSH. Пользователь нажимает на него. Приложение становится активным. После этого отрабатывает OnReceiveNotificationEvent: очищаются уведомления и создается новое. Пользователю надо повторно на него нажать и тогда сработает обработчик. Вопрос: Как получить текст (или любое другое поле - не важно) ЭТОГО push-уведомления после запуска/вывода приложения из фона? Допущение: Если ЭТО уведомление (запустившее приложение) идентифицировать нельзя, то как можно понять, что запуск произведен именно по нажатию на push? Задача актуальна не только для Android, но и iOS. Буду ОЧЕНЬ БЛАГОДАРЕН за помощь!
  15. 2 likes
    да, T(Net)HTTPClient как раз и работает адекватно на всех платформах при запуске проверить функцией CheckInet, если нету доступа показать окно с прокси
  16. 2 likes
    о чем и речь, в стартере есть только win32 нужен trial. Он идет в версии Architect
  17. 2 likes
    По 1-му вопросу для MacOS: function CheckRunning: Boolean; var sl: TStringList; iCount: Integer; s: String; begin sl := TStringList.Create; try GetRunningAplications(sl); iCount := 0; for s in sl do if SameText(s, APP_BundleID) then // APP_BundleID - константа с BundleID приложения Inc(iCount); Exit(iCount < 2) finally sl.Free; end; end; procedure GetRunningAplications(AList: TStrings); var WorkSpace: NSWorkSpace; App: NSRunningApplicationEx; i: Integer; list: NSArray; begin WorkSpace := TNsWorkspace.Wrap(TNsWorkSpace.OCClass.SharedWorkspace); list := Workspace.runningApplications; if (list <> nil) and (list.count > 0) then begin for i := 0 to list.count-1 do begin App := TNSRunningApplicationEx.Wrap(list.objectAtIndex(i)); if App.bundleIdentifier <> nil then AList.Add(string(App.bundleIdentifier.UTF8String)) else AList.Add(String(App.executableURL.path.UTF8String)); end; end; end; Ответ на 3-ий вопрос сам уже долго ищу
  18. 2 likes
    чтобы прям кросс, думаю такой код подойдёт function StartGranted: boolean; // uses System.IOUtils begin Result := not TFile.Exists(TPath.Combine(TPath.GetDocumentsPath, 'IamStarted')); TFile.WriteAllText(TPath.Combine(TPath.GetDocumentsPath, 'IamStarted'), ''); end; в dpr пишем begin if StartGranted then begin Application.Initialize; Application.CreateForm(TForm2, Form2); Application.Run; end; end. ну и в дестрое главной формы procedure TForm2.FormDestroy(Sender: TObject); //uses System.IOUtils; begin TFile.Delete(TPath.Combine(TPath.GetDocumentsPath, 'IamStarted')); end; Но это не точно, может есть и аналог mutex'a в MacOS
  19. 2 likes
    Для Windows как и в VCL можно использовать Mutex-ы: // в dpr-е uses FMX.Forms, Winapi.Windows, ... {$R *.res} var MUT: THandle; begin MUT := OpenMutex(MUTEX_ALL_ACCESS, false, 'MySuperProgram'); if MUT <> 0 then Application.Terminate; if MUT = 0 then MUT := CreateMutex(nil, false, 'MySuperProgram'); Application.Initialize; ...
  20. 2 likes
    ага, посмотрел логом, думаю правильней будет так // ZuBy *** procedure TCustomWebBrowser.FormHandleCreated(const Sender: TObject; const Msg: TMessage); var WBService: IFMXWBService; begin if not(Sender.ClassNameIs('TCustomPopupForm')) then if not(csDesigning in ComponentState) and TPlatformServices.Current.SupportsPlatformService(IFMXWBService, WBService) then begin FWeb := WBService.CreateWebBrowser; FWeb.SetWebBrowserControl(Self); FWeb.UpdateContentFromControl; FWeb.URL := FURL; FWeb.Navigate; end; end; // *** ZuBy не реагировать на создание Попап окон, на формы это не влияет. Сильно не тестил, так что хз.
  21. 2 likes
    нет такой проблемы, ваш код у меня отработал так uses System.Net.HTTPClient; procedure TForm2.Button1Click(Sender: TObject); var aHttp: THTTPClient; aStr: TStringStream; begin aHttp := THTTPClient.Create; aStr := TStringStream.Create('', TEncoding.UTF8); try aHttp.Get('http://www.cbr.ru/', aStr); Memo1.text := aStr.DataString; finally aHttp.Free; aStr.Free; end; end;
  22. 2 likes
    Попробовал поработать с TPath. К сожалению он некорректно обрабатывает (точнее не обрабатывает) квадратичные кривые Безье. Ошибка как в Berlin'е так и в Tokyo: procedure TPathData.SetPathString(const Value: string); ...... 'Q', 'q': begin GetPointFromString(PathString, Pos); GetPointFromString(PathString, Pos); end; ..... Вроде как должно быть: procedure TPathData.SetPathString(const Value: string); ...... 'Q', 'q': begin QuadCurveTo(GetPointFromString(PathString, Pos), GetPointFromString(PathString, Pos)); end; Задумался: Отправлять Bugreport или нет?
  23. 2 likes
    // uses FMX.Platform var LocaleService: IFMXLocaleService; ... if TPlatformServices.Current.SupportsPlatformService(IFMXLocaleService, IInterface(LocaleService)) then Result := LocaleService.GetCurrentLangID; ...
  24. 2 likes
    https://msdn.microsoft.com/ru-ru/library/windows/desktop/dd318123(v=vs.85).aspx ?
  25. 2 likes
    TAndroidHelper.Context.getResources().getIdentifier( StringToJString('название картинки без расширения'), StringToJString('drawable'), TAndroidHelper.Context.getPackageName); Чтобы картинки отображались согласно скейлу девайса, нужно чтобы они были во всех вариациях ldpi; mdpi; hdpi; xhdpi и тд... Ну и деплоить их правильно!
  26. 2 likes
    Ломать не строить, здесь нет ни каких сложностей. TImageList содержит две коллекции Source и Destination. Удаляете из них Item`ы как из обычных коллекций TCollection с помощью методов Delete и Clear. В Source находятся сами изображения, в Destination ссылки на Source. Если удалите только из Source, то в нумерация изображений не поменяется и останутся пустые элементы, хотя расход памяти уменьшится. Если удалите только из Destination, то нумерация картинок съедет, и расход памяти почти не изменится. Каждый элемент Destination может содержать несколько ссылок на Source это коллекция Layers, из которой точно также можно удалять элементы.
  27. 2 likes
    Думаю будет полезно многим.Сам делал так же недавно в одном проекте,лучше этого метода тоже ничего не придумал.Да и svg оказался довольно годным форматом,который легко поддается манипуляциям. Вот так у меня выглядит:
  28. 2 likes
    procedure TForm1.FormCreate(Sender: TObject); begin ScrollBox.AniCalculations.Animation := True; ScrollBox.AniCalculations.BoundsAnimation := True; ScrollBox.AniCalculations.TouchTracking := [ttVertical, ttHorizontal]; end;
  29. 1 like
    То есть просто вы раньше не добавляли наклонную черту-разделитель между директорией и именем файла. Вот и вся загвоздка.
  30. 1 like
    Вот код, который вернёт путь к исполняемому файлу (тот, который деплоится в "Contents\MacOS\") function GetModuleFName(AModule: Cardinal): string; begin SetLength(Result, MAX_PATH); GetModuleFileName(AModule, @Result[1], MAX_PATH); SetLength(Result, StrLen(PChar(Result))); end; function GetModuleFolder: string; begin Result := IncludeTrailingPathDelimiter(ExtractFilePath(GetModuleFolder(HInstance))); end; :
  31. 1 like
    на билдере вроде так TPath::GetDocumentsPath() ну или вот так, чтобы уж наверняка System::IOutils::TPath::GetDocumentsPath()
  32. 1 like
    Привожу пример готового FMX приложения, которое рисует на форме с помощью интерфейса IDirect3DDevice9. В примере реализован вызов анонимного метода Present() интерфейса IDirect3DDevice9, имея ссылку на интерфейс и порядковый номер метода. Данная реализация пригодится при установке ловушек (Hooks). Вкратце, суть реализации такая: Объявляю процедурный тип нужного метода type TPresent9 = function(pSourceRect, pDestRect: PRect; hDestWindowOverride: HWND; pDirtyRegion: PRgnData): HResult of object; stdcall; Объявляю переменную этого типа var PPresent: TPresent9; begin ... IntRefToMethPtr(d3d9Dev, PPresent, 17); PPresent(nil, nil, DParametrs.D3DPP.hDeviceWindow, nil); Реализую процедуру получения метода интерфейса по номеру procedure IntRefToMethPtr(const IntRef; var MethPtr; MethNo: Integer); type TVtable = array [0 .. 999] of Pointer; PVtable = ^TVtable; PPVtable = ^PVtable; begin // QI=0, AddRef=1, Release=2, etc TMethod(MethPtr).Code := PPVtable(IntRef)^^[MethNo]; TMethod(MethPtr).Data := Pointer(IntRef); end; А теперь получаем метод интерфейса по его порядковому номеру и вызываем его IntRefToMethPtr(d3d9Dev, PPresent, 17); PPresent(nil, nil, DParametrs.D3DPP.hDeviceWindow, nil); Благодарю за оценку этого решения на StackOverflow. Скачать пример: D3DDemo.zip
  33. 1 like
    Огромное спасибо Равиль! Как хорошо что вы помогаете. Итак для тех кто не знает, в TListView есть режим DynamicAppearance , который позволяет добавлять предустановленные элементы - картинки, текст, GlyphButon. В хелпе написано что их может быть любое количество. Итак добавляем TListView, в панели Structure выбираем TListView > ItemAppearance > Item. В инспекторе объектов выбрать свойство Appearance и комбобоксе Dynamic Appearance. Рядом в инспекторе появится свойство Objects - нажать на него и там уже добавляем нужные поля. Там же можно переименовать поле, в AppearanceObjectName чтобы позже использовать в RunTime. У меня периодически на этих этапах вылетает Catastrophic Failure и среду приходится терминировать с диспетчера (Berlin Update 2). Дальше, жмем правой кнопкой мыши по ListView и выбираем Toggle Design Mode, где можно увидеть эти добавленные Custom поля и расставить их мышкой и указать выравнивание. Это имя затем можно использовать в Runtime, для картинки это индекс в ImageList, который нужно указать в ListView таким образом (за это еще раз спасибо Равилю! :), почему это сделали так неочевидно и почему это не указано в мануале, остается загадкой.. Для TImageObjectAppearance с именем Star - ListView1.Items.Add.Data['Star'] := Integer(1); Например заполняем список с картинками с индексами 0 и 1: procedure TForm5.FormShow(Sender: TObject); var I: Integer; begin for I := 0 to 9 do begin with ListView1.Items.Add do begin Text := 'Item ' + I.ToString; Data['Star'] := Integer(I mod 2 = 0); end; end; end; Переключаем с картинки с индексом 1 на 0 и наоборот. procedure TForm5.ListView1ItemClick(const Sender: TObject; const AItem: TListViewItem); begin AItem.Data['Star'] := AItem.Data['Star'].AsInteger xor 1; end ;
  34. 1 like
  35. 1 like
    The March winner of the Embarcadero Cool App Contest is the Mimix 3D Profile Scanner by intricad. I looked at this app a few years ago, and found it pretty impressive then. It uses a really cool technique to capture a 3D impression with only your monitor and a standard webcam. Mimix 3D Profile Scanner Personal allows you to make 3D impressions using your webcam and PC monitor screen. mimix 3D Profile Scanner Personal uses a set of 4 black and white patterns which are projected by your computer screen while your camera captures the images of your face in front of the screen. The images are then processed to reveal a 3D impression. Under proper lighting conditions mimix 3D can capture scenes and objects with incredible detail recovery. The trick is to be in a very dark room, and have a good webcam and bright screen. After the scan you can create cool effects by relighting the scene or 3D print your impression. It is built for Windows using Delphi, VCL, TMS Components, Eurekalog and ShellBrowser. Check out the video or download the free scanner for yourself! [YoutubeButton url='https://youtu.be/3L7TjscXpCI'] Be sure to enter you cool app for a chance to win a $500 gift card. New winners every month! Просмотр полной статьи
  36. 1 like
    что за версия и как определили что нет? мобильная разработка только для Enterprise и Architect может это VCL проект?
  37. 1 like
    Спасибо большое! На Билдере получилось так: #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 надо как-то уничтожать. Хотя, это интерфейс…
  38. 1 like
    задать функцию от времени например если v(t)= const, то v постоянна на любом участке. если v(t) = const + sin(t * coeff ) * amplitude то скорость меняется как вам нужно. остается подобрать coeff и amplitude для нахождения x и y будет менее тривиальная формула, но можно вычислить а еще эта функциональность задается свойствами AnimationType и Interpolation можно посмотреть в исходниках, как там вычисляется Position
  39. 1 like
  40. 1 like
    Я про это говорю ещё с первого Berlina. См При этом такой проблемы я не увидел на Win10
  41. 1 like
    Для Android лучше Berlin использовать с последним Update 2. На Tokyo Android глючный и тормозит, фактически программы получаются не юзабельные, для Tokyo лучше подождать обновления. Все детали на форуме эбмаркадеры.
  42. 1 like
    В общем вот работающий костыль, который полностью убирает полосы. 2 Timage лежат на TLayout. Если после каждого поворота менять высоту Tlayout на 0,001 туда-обратно, то полос нет. На глаз никакого движения не заметно. Жмем по FloatAnimation и выбираем событие OnProcess. Далее procedure TfrmSplash.FloatAnimation1Process(Sender: TObject); begin {$IFDEF MSWINDOWS} if Layout1.Height > fNormHeight then Layout1.Height := Layout1.Height - 0.001 else Layout1.Height := Layout1.Height + 0.001; {$ENDIF} end; procedure TfrmSplash.FormCreate(Sender: TObject); begin fNormHeight := Layout1.Height; end;
  43. 1 like
  44. 1 like
    Не надо мне объяснять, что iOs хранит файлы приложения в спец директории приложения. Это я прекрасно знаю. Я тебе о другом. В xcode можно выгрузить твою программу обратно. Делается это тут: Нажимаешь download container И получает директорию вида: название программы 2017-04-19 14:20.56.557.xcappdata Лезешь в нее простым totall comm и смотрит директорию для документов: Documents . У меня лично пробные файлы задеплоитманные до этого оказались там где нужно. Я указал, как и советовал Ярослав: Указываешь путь startup\documents
  45. 1 like
    а то что на картинке, реализуется в 2 строки именно так как вы и предположили
  46. 1 like
  47. 1 like
  48. 1 like
    у гансмокера есть старая статья про глобалки и использование интерфейса там ни добавить ни убавить для курсовой пойдет любой хоррор-стайл программирования если начать нормально работать, то это всегда выливается в жутчайшую кашу из г""на и палок костылей. такой код непереносим, немасштабируем, нетестируем, нечитаем, неподдерживаем
  49. 1 like
    deadlock? - легко: TCriticalSection *cs = new TCriticalSection(); cs->Enter(); cs->Enter();
  50. 1 like
    Спасибо большое, вроде нарисовалось. Судя по вашим ответам, вы большой спец в этой области. не могли бы посоветовать хорошую книгу или другие источники по программированию для андроид на последних Делфи. А то приходится тыкаться как слепой котенок (Делфи 7, на котором раньше программировал, сильно отличается от ХЕ8) спец) он один из разработчиков Firemonkey ну тогда особое уважение: работать и находить время на общение со слепыми котятами типа меня - это ж какая сила воли нужна
This leaderboard is set to Москва/GMT+03:00