Delphi 2010 - How to Copy and Clear the TShape - delphi

Ok, after working with TShape, I need to clean my "Shape1" from Lines and Text.
And also how to copy everything in "Shape1" into "Shape2" ?
Thanks B4 ^o^
type
TShape = class(ExtCtrls.TShape); //interposer class
TForm1 = class(TForm)
Shape1: TShape;
Shape2: TShape;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
// Draw some text on Shape1 := TShape
Shape1.Canvas.Font.Name :='Arial';// set the font
Shape1.Canvas.Font.Size :=20;//set the size of the font
Shape1.Canvas.Font.Color:=clBlue;//set the color of the text
Shape1.Canvas.TextOut(10,10,'1999');
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
// Copy everything from Shape1 to Shape2 (make a duplication)
// How to do it ?
showmessage('copy Shape1 into Shape2');
end;
End.

Following pseudo-code makes a copy of SourceShape canvas content to the TargetShape canvas, but only until the TargetShape is refreshed:
procedure TForm1.Button1Click(Sender: TObject);
begin
TargetShape.Canvas.CopyRect(Rect(0, 0, TargetShape.ClientWidth,
TargetShape.ClientHeight), SourceShape.Canvas, Rect(0, 0,
SourceShape.ClientWidth, SourceShape.ClientHeight));
end;
To clear the previously copied content, you can use the following:
procedure TForm1.Button2Click(Sender: TObject);
begin
TargetShape.Invalidate;
end;
To keep your drawing persistent you need to implement your own OnPaint event, in which whenever it fires, copy the current canvas content from the source to target using the CopyRect method like shown above.
But the question is then, why to use a TShape control at all. It would be better to use TPaintBox and draw your stuff by yourself including the shapes that are drawn by TShape control.

Related

Disable scrolling possibility of TWebBrowser

Does anyone know, how to disable scrolling possibility of TWebBrowser control in a Firemonkey iOS / Android application? My goal is to get absolutely static element that will not react on touches and so on.
There is no single setting or action that disables all user actions of the Fmx.TWebBrowser. But there is a feature you can use for your purpose.
The feature I refer to, is Fmx.WebBrowser.TCustomWebBrowser.CaptureBitmap documented here
Description
Captures the currently visible Web page as a bitmap.
This method returns a TBitmap object, which allows you to create,
manipulate and store images in memory or as files on a disk. The
scenario of the use of this method could be as follows:
1. Call this method to capture a visible Web page as a bitmap.
2. Hide a TWebBrowser control.
3. Display the bitmap and overlay other components (such as buttons or popups) on top of the bitmap.
In your case you would just hide the WB and display the bitmap.
Tested with the following code:
type
TForm25 = class(TForm)
Button1: TButton;
WebBrowser1: TWebBrowser;
Edit1: TEdit;
Image1: TImage;
Timer1: TTimer;
procedure Button1Click(Sender: TObject);
procedure WebBrowser1DidFinishLoad(ASender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
bmp: TBitmap;
public
{ Public declarations }
end;
implementation
procedure TForm25.Button1Click(Sender: TObject);
begin
WebBrowser1.URL := Edit1.Text;
end;
procedure TForm25.Timer1Timer(Sender: TObject);
begin
bmp := WebBrowser1.CaptureBitmap;
Image1.Bitmap := bmp;
end;
procedure TForm25.WebBrowser1DidFinishLoad(ASender: TObject);
begin
Timer1.Enabled := True;
end;
With the WB hidden, it cannot be operated on.
The timer (1000 ms) I added because my attempts to capture the image already in the OnDidFinishLoad() event did nöt succeed.

For loop continue going after reaching goal. Delphi

This issue appears only with numbers, bigger, then 12 including.
Those two pictures captured in one time. How it is even possible?
For loop must go from 0 to 12-1=11, doesn't it?
Nevertheless, when I use while loop instead, it works fine.
Is it my fault or Delphi's?
P.S. Code down bellow.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Grids;
type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
Label1: TLabel;
Button3: TButton;
Label2: TLabel;
Label3: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure StringGrid1KeyPress(Sender: TObject; var Key: Char);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
n:Integer;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); //Button, that sets array length
var
i, index:Integer;
begin
val(Edit1.Text, n, index);
if(index<>0) then
begin
ShowMessage('Wrong number');
Edit1.Clear();
exit;
end;
StringGrid1.ColCount:=n;
for i:=0 to n-1 do
StringGrid1.Cells[i,0]:=IntToStr(i+1);
StringGrid1.SetFocus();
end;
procedure TForm1.Button2Click(Sender: TObject); //Main button
var
i, index:Integer;
a:array[0..10] of Real;
denom, sum:Real;
begin
i:=0;
sum:=0;
denom:=-1;
//that for loop from screenshot is here
for i:=0 to n-1 do
//while i<=(n-1) do
begin
Val(StringGrid1.cells[i,1], a[i], index);
if(index<>0) then
begin
ShowMessage('Wrong number with ' + IntToStr(i+1) + ' Id');
StringGrid1.Col:=i;
StringGrid1.Row:=1;
StringGrid1.SetFocus();
exit;
end;
a[i]:=a[i]/denom;
sum:=sum+a[i];
StringGrid1.Cells[i,2]:=FloatToStrF(a[i],ffFixed,5,3);
denom:=-denom*(i+2);
//Inc(i);
end;
Label2.Caption:=FloatToStrF(sum,ffFixed,5,3);
end;
//code down bellow just allow to go to another cell by pressing Enter
procedure TForm1.StringGrid1KeyPress(Sender: TObject; var Key: Char);
begin
if (Key=#13) and (StringGrid1.Col=(n-1)) then
Button2.SetFocus()
else if (Key=#13) and (StringGrid1.Col<>(n-1)) then
StringGrid1.Col:=StringGrid1.Col+1;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
Close();
end;
end.
As to answer your question of 'how is this even possible'...
In your screen, n is 12. As pointed out by Kermation, the highest index of a is 10, so when i is 11, unless you have range checking activated, when you write to a[11] (i=11) you will overwrite something else. This is in the local variable area so it might be i, for instance, or even internal variables you can't see like the limit used for the for loop, which is calculated at the start of the loop. Once you allow this to happen, pretty much anything is possible.
Of course the exact manifestation of the problem will very from one version of the compiler to another. In one version you might get away with it. in another you won't.
Array a size was smaller, then amount of cells.

Setfocus to the searchbox in a tlistview

I am working in Seattle, writing a FM application for windows only.
I have A tlistview on my form and have it populated with data.
I have the search option turned on.
How do I programmatically set focus to the search box?
How do I increase the size and font size of the search box?
thanks
The searchbox is not intended to be accessed programmatically except for setting it visible and to fire event when changed. Otherwise it is intended to be accessed only by the user.
Therefore, access is a little bit involved. However, the example of the OnSearchChange event inspired the following answer:
uses ..., FMX.SearchBox;
type
TForm17 = class(TForm)
ListView1: TListView;
Button1: TButton;
Label1: TLabel;
...
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
sb: TSearchBox; // a local reference
...
end;
implementation
procedure TForm17.Button1Click(Sender: TObject);
begin
if Assigned(sb) then
sb.SetFocus;
end;
procedure TForm17.FormCreate(Sender: TObject);
var
i: integer;
begin
ListView1.SearchVisible := True; // or set in the Object Inspector at design time
for i := 0 to ListView1.Controls.Count-1 do
if ListView1.Controls[I].ClassType = TSearchBox then
begin
sb := TSearchBox(ListView1.Controls[i]);
Break;
end;
end;
procedure TForm17.ListView1SearchChange(Sender: TObject);
begin
if Assigned(sb) then
Label1.Text := sb.Text;
end;
At form creation we search the SearchBox control and if found we store a reference to it in the sb: TSearchBox; field. Then access is quite straightforward.

How to get a Frame Bitmap from a Video File by DsPack Components?

Is it possible to get a bitmap from a video file by DsPack components?
In this case I'm using this code; but It can't take a screenshot Image:
type
TForm4 = class(TForm)
FilterGraph1: TFilterGraph;
VideoWindow1: TVideoWindow;
btnPlay: TButton;
SampleGrabber1: TSampleGrabber;
btnTakePicture: TButton;
Image1: TImage;
procedure btnPlayClick(Sender: TObject);
procedure btnTakePictureClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
...
procedure TForm4.btnPlayClick(Sender: TObject);
begin
SampleGrabber1.FilterGraph := FilterGraph1;
VideoWindow1.FilterGraph := FilterGraph1;
FilterGraph1.Active := true;
FilterGraph1.RenderFile('C:\TEMP\1.mp4');
FilterGraph1.Play;
end;
procedure TForm4.btnTakePictureClick(Sender: TObject);
begin
SampleGrabber1.GetBitmap(Image1.Picture.Bitmap);
end;
Is it possible to Fix This code?
after a while I found a sample for solving this problem:
we can use "SnapShot.dpr". this is a sample which distributed with DsPack Components.

How to write a number on a TShape Component?

I have a TShape Component. I need to load it dynamically and I need to place a number on that TShape. If anyone knows the way - please suggest it to me.
Thanks Rakesh
You can use the Canvas property of the TShape component to draw the number, to access this protected property you must create descendent class of TShape and publish that property or just use a interposer class.
type
TShape = class(ExtCtrls.TShape); //interposer class
TForm1 = class(TForm)
Shape1: TShape;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Shape1.Canvas.Font.Name :='Arial';// set the font
Shape1.Canvas.Font.Size :=20;//set the size of the font
Shape1.Canvas.Font.Color:=clBlue;//set the color of the text
Shape1.Canvas.TextOut(10,10,'1999');
end;
Place a TLabel above it and make its background transparent (Transparent = True). Edit text alignment if needed (Alignment := taCenter)

Resources