I am having one Delphi XE2 Project to display scrolling text (better "Marquee Text").
In my project I am having Timer1, Timer2, Button1, Button2, Label1 and Label2.
My object is to display some left scrolling text on Label1 after Button1.Click using Timer1 and some right scrolling text on Label2 after Button1.Click using Timer2.
I have defined the following codes:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
Button2: TButton;
Timer1: TTimer;
Timer2: TTimer;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure Timer2Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Timer1.Enabled := true;
Timer2.Enabled := true;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Timer1.Enabled := false;
Timer2.Enabled := false;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Timer1.Interval := 100;
Timer2.Interval := 100;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
const
{$WRITEABLECONST ON}
ScrollingText : string = 'This is left scrolling text ';
{$WRITEABLECONST OFF}
var
ScrollPosition: Integer;
begin
Label1.Caption := ScrollingText;
for ScrollPosition := 1 to (Length(ScrollingText) - 1) do
begin
ScrollingText[ScrollPosition] := Label1.Caption[ScrollPosition + 1];
ScrollingText[Length(ScrollingText)] := Label1.Caption[1];
end;
end;
procedure TForm1.Timer2Timer(Sender: TObject);
const
{$WRITEABLECONST ON}
ScrollingText : string = 'This is right scrolling text ';
{$WRITEABLECONST OFF}
var
ScrollPosition: Integer;
begin
Label2.Caption := ScrollingText;
for ScrollPosition := (Length(ScrollingText) - 1) to 1 do
begin
ScrollingText[ScrollPosition] := Label2.Caption[ScrollPosition - 1];
ScrollingText[Length(ScrollingText)] := Label2.Caption[1];
end;
end;
end.
My problem is that Left Scrolling is happening using Timer1 but Right Scrolling is not happening using Timer2.
The for loop in Timer2Timer should run down instead of up:
procedure TForm1.Timer2Timer(Sender: TObject);
const
{$WRITEABLECONST ON}
ScrollingText : string = 'This is right scrolling text ';
{$WRITEABLECONST OFF}
var
ScrollPosition: Integer;
begin
Label2.Caption := ScrollingText;
for ScrollPosition := (Length(ScrollingText) - 1) downto 2 do
begin
ScrollingText[ScrollPosition] := Label2.Caption[ScrollPosition - 1];
ScrollingText[1] := Label2.Caption[Length(ScrollingText) - 1];
end;
end;
But I suggest not using writeable const nor using the for loop at all:
procedure TForm1.FormCreate(Sender: TObject);
begin
...
Label2.Caption := 'This is right scrolling text ';
end;
procedure TForm1.Timer2Timer(Sender: TObject);
var
S: String;
begin
S := Label2.Caption;
S := S[Length(S)] + Copy(S, 1, Length(S) - 1);
Label2.Caption := S;
end;
Related
I am new to Delphi. I would like to know, is there any way to add any Caption or Text inserted/created by the user in a Form to a StringGrid automatically?
For example, using for a simple translator VCL, the Form detects a Button added and the Caption of this new Button automatically appears in the StringGrid to go for the translating process.
unit frmTranslation_u;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons, Vcl.ExtCtrls,
Vcl.Grids;
type
TfrmTranslation = class(TForm)
pnlPersonalInformation: TPanel;
lblFirstName: TLabel;
lblSureName: TLabel;
edtFirstName: TEdit;
edtSurName: TEdit;
pnlAction: TPanel;
btnEnglish: TButton;
btnAfrikaans: TButton;
btnDisplay: TButton;
bmbReset: TBitBtn;
bmbClose: TBitBtn;
memResult: TMemo;
sgdData: TStringGrid;
procedure btnAfrikaansClick(Sender: TObject);
procedure btnEnglishClick(Sender: TObject);
procedure btnDisplayClick(Sender: TObject);
procedure bmbResetClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure sgdDataClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frmTranslation: TfrmTranslation;
implementation
{$R *.dfm}
procedure TfrmTranslation.bmbResetClick(Sender: TObject);
begin
// Clear the edit
edtFirstName.Clear;
edtSurName.Clear;
// Clear The memo
memResult.Clear;
// Shift the focus to the first name edit
edtFirstName.SetFocus;
end;
procedure TfrmTranslation.btnAfrikaansClick(Sender: TObject);
begin
lblFirstName.Caption := 'Noemnaam';
lblSureName.Caption := 'Van';
frmTranslation.Caption := 'Vertaling';
lblFirstName.Left := 32;
lblSureName.Left := 80;
btnAfrikaans.Enabled := False ;
btnEnglish.Enabled := true;
end;
procedure TfrmTranslation.btnDisplayClick(Sender: TObject);
begin
// show the full name in the memo
memResult.Lines.Add('You Added '+edtFirstName.Text +' '+ edtSurName.Text);
end;
procedure TfrmTranslation.btnEnglishClick(Sender: TObject);
begin
lblFirstName.Caption := 'First Name';
lblSureName.Caption := 'Surname';
frmTranslation.Caption := 'translation';
lblFirstName.Left := 40 ;
lblSureName.Left := 50 ;
btnEnglish.Enabled := false ;
btnAfrikaans.Enabled := true ;
end;
procedure TfrmTranslation.FormCreate(Sender: TObject);
var
i, iCol, iRow : integer ;
begin
sgdData.Cells[0,0] := 'NAME';
sgdData.Cells[1,0] := 'TYPE';
sgdData.Cells[2,0] := 'Id_LAN';
sgdData.Cells[3,0] := 'VALUE';
end;
procedure TfrmTranslation.sgdDataClick(Sender: TObject);
begin
end;
end.
I am testing how to spin image in Delphi (on Android). For some reason it works only if I move two fingers on the screen. And the rotation isn't smooth. Ideally on-clik on the image with one finger I would like to have the image spinning until it's stopped by another click. Also, is there a better more Delphi like way to achieve this? I have this code (RAD Delphi 10.4):
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Objects,
FMX.Colors, System.IOUtils, FMX.Gestures, System.Math, FMX.Media;
type
TForm1 = class(TForm)
ColorBox1: TColorBox;
ColorBox2: TColorBox;
ColorBox3: TColorBox;
ColorBox4: TColorBox;
ColorBox5: TColorBox;
ColorBox6: TColorBox;
Image1: TImage;
GestureManager1: TGestureManager;
MediaPlayer1: TMediaPlayer;
procedure ColorBox1Click(Sender: TObject);
procedure ColorBox2Click(Sender: TObject);
procedure ColorBox3Click(Sender: TObject);
procedure ColorBox4Click(Sender: TObject);
procedure ColorBox5Click(Sender: TObject);
procedure ColorBox6Click(Sender: TObject);
procedure Image1Gesture(Sender: TObject; const EventInfo: TGestureEventInfo;
var Handled: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
{$R *.LgXhdpiPh.fmx ANDROID}
procedure TForm1.ColorBox1Click(Sender: TObject);
var
number: Integer;
stop: Boolean;
begin
//Image1.Bitmap.LoadFromFile('../../images/black.png')
Image1.Bitmap.LoadFromFile(TPath.GetDocumentsPath + PathDelim + 'black.png');
MediaPlayer1.FileName := TPath.Combine(TPath.GetDocumentsPath, 'spinner.3gp');
MediaPlayer1.Play;
end;
procedure TForm1.ColorBox2Click(Sender: TObject);
begin
//Image1.Bitmap.LoadFromFile('../../images/blue.png')
Image1.Bitmap.LoadFromFile(TPath.GetDocumentsPath + PathDelim + 'blue.png');
end;
procedure TForm1.ColorBox3Click(Sender: TObject);
begin
//Image1.Bitmap.LoadFromFile('../../images/red.png')
Image1.Bitmap.LoadFromFile(TPath.GetDocumentsPath + PathDelim + 'red.png');
end;
procedure TForm1.ColorBox4Click(Sender: TObject);
begin
//Image1.Bitmap.LoadFromFile('../../images/green.png')
Image1.Bitmap.LoadFromFile(TPath.GetDocumentsPath + PathDelim + 'green.png');
end;
procedure TForm1.ColorBox5Click(Sender: TObject);
begin
//Image1.Bitmap.LoadFromFile('../../images/yellow.png')
Image1.Bitmap.LoadFromFile(TPath.GetDocumentsPath + PathDelim + 'yellow.png');
end;
procedure TForm1.ColorBox6Click(Sender: TObject);
begin
//Image1.Bitmap.LoadFromFile('../../images/pink.png')
Image1.Bitmap.LoadFromFile(TPath.GetDocumentsPath + PathDelim + 'pink.png');
end;
procedure TForm1.Image1Gesture(Sender: TObject;
const EventInfo: TGestureEventInfo; var Handled: Boolean);
var
LObj: IControl;
image: TImage;
begin
LObj := Self.ObjectAtPoint(ClientToScreen(EventInfo.Location));
if LObj is TImage then
begin
image := TImage(LObj.GetObject);
image.RotationAngle := RadToDeg(-EventInfo.Angle);
end;
end;
end.
It's better to use TImage's OnClick event instead of Gesture, I suppose.
const
RotationDelta = 0.5;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
Timer1.Enabled := false; //to disable rotation
Timer1.Interval := 20;
end;
procedure TForm1.Image1Click(Sender: TObject);
begin
Timer1.Enabled := not Timer1.Enabled; //Timer.Interval should be 20-30 ms
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Image1.RotationAngle := Image1.RotationAngle + RotationDelta; //rotate image
end;
It's not very good implementation because TTimer is not very acurate, but it's good enough for general purpose. If you want slower or faster rotating you should change RotationDelta respectively.
But my advice will only work if you want to enable/disable rotation by clicking image, not while sliding.
P.S. Checked this solution on Delphi 10.1, but on Windows only.
i need help to speedup my project,i have 2 ListBoxs, the first is full with URLs, the second i store in it the URLs that causes 404 error from Listbox1, its just checking process. the idhttp takes about 2s to check 1 url, i dont need the html, cause the decryption process takes time, So i decided to add threads in my project, my code so far
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
IdSSLOpenSSL, Vcl.StdCtrls, IdBaseComponent, IdComponent,
IdTCPConnection, IdTCPClient, IdHTTP;
type
TForm1 = class(TForm)
IdHTTP1: TIdHTTP;
Button1: TButton;
ListBox1: TListBox;
ListBox2: TListBox;
Button3: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
public
end;
Type
TMyThread = class(TThread)
IdHTTP1: TIdHTTP;
Button1: TButton;
ListBox1: TListBox;
ListBox2: TListBox;
Button3: TButton;
Memo1: TMemo;
private
fStatusText : string;
lHTTP: TIdHTTP;
protected
procedure Execute; override;
public
Constructor Create(CreateSuspended : boolean);
end;
var
Form1: TForm1;
procedure TForm1.Button3Click(Sender: TObject);
var
MyThread : TMyThread;
begin
MyThread := TMyThread.Create(True);
MyThread.Start;
end;
constructor TMyThread.Create(CreateSuspended : boolean);
var
s: string;
IdSSL : TIdSSLIOHandlerSocketOpenSSL;
begin
FreeOnTerminate := True;
inherited Create(CreateSuspended);
lHTTP := TIdHTTP.Create(nil);
IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
lHTTP.ReadTimeout := 30000;
lHTTP.IOHandler := IdSSL;
IdSSL.SSLOptions.Method := sslvTLSv1;
IdSSL.SSLOptions.Method := sslvTLSv1;
IdSSL.SSLOptions.Mode := sslmUnassigned;
lHTTP.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(lHTTP);
lHTTP.HandleRedirects := True;
finally
end;
end;
destructor TMyThread.Destroy;
begin
inherited;
end;
procedure TMyThread.Execute;
var
s: string;
i: Integer;
satir: Integer;
str: TStringList;
newStatus : string;
begin
fStatusText := 'TMyThread Starting...';
Synchronize(Showstatus);
fStatusText := 'TMyThread Running...';
while (not Terminated) do
begin
for i:= 0 to satir-1 do
begin
try
lHTTP.Get('http://website.com/'+ListBox1.Items.Strings[i]);
Memo1.Lines.Add(ListBox1.Items[i])
except
on E: EIdHTTPProtocolException do
begin
if E.ErrorCode <> 404 then
raise;
ListBox2.Items.Add(ListBox1.Items[i]);
end;
end;
end;
end;
if NewStatus <> fStatusText then
begin
fStatusText := newStatus;
Synchronize(Showstatus);
end;
end;
procedure TMyThread.ShowStatus;
begin
Form1.Caption := fStatusText;
end;
end.
now when i hit button3 the Form caption goes TMyThread is Starting... and nothing happens after!, please have a look at the codes, Many thanks.
You should be using a separate thread for each URL, not using a single thread
that loops through all of the URLs.
Try something more like this instead:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
ListBox1: TListBox;
ListBox2: TListBox;
Button3: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
procedure MyThreadPathResult(const APath: string; AResult: Boolean);
procedure MyThreadStatus(const AStr: string);
end;
var
Form1: TForm1;
implementation
uses
IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, IdSSLOpenSSL;
type
TMyThreadPathResultEvent = procedure(const APath: string; AResult: Boolean) of object;
TMyThreadStatusEvent = procedure(const APath, AStr: string) of object;
TMyThread = class(TThread)
private
fPath: string;
fOnPathResult: TMyThreadPathResultEvent;
fOnStatus: TMyThreadStatusEvent;
procedure PathResult(AResult: Boolean);
procedure ShowStatus(const Str: string);
protected
procedure Execute; override;
public
constructor Create(const APath: string); reintroduce;
property OnPathResult: TMyThreadPathResultEvent read fOnPathResult write fOnPathResult;
property OnStatus: TMyThreadStatusEvent read fOnStatus write fOnStatus;
end;
procedure TForm1.Button3Click(Sender: TObject);
var
i: Integer;
Thread: TMyThread;
begin
for i := 0 to ListBox1.Items.Count-1 do
begin
Thread := TMyThread.Create(ListBox1.Items.Strings[i]);
Thread.OnPathResult := MyThreadPathResult;
Thread.OnStatus := MyThreadStatus;
Thread.Start;
end;
end;
procedure TForm1.MyThreadPathResult(const APath: string; AResult: Boolean);
begin
if AResult then
Memo1.Lines.Add(APath)
else
ListBox2.Items.Add(APath);
end;
procedure TForm1.MyThreadStatus(const AStr: string);
begin
Caption := AStr;
end;
constructor TMyThread.Create(const APath: string);
begin
inherited Create(True);
FreeOnTerminate := True;
fPath := APath;
end;
procedure TMyThread.Execute;
var
lHTTP: TIdHTTP;
IdSSL: TIdSSLIOHandlerSocketOpenSSL;
begin
ShowStatus('TMyThread Starting...');
lHTTP := TIdHTTP.Create(nil);
try
lHTTP.ReadTimeout := 30000;
lHTTP.HandleRedirects := True;
IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(lHTTP);
IdSSL.SSLOptions.Method := sslvTLSv1;
IdSSL.SSLOptions.Mode := sslmClient;
lHTTP.IOHandler := IdSSL;
ShowStatus('TMyThread Running...');
try
lHTTP.Get('http://website.com/'+fPath, TStream(nil));
except
on E: EIdHTTPProtocolException do
begin
if E.ErrorCode = 404 then
PathResult(False)
else
raise;
end;
end;
finally
lHttp.Free;
end;
PathResult(True);
end;
procedure TMyThread.PathResult(AResult: Boolean);
begin
if Assigned(fOnPathResult) then
begin
TThread.Synchronize(
procedure
begin
if Assigned(fOnPathResult) then
fOnPathResult(fPath, AResult);
end
);
end;
end;
procedure TMyThread.ShowStatus(const Str: string);
begin
if Assigned(fOnStatus) then
begin
TThread.Synchronize(
procedure
begin
if Assigned(fOnStatus) then
fOnStatus(fPath, Str);
end
);
end;
end;
end.
With that said, you could consider using Delphi's Parallel Programming Library instead:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
ListBox1: TListBox;
ListBox2: TListBox;
Button3: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
uses
System.Threading, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, IdSSLOpenSSL;
procedure TForm1.Button3Click(Sender: TObject);
begin
TParallel.&For(0, ListBox1.Items.Count-1,
procedure(AIndex: Integer)
var
lPath: string;
lHTTP: TIdHTTP;
IdSSL: TIdSSLIOHandlerSocketOpenSSL;
begin
TThread.Synchronize(nil,
procedure
begin
Form1.Caption := 'Task Starting...';
lPath := ListBox1.Items.Strings[AIndex];
end;
end;
lHTTP := TIdHTTP.Create(nil);
try
lHTTP.ReadTimeout := 30000;
lHTTP.HandleRedirects := True;
IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(lHTTP);
IdSSL.SSLOptions.Method := sslvTLSv1;
IdSSL.SSLOptions.Mode := sslmClient;
lHTTP.IOHandler := IdSSL;
TThread.Synchronize(nil,
procedure
begin
Form1.Caption := 'Task Running...';
end;
end;
try
lHTTP.Get('http://website.com/'+lPath, TStream(nil));
except
on E: EIdHTTPProtocolException do
begin
if E.ErrorCode = 404 then
begin
TThread.Synchronize(nil,
procedure
begin
Form1.ListBox2.Items.Add(lPath);
end
);
end;
Exit;
end;
end;
finally
lHttp.Free;
end;
TThread.Synchronize(nil,
procedure
begin
Form1.Memo1.Lines.Add(lPath);
end
);
end
);
end;
end.
Or:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
ListBox1: TListBox;
ListBox2: TListBox;
Button3: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
uses
System.Threading, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, IdSSLOpenSSL;
procedure TForm1.Button3Click(Sender: TObject);
var
i: Integer;
lPath: string;
begin
for i := 0 to ListBox1.Items.Count-1 do
begin
lPath := ListBox1.Items.Strings[i];
TTask.Create(
procedure
var
lHTTP: TIdHTTP;
IdSSL: TIdSSLIOHandlerSocketOpenSSL;
begin
TThread.Synchronize(nil,
procedure
begin
Form1.Caption := 'Task Starting...';
end;
end;
lHTTP := TIdHTTP.Create(nil);
try
lHTTP.ReadTimeout := 30000;
lHTTP.HandleRedirects := True;
IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(lHTTP);
IdSSL.SSLOptions.Method := sslvTLSv1;
IdSSL.SSLOptions.Mode := sslmClient;
lHTTP.IOHandler := IdSSL;
TThread.Synchronize(nil,
procedure
begin
Form1.Caption := 'Task Running...';
end;
end;
try
lHTTP.Get('http://website.com/'+lPath, TStream(nil));
except
on E: EIdHTTPProtocolException do
begin
if E.ErrorCode = 404 then
begin
TThread.Synchronize(nil,
procedure
begin
Form1.ListBox2.Items.Add(lPath);
end
);
end;
Exit;
end;
end;
finally
lHttp.Free;
end;
TThread.Synchronize(nil,
procedure
begin
Form1.Memo1.Lines.Add(lPath);
end
);
end
).Start;
end;
end;
end.
My Code for video recording is given, the recording is not in a smooth way i.e. the place where I turn my camera appears on the preview view late. How I can resolve this issue
unit VideoAttachmentUnit;
interface
uses
System.SysUtils,
System.Types,
System.UITypes,
System.Classes,
System.Variants,
FMX.Types,
FMX.Controls,
FMX.Forms,
FMX.Dialogs,
FMX.StdCtrls,
FMX.Media,
FMX.Platform,
FMX.Objects,
FMX.Layouts,
FMX.Memo,
FMX.Controls.Presentation;
type
TVideoAttachmentForm = class(TForm)
NavBar: TToolBar;
CameraChangeBtn: TButton;
PlayBtn: TButton;
CloseScreenBtn: TButton;
ToolBar1: TToolBar;
StartRecordingBtn: TButton;
StopRecordingBtn: TButton;
ImageCameraView: TImage;
CameraComponent: TCameraComponent;
procedure FormCreate(Sender: TObject);
procedure CloseScreenBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure CameraChangeBtnClick(Sender: TObject);
procedure StartRecordingBtnClick(Sender: TObject);
procedure StopRecordingBtnClick(Sender: TObject);
procedure CameraComponentSampleBufferReady(Sender: TObject;
const ATime: TMediaTime);
private
{ Private declarations }
procedure GetImage;
procedure InitialSettingsForTheRecording;
public
function AppEvent(AAppEvent: TApplicationEvent; AContext: TObject): Boolean;
end;
var
VideoAttachmentForm: TVideoAttachmentForm;
WhichCamera:String;
procedure DisplayTheVideoAttachmentScreen;
implementation
{$R *.fmx}
procedure DisplayTheVideoAttachmentScreen;
begin
try
Application.CreateForm(TVideoAttachmentForm , VideoAttachmentForm);
VideoAttachmentForm.Show;
finally
end;
end;
procedure TVideoAttachmentForm.CameraChangeBtnClick(Sender: TObject);
var
LActive: Boolean;
begin
{ Select Back Camera }
LActive := CameraComponent.Active;
try
CameraComponent.Active := False;
if WhichCamera = 'BackCamera' then
begin
CameraComponent.Kind := TCameraKind.FrontCamera;
WhichCamera := 'FrontCamera';
end
else if WhichCamera = 'FrontCamera' then
begin
CameraComponent.Kind := TCameraKind.BackCamera;
WhichCamera := 'BackCamera';
end;
finally
CameraComponent.Active := LActive;
end;
end;
procedure TVideoAttachmentForm.CameraComponentSampleBufferReady(Sender: TObject;
const ATime: TMediaTime);
begin
TThread.Synchronize(TThread.CurrentThread, GetImage);
ImageCameraView.Width := ImageCameraView.Bitmap.Width;
ImageCameraView.Height := ImageCameraView.Bitmap.Height;
end;
procedure TVideoAttachmentForm.CloseScreenBtnClick(Sender: TObject);
begin
VideoAttachmentForm.Close;
end;
procedure TVideoAttachmentForm.FormCreate(Sender: TObject);
var
AppEventSvc: IFMXApplicationEventService;
begin
if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationEventService, IInterface(AppEventSvc)) then
AppEventSvc.SetApplicationEventHandler(AppEvent);
end;
procedure TVideoAttachmentForm.FormShow(Sender: TObject);
begin
InitialSettingsForTheRecording;
end;
function TVideoAttachmentForm.AppEvent(AAppEvent: TApplicationEvent; AContext: TObject): Boolean;
begin
case AAppEvent of
TApplicationEvent.WillBecomeInactive:
CameraComponent.Active := False;
TApplicationEvent.EnteredBackground:
CameraComponent.Active := False;
TApplicationEvent.WillTerminate:
CameraComponent.Active := False;
end;
end;
procedure TVideoAttachmentForm.InitialSettingsForTheRecording;
var
LSettings: TVideoCaptureSetting;
begin
CameraComponent.Kind := TCameraKind.BackCamera;
WhichCamera := 'BackCamera';
if CameraComponent.HasTorch then
begin
CameraComponent.TorchMode := TTorchMode.ModeAuto;
end;
CameraComponent.Quality := TVideoCaptureQuality.CaptureSettings;
CameraComponent.CaptureSettingPriority := TVideoCaptureSettingPriority.FrameRate;
end;
procedure TVideoAttachmentForm.StartRecordingBtnClick(Sender: TObject);
begin
CameraComponent.Active := True;
end;
procedure TVideoAttachmentForm.StopRecordingBtnClick(Sender: TObject);
begin
CameraComponent.Active := False;
end;
procedure TVideoAttachmentForm.GetImage;
begin
CameraComponent.SampleBufferToBitmap(ImageCameraView.Bitmap, True);
end;
end.
i used 30 png pictures on a transplanted from to make a simple animation, a Timer make an event every 33 Millisecond to change the visibility of the TImage Components which have the png images, i tried all the method suggested in other posts to stop flickering but could not solve the problem.
unit Animation;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, AdvShaper, pngimage, ExtCtrls, StdCtrls;
type
TAnimation_Form = class(TForm)
Image1: TImage;
Timer: TTimer;
Image2: TImage;
Image3: TImage;
Image4: TImage;
Image5: TImage;
Image6: TImage;
Image7: TImage;
Image8: TImage;
Image9: TImage;
Image10: TImage;
Image11: TImage;
Image12: TImage;
Image13: TImage;
Image14: TImage;
Image15: TImage;
Image16: TImage;
Image17: TImage;
Image18: TImage;
Image19: TImage;
Image20: TImage;
Image21: TImage;
Image22: TImage;
Image23: TImage;
Image24: TImage;
Image25: TImage;
Image26: TImage;
Image27: TImage;
Image28: TImage;
Image29: TImage;
Image30: TImage;
Exit: TButton;
procedure TimerTimer(Sender: TObject);
procedure ExitClick(Sender: TObject);
private
{ Private declarations }
Image_Counter:Integer;
procedure ChooseImage(I:Integer);
procedure Init();
public
{ Public declarations }
end;
procedure Run_Animation_Form();
procedure Finish_Animation_Form();
implementation
var
Animation_Form: TAnimation_Form;
{$R *.dfm}
procedure Finish_Animation_Form();
Begin
Animation_Form.Close;
End;
procedure Run_Animation_Form();
Begin
Animation_Form := TAnimation_Form.Create(nil);
Try
Animation_Form.Init();
Animation_Form.ShowModal();
Finally
Animation_Form.Free;
End;
End;
{ TAnimation_Form }
procedure TAnimation_Form.ChooseImage(I: Integer);
begin
TwinControl(FindComponent(Format('Image%d',[I]))).Visible := False;
TwinControl(FindComponent(Format('Image%d',[I+1]))).Visible := True;
end;
procedure TAnimation_Form.ExitClick(Sender: TObject);
begin
Close;
end;
procedure TAnimation_Form.Init;
begin
TransparentColor := True;
TransparentColorValue := Color;
Image1.Visible := True;
Image_Counter:=1;
ControlStyle:=ControlStyle - [csOpaque];
BorderWidth := 10;
Anchors := [akLeft, akTop, akBottom, akRight];
end;
procedure TAnimation_Form.TimerTimer(Sender: TObject);
begin
if Image_Counter >= 30 then
Begin
Image30.Visible := False;
Image1.Visible := True;
Image_Counter:=1;
End
else
Begin
ChooseImage(Image_Counter);
Inc(Image_Counter);
End;
end;
end.
Thanks for your help and sorry for my bad English
Rather than using multiple overlapping TImage objects and swapping their Visible property, I would suggest you create an array of 30 TPNGImage objects and then either:
use a single TImage that is always visible and assign the desired PNG to its TImage.Picture property whenever the TTimer elapses:
unit Animation;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, AdvShaper, pngimage, ExtCtrls, StdCtrls;
type
TAnimation_Form = class(TForm)
Image1: TImage;
Timer: TTimer;
Exit: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure TimerTimer(Sender: TObject);
procedure ExitClick(Sender: TObject);
private
{ Private declarations }
Image_Counter: Integer;
Images: array[0..29] of TPNGImage;
public
{ Public declarations }
end;
procedure Run_Animation_Form();
procedure Finish_Animation_Form();
implementation
var
Animation_Form: TAnimation_Form = nil;
{$R *.dfm}
procedure Finish_Animation_Form();
Begin
if Animation_Form <> nil then
Animation_Form.Close;
End;
procedure Run_Animation_Form();
Begin
Animation_Form := TAnimation_Form.Create(nil);
Try
Animation_Form.ShowModal();
Finally
FreeAndNil(Animation_Form);
End;
End;
{ TAnimation_Form }
procedure TAnimation_Form.FormCreate(Sender: TObject);
var
I: Integer;
begin
for I := Low(Images) to High(Images) do
begin
Images[I] := TPNGImage.Create;
// load PNG image into Images[I] as needed...
end;
// FYI, these properties can be set at design time...
TransparentColor := True;
TransparentColorValue := Color;
Image1.Visible := True;
BorderWidth := 10;
Anchors := [akLeft, akTop, akBottom, akRight];
Image_Counter := 0;
Image1.Picture := Images[0];
ControlStyle := ControlStyle - [csOpaque];
end;
procedure TAnimation_Form.FormDestroy(Sender: TObject);
var
I: Integer;
begin
for I := Low(Images) to High(Images) do
Images[I].Free;
end;
procedure TAnimation_Form.ExitClick(Sender: TObject);
begin
Close;
end;
procedure TAnimation_Form.TimerTimer(Sender: TObject);
begin
Inc(Image_Counter);
if Image_Counter > High(Images) then
Image_Counter := 0;
Image1.Picture := Images[Image_Counter];
end;
end.
use a single TPaintBox and assign an OnPaint event handler to it that draws the current PNG onto the TPaintBox.Canvas, and then have the TTimer simply update the current PNG and call TPaintBox.Invalidate() to trigger a repaint:
unit Animation;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, AdvShaper, pngimage, ExtCtrls, StdCtrls;
type
TAnimation_Form = class(TForm)
PaintBox1: TPaintBox;
Timer: TTimer;
Exit: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure TimerTimer(Sender: TObject);
procedure ExitClick(Sender: TObject);
procedure PaintBox1Paint(Sender: TObject);
private
{ Private declarations }
Image_Counter: Integer;
Images: array[0..29] of TPNGImage;
public
{ Public declarations }
end;
procedure Run_Animation_Form();
procedure Finish_Animation_Form();
implementation
var
Animation_Form: TAnimation_Form = nil;
{$R *.dfm}
procedure Finish_Animation_Form();
Begin
if Animation_Form <> nil then
Animation_Form.Close;
End;
procedure Run_Animation_Form();
Begin
Animation_Form := TAnimation_Form.Create(nil);
Try
Animation_Form.ShowModal();
Finally
FreeAndNil(Animation_Form);
End;
End;
{ TAnimation_Form }
procedure TAnimation_Form.FormCreate(Sender: TObject);
var
I: Integer;
begin
for I := Low(Images) to High(Images) do
begin
Images[I] := TPNGImage.Create;
// load PNG image into Images[I] as needed...
end;
// FYI, these properties can be set at design time...
TransparentColor := True;
TransparentColorValue := Color;
Image1.Visible := True;
BorderWidth := 10;
Anchors := [akLeft, akTop, akBottom, akRight];
Image_Counter := 0;
ControlStyle := ControlStyle - [csOpaque];
end;
procedure TAnimation_Form.FormDestroy(Sender: TObject);
var
I: Integer;
begin
for I := Low(Images) to High(Images) do
Images[I].Free;
end;
procedure TAnimation_Form.ExitClick(Sender: TObject);
begin
Close;
end;
procedure TAnimation_Form.TimerTimer(Sender: TObject);
begin
Inc(Image_Counter);
if Image_Counter > High(Images) then
Image_Counter := 0;
PaintBox1.Invalidate;
end;
procedure TAnimation_Form.PaintBox1Paint(Sender: TObject);
begin
PaintBox1.Canvas.Draw(0, 0, Images[Image_Counter]);
// or:
// PaintBox1.Canvas.StretchDraw(Rect(0, 0, PaintBox1.Width, PaintBox1.Height), Images[Image_Counter]);
end;
end.