Wednesday, 12 September 2018
Delphi - Add an icon to a Node in TTreeView
1. Add your tree view to the form.
2. Add an TImageList to the form.
3. Double click on the ImageList component and add some images in.
4. Go to the Properties of the TreeView > Drop down the 'Images' property and select the name of the ImageList you've added.
5. Now in your code, where you're populating the treeview, you can add in code to set an icon/image to each node by referncing the image index:
//This will set the image of the node when resting
MyNode.ImageIndex := 0;
//This will set the image of node when selected
MyNode.SelectedIndex := 0;
The index number refers to the image in the IMageList. This is zero based so the first image would be 0, the second would 1 and so on...
Monday, 30 July 2018
Delphi - Sort an Object List by Property
Below is a quick example of how to use the .Sort function. In this case i have two objects declared in the Type seciton. On form create i am creating an instance of TPersons, then creating a number of dummy TPersons and adding them to my 'Persons'. Then behind a button click i am sorting the order of the Persons using the following code:
Persons.Sort(TComparer<TPerson>.Construct(
function (const L,R: TPerson): integer
begin
if L.Name > R.Name then
Result := 1
else if L.Name < R.Name then
Result := -1
else
Result := 0;
end
));
end;
To recreate this simple example, drop a memo and a button on a form. The make your code look like this:
unit Unit2;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.Controls.Presentation, FMX.StdCtrls, Generics.Collections, FMX.ScrollBox,
FMX.Memo, Generics.Defaults;
type
TForm2 = class(TForm)
Button1: TButton;
Button2: TButton;
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TPerson = class(TObject)
Name: string;
Age: integer;
end;
TPersons = class(TObjectList<TPerson>)
end;
var
Form2: TForm2;
implementation
{$R *.fmx}
var
Persons: TPersons;
procedure TForm2.Button1Click(Sender: TObject);
var
Person: TPerson;
I: Integer;
begin
for Person in Persons do
begin
Persons.Sort(TComparer<TPerson>.Construct(
function (const L,R: TPerson): integer
begin
if L.Name > R.Name then
Result := 1
else if L.Name < R.Name then
Result := -1
else
Result := 0;
end
));
end;
for I := 0 to Persons.Count -1 do
begin
Memo1.Lines.Add(Persons[I].Name);
end;
end;
procedure TForm2.FormCreate(Sender: TObject);
var
Person: TPerson;
I: Integer;
begin
Persons := TPersons.Create(true);
Person := TPerson.Create;
Person.Name := 'John';
Person.Age := 34;
Persons.Add(Person);
Person := TPerson.Create;
Person.Name := 'James';
Person.Age := 31;
Persons.Add(Person);
Person := TPerson.Create;
Person.Name := 'Sally';
Person.Age := 21;
Persons.Add(Person);
end;
procedure TForm2.FormDestroy(Sender: TObject);
begin
Persons.Free;
end;
end.
Monday, 23 July 2018
Delphi FMX/Firemonkey - Fill a Rect/RoundRect/Ellipse with a Image/Bitmap
Here is a simple example of how to fill a given shape (TRectangle, TRoundRect, TEllipse etc) with the bitmap which belongs to an image. In this example i have created a new project, dropped a button and an RoundRect onto the form. On the Button Click i have the following code:
procedure TForm1.Button1Click(Sender: TObject);
var
Image: TImage;
begin
Image := TImage.Create(self);
Image.Bitmap.LoadFromFile('C:\Temp\Test.jpg');
RoundRect1.Fill.Kind := TbrushKind.Bitmap;
RoundRect1.Fill.Bitmap.WrapMode := TWrapMode.TileStretch;
RoundRect1.Fill.Bitmap.Bitmap := Image.Bitmap;
end;
This will create a new instance of a TImage. Load my Test.jpg file into its Bitmap property. Then set the Image to fill the space in the RoundRect.
procedure TForm1.Button1Click(Sender: TObject);
var
Image: TImage;
begin
Image := TImage.Create(self);
Image.Bitmap.LoadFromFile('C:\Temp\Test.jpg');
RoundRect1.Fill.Kind := TbrushKind.Bitmap;
RoundRect1.Fill.Bitmap.WrapMode := TWrapMode.TileStretch;
RoundRect1.Fill.Bitmap.Bitmap := Image.Bitmap;
end;
This will create a new instance of a TImage. Load my Test.jpg file into its Bitmap property. Then set the Image to fill the space in the RoundRect.
Thursday, 19 July 2018
Delphi - Set Font Property of a Component in Firemonkey/FMX
In order to set the font property of a component in FMX there are two ways you can do it:
1) In design time. By dropping a component onto the form and then changing its properties in the Object Inspector you can alter the properties of the font (font fmaily, size, color etc).
2) At run time. If, for example, you have a project which drops a series of labels onto a form when a button is clicked then you'll need to handle the changing of the font in your code.
Option 1 is pretty straight forward but it's worth noting that if you make this change, you can view the effect this has had by saving your project and then opening up the .fmx file in notedpad and looking to see what has changed. In my project, i added a label to my form and changed the Text Settings > Font Color to be 'crimson'. In my .fmx file i can see that there are now two new lines:
object Label1: TLabel
Position.X = 120.000000000000000000
Position.Y = 352.000000000000000000
TextSettings.FontColor = claCrimson
StyledSettings = [Family, Size, Style]
Text = 'Label1'
end
This shows us what the impact was of changing the font color. The first change is to be expected since the property we changed was the FontColor. The second change is important, however, since it shows us what other change delphi made under the covers - namely that delphi altered the StyledSettings. The styled settings tell delphi whether to pull down the projects style settings (i.e. those which may be applied through a stylebook) for a given setting. Thus if you go back to design time and drop down the StyledSettings option, you'll see that 'FontColor' is currently unchecked. If you check the box against it, the font in the label will cease to be red.
Thus, if you're creating new components at run time and need to alter some property of the font style, you'll need to include two lines - one to set the font setting and one to uncheck the relevant setting in StyledSettings:
MyLabel.TextSettings.FontColor := TAlphaColor($FF009900);
MyLabel.StyledSettings := [TStyledSetting.Family, TStyledSetting.Size, TStyledSetting.Style];
1) In design time. By dropping a component onto the form and then changing its properties in the Object Inspector you can alter the properties of the font (font fmaily, size, color etc).
2) At run time. If, for example, you have a project which drops a series of labels onto a form when a button is clicked then you'll need to handle the changing of the font in your code.
Option 1 is pretty straight forward but it's worth noting that if you make this change, you can view the effect this has had by saving your project and then opening up the .fmx file in notedpad and looking to see what has changed. In my project, i added a label to my form and changed the Text Settings > Font Color to be 'crimson'. In my .fmx file i can see that there are now two new lines:
object Label1: TLabel
Position.X = 120.000000000000000000
Position.Y = 352.000000000000000000
TextSettings.FontColor = claCrimson
StyledSettings = [Family, Size, Style]
Text = 'Label1'
end
This shows us what the impact was of changing the font color. The first change is to be expected since the property we changed was the FontColor. The second change is important, however, since it shows us what other change delphi made under the covers - namely that delphi altered the StyledSettings. The styled settings tell delphi whether to pull down the projects style settings (i.e. those which may be applied through a stylebook) for a given setting. Thus if you go back to design time and drop down the StyledSettings option, you'll see that 'FontColor' is currently unchecked. If you check the box against it, the font in the label will cease to be red.
Thus, if you're creating new components at run time and need to alter some property of the font style, you'll need to include two lines - one to set the font setting and one to uncheck the relevant setting in StyledSettings:
MyLabel.TextSettings.FontColor := TAlphaColor($FF009900);
MyLabel.StyledSettings := [TStyledSetting.Family, TStyledSetting.Size, TStyledSetting.Style];
Monday, 9 July 2018
Delphi - Load Image From Project Resource (FMX) - Simple Example
For this example i have a created a new FMX (firemonkey) form. I have added a button and an image onto the. I have then gone to Project > Resources and Images, and loaded in a bitmap image. I have set:
Resource Identifier: 'Bitmap_1'.
Resource Type: 'RCDATA'
Back on my form i have double clicked on the button and behind the button click put the code to instantiate a resource stream, load the image into it, assign it to a bitmap and then set it to be the image on the form.
unit Unit2;
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.Controls.Presentation, FMX.StdCtrls;
type
TForm2 = class(TForm)
Image1: TImage;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.fmx}
procedure TForm2.Button1Click(Sender: TObject);
var
B: TBitmap;
RS: TResourceStream;
begin
RS := TResourceStream.Create(HInstance, 'Bitmap_1', RT_RCDATA);
try
B := TBitmap.Create;
B.LoadFromStream(RS);
Image1.Bitmap := B;
finally
RS.Free;
end;
end;
end.
Resource Identifier: 'Bitmap_1'.
Resource Type: 'RCDATA'
Back on my form i have double clicked on the button and behind the button click put the code to instantiate a resource stream, load the image into it, assign it to a bitmap and then set it to be the image on the form.
unit Unit2;
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.Controls.Presentation, FMX.StdCtrls;
type
TForm2 = class(TForm)
Image1: TImage;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.fmx}
procedure TForm2.Button1Click(Sender: TObject);
var
B: TBitmap;
RS: TResourceStream;
begin
RS := TResourceStream.Create(HInstance, 'Bitmap_1', RT_RCDATA);
try
B := TBitmap.Create;
B.LoadFromStream(RS);
Image1.Bitmap := B;
finally
RS.Free;
end;
end;
end.
Thursday, 26 April 2018
Delphi - TFileStream - Simple Example
TFileStream can be handy for looking at a file without having to actually load it into memory since it just provides a more efficient way to view it on disk. Below is a very simple example illustrating how to locate a character in a filestream:
procedure TForm1.Button1Click(Sender: TObject);
var
FS: TFileStream;
X: char;
begin
FS := TFileStream.Create('C:\Temp\Example.txt', fmOpenRead);
try
FS.Position := 0;
FS.Read(X,2);
ShowMessage(X);
finally
FS.Free;
end;
end;
This will create a filestream based on the information fed to the constructor, i.e. the file and the mode of operation.
It will then set the position of the filestream to 0, i.e. what is my start point in the stream (it's 0 by default but if you wanted to alter your start point, this is how you'd do it).
It will then perform a Read on the string. It will start at the current position (in this case 0) and then read the number of bytes specified (in this case 2) and it will store these bytes in memory at a given location (in this case X).
It will then show a message of the first character in the text file.
Finally we free the filestream which ensures there is no memory leak.
NB, it is important to declare the X var at the start, since this will ensure that memory space is created. This space will then be used by FS.Read later to store data extracted from the filestream. In this example i have set it to be a char, since a char is 2 bytes of memory and i was just extracting the first two bytes of the stream but you could set it to something different so long as that something requires the same (or greater) memory than the amount of information you plan to extract from the filestream.
procedure TForm1.Button1Click(Sender: TObject);
var
FS: TFileStream;
X: char;
begin
FS := TFileStream.Create('C:\Temp\Example.txt', fmOpenRead);
try
FS.Position := 0;
FS.Read(X,2);
ShowMessage(X);
finally
FS.Free;
end;
end;
This will create a filestream based on the information fed to the constructor, i.e. the file and the mode of operation.
It will then set the position of the filestream to 0, i.e. what is my start point in the stream (it's 0 by default but if you wanted to alter your start point, this is how you'd do it).
It will then perform a Read on the string. It will start at the current position (in this case 0) and then read the number of bytes specified (in this case 2) and it will store these bytes in memory at a given location (in this case X).
It will then show a message of the first character in the text file.
Finally we free the filestream which ensures there is no memory leak.
NB, it is important to declare the X var at the start, since this will ensure that memory space is created. This space will then be used by FS.Read later to store data extracted from the filestream. In this example i have set it to be a char, since a char is 2 bytes of memory and i was just extracting the first two bytes of the stream but you could set it to something different so long as that something requires the same (or greater) memory than the amount of information you plan to extract from the filestream.
Subscribe to:
Posts (Atom)