Hi

I have a problem concerning image lists. In a treeview window procedure, when I receive a TVM_SETIMAGELIST message, I call the following procedure, that does some graphic operations to the images (in particular, it replaces every pixel with the COLOR_WINDOW system color with a neighboring color).

; Filter an image list to prevent unwanted transparency

ImageList_NoTransparency proc uses ebx esi edi hwnd,himl
local hdc :dword ;Window device context
local memdc :dword ;Memory device context
local hold :dword ;Old bitmap object in memory DC
local transclr :dword ;Transparent color (COLOR_WINDOW)
local iinfo :IMAGEINFO ;Image info
local binfo :BITMAP ;Bitmap info

mov transclr,$invoke (GetSysColor,COLOR_WINDOW)
mov hdc,$invoke (GetDC,hwnd)
mov memdc,$invoke (CreateCompatibleDC,eax)
invoke ImageList_GetImageCount,himl
.if eax != 0
xchg eax,ebx
dec ebx
.repeat
invoke ImageList_GetImageInfo,himl,ebx,addr iinfo
.if eax != 0
invoke GetObject,iinfo.hbmImage,sizeof BITMAP,addr binfo
invoke SelectObject,memdc,iinfo.hbmImage ;<== Here's the problem
.if eax != 0
mov hold,eax
mov esi,binfo.bmWidth
dec esi
.repeat
mov edi,binfo.bmHeight
dec edi
.repeat
invoke GetPixel,memdc,esi,edi
.if eax == transclr
sub al,1
jae @F
add al,2
@@: invoke SetPixel,memdc,esi,edi,eax
.endif
sub edi,1
.until sign?
sub esi,1
.until sign?
invoke SelectObject,memdc,hold
.endif
.endif
sub ebx,1
.until sign?
.endif
invoke DeleteDC,memdc
invoke ReleaseDC,hwnd,hdc
ret

ImageList_NoTransparency endp


My problem is that I can't select the bitmaps returned by ImageList_GetImageInfo into a memory device context. I know it should be possible, or the only way to access the bitmaps would be ripping the bitmap bits myself (with GetObject). Or is it?

Am I doing something wrong here? Or is it that, against all logic, the bitmaps in an image list can't be selected?
:confused:
Posted on 2003-08-05 11:38:51 by QvasiModo
Why not just create a compatible bitmap, select it into the DC then use imagelist_draw to draw onto the bitmap. You can then use the imagelist_replace function after you have altered it.
Posted on 2003-08-05 11:53:04 by donkey
Thanks, donkey! Great idea! :alright:
I still wonder why I can't select those bitmaps into a DC... this makes ImageList_GetImageInfo almost useless...
Posted on 2003-08-05 11:57:47 by QvasiModo
It should have worked according to the docs on the function, can't say why it doesn't. This is what it says about the ImageList_GetImageInfo function:
The ImageList_GetImageInfo function fills an IMAGEINFO structure with information about a single image, including the handles of the image and mask bitmaps, the number of color planes and bits per pixel, and the bounding rectangle of the image within the image bitmap. You can use this information to directly manipulate the bitmaps for the image

That appears to be exactly what you need, could be one of those "random features". :) after all I don't see anything about color planes in this structure:
typedef struct {

HBITMAP hbmImage;
HBITMAP hbmMask;
int Unused1;
int Unused2;
RECT rcImage;
} IMAGEINFO, *LPIMAGEINFO;

[b]Members[/b]

[b]hbmImage[/b]
Handle to the bitmap that contains the images.
[b]hbmMask[/b]
Handle to a monochrome bitmap that contains the masks for the images.
If the image list does not contain a mask, this member is NULL.
[b]Unused1[/b]
Not used. This member should always be zero.
[b]Unused2[/b]
Not used. This member should always be zero.
[b]rcImage[/b]
Bounding rectangle of the specified image within the bitmap specified by hbmImage.
Posted on 2003-08-05 12:06:06 by donkey
Hi,

some API's only work with bitmaps, selected to a hdc.
Other functions (and messages) only work with bitmaps, not selected to a hdc.
Try that.

Moderators:
Please don't clear my new atavar. It's not pornographical, it's art :cool:.

Greetings,
Nordwind64
Posted on 2003-08-06 08:19:23 by Nordwind64

Hi,

some API's only work with bitmaps, selected to a hdc.
Other functions (and messages) only work with bitmaps, not selected to a hdc.
Try that.


The problemis I want to make changes in the bitmap bits, unless I do it with raw access, I have to select the bitmaps into DCs...

Here's my new code:
; Filter an image list to prevent unwanted transparency

ImageList_NoTransparency proc uses ebx esi edi hwnd,himl
local hdc :dword ;Window device context
local memdc :dword ;Memory device context
local hbmp :dword ;Compatible bitmap object
local hold :dword ;Previous bitmap object in memory DC
local transclr :dword ;Transparent color (COLOR_WINDOW)
local iinfo :IMAGEINFO ;Image info
local binfo :BITMAP ;Bitmap info

mov transclr,$invoke (GetSysColor,COLOR_WINDOW)
mov hdc,$invoke (GetDC,hwnd)
mov memdc,$invoke (CreateCompatibleDC,eax)
invoke ImageList_GetImageCount,himl
.if eax != 0
xchg eax,ebx
dec ebx
.repeat
invoke ImageList_GetImageInfo,himl,ebx,addr iinfo
.if eax != 0
invoke GetObject,iinfo.hbmImage,sizeof BITMAP,addr binfo
.if eax != 0
mov hbmp,$invoke (CreateCompatibleBitmap,hdc,binfo.bmWidth,binfo.bmHeight)
mov hold,$invoke (SelectObject,memdc,eax)
invoke ImageList_Draw,himl,ebx,memdc,0,0,ILD_NORMAL
mov esi,binfo.bmWidth
dec esi
.repeat
mov edi,binfo.bmHeight
dec edi
.repeat
invoke GetPixel,memdc,esi,edi
.if eax == transclr
sub al,1
jae @F
add al,2
@@: invoke SetPixel,memdc,esi,edi,eax
.endif
sub edi,1
.until sign?
sub esi,1
.until sign?
invoke SelectObject,memdc,hold
invoke ImageList_Replace,himl,ebx,hbmp,iinfo.hbmMask
invoke DeleteObject,hbmp
.endif
.endif
sub ebx,1
.until sign?
.endif
invoke DeleteDC,memdc
invoke ReleaseDC,hwnd,hdc
ret

ImageList_NoTransparency endp

I'm still intrigued about why my previous idea didn't work...

Moderators:
Please don't clear my new atavar. It's not pornographical, it's art :cool:.


It would be good to see more of those artistic avatars around here... ;)
Posted on 2003-08-06 15:59:02 by QvasiModo
Hi,

The problemis I want to make changes in the bitmap bits, unless I do it with raw access, I have to select the bitmaps into DCs...


You could create a little bitmap and select it to your hdc. Now your bitmap is unselected.
After all you can reselect your bitmap...

It would be good to see more of those artistic avatars around here...


Yes, yes !

Greetings,
Nordwind64
Posted on 2003-08-07 14:05:34 by Nordwind64
I'm not sure of what you mean... the bitmap I wanted to use is returned by ImageList_GetImageInfo, so if it was previously selected into a different DC, I don't know wich one. I don't have my bitmaps selected into any DC when I call ImageList_Add.

The only solution I could find is the one donkey gave me... creating a new bitmap, and drawing with ImageList_Draw, the replacing the original image with the new one. What I originally wanted to do was to work on the original bitmap directly, to save some time and space (no need to create extra bitmaps, no need to replace images in list, less API calls and resources).
Posted on 2003-08-07 14:35:05 by QvasiModo
Hi QvasiModo,

hmm, sorry.
I have not spend much time watching your sourcecode...
Did not know another solution.

Greetings,
Nordwind64
Posted on 2003-08-07 22:43:23 by Nordwind64
Hey, no problem. :)
Posted on 2003-08-08 10:46:27 by QvasiModo