How to add design time icon for FireMonkey component? - delphi

I have read this article by Paweł Głowacki and I have been able to display an icon for my component. The result is the following:
I can see the image in the Tool Palette and in the structure view. By the way in the designer I see the default icon:
How can I display the icon of my component in the designer as well?
I am using Delphi Tokyo 10.2 Update 2. I have followed the article I have linked to get the image shown. My component is the following:
type
TEquationSolver = class(TComponent)
//code...
end;
Basically, I have done the following:
I have created 3 bitmaps (16x16 24x24 32x32) and a png (128x128)
I have added them as resources going into Project > Resources and Images
I have called them TEquationSolver with the suffix that indicates the size. In this way they are properly displayed on the IDE.
What am I missing for the design time part? In this article I have read the following:
Our guide is: Use PNG if you want very easy backwards compatibility,
or small file (BPL) size; use bitmaps if you want fast loading. We
use bitmaps for 16, 24, and 32px icons, and PNG for the 128px icons.
In fact I have 16x16, 24x24, 32x32 bitmaps and the 128px png. Is there something else?

It seems that you have to create the files I have shown above plus the image for the Designer. The latter needs to match the name of the class that inherits from TComponent (in my case):
As you can see I have added another bitmap (it's the 32x32, I have just made a copy and changed the name) and I have used TEquationSolver as name. After a Build + Install I have the following result:
Note that I could have added only logo.bmp as resource (with the ID that matches the TComponent-derived class name) and it would have worked anyway. The problem is that the pictures won't be neat because they'll be resized and they may appear blurred, like in my case.
For this reason I think that it's good:
Put an image that will appear in the form designer
Put the 16x16, 24x24, 32x32 and 128x128 that will be used by the IDE
The difference is evident in my case. When I have only a single bitmap the quality of the image is low but when I provide the various sizes they look better.

Related

How can I find the correct size of tray bar icons? [duplicate]

I noticed that my app sends icons to the Windows tray with a size of 16x16 pixels--and my Vista PC I've got a doublewide taskbar that appears to show icons at 18x18. The resizing artifacts on my app's icon look awful. How can I ask Windows what size the icons should be?
Edit
I'm generating the icon dynamically, with a pixel font text overlay. It seems wasteful to generate a bunch of icon sizes dynamically, so it would be nice to avoid building an icon with all the "possible" sizes (not that I'm even sure what those are).
GetSystemMetrics(SM_CXSMICON) returns 16--the incorrect value.
GetThemeBackgroundContentRect didn't help, either.
Create your icons in multiple formats, and let Windows select the one it wants.
Here's the Wikipedia article on the .ico format.
If you really need to know, GetSystemMetrics with a parameter of SM_CXICON or SM_CYICON will tell you the width and height that Windows wants to load.
Mark's core answer is the right one: Create your icons in multiple formats and let Windows choose the right one. Don't forget to do 32x32 and 64x64 icons for HighDPI scenarios.
But SM_CXICON/SM_CYICON won't necessarily return the size that will be used in the taskbar. The taskbar chooses the right icon size for it's size (this is much more important in Window 7).
Just provide appropriately sized icons and you should be ok.
Your best bet may be GetThemeBackgroundContentRect passing TBN_BACKGROUND as iPartId for the tray notify background.
GetThemeBackgroundContentRect should return the size defined by the current theme that may be used for drawing without overlapping the borders of the parent element. If I'm reading this correctly, that would be the largest sized notification icon permissible and presumably the size that is being used.
Testing with multiple DPI settings is probably the easiest way to tell if this is returning the correct value.
Per the NOTIFYICONDATA documentation:
If only a 16x16 pixel icon is provided, it is scaled to a larger size in a system set to a high dpi value. This can lead to an unattractive result. It is recommended that you provide both a 16x16 pixel icon and a 32x32 icon in your resource file. Use LoadIconMetric to ensure that the correct icon is loaded and scaled appropriately. See Remarks for a code example.
...
...
// Load the icon for high DPI.
LoadIconMetric(hInst, MAKEINTRESOURCE(IDI_SMALL), LIM_SMALL, &(nid.hIcon));
...
So, creating icons dynamically really isn't the best option. You should provide multiple icons of different sizes statically in your program resources and let Windows choose the best one it wants.

A button control and underlying replacement for TBitmap that properly handles PNG transparency without writing pre-blend code

Delphi 2010's TSpeedButtons did not seem to really support PNG transparency properly, because the Glyph property uses a TBitmap internally, and TBitmap is for bitmaps, and doesn't support PNG transparency properly, and TSpeedButton.Glyph can't support transparency then.. update: But the actual problem was that I had some external stuff (Developer Express components) that was rendering delphi's PNG support non-functional, TImage on the other hand, while it still TPicture, and can support PNG, was also affected by this Developer express bug.
A question was already asked about here, and the answer shows how to use pre-blending so that transparency won't turn into black pixels. I want to know if there is another button control that will use alpha-blended PNGs loaded at designtime, and which does not convert the PNG resources into BMP format discarding the alpha channel and, causing the black border shown here.
In short, this control would not use TBitmap, and would not use the color key transparency feature that is all TBitmap has.
To repeat, I am not asking how to solve the black-around-the-outside issue while still using the out-of-date TBitmap/TSpeedButton based VCL functionality, because it lacks modern PNG transparency functionality, I am asking about replacing it with something else that "just works".
As a secondary drawback, converting a small .png file into a .DFM bitmap resource is essentially wasting space and making my form .DFM content too large. Native .png file format storage within the .dfm should make the resulting forms smaller.
Update: PngComponents look like they should work, but I got an Invalid Graphic format error when I try to load a png into the Png speedbutton. Note that the Png image list component has no such problems. It seems that cxLibrary (a developer express package) is breaking things. Once I removed all developer express stuff, this problem goes away. So although I have selected Pngcomponents as the answer, if you have devex stuff installed, use their buttons instead, and not pngcomponents.
You may have a look at PngComponents. It has a TPngSpeedbutton and some other controls working directly with PngImages.
You could also look into the TMS Software Component called TAdvGlowButton as this supports PNG images with alpha transparency.
Link to site...
It turns out that cxButton that comes in the Developer Express VCL component pack also supports PNG buttons.

Clipping a filmstrip in png format (Delphi 2010)

I have a filmstrip of images in png format like this:
I'd like to know how to clip each of the images and put these images in a TImageList control, always preserving the transparency.
[EDIT]
Yes, at designtime the trick mentioned by RRUZ works fine, but I wanted to clip the images at runtime, i.e. by loading the filmstrip from resource or file
You must follow these steps:
set ColorDepth property to cd32Bit,
DrawingStyle to dsTransparent,
Height= 48,
Width=48,
then load the image and the result will be
Just import into the imagelist. It'll complain that it's too big and offer to break it into pieces for you. Works fine for me on D2005.
Another cool tip: I use AWIcons Pro http://www.awicons.com/icon-editor/ to edit icons (nice editor!). It has a feature that can export an icon as an imagelist (.bmp or .png format), thus making the filmstrip out of an icon. This makes it really handy to edit these things in .ico format, with a series of cells all the same size and depth, with each cell varying slightly. Then you export as an imagelist (I use .png) and then Delphi can break them back out into individual cells. Very slick. AWIcons isn't free, but features like this really make it productive.
At runtime, you would have to call TImageList.FileLoad. Except it won't work.
This in turn calls ImageList_LoadImage, with uFlags parameter value including the bit LR_LOADFROMFILE, which causes Windows to load from a file on disk. This underlying functionality only supports TBitmap (BMP) format.
See the nearly-duplicate question. PNG support is a designtime feature that is converting the PNG data into an internal non-PNG and not-exactly-a-BMP-either format, used internally by MS Common Controls library. View your DFM as text, and you will see what your PNG inputs have been turned into. The other answers show you that transparency is preserved, using bitmap-color based transparency.
If you want to keep your data in PNG format, you shouldn't be using a VCL TImageList to store it, because you're going to have to do a conversion from PNG to TBitmap to actually use TImageList.

Problem changing icon in Delphi 2007

I've been working with a program someone else has made and I wanted to change the icon.
The icon I have is 256x256. I used http://converticon.com/ to create the icon (from a bmp I think). I used the icon in Inno Setup to create an installer and it worked fine
So I go to Options -> Application and attempt to load it. However, Delphi 2007 gives me an error 'The parameter is incorrect.' with this info: http://i.stack.imgur.com/vRCgs.png
When I do the same thing in Delphi XE, it works and loads the icon and changes it on compile. I can't use XE right now because the program uses a math parser that has a problem with unicode (thats something to fix for later haha)
So, what I did was open the project in XE, change the icon, save it, delete the dproj and open it in 2007. This works, compiles and displays the correct icon, but when I go to the project options, it gives me the same 'The parameter is incorrect' error.
The workaround isn't a big deal, but I shouldn't need to do it. Does anyone know why I can't change the icon in Delphi 2007?
Edit: I just used that same converticon site to convert the 256x256 icon to 192x192 and smaller and now it works perfectly. Thanks for the answers
The "icon" file is actually a collection of images, at different resolution and using different encodings. When I'm creating my icons I'm making sure they don't actually contain the 256x256 PNG-encoded version because development tools built before Windows Vista don't understand that. And that includes your Delphi 2007 and my Delphi 7. I also remove the alpha-encoded 256x256 icon because it simply makes the file needlessly large.
You've got two fixes possible:
Find an ICO editor and remove all of the larger formats until your Delphi accepts the icon. I personally never seen the 256x256 used in the real world, they'd take up huge amounts of space on user's Desktop or in Windows Explorer.
Use a dummy icon and replace the icon resource in the generated exe after Delphi is done with it. This way you can keep all of the larger image formats, including the 256x256 PNG image.
Edit to correct an error
If possible, always include the 256x256 image, Windows scales that down for everything above 64x64.
I always assumed Windows Explorer would show an image that's based on the closest matching image size available in the ICO. That is, if a 128x128 image is necessary, Windows would use the 128x128 image if available, or scale down the 256x256 image if that's available, or scale up the 96x96 image. Apparently that's not so. I've just made a test icon consisting of several image formats, including 32, 48, 72, 96, 128 and 256 consisting of simple blobs of color (using the flood-fill tool). In Windows Explorer I cycled throw the various Display Modes, and it became apparent that starting with "Large Icon" (and that's not very large) Windows will scale down the 256x256 icon, and if that's not available, use the 48x48 icon, unscaled! The result is truly ugly and unexpected. The 72x72, 96x96 and 128x128 icons were simply ignored.
Thank you David for pointing this out.
Older versions of Delphi don't support 256px Vista icons. I believe that 2010 does not support them so I guess the limitation was fixed in XE.
When working with an older Delphi you'll need to keep the 256px icon out of the IDE. You can still build an executable with a 256px icon from the command line compiler - I used to do just this before upgrading from Delphi 6. But to do this requires the use of a competent resource compiler, for example the Microsoft one.
2007 will let you select icons with a 256 pixel image. Here is what I tried:
The default icon for Delphi XE contains several image sizes, including a 256 pixel image.
If I extract the icon from a Delphi XE application using a resource editor, I can add that icon to a Delphi 2007 application using the IDE's project options. I don't get an error, and the icon images show as expected in Windows Vista/7 using Explorer at different sizes.
If I take the same icon that worked in Delphi 2007 and remove all of the image sizes other than the 256 pixel image using IcoFX, and try to select it again, then I get an error.
Try creating a .ico that includes other image sizes and see if that works for you.

TImage losing loaded picture

Running Turbo Delphi Pro.
I'm using TImage to display a png image.
When I restart Delphi and load the dpr file, TImage is still there, but the picture is lost,
requiring a reload of the picture before compiling.
At first I thought it's a path issue, so I loaded the picture from the same directory as the dpr, but it didn't help.
What else can I try?
Try this:
Open your project and your Form with
the PNG.
(Re)Load the PNG image.
Save and close your Form.
With a text editor, load your Form
DFM
I bet you don't have a big binary in
your TImage object, because the PNG content
has not been saved.
Bottom line, you'd have to include it as a resource and load it dynamically at runtime.
I ran into this problem as well with D2006. The solution I used is similar to François'.
I have a TPngImageCollection component that I collect all the images in at design time. You will need to find unit PngImageList off the web. The TPngImageCollection component has the advantage that you can have a collection of PNG images of differing sizes.
At run-time on startup, I assign the TImages from each of the collection members:
Image1.Picture.Assign (ImageCollection.Items [0].PNGImage) ;
Image2.Picture.Assign (ImageCollection.Items [1].PNGImage) ;
Image3.Picture.Assign (ImageCollection.Items [2].PNGImage) ;
etc
Bingo - you can produce your PNG originals with alpha transparency (I use PhotoPlus 6.0 from Serif - free and very capable) and show them in a TImage.

Resources