Author |
Topic  |
PeterPanino
   
993 Posts |
Posted - Apr 17 2020 : 14:05:17
|
In the Delphi 10.3.3 IDE, I have a question with the Resource Loader demo, after clicking the button "Load Resources in this Exe":
1. On the "Version" node, I see no version but an icon.
2. On the "Manifest" node, I see no Manifest but an icon.
Etc. etc.
So how can I FILTER the resources tree to show only nodes containing image data? (E.g. images, icons, cursors, etc.). Is this possible? |
|
PeterPanino
   
993 Posts |
Posted - Apr 17 2020 : 14:35:00
|
Or: How can I extract the Manifest text string from the buffer (from the Node.Data) in the TreeView1Change event-handler? |
 |
|
PeterPanino
   
993 Posts |
Posted - Apr 17 2020 : 14:43:02
|
But with this code:
if (m_ResourceExtractor.FriendlyTypes[res.TypeIndex] = 'Manifest') then
begin
CodeSite.Send('TMainForm.TreeView1Change: Manifest', buffer);
end;
...I see only Chinese characters... |
 |
|
xequte
    
39140 Posts |
Posted - Apr 18 2020 : 03:02:53
|
Hi Peter
I don't know codesite, but make sure it is treating the buffer as a PAnsiChar, e.g.
You can access the string as:
SetString( s, PAnsiChar(buffer), bufferLen);
But it depends on the resource type (it is not well documented).
You can filter the items added to the treeview in the LoadFile() event by comparing the type to:
const RT_ACCELERATOR = $00000009; RT_ANICURSOR = $00000015; RT_ANIICON = $00000016; RT_BITMAP = $00000002; RT_CURSOR = $00000001; RT_DIALOG = $00000005; RT_DLGINCLUDE = $00000011; RT_FONT = $00000008; RT_FONTDIR = $00000007; RT_GROUP_CURSOR = $0000000C; RT_GROUP_ICON = $0000000E; RT_HTML = $00000017; RT_ICON = $00000003; RT_MANIFEST = $00000018; RT_MENU = $00000004; RT_MESSAGETABLE = $0000000B; RT_PLUGPLAY = $00000013; RT_RCDATA = $0000000A; RT_STRING = $00000006; RT_VERSION = $00000010; RT_VXD = $00000014;
Nigel Xequte Software www.imageen.com
|
 |
|
PeterPanino
   
993 Posts |
Posted - Apr 18 2020 : 17:59:41
|
Hi Nigel,
1. where did you get those constants? Unfortunately, they don't contain constants for PNG, JPG. So I used this filter method:
if not ContainsText(IMAGETYPES, m_ResourceExtractor.FriendlyTypes[i]) then CONTINUE;
// Load Resources
procedure TMainForm.LoadFile(const sFileName: string);
const // How to use these constants to filter nodes? (Does not contain PNG, SVG, JPG)
RT_ACCELERATOR = $00000009;
RT_ANICURSOR = $00000015;
RT_ANIICON = $00000016;
RT_BITMAP = $00000002;
RT_CURSOR = $00000001;
RT_DIALOG = $00000005;
RT_DLGINCLUDE = $00000011;
RT_FONT = $00000008;
RT_FONTDIR = $00000007;
RT_GROUP_CURSOR = $0000000C;
RT_GROUP_ICON = $0000000E;
RT_HTML = $00000017;
RT_ICON = $00000003;
RT_MANIFEST = $00000018;
RT_MENU = $00000004;
RT_MESSAGETABLE = $0000000B;
RT_PLUGPLAY = $00000013;
RT_RCDATA = $0000000A;
RT_STRING = $00000006;
RT_VERSION = $00000010;
RT_VXD = $00000014;
const
IMAGETYPES = 'Cursor|Bitmap|Icon|GroupCursor|GroupIcon|PNG|SVG|JPG';
var
i, j, k: integer;
p1, p2: TTreeNode;
begin
if assigned(m_ResourceExtractor) then
m_ResourceExtractor.Free;
TreeView1.Items.Clear;
m_ResourceExtractor := TIEResourceExtractor.Create(sFileName);
if m_ResourceExtractor.IsValid then
begin
for i := 0 to m_ResourceExtractor.TypesCount - 1 do
begin
if chkOnlyImages.Checked then
if not ContainsText(IMAGETYPES, m_ResourceExtractor.FriendlyTypes[i]) then CONTINUE;
p1 := TreeView1.Items.Add(nil, m_ResourceExtractor.FriendlyTypes[i]);
for j := 0 to m_ResourceExtractor.NamesCount[i] - 1 do
if m_ResourceExtractor.IsGroup[i] then
begin
p2 := TreeView1.Items.AddChild(p1, m_ResourceExtractor.Names[i, j]);
for k := 0 to m_ResourceExtractor.GroupCountFrames[i, j] - 1 do
begin
TreeView1.Items.AddChildObject(p2, IntToStr(m_ResourceExtractor.GroupFrameWidth[i, j, k])
+ ' x ' + IntToStr(m_ResourceExtractor.GroupFrameHeight[i, j, k]) + ' '
+ IntToStr(m_ResourceExtractor.GroupFrameDepth[i, j, k]) + '-bit', m_ResourceExtractor.GetResourceBookmark(i, j, k));
end;
end
else
begin
TreeView1.Items.AddChildObject(p1, m_ResourceExtractor.Names[i, j], m_ResourceExtractor.GetResourceBookmark(i, j));
//CodeSite.Send('TMainForm.LoadFile: m_ResourceExtractor.Names[i, j]', m_ResourceExtractor.Names[i, j]);
end;
end;
end;
end;
It works. What do you think?
2. When I copy the image from the resource displayed in ImageEnView1 to the clipboard:
ImageEnView1.IEBitmap.CopyToClipboard(); ...then I get a BLACK background. How can I get a TRANSPARENT background instead?
3. What are the 132 images in the ImageList for?
4. Do you plan for TImageEnView to make it also render SVG images in the future?
5. The method SetString( s, PAnsiChar(buffer), bufferLen); works only for the Manifest resource. It does not work for resources of type String, Version and Dialog. How can these resource types be extracted and displayed?
|
 |
|
xequte
    
39140 Posts |
Posted - Apr 18 2020 : 21:17:00
|
Hi
0. RT values are defined in the Windows unit.
1. Yes, that looks good.
2. I'm actually not sure how transparency is handled by the clipboard in a generic way. I'll need to investigate that and see if it is possible.
3. Those are used for in-built and hover toolbars of TImageEnView and TIERichEdit
4. Yes. It is on our to-do list, and a particular area of interest for me
5. I can't find good documentation on that. If you can find some, please pass it on.
Nigel Xequte Software www.imageen.com
|
 |
|
PeterPanino
   
993 Posts |
Posted - Apr 19 2020 : 05:13:34
|
First I get the resource data from the TreeView:
res := TIEResourceBookmark(ANode.Data);
buffer := m_ResourceExtractor.GetBuffer(res, bufferLen);
Then I view the resource image in ImageEnView:
ImageEnView1.IO.Params.IsResource := true;
ImageEnView1.IO.LoadFromBuffer(buffer, bufferLen, fileType);
This works without problems.
But when I try to add the resource image to an ImageEnMView:
ImageEnMView1.MIO.LoadFromBuffer(buffer, bufferLen, fileType);
...then it does not work: The Multiview remains empty (ImageEnMView1.ImageCount = 0 before and after ImageEnMView1.MIO.LoadFromBuffer)
So, how can I add a resource image to a MultiView? |
 |
|
xequte
    
39140 Posts |
Posted - Apr 19 2020 : 16:00:45
|
Hi
With TImageEnMView, LoadFromBuffer can only be used for multiframe formats. You should load the resource into a TIEBitmap and then use TImageEnMView.AppendImage( bmp );
Nigel Xequte Software www.imageen.com
|
 |
|
PeterPanino
   
993 Posts |
Posted - Apr 26 2020 : 14:19:33
|
How can I load the resource into a TIEBitmap if this is the only resource data available:
res := TIEResourceBookmark(ANode.Data);
buffer := m_ResourceExtractor.GetBuffer(res, bufferLen);
|
 |
|
PeterPanino
   
993 Posts |
Posted - Apr 26 2020 : 15:34:05
|
Instead of loading the resource into a TIEBitmap now, I load it the normal way into TImageEnView and then append that to the MultiView. It works. |
 |
|
xequte
    
39140 Posts |
Posted - Apr 26 2020 : 15:55:55
|
Hi
To load a resource into a TIEBitmap:
...
bmp := TIEBitmap.Create;
bmp.ParamsEnabled := True; // We need the params
bmp.Params.IsResource := true;
bmp.Read(buffer, bufferLen, fileType);
...
Nigel Xequte Software www.imageen.com
|
 |
|
PeterPanino
   
993 Posts |
Posted - Apr 27 2020 : 05:50:18
|
Thanks, Nigel.
There is another question: When adding images to a MultiView, is it possible to exclude DOUBLES, for example:

Doubles are considered images which are bit-identical.
I could create a Hash of every image to append and then check whether that Hash already exists. But maybe something like this is already built-in in TImageEnMView? |
 |
|
xequte
    
39140 Posts |
|
PeterPanino
   
993 Posts |
Posted - Apr 28 2020 : 10:59:24
|
SetString(s, PAnsiChar(buffer), bufferLen);
...in some cases s includes an existing BOM:

How to avoid including the BOM? |
 |
|
PeterPanino
   
993 Posts |
Posted - May 01 2020 : 14:05:26
|
You wrote:
"5. I can't find good documentation on that. If you can find some, please pass it on."
If I use PAnsiChar then the string is empty:
SetString(s, PAnsiChar(buffer), bufferLen);

However, when I use PWideChar then I get the full string:
SetString(s, PWideChar(buffer), bufferLen);

So this seems to be the solution. But how do I know when I have to use PAnsiChar or PWideChar? (With the "Manifest" string I have to use PAnsiChar).
And there are still some strange control characters in the text. So maybe PWideChar is not the best way to extract the resource strings? |
 |
|
xequte
    
39140 Posts |
|
PeterPanino
   
993 Posts |
Posted - May 04 2020 : 05:05:40
|
As I described, I show the Resource images in a TImageEnMView:

As you can see, these are images of different dimensions and different bitness which I want to show as BottomText for each image.
Currently, I have this setting:

...because I did not find a setting that shows both dimensions and bitness as BottomText for each image.
So how can I show both dimensions and bitness as BottomText for each image? (E.g. 32 x 32 8-bit) |
 |
|
PeterPanino
   
993 Posts |
Posted - May 04 2020 : 07:44:59
|
After reading the documentation, I came to this solution:
procedure TformMain.ImageEnMView1GetText(Sender: TObject; Index: Integer; Position: TIEMTextPos; var Text: WideString);
begin
if Position = iemtpBottom then
Text := IntToStr(ImageEnMView1.ImageWidth[Index]) + ' x ' +
IntToStr(ImageEnMView1.ImageHeight[Index]) + ' ' +
IntToStr(ImageEnMView1.ImageBitCount[Index]) + '-bit';
end;
...which results in this BottomText:

But as you can see from the screenshot, the BottomText shows 24-bit where the Resource Demo shows 32-bit!
What is wrong here? |
 |
|
PeterPanino
   
993 Posts |
Posted - May 04 2020 : 16:59:52
|
How do I load an AVI from a Resource?
ImageEnView1.IO.LoadFromBuffer(buffer, bufferLen, ioAVI);
...does not work! |
 |
|
xequte
    
39140 Posts |
Posted - May 07 2020 : 18:18:43
|
Hi
ImageEn only supports loading of AVI videos from a file. You would need to save the content to a temporary file and then load it.
Nigel Xequte Software www.imageen.com
|
 |
|
PeterPanino
   
993 Posts |
Posted - May 08 2020 : 14:02:47
|
Hi Nigel,
when I try to save the images in the TImageEnMView (filled from a TImageEnView with ImageEnMView1.AppendImage(ImageEnView1.IEBitmap)) to a multi-image format:
ImageEnMView1.MIO.SaveToFileTIFF(MyFileSaveDialog.FileName);
...then the resulting file is not a valid image file!
It works ONLY if the images were extracted from a Bitmap resource. When extracted from another image type resource then the resulting file is not a valid image file! |
 |
|
Topic  |
|