I'm desperately in need of someone's help :'(
Yesterday I was working on routine that can split given bitmap to a number of smaller ones. You know for skinning purpose, you have like up/down/middle state of button in one file. In my case there would be 16 separate bitmap files, if grouping wasn't used. You may also remember ImageList_.. that does exactly the same thing, but one remark - I cannot make it to return bitmap instead of icon, so I decided, it would be wiser to make my own routine for that purpose. I chose the simplest way - in bmp all images-states are laid out from top to bottom, so I'll need just add certain offset to get a pointer to the image-state I want. However, nothing so simple as I have imagined - nothing seems to be working, probably disagreement between DIB and DDB.
.data?
ALIGN 4
brTab dd 3 dup (?)
.code
; create DIB
... invoke LoadImage,hInstance, 13002, IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR+LR_CREATEDIBSECTION+LR_DEFAULTSIZE
mov bmp, eax
... invoke GetBmpArray, hWin, bmp, 92, 31, 93, ADDR bmpTab ; 3 images-states: 92x31
... ; after return [bmpTab+0], [bmpTab+4], [bmpTab+8] should be valid DDB handles
; routine that doesn't work
GetBmpArray proc uses esi edi ebx hWin:DWORD, hBmp:DWORD, im_x:DWORD, im_y:DWORD, im_cy:DWORD, pBmp:DWORD
LOCAL dibs:DIBSECTION
LOCAL bmpi:BITMAPINFO
LOCAL bytes:DWORD
LOCAL dc:DWORD
LOCAL bmpX:DWORD
LOCAL mdc:DWORD
mov eax, im_cy
xor edx, edx
div im_y
mov ebx, eax
mov eax, im_x
mul im_y
lea eax, [eax+eax*2]
mov bytes, eax
invoke GetDC, hWin
mov dc, eax
invoke CreateCompatibleDC, dc
mov mdc, eax
invoke GetObject, hBmp, sizeof DIBSECTION, ADDR dibs ; get all pixels
invoke GetDIBits, dc, hBmp, 0, im_cy, 0, ADDR bmpi, DIB_RGB_COLORS ; fill BITMAPINFO
mov bmpi.bmiHeader.biSize, sizeof BITMAPINFOHEADER
mov eax, im_y
mov bmpi.bmiHeader.biHeight, eax
mov eax, bytes
mov bmpi.bmiHeader.biSizeImage, eax
test ebx, ebx
jz @exit
;-----
@@:
dec ebx
mov eax, ebx
mul bytes
add eax, dibs.dsBm.bmBits
mov esi, eax
invoke CreateCompatibleBitmap, dc, im_x, im_y
mov bmpX, eax
invoke SelectObject, mdc, bmpX
invoke SetDIBits, mdc, bmpX, 0, im_y, esi, ADDR bmpi, DIB_RGB_COLORS ; replace bits
.if eax==0 ; fails here
invoke MessageBox,0,0,0,0
.endif
mov eax, bmpX
mov ecx, ebx
shl ecx, 2
add ecx, pBmp
mov [ecx], eax
test ebx, ebx
jnz @B
@exit:
invoke ReleaseDC, hWin, dc
invoke DeleteDC, mdc
;-----
ret
GetBmpArray endp
If there is another way, or any suggestion I would like to hear it :U
This forum is a miracle: I have a working solution already & it's quite simple.
For those who may use this routine
hWin - current window, that bitmaps will be compatible with
hBmp - handle of DDB bitmap (usually got using LoadBitmap) (it will be divided to as many as needed)
im_y - height of one image-state in pixels
pBmp - pointer to array of dwords that receives handles of bitmaps
It's a good alternative for those who find ImageList_.. inconvenient (for the reason that ImageList... doesn't return bitmap handle)
GetBmpArray proc uses esi hWin:DWORD, hBmp:DWORD, im_y:DWORD, pBmp:DWORD
LOCAL bmp :BITMAP
LOCAL dc :DWORD
LOCAL bmpX :DWORD
LOCAL mdc :DWORD
LOCAL mdcX :DWORD
invoke GetDC, hWin
mov dc, eax
invoke GetObject, hBmp, sizeof BITMAP, ADDR bmp
mov eax, bmp.bmHeight
xor edx, edx
div im_y
mov esi, eax
invoke CreateCompatibleDC, dc
mov mdc, eax
invoke CreateCompatibleDC, dc
mov mdcX, eax
invoke SelectObject, mdcX, hBmp
test esi, esi
jz @exit
;-----
@@:
dec esi
invoke CreateCompatibleBitmap, dc, bmp.bmWidth, im_y
mov bmpX, eax
invoke SelectObject, mdc, bmpX
mov eax, esi
mul im_y
invoke BitBlt, mdc, 0, 0, bmp.bmWidth, im_y, mdcX, 0, eax, SRCCOPY
invoke GetCurrentObject, mdc, OBJ_BITMAP
mov ecx, esi
shl ecx, 2
add ecx, pBmp
mov [ecx], eax
test esi, esi
jnz @B
@exit:
;-----
invoke ReleaseDC, hWin, dc
invoke DeleteDC, mdcX
invoke DeleteDC, mdc
ret
GetBmpArray endp
Yep,
Thats the way it was done back in win3.0-1 etc .... BitBlt whatever bits of one bitmap onto another. This is how toolbars and other bitmaps were handled in pre-win95 Windows.