Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Semi-transparent layer over ListView in Delphi?

In Delphi XE2, I have a ListView with thumbnails of images. When I click one of the thumbnails, I want the ListView to be covered with a dark semi-transparent layer and have the clicked image zoomed on top of this layer.

Since it is not possible to put a TImage on top of a ListView, I tried to use another form with AlphaBlend 128 transparency for the layer. However, this AlphaBlend form makes also the TImage on it Alpha-transparent.

So the target seems be to make the layer form AlphaBlend-transparent but not the image on it. How can this be achieved?


EDIT on 7.Aug.2012:

SOLVED!! Thanks to Remy Lebeau, who gave me the decisive hint to parenting the image. I've found TW7Image from TMS which is the only image type I know having an Opacity (i.e. AlphaBlend) property. I used this procedure:

In W7Image, load a Black image in Picture property, set Opacity to 192 and set Stretch mode.

Set other image to Center, Proportional etc, then:

// In this order (!):
// 1.
imgSemiTransparentBlackLayer.Parent := MyListView;
imgSemiTransparentBlackLayer.Align := alClient;
// 2.
imgTop.Picture.LoadFromFile('MyPicture.png');
imgTop.Parent := MyListView;
imgTop.Align := alClient;
like image 551
user1580348 Avatar asked Oct 07 '22 00:10

user1580348


1 Answers

The TForm.AlphaBlend property applies to the entire TForm as a whole. What you need is per-pixel alpha-blending instead, which TForm does not natively support. You could call UpdateLayeredWindow() to implement per-pixel alpha, but that may conflict with the VCL's use of SetLayeredWindowAttributes().

For a purely VCL solution, you could try using two TForm objects. Have one TForm contain just the TImage and no background, then have a second TForm lay on top of it, where the second TForm has both its TransparentColor and AlphaBlend properties enabled, has a square of the TransparenColorValue that is the same dimensions as the TImage, and has a dark background color that gets alpha-blended with whatever is underneath it.

An alternative solution would be to use the Win32 API CreateWindowEx() function directly to create the image window, then you can use UpdateLayeredWindow() on it. That requires you to create an in-memory bitmap to back the window drawing, so you can draw your image directly on to that bitmap, rather than using a TImage component. Then you just give it a dark background and specify a per-pixel alpha for the bitmap pixels surrounding the image pixels.

BTW, you can put a TImage on top of a TListView, if you set the TListView as the TImage.Parent. You just won't be able to alpha-blend the TImage, that's all.

like image 106
Remy Lebeau Avatar answered Oct 24 '22 10:10

Remy Lebeau