0

I needs ideas on how to track-down / solve this problem:

I have a potential customer who states that on Windows 7 32bit my software is giving this error:

imagelist Failed to read ImageList data from stream

Person has given this additional information:

  • Program does work with Areo theme enabled
  • Program throws the error on classic theme
  • IE 11 is installed
  • Person reports having both 5.82.7601.18837 comctl32.dll in system32 folder and 6.10.7601.23039 comctl32.dll in winsxs folder

(Quick note for those who not aware - since WinXP both versions have shipped as default)

...

The executable is built using XE4 on a themed Windows 10 and works on at least (own tested)

  • win10/32bit
  • win10/64bit
  • WinXP/32bit/classic-theme
  • HyperV-Virtual-Win7-SP1/32bit/classic-theme/16bitcolor

My TImagelist is set to "cdDeviceDependent" (which corresponds to ILC_COLORDDB)

...

This is my manifest extracted from my executable using a resource explorer:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
  <dependency>
    <dependentAssembly>
      <assemblyIdentity
        type="win32"
        name="Microsoft.Windows.Common-Controls"
        version="6.0.0.0"
        publicKeyToken="6595b64144ccf1df"
        language="*"
        processorArchitecture="*"
      />
    </dependentAssembly>
  </dependency>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel
          level="asInvoker"
          uiAccess="false"
        />
      </requestedPrivileges>
    </security>
  </trustInfo>
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
      <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
      <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
      <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
    </application>
  </compatibility>
</assembly>

...

TODO

I have noticed in documentation that for ImageList_WriteEx is states: "You should not create an image list that is written with the ILP_DOWNLEVEL flag with ILC_COLOR32"...

I am not sure what happens when compiling on a 32bit-color system using "ILC_COLORDDB" as value?

My thinking is/was that ILP_DOWNLEVEL would possible be ignore... And thus more likely to fail when read by 5.x ComCtl32? But I have not been able to find any such cases described on the internet, but...

Also it appears my executable works on a virtual Win7-SP1-32bit-16color-classic-themes configuration...

...

TODO

Send a debug tool to fetch/confirm the actual version loaded on comctl32.dll

...

TRIED

I have tried pointing the user to an old version with a manifest without the **compability section. That did not make any difference.

Tom
  • 3,587
  • 9
  • 69
  • 124
  • 1
    Can you check if V6 of ComCtl32.dll is actually available on that Win 7 system? – Uwe Raabe Dec 16 '18 at 21:00
  • In addition, IIRC also switching Win 7 to the Classic theme can have the same effect. – Uwe Raabe Dec 16 '18 at 21:09
  • --(1)-- I will have to find instructions for the user on how he can check (or I have to write/find a utility that does that) as I have no access to the computer --(2)-- I have just asked the user this. However, I find it puzzling why my Delphi program would not run on a Windows using classic theme... Have I configured my manifest file incorrectly? (I believe the ComCtl32 affects save/load stream data, but even so) – Tom Dec 16 '18 at 21:41
  • What fails is [this](https://learn.microsoft.com/en-us/windows/desktop/api/commctrl/nf-commctrl-imagelist_read). Unfortunately it doesn't tell anything about why it fails. – Sertac Akyuz Dec 16 '18 at 22:10
  • Just quick note - customer responded he is using "Classic theme" (I am asking him to try using e.g. Aero to confirm that is the reason) .... But that would mean that the users system when using classic-theme is using a very old ComCtl32 version right? From my reading the imagelist read problem shoud only occur if Delphi uses ComCtrl32 6.x when saving DFM/imagelist data and then program is loading DFM/imagelist data using ComcTL32 < 4.72 – Tom Dec 17 '18 at 06:24
  • 1
    Start from somewhere. Send an executable with the same manifest and imagelist that retrieves the version (`@GetDllVersion := GetProcAddress(LoadLibrary(comctl32), 'DllGetVersion'` ...). – Sertac Akyuz Dec 17 '18 at 17:06
  • I will do that. For "round 1" I have asked the customer to check an earlier version where the manifest file does not have the – Tom Dec 17 '18 at 23:58
  • Scratch that - not a manifest issue. Old version also did not work. – Tom Dec 18 '18 at 00:33
  • On my Windows 7 machine I only have ComCtl32 version 5.82. Granted my machine doesn't have all windows updates installed since I have automatic windows update turned off. – SilverWarior Dec 18 '18 at 03:42
  • 1
    @SilverWarior You are sure you do not have it in WinSxS? V6 was already part of WindowsXP vanilla distributions... (But you find it in WinSxS folder) It is my understanding that Delphi applications should still work fine since if an app requests V6 in manifest - and it is not there - V5 will be used instead. But quite unlucky with the image streaming... But there has to be other Delphi developers encountering this then. – Tom Dec 18 '18 at 08:53
  • 1
    What @SertacAkyuz said. You need to check the comctl32 DLL version. It is quite possible that Delphi IDE saved the list in a newer sream format that the client can't read with an older ComCtl32 version. A side note: I never trust the DFM streaming the image list so I keep the bitmap itself (not stream format) as a resource in a separate DLL or in my EXEs, and load it into the imagelist at run-time via `ImageList_LoadImage`. – kobik Dec 18 '18 at 09:55
  • @kobik I am considering doing a custom solution as well - will let you know what I end up doing. – Tom Dec 18 '18 at 22:55
  • The issue does not make much sense though either way. Looking at TCustomImageList.WriteData Delphi XE4 always writes in old format - either by using V6 "downlevel" param - see ImageListWriteExProc(Handle, ILP_DOWNLEVEL, SA) https://learn.microsoft.com/en-us/windows/desktop/api/commctrl/nf-commctrl-imagelist_writeex .... or if V6 not available then ImageList_Write(Handle, SA) ... so the imagelist data should be saved correctly no matter what (and I do not see any special comments regarding anything like Win10 ComCtl32 V6 ignoring "downlevel" param) – Tom Dec 19 '18 at 00:27
  • Although... TImageList uses ColorDepth "cdDeviceDependent" And the above documentatiton link does say "You should not create an image list that is written with the ILP_DOWNLEVEL flag with ILC_COLOR32." ... Maybe worth researching further if something is going on there... – Tom Dec 19 '18 at 00:36
  • Seaching Google for "ImageList_WriteEx ILP_DOWNLEVEL ILC_COLORDDB" does not yield results. But logically, if my computer is configured to 32bit ... Then does ILC_COLORDDB not map down to ILC_COLOR32 inside Windows when I am compiling my application? And if so (since 32bit colors a V6 only thing) it would ignore the ILP_DOWNLEVEL parameter? I am not sure - I may be rambling, but looking at the Delphi TImageList code its stream format should otherwise always be ComCtl32 V5 compatible ... Seems to me culprit must be something doing that is not working properly. But Delphi's code look very clean. – Tom Dec 19 '18 at 01:47
  • One more bit of info. I have a fully patched WinXP computer running classic themes... It works there. – Tom Dec 20 '18 at 15:10
  • 1
    Why don't you/we even know yet what exact version of comctl32 loads your executable at the customer site? – Sertac Akyuz Dec 20 '18 at 15:22
  • @SertacAkyuz because when you sell shareware you do not know the users very well? And it is often limited how many tests you can put them to when they have yet to purchase (if I wrote customer that was a mistake. He was a person who said he would probably buy if problem could be resolved) – Tom Dec 20 '18 at 17:17

1 Answers1

-4

By default the ComCtl32 version on Windows 7 is 5.82 and not 6.x.

Common Control Versions

So you will have to modiffy your manifest acordingly to allow use Comctl32 version compatible with Windows 7.

That is of course if your application isn't using some feature that isn't present in ComCtl32 version 5.82. If it does then you will have to implement some workarround to it or simply remove Windows 7 from officially supported platforms for your application.

SilverWarior
  • 7,372
  • 2
  • 16
  • 22
  • 2
    You have to read the table you link, just two rows below. Windows 7 shipped with both 5.82 and 6.10. – Sertac Akyuz Dec 17 '18 at 15:05
  • @SertacAkyuz It is possible that some windows update might have shipped with newer ComCtl32 file but by default ComCtl32 ver. 5.82 is used. In fact when I check ComCtl32 version on my Windows 7 machine I only have version 5.82. Granted I don't have my machine fully updated since I'm installing windows updates manually from time to time instead of leaving automatic updates enabled. So my answer is perfectly valid and thus don't know why it was flagged for deletion. Besides in order to get best compatibility you should target the lowest excepted version of ComCtl32 possible. – SilverWarior Dec 18 '18 at 03:36
  • You will find V6 in WinSxS folder. V6 was even shipped with vanilla Windows XP (what makes themes work in Windows XP) See: https://www.geoffchappell.com/studies/windows/shell/comctl32/history/index.htm – Tom Dec 18 '18 at 08:55
  • No, the link is accurate, your answer is wrong. In addtion to the answer, your comment does not make sense too. You have to target version 6 in order to even have visual styles (runtime themes). – Sertac Akyuz Dec 18 '18 at 10:13