In Delphi 2007, images are loaded in a TImageList at design time. This introduces the following problem:
I have a folder containing the graphics I'm using in my application
Whenever I want to change, say, the icon for 'save', I have to
Change the graphic in the folder (for my own purposes)
Iterate along all TImageLists in the application
Change the graphic in the TImageList
Is there any way (component, compile script, ...) to perform steps 2 and 3 automatically, that is, specify only paths of graphics at design time, creating a dependence on the actual graphic files?
You could create a descendant of TImageList and add that kind of logic there.
Since components referring to images inside a TImageList do that by index, it would be easiest to have your descendant to have a ImagePaths property of type TStrings that is formatted like this:
#=Filename
And maybe add a property BasePath of type string as well.
Then upon loading that component, it could automagically reload those images in memory.
You could even make it a design-time expert which loads the images in the designer.
--jeroen
Classes are never fully compiletime. Designtime classes are streamed from resources too.
I load the images into the TImagelist at runtime. For this very reason, I do not assign any images at design time. They are all added as a resource to the exe and I load them at runtime from there. This also means that the images can be changed without recompiling the exe.
Related
Is it possible to access the images in TImageCollection from the executable or the resource file. i.e. outside the IDE. How are these images held?
Yes, image list and image collection images are stored in the DFM files. You can see this if you go to the form or data module containing the image list or collection, and then press Alt+F12 to see the DFM code. Alternatively, you can simply open the DFM file in your favourite text editor.
And these DFMs are embedded into your EXE as RCDATA resources, so you can see them if you open your EXE in a resource editor.
At runtime, your EXE can access the images via the TImageCollection.Images property, which is a collection of TImageCollectionItem objects.
TImageCollectionItem has a SourceImages property, which is a collection of TImageCollectionSourceItem objects.
TImageCollectionSourceItem has an Image property of type TWICImage
In the past, I have written custom components for Borland C++Builder. Some of these were derived from existing components, for example:
class PACKAGE TMyEdit : public TEdit
{
...
}
For some of these, I have also made custom bitmaps for the palette (.dcr files). I know how to create and edit them; that's not the point here.
Nowadays, I'm using a newer version of the IDE, Embarcadero C++Builder XE, and I notice a difference in behaviour for components without a .dcr file.
In the old days, the bitmap on the palette would be the same as the one where the component was derived from. Let's say the TMyEdit had the same bitmap as the TEdit.
But now, these components get a default icon. So all components without a .dcr file look alike on the palette.
I see 2 possible ways to solve this:
Is there perhaps some way to indicate in the source files that I want to inherit the bitmap of the original component?
If that isn't possible, I'll have to create new .dcr files for each new component. Is there a neat way to retrieve the original bitmaps? Perhaps there exists a resource file? Or an option in a wizard that I haven't found yet? If not, I'll have to resort to using Alt-PrtScn and MSPaint. That would work, but it would be tedious.
In VCL I used TOpenPictureDialog for loading of image files because it's useful to see a preview when selecting from a long list of files. I also used it for loading my own binary file format by creating a class derived from TGraphic, overriding the load and draw functions and registering it with TPicture. Now I've moved to FMX and would like a similar preview, but there is no TOpenPictureDialog. My only alternative currently seems to be to create a custom form for loading these files, including the ability to browse folders, etc, which seems like a big job to replicate all the functionaly of TOpenPictureDialog. Before I do that I wonder if anyone knows of a pre-existing component that does this? I'd like to support Windows and OSX initially.
If I do end up making my own component, would it be easier to start from scratch or to derive from and extend TOpenDialog? It seems that TOpenDialog is just running the default Windows open dialog in Windows so it seems unlikely that I could do that.
This is one of the few things missing from FMX that is available in VCL.
I made a custom component that needs a rather large (say 1MB) UTF8 text to function. For development purposes, I just loaded this from a file. Now I want to get rid of that file. What is the easiest way to store its contents in the component, such that the user of the component needn't bother with this?
First I tried making it string constant, but soon Delphi started to complain in many different ways (too long or too many, out of memory, etc.). When I switched to embedding it as a resource, I found that the resource will not be automatically compiled into the actual application as well, so it's not transparent to the component user...
Update
I got it working if I create a resource file myself, which I manually add to the unit. Then, I still need a pre-build event for it to be actual. The question remains why it doesn't work if I add it to the package, via the Delphi menu, rather than to the unit. And why {$R myresource.res myresource.rc} doesn't compile it automatically as it should...?
Update 2
Apparently the resource script needs to be added to the project for automatic compilation to work.
Adding the {$R myresource.res} line in the unit containing the component should work.
You can add the myresource.rc file to the component's package to make Delphi generate myresource.res automatically.
I have a large application which i want to migrate to Arabic. I have defined the strings that we show to the user under the resourcestring keyword.
I am using the External Translation manager provided with Delphi 6. However, I am not very much comfortable using the tool. I want to create a resource only dll with all the translated strings like how the Delphi ETM does, and then switch between languages at run-time at the click of a button.
I was able to link the resourcestrings to the Dll, but how about form's captions and hints and the component properties? I am loading the Dll at runtime depending on the language, but the form properties are not reflecting as they were not available in the Dll.
Any pointers in the right direction ???
Thanks
Rahul W
What the Delphi localization tool and runtime support do is to redirect resource loading - including forms - from the executable to the DLL. Forms, their components and controls (non default properties) are stored as resources into the executable (as long as you don't create them fully at runtime - but then you would have to set their properties one by one).
Thereby if you want to work alike the standard translation tool you have to work the same way. What the DLL Resource Wizard does is to extract all project .dfm (and those you add manually) and resourcestrings to a copy that can be localized. When an app is started the form loading code checks from where the .dfm should be loaded. You should override this code to load your resources.
Be aware that changes language at runtime may need a different approach, because loading a whole form from resources may "reset" it to the creation state. On the other hand, compared to approaches like gettext, it allows to localize far more than the form text, including images, colors, and to adapt control sizes to the new string easily. IMHO gettext is good for simple needs, but when localization becomes a complex task and you may need to localize for a very different "culture", more powerful tools are needed.