I have a bitmap created by CreateDIBSection and i'm trying to manipulate the image by changing the values pointed to by the pointer returned to the *ppvBits argument. When I call UpdateWindow the image looks exacly the same???

the window handles WM_PAINT like this



IF uMsg==WM_PAINT
invoke BeginPaint, hWnd, addr ps
invoke BitBlt, eax, 0, 0, dwWidth, dwHeight, hdc, 0, 0, SRCCOPY
invoke EndPaint, hWnd, addr ps

hdc is the device context that has the bitmap selected into it.
Posted on 2003-11-26 19:33:40 by ENF
I have found that the number returned in ppvBits is unreliable. Use the GetObject function to obtain a good pointer to the DIBits...

LOCAL sbmp	:DIBSECTION

invoke GetObject,hBmp,SIZEOF DIBSECTION,ADDR sbmp
mov eax,sbmp.dsBm.bmBits
mov pDIBits,eax
Posted on 2003-11-26 19:37:14 by donkey
thanx donkey but it still isn't working.
Is it possible that windows dosen't allow writing to a bitmap in the way while it is selected into a DC?
Posted on 2003-11-26 21:54:55 by ENF
Nope, I write all of my pixels in TBPaint using the direct method and the bitmap is selected into a DC at the time. There should be no problem with that at all. This is a procedure that will set a single pixel, it is not efficient but slightly better than SetPixelV, you can try it. It assumes a 32bit DIB section (which is what I use in TBPaint internally).

SetPixelD proc PixelDC:DWORD, PixelX:DWORD, PixelY:DWORD, cPixel:DWORD

LOCAL sbmp :DIBSECTION
LOCAL hBmp :DWORD
LOCAL pDIBits :DWORD

; Images are always 32bpp for alpha so no aligment is necessary
; Bottomup DIB - Origin for DIB is bottom left

invoke GetCurrentObject,PixelDC,OBJ_BITMAP
mov hBmp,eax
invoke GetObject,hBmp,SIZEOF DIBSECTION,ADDR sbmp
mov eax,sbmp.dsBm.bmBits
mov pDIBits,eax

; Verify the requested pixel
mov eax,PixelX
mov ecx,PixelY
.IF eax >= sbmp.dsBm.dwWidth|| ecx >= sbmp.dsBm.dwHeight
ret
.ENDIF

; Find the appropriate entry in the array of bits
; Calculate the offset to the first entry in scan line
mov eax, imageX
mov ecx,imageY
sub ecx,PixelY
dec ecx
mul ecx
shl eax,2 ; adjust for DWORD size
push eax ; push the result onto the stack

mov eax,PixelX
shl eax,2 ; adjust for DWORD size
pop ecx ; pop the scan line offset off the stack
add eax,ecx

add eax,pDIBits ; add the offset to the DIB bits
mov ecx,cPixel
; The dword must be reversed to set the right RGB order
bswap ecx
shr ecx,8
mov DWORD PTR [eax],ecx

ret
SetPixelD endp


EDIT : Just thought of this, in a DIB section with a positive height you know that you access it upside dwon right ? Pixel 0 is the bottom left pixel.
Posted on 2003-11-26 22:01:41 by donkey
Just thought of this, in a DIB section with a positive height you know that you access it upside dwon right ? Pixel 0 is the bottom left pixel.


I never knew that
Posted on 2003-11-26 22:12:01 by ENF
I fixed it.
The problem was that my window procedure was never receiving WM_PAINT....calling InvalidateRect before UpdateWindow has solved it. I had thought the whole point of the UpdateWinodw function was to send the WM_PAINT message.
Posted on 2003-11-26 23:01:38 by ENF
UpdateWindow wll only send a WM_PAINT if there is a region marked for update with InvalidateRect.

The function sends a WM_PAINT message directly to the window procedure of the specified window, bypassing the application queue. If the update region is empty, no message is sent.
Posted on 2003-11-26 23:16:54 by donkey