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
hdc is the device context that has the bitmap selected into it.
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.
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
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?
Is it possible that windows dosen't allow writing to a bitmap in the way while it is selected into a DC?
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).
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.
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.
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
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.
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.
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.