• Re: ImageList_GetImageInfo - alter the bitmap(s) ?

    From Richard@21:1/5 to All on Mon Nov 4 16:57:52 2024
    [Please do not mail me a copy of your followup]

    "R.Wieser" <address@is.invalid> spake the secret code <vdg6rq$2kuoo$1@dont-email.me> thusly:

    but the docs say GetImageInfo returns an ImageInfo structure, which
    includes an hBitmap.

    Indeed it does. Having the bitmap(s) is where my problems started. :-\

    I'm confused. The ImageList is giving you the *handle* of the bitmap
    that it is using. So whatever you do using that bitmap handle as the
    target of some drawing operation will update the bitmap that is being
    used by the ImageList.

    Are you not seeing the changes in the ImageList?

    Remember that if you change the ImageList that was used to draw
    something on screen, you'll need to redraw whatever control is using
    the ImageList to see the effect on screen, e.g. call InvalidateRect.
    --
    "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
    The Terminals Wiki <http://terminals-wiki.org>
    The Computer Graphics Museum <http://computergraphicsmuseum.org>
    Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Mon Nov 4 18:28:19 2024
    Richard,

    Indeed it does. Having the bitmap(s) is where my problems started. :-\

    I'm confused.

    Yes, you are. :-)

    The ImageList is giving you the *handle* of the
    bitmap that it is using. So whatever you do using that bitmap
    handle as the target of some drawing operation will update the
    bitmap that is being used by the ImageList.

    To be able to alter a HBITMAP you need to select it into a "device context" (DC). described in the docs you can only do that into one at a time (1).

    And as an imagelist has already selected the bitmap(s) into its own DC (2)
    ...

    (1) https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-selectobject

    "An application cannot select a single bitmap into more than one DC at a
    time."

    Are you not seeing the changes in the ImageList?

    See above. As long as I can't select the HBITMAP into a DC I can't draw on
    it.

    you'll need to redraw whatever control is using the ImageList
    to see the effect on screen, e.g. call InvalidateRect.

    Yes, I know. Still, thanks for mentioning it.

    (2) For one test I dug into the "hImageList" structure and found its DCs.
    By using those I was able to both alter the bitmap(s) and draw it (in the "paint" event) onto the dialog.

    But as using stuff from within unspecified, "MS internal" structures is a
    bit of a no-no (and it also caused its own problems) ...

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Richard@21:1/5 to All on Mon Nov 4 17:47:10 2024
    [Please do not mail me a copy of your followup]

    "R.Wieser" <address@is.invalid> spake the secret code <vgb086$121de$1@dont-email.me> thusly:

    The ImageList is giving you the *handle* of the
    bitmap that it is using. So whatever you do using that bitmap
    handle as the target of some drawing operation will update the
    bitmap that is being used by the ImageList.

    To be able to alter a HBITMAP you need to select it into a "device context" >(DC). described in the docs you can only do that into one at a time (1).

    And as an imagelist has already selected the bitmap(s) into its own DC (2) >...

    I see that on ComCtl32.dll version 6 or later, they have a way for you
    to QueryInterface for an IImageList interface which has a Replace
    method that you can use to replace the bitmap. So they do expose a
    way to do it in later versions of the common controls library. <https://learn.microsoft.com/en-us/windows/win32/api/commctrl/nf-commctrl-himagelist_queryinterface>

    Can you use that?

    If not, have you tried calling ShowWindow to hide the control and then
    try to select the bitmap into a DC? Perhaps if the window is hidden,
    it deselects the bitmap from its internal DC.

    Also, maybe I missed it in the thread where you stated it, but I
    assume you're using the image list in association with another
    control. Have you tried just creating a new image list with the
    updated bitmap and replacing the image list on the target control?
    --
    "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
    The Terminals Wiki <http://terminals-wiki.org>
    The Computer Graphics Museum <http://computergraphicsmuseum.org>
    Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Mon Nov 4 19:56:58 2024
    Richard,

    I see that on ComCtl32.dll version 6 or later, they have a way
    for you to QueryInterface for an IImageList interface which has
    a Replace method that you can use to replace the bitmap.

    The "IImageList::Replace" method you mean (or the function
    "ImageList_Replace") ? Yes, you can replace the image *of a single item*
    with that. Which is rather useless when you have a big bitmap (from "ImageList_GetImageInfo"), with all items on it.

    But you've skipped the most important part of the problem: How do I edit
    that big bitmap ?

    MS tells me that its possible : "The information in this structure can be
    used to directly manipulate the bitmaps for the image" ?

    ( https://learn.microsoft.com/en-us/windows/win32/api/commctrl/nf-commctrl-imagelist_getimageinfo )

    But how ?

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Richard@21:1/5 to All on Mon Nov 4 21:56:35 2024
    [Please do not mail me a copy of your followup]

    "R.Wieser" <address@is.invalid> spake the secret code <vgb5e6$130d7$1@dont-email.me> thusly:

    Richard,

    I see that on ComCtl32.dll version 6 or later, they have a way
    for you to QueryInterface for an IImageList interface which has
    a Replace method that you can use to replace the bitmap.

    The "IImageList::Replace" method you mean (or the function >"ImageList_Replace") ?

    I didn't notice the function until you mentioned it, but they seem to
    be the same.

    Have you tried the function? It seems to do what you want.

    Without decompiling, we don't know what the implementation does, but
    if I were to implement it, I would take the given bitmap and use that
    as a source for a copy operation into the internal bitmap used by the
    image list. Otherwise you impose the requirement on the caller that
    the supplied bitmap must outlive the image list, which is not only a
    poor design but isn't documented in the Replace or Add functions for
    image lists. In fact, the Add function documentation explicitly
    mentions that the supplied bitmap is copied into an "internal data
    structure".

    Yes, you can replace the image *of a single item*
    with that. Which is rather useless when you have a big bitmap (from >"ImageList_GetImageInfo"), with all items on it.

    Again, without decompiling, we can't infer what happens behind the
    scenes. At best, we should only be going by what is documented
    behavior, and it seems that ImageList_Replace is the function provided
    to do what you want.

    Again, have you tried that and does it give the desired visual
    results?

    If yes, what exactly is the problem?

    But you've skipped the most important part of the problem: How do I edit
    that big bitmap ?

    I don't think you can edit it directly; you are intended to use the
    ImageList functions to replace images as a whole. The bitmap handle
    in the IMAGEINFO struct could be use as the source for a bitmap copy,
    but as you (and the documentation points out) the bitmap is selected
    into a DC and there's no way to obtain that internal DC. I'm away
    from my copy of Rector & Newcomer, so I don't have anything besides
    the MS docs to go on.

    It's entirely possible that this "manipulate the bitmap directly"
    language is a holdover from Win16 and isn't relevant to Win32.
    --
    "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
    The Terminals Wiki <http://terminals-wiki.org>
    The Computer Graphics Museum <http://computergraphicsmuseum.org>
    Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to Even though MS on Tue Nov 5 10:46:24 2024
    Richard,

    The "IImageList::Replace" method you mean (or the function >>"ImageList_Replace") ?

    I didn't notice the function until you mentioned it, but they seem
    to be the same.

    Have you tried the function? It seems to do what you want.

    [quote=me]
    Yes, you can replace the image *of a single item* with that. Which is
    rather useless when you have a big bitmap (from "ImageList_GetImageInfo"),
    with all items on it.
    [/quote]

    Without decompiling, we don't know what the implementation does,

    Yes, we do. That is what the "learn.microsoft.com" website is for.

    but if I were to implement it, I would take the given bitmap and use
    that as a source for a copy operation into the internal bitmap used
    by the image list.

    There are exacly *two* functions which accept images for multiple items, and those do not seem to accept a grid of them (such as ImageList_GetImageInfo returns), looking at the explanation "The number of images is inferred from
    the width of the bitmap" to the "hbmImage" argument.

    In fact, the Add function documentation explicitly mentions that
    the supplied bitmap is copied into an "internal data structure".

    Besides the above problem, how does that "add" function REPLACE the
    origional bitmap ?

    Again, without decompiling, we can't infer what happens behind the
    scenes.

    Again, yes we can. Its called "reading the documentation". Unless you want
    to claim that the MS documentation is untrustworthy and should be ignored.
    :-)

    At best, we should only be going by what is documented behavior,
    and it seems that ImageList_Replace is the function provided
    to do what you want.

    The "iIndex" parameter and its "An index of the image to replace"
    explanation to that function tells me otherwise.

    Again, have you tried that and does it give the desired visual
    results?

    If yes, what exactly is the problem?

    You want me to test something that is at odds with the explanation to those* functions ? Why ? Just to see if you can catch MS on having made a mistake
    ?

    * you're flip-flopping, without saying, between the "add" and the "replace" function.

    But, have it your way. Testing both ... No, neither works as you expected.

    But you've skipped the most important part of the problem: How do I
    edit that big bitmap ?

    I don't think you can edit it directly;

    Even though MS says otherwise ? On what grounds ?

    you are intended to use the ImageList functions to replace images as a
    whole.

    Nope. There is not a single function which does that.

    The bitmap handle in the IMAGEINFO struct could be use as the source
    for a bitmap copy,

    Ofcourse you can. You just don't get the result you think you should be getting. :-p

    but as you (and the documentation points out) the bitmap is selected
    into a DC and there's no way to obtain that internal DC.

    :-) Guess again. Its even easy to get those DC's. But, as mentioned
    earlier, poking into undocumented structures is a bit of a no-no.

    I'm away from my copy of Rector & Newcomer, so I don't have anything
    besides the MS docs to go on.

    As mentioned and shown, the latter is what I'm using too. And as such I'm wondering about how you got to your "can be used to replace the full image" conclusion.

    It's entirely possible that this "manipulate the bitmap directly"
    language is a holdover from Win16 and isn't relevant to Win32.

    You mean that that "information" has survived for almost a quarter of
    century and multiple "remove everything about old Windows versions" cleanups
    ? Well, I guess that is possible. Everything is.

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Thu Nov 7 10:39:51 2024
    Richard,

    you are intended to use the ImageList functions to replace images
    as a whole.

    Nope.

    I should perhaps extended on that "nope".

    Nope, thats *your* goal.

    *Mine* was to be able to alter the appearance of certain items in the
    ImageList (and keep the rest as-is). Like drawing stuff onto them and/or combine multiple items into a single one.

    ... Which I figured out how to do before starting this thread.

    My question was solely aimed at trying to find a simpler solution, one that
    the MS documentation suggested was available.


    But *you* wanted to see if those "replace" and "add" functions didn't
    secretly do much more than what they where documented to do, and I decided
    to humor you.

    First try:

    Trying to "replace" or "add" using the bitmaps returned by "GetImageInfo" always fails - due to the same reason you can't draw on those bitmaps: they
    are already loaded into a DC. As a result the "replace" visually didn't
    seem to do anything, and "add" just appended some blackness.

    I could have stopped there-and-than, as it didn't do what *I* wanted.


    Second try:

    But I said I would humor you, and that means to me I follow *your* lead, not mine. So I replaced the bitmaps by two I loaded from file, and tried
    again - just to see if that would work better.

    It did. Visually the "replace" function now showed a change, and the "add" function added something beyond blackness - but both failed to load all of
    the offered bitmaps contents.

    And that was the result I posted.


    Bottom line:

    You've replaced my request for information with some quite different - and
    by it skipping over the "how do I edit the imagelists own bitmaps ?" problem
    to begin with, while you didn't even bother to explain why you thought you
    knew better than MS own documentation.

    Also, you decided that some undocumented behaviour (of the "replace" and
    "add" functions) would be fully acceptable to me, while I already posted
    that I could infact edit those internal bitmaps *if* I would not mind
    relying on some undocumented stuff - which I indicated I didn't want to do.

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)