Setting up background images for forms in Delphi - delphi

How can I make my program load an image and make it the background for a form?
I need the exact code for it. I've looked all over the internet and the only things I've found are various tweaks and fixes to make backgrounds work as intended in special circumstances. I've also tried some Delphi books I have and I can't find it anywhere.

Put a TImageon your form. Make sure it's behind all other controls on the form. You can right-click it and choose the "send to back" menu option.
Load a graphic.
var
img: TBitmap;
begin
img := TBitmap.Create;
try
img.LoadFromFile('S:\background.bmp');
Assign it to the image control.
Image1.Picture := img;
Clean up.
finally
img.Free;
end;
end;
You can also combine the last three steps to load the graphic and put it in the image control all at once. Thanks to Jon for the suggestion.
Image1.Picture.LoadFromFile('B:\background.bmp');
See also: How to add background images to Delphi forms

What I would do is use the forms OnPaint event, get the canvas (Form1.Canvas), and then use the Draw method (which takes an image) to draw the image you want. Something like the following:
procedure TForm1.FormPaint(Sender: TObject);
var
mypic: TBitMap;
begin
mypic := TBitMap.Create;
try
mypic.LoadFromFile('cant.bmp');
Form1.Canvas.Draw(0, 0, mypic);
finally
FreeAndNil(mypic);
end;
end;
Note that this could be extremely slow.

This is the way all my applications show a form image. I load the image at form creation or when the application calls a specific showing event
var
vDest, vRect: TRect;
begin
vRect := Rect(0, 0, FBackgroundImage.Width, FBackgroundImage.Height);
vDest := Rect(0,0,Self.Width, Self.Height);
Canvas.StretchDraw(vDest, FBackgroundImage);
if FileExists(this) then
FBackgroundImage.LoadFromFile(this);

#Brendan
thanks
//from Brendan code;
var
vDest, vRect: TRect;
FBackgroundImage: TGraphic;
begin
FBackgroundImage := image1.Picture.Graphic; //LOAD from invisible image
vRect := Rect(0, 0, FBackgroundImage.Width, FBackgroundImage.Height);
vDest := Rect(0,0,Self.Width, Self.Height);
Canvas.StretchDraw(vDest, FBackgroundImage);
end;

Related

How to read a file in a TTask? (Delphi, fmx)

I need to read bitmap files and then copy them in an image component. I would like to do this in a TTask to keep the GUI responsive. If I run the minimized code below, then sometimes the apple image appears correctly and sometimes it appears without content (a grey square). If I put the bmp.LoadFromFile(..) in the TThread.Synchronize, then it seems to works fine, but is it necessary to put it in the TThread.Synchronize?
I do not understand why it does not work as is, because 1) if I look at the source code of LoadFromFile then the procedure starts with TMonitor.Enter(Self); and 2) when I save the bmp twice as commented out in the code, then the first save always contains the correct image (so the LoadFromFile seems to work), but the second save sometimes gives the correct image and sometimes a black image (but with the correct size)?
I am new to threading, so am hoping that someone can shed some light on this and what the correct way is to read images in a TTask. I am using Delphi 10.3.3.
Thanks,
Gerard
procedure TForm1.Button3Click(Sender: TObject);
begin
TTask.Run(procedure
var bmp: TBitmap;
begin
bmp := TBitmap.Create;
bmp.LoadFromFile('apple.bmp');
// bmp.SaveToFile('apple1.bmp');
// bmp.SaveToFile('apple2.bmp');
TThread.Synchronize(nil,
procedure
begin
Form1.Image1.bitmap.CopyFromBitmap(bmp, Rect(0, 0, bmp.Width, bmp.Height), 100, 100 );
end);
bmp.Free;
end);
end;

Add icons to TTabControl in Firemonkey

First of all I have to say that I've read this question of SO. But actually it wasn't helpful for me.
I want to add icons to TTabControl but it doesn't seems as easy as I can do it in VCL (TPageControl). As you know there is no something like Image Index in TTabControl.
So what's the easiest way to do this?
Thanks for your help.
I would suggest not going down the route of modifying the style given the inherent 'copy and paste "inheritance"' nature of the exercise, which becomes an issue if you're targeting more than one OS (even just Windows 7 and Windows 8.x). Instead, try this:
1) For each item you want an icon on, change its TextAlign property to taTrailing and pad its Text with four leading space characters.
2) Add one TImage to the form per tab, and load small bitmaps into them as desired.
3) Associate each tab item with its image by (for example) assigning its TagObject property to the image control in an OnCreate handler for the form:
procedure TForm1.FormCreate(Sender: TObject);
begin
TabItem1.TagObject := Image1;
//...
end;
4) Assign each tab item's OnPaint event the following shared event handler:
procedure TForm1.TabItemPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
var
B: TBitmap;
SrcR, DstR: TRectF;
TabItem: TTabItem;
begin
TabItem := (Sender as TTabItem);
B := (TabItem.TagObject as TImage).Bitmap;
SrcR := RectF(0, 0, B.Width, B.Height);
DstR := SrcR;
DstR.Fit(RectF(ARect.Left, ARect.Top, ARect.Left + ARect.Height, ARect.Bottom));
if not TabItem.IsSelected then DstR.Offset(0, 1);
Canvas.DrawBitmap(B, SrcR, DstR, 1);
end;

Take a screenshot of a particular area

I am using Lazarus and I have a TImage inside a form. The black table is a TImage and the numbers are labels. I need to take a screenshot of the red area I drew.
How can I perform this?
I have Lazarus 1.0.14 and I didn't find any example about this. Any suggestion?
This is a painful design, but well, one simple way might be to put all the controls on a common container and copy its canvas to a bitmap. The following example assumes, that you have put your image and all the labels on a common TPanel control (Panel1):
procedure TForm1.Button1Click(Sender: TObject);
var
R: TRect;
Bitmap: TBitmap;
begin
Bitmap := TBitmap.Create;
try
R := Rect(0, 0, Panel1.Width, Panel1.Height);
Bitmap.SetSize(Panel1.Width, Panel1.Height);
Bitmap.Canvas.CopyRect(R, Panel1.Canvas, R);
Bitmap.SaveToFile('C:\Screenshot.bmp');
finally
Bitmap.Free;
end;
end;
You can use GetFormImage to get the form image, and keep the part that corresponds to your image area in it:
var
Bmp: TBitmap;
begin
Bmp := GetFormImage;
try
Bmp.Canvas.CopyRect(Image1.ClientRect, Bmp.Canvas, Image1.BoundsRect);
Bmp.SetSize(Image1.Width, Image1.Height);
Bmp.SaveToFile('....');
finally
Bmp.Free;
end;

Delphi: paint column of list view

I draw a list view with OwnerDraw. I need to paint the first column. But I cannot understand how.
I tried:
procedure TFrame6.DownloadListCustomDraw(Sender: TCustomListView;
const ARect: TRect; var DefaultDraw: Boolean);
var
R: TRect;
begin
DefaultDraw := False;
Sender.Canvas.Brush.Color := $F7F7F7;
Sender.Canvas.Brush.Style := bsSolid;
R := ARect;
R.Right := ListView_GetColumnWidth(DownloadList.Handle, DownloadList.Columns[0].Index);
Sender.Canvas.FillRect(R);
DefaultDraw := True;
end;
But I draw over items. How to draw correctly, items and a background?
Thanks!
Summary from comments:
I suggest you to read this delphiDabbler article and hope that it contains enough information to resolve your problem. E.g. Example 1 shows how to change background and Example 4 shows point where item appearance can be changed.
Small tip: don't restore DefaultDraw to True at the end of the handler if you don't want text to be drawn.
I suggest you use VirtualStringTree if you want a lot of customization on the list. Its easy to use and almost anything is possible and most of all freeware. The component can be downloaded at Soft-Gems and few example can be found here

Delphi - Populate an imagelist with icons at runtime 'destroys' transparency

I've spended hours for this (simple) one and don't find a solution :/
I'm using D7 and the TImageList. The ImageList is assigned to a toolbar.
When I populate the ImageList at designtime, the icons (with partial transparency) are looking fine.
But I need to populate it at runtime, and when I do this the icons are looking pretty shitty - complete loose of the partial transparency.
I just tried to load the icons from a .res file - with the same result.
I've tried third party image lists also without success.
I have no clue what I could do :/
Thanks 2 all ;)
edit:
To be honest I dont know exactly whats going on. Alpha blending is the correkt term...
Here are 2 screenies:
Icon added at designtime:
(source: shs-it.de)
Icon added at runtime:
(source: shs-it.de)
Your comment that alpha blending is not supported just brought the solution:
I've edited the image in an editor and removed the "alpha blended" pixels - and now it looks fine.
But its still strange that the icons look other when added at runtime instead of designtime. If you (or somebody else ;) can explain it, I would be happy ;)
thanks for you support!
To support alpha transparency, you need to create the image list and populate it at runtime:
function AddIconFromResource(ImageList: TImageList; ResID: Integer): Integer;
var
Icon: TIcon;
begin
Icon := TIcon.Create;
try
Icon.LoadFromResourceID(HInstance, ResID);
Result := ImageList.AddIcon(Icon);
finally
Icon.Free;
end;
end;
function AddPngFromResource(ImageList: TImageList; ResID: Integer): Integer;
var
Png: TPngGraphic;
ResStream: TStream;
Bitmap: TBitmap;
begin
ResStream := nil;
Png := nil;
Bitmap := nil;
try
ResStream := TResourceStream.CreateFromID(HInstance, ResID, RT_RCDATA);
Png := TPNGGraphic.Create;
Png.LoadFromStream(ResStream);
FreeAndNil(ResStream);
Bitmap := TBitmap.Create;
Bitmap.Assign(Png);
FreeAndNil(Png);
Result := ImageList.Add(Bitmap, nil);
finally
Bitmap.Free;
ResStream.Free;
Png.Free;
end;
end;
// this could be e.g. in the form's or datamodule's OnCreate event
begin
// create the imagelist
ImageList := TImageList.Create(Self);
ImageList.Name := 'ImageList';
ImageList.DrawingStyle := dsTransparent;
ImageList.Handle := ImageList_Create(ImageList.Width, ImageList.Height, ILC_COLOR32 or ILC_MASK, 0, ImageList.AllocBy);
// populate the imagelist with png images from resources
AddPngFromResource(ImageList, ...);
// or icons
AddIconFromResource(ImageList, ...);
end;
I had the exact same problems a couple of years ago. It's a Delphi problem. I ended up putting the images in the list at design time, even though I really didn't want to. I also had to use a DevExpress image list to get the best results and to use 32 bit color images.
As Jeremy said this is indeed a Delphi limitation.
One work around I've used for images that I was putting onto buttons (PNGs with alpha transparency in my case) is to store the PNGs as resources, and at run time paint them onto a button sized bitmap filled with clBtnFace. The bitmap was then used as the control's glyph.
Delphi's built in support for icons with alpha masks is very limited, however there's an excellent icon library kicon which may help.

Resources