hi

i'm trying to bitblt an area of a dc into another area of the same dc.
the original area consists of a bitmap.

however, all i get is a black area being bitblted.

what went wrong? can't i use CreateCompitableBitmap to create a new bitmap based on the dc?

CODE:

;############################## WndProc ##############################

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL ps:PAINTSTRUCT
LOCAL hdc:HDC
LOCAL hMemDC:HDC
LOCAL rect:RECT

.if uMsg==WM_CREATE
invoke LoadBitmap,hInstance,IDB_MAIN
mov hBitmap,eax
.elseif uMsg==WM_PAINT
invoke BeginPaint,hWnd,addr ps
mov hdc,eax
invoke CreateCompatibleDC,hdc
mov hMemDC,eax
invoke SelectObject,hMemDC,hBitmap
invoke GetClientRect,hWnd,addr rect
invoke BitBlt,hdc,0,0,rect.right,rect.bottom,hMemDC,0,0,SRCCOPY
invoke DeleteDC,hMemDC
invoke EndPaint,hWnd,addr ps
.elseif uMsg==WM_COMMAND
mov eax, wParam
.if ax==IDM_DUPLICATE
invoke DuplicateBM, hWnd, addr bInfo
.else
invoke DestroyWindow, hWnd
.endif
.elseif uMsg==WM_DESTROY
invoke DeleteObject,hBitmap
invoke PostQuitMessage,NULL
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp

;############################## DuplicateBM ##############################

DuplicateBM proc hWnd:HWND, bInfoPtr:DWORD
local memDC :DWORD
local cmpBM :DWORD
local cmpDC :DWORD
local prvObj :DWORD

invoke GetDC, hWnd
mov memDC, eax

invoke CreateCompatibleDC, memDC
mov cmpDC, eax

invoke CreateCompatibleBitmap, memDC, 334, 207
mov cmpBM, eax

invoke SelectObject, cmpDC, cmpBM
mov prvObj, eax

invoke BitBlt,memDC,350,0,334,207,cmpDC,0,0,SRCCOPY

invoke DeleteDC,cmpDC
invoke DeleteDC,memDC
ret
DuplicateBM endp
Posted on 2003-11-14 03:30:08 by trexxz
In DuplicateBM you create a blank (black) bitmap , and you blt it onto the window, and you don't ReleaseDC. Thus, the window gets locked for WM_PAINT, and the blackness stays . Add that ReleaseDC at the end of the function, and maybe you should beforehand fill the new bitmap with some data, blt-ing from a DC with hBitmap
Posted on 2003-11-14 04:11:02 by Ultrano
Instead of your invoke DuplicateBM, hWnd, addr bInfo instruction, how about simply trying
invoke BitBlt,hdc,350,0,334,207,hcd,0,0,SRCCOPY
(or whatever other section you want to duplicate.)

I have to assume that the DuplicateBM proc which you posted is only a portion of the intended one; otherwise, the bInfo parameter would seem useless.

Raymond
Posted on 2003-11-14 14:08:25 by Raymond
> Ultrano

Do you mean like this?

invoke ReleaseDC, cmpDC
invoke ReleaseDC, memDC

> Raymond

You are right! It's useless! :tongue:


What i'm trying to do here is to see if i can create a "screen capture / a copy" of the original bitmap from the DC and BitBlt it into another area of the DC. I do not want to use back the hBitmap.

How can i do that?
Posted on 2003-11-17 00:43:24 by trexxz
if i can create a "screen capture / a copy" of the original bitmap from the DC and BitBlt it into another area of the DC
My suggested line of code should do exactly that. Written in another way

invoke BitBlt,hdc,Xi,Yi,Wt,Ht,hdc,Xo,Yo,SRCCOPY

Wt and Ht would be the size of the area to be copied.
Xo and Yo would be the top left corner coordinates of the area to be copied.
Xi and Yi would be the top left corner coordinates of the area where you want to copy it to.

Raymond
Posted on 2003-11-17 08:01:46 by Raymond
Thanks Raymond

Your code somehow does the job. :alright:
But i want to BitBlt to the compatibleDC without using the original bitmap. (hBitmap) :(
Posted on 2003-11-19 01:18:57 by trexxz
trexxz
without using the original bitmap. (hBitmap)
Never? Or only once?

...

invoke GetDC, hWnd
mov memDC, eax
...
invoke DeleteDC,memDC ; !!! wrong, need invoke ReleaseDC, hWnd, memDC
...
Posted on 2003-11-19 02:37:18 by P2M
use hBitmap once during BitBlt to the DC.
subsequently no.

do you mean i 'll have to release the DC before deleting or release DC is enough. (there is no need to delete DC?)
Posted on 2003-11-19 02:48:05 by trexxz
Hi,

The device context for your control is owned by Windows, so you cannot delete it, as a matter of fact under some circumstances it can lead to a GPF. For all device contexts handles obtained from GetDC you must use ReleaseDC but never delete them. This also applies to those that are passed to your program from Windows in structures such as PAINTSTRUCT. The only DC's that you delete are those that you create via CreateDC and CreateCompatibleDC.
Posted on 2003-11-19 02:54:08 by donkey
thanks donkey ! :grin:
Posted on 2003-11-19 02:57:17 by trexxz
trexxz
use hBitmap once during BitBlt to the DC. subsequently no.
Don't care has not understood.


...

.elseif uMsg==WM_PAINT
invoke BeginPaint,hWnd,addr ps
mov hdc,eax
invoke CreateCompatibleDC,hdc
mov hMemDC,eax
invoke SelectObject,hMemDC,hBitmap

; !!! need to restore prev bitmap
push eax

invoke GetClientRect,hWnd,addr rect
invoke BitBlt,hdc,0,0,rect.right,rect.bottom,hMemDC,0,0,SRCCOPY

; !!! restore prev bitmap
pop eax
invoke SelectObject, hMemDC, eax

invoke DeleteDC,hMemDC
invoke EndPaint,hWnd,addr ps
...


DuplicateBM proc hWnd:HWND, bInfoPtr:DWORD

local memDC :DWORD
local cmpBM :DWORD
local cmpDC :DWORD
local prvObj :DWORD

invoke GetDC, hWnd
mov memDC, eax

invoke CreateCompatibleDC, memDC
mov cmpDC, eax

invoke CreateCompatibleBitmap, memDC, 334, 207
mov cmpBM, eax

invoke SelectObject, cmpDC, cmpBM
mov prvObj, eax

; cmpDC is empty
; why memDC is destination
invoke BitBlt,memDC,350,0,334,207,cmpDC,0,0,SRCCOPY

; !!! need to restore prev bitmap
invoke SelectObject, cmpDC, prvObj

invoke DeleteDC,cmpDC
invoke ReleaseDC,memDC
ret
DuplicateBM endp
Posted on 2003-11-19 03:22:03 by P2M
I apologize for writing unclear codes.
This is what i was trying to:

1. BitBlt a bitmap file onto the DC.
2. I want to create a duplicate of the bitmap object loaded onto the DC.
3. Therefore i used CreateCompatibleDC to create a compatibleDC. I thought that the compatibleDC contains the bitmap object / info in it.
4. Next, i created a bitmap with CreateCompatibleBitmap based on the compatibleDC.
5. Lastly, i BitBlt the created compatiblebitmap onto the original DC, on the right hand side of the original bitmap.
6. But in the end, only a black area appeared.

Guess, i was wrong to do it this way..??
How should i do it????
:confused:
Posted on 2003-11-19 03:36:36 by trexxz
Hi trexxz,

Well, I think that there are a few things that need to be explained here.

When you want to copy one section of an image to another you select that image into a device context then use BitBlt to copy it into itself. In order to avoid problems Windows copies the specified source portion into a buffer then transfers it back to the DC. This has the advantage that you cannot overwrite a pixel before it is copied. So to do what you want Raymond's method is absolutely correct. If you do not want to alter the original bitmap you have to make a copy of it first, when you call CreateCompatibleBitmap you are creating a blank bitmap that is filled with color 0 of the current system pallette (almost always Black). So you must first copy your reference (origianl) bitmap onto the temporary one, for this you need two device contexts, one to hold the reference bitmap and one to hold the temporary one then you BitBlt the reference bitmap to the temporary one giving you an exact copy.

[b]Procedure to copy a bitmap[/b]


LOCAL bmp :BITMAP
LOCAL memDC1 :DWORD
LOCAL memDC2 :DWORD
LOCAL oldobj1 :DWORD
LOCAL oldobj2 :DWORD

; Find the size of the bitmap
invoke GetObject,hBmp,SIZEOF BITMAP,ADDR bmp
invoke GetDC,hWnd
mov hdc,eax
; Never create a bitmap using a memory DC, it will be monochrome
invoke CreateCompatibleBitmap,hdc,bmp.bmWidth,bmp.bmHeight
mov hTempBmp,eax

; Create two memory DCs to copy the bitmap
invoke CreateCompatibleDC,hdc
mov memDC1,eax
invoke CreateCompatibleDC,hdc
mov memDC2,eax
; Release the DC obtained by windows
invoke ReleaseDC,hWnd,hdc

; Select the bitmaps into the memory DCs
invoke SelectObject,memDC1,hBmp ; reference bitmap
mov oldobj1,eax ; <- this is very important
invoke SelectObject,memDC2,hTempBmp ; temporary bitmap
mov oldobj2,eax ; <- this is very important

invoke BitBlt,memDC2,0,0,bmp.bmWidth,bmp.bmHeight,memDC1,0,0,SRC_COPY

; Select the bitmaps out of the memory DCs and delete the memDCs
; failure to select the bitmaps out will cause a massive GDI leak on Win98SE
invoke SelectObject,memDC1,oldobj1
invoke SelectObject,memDC2,oldobj2
invoke DeleteDC,memDC1
invoke DeleteDC,memDC2
Posted on 2003-11-19 03:50:47 by donkey
>donkey

thanks for your detailed explanation on the CreateCompatibleDC and CreateCompatibleBitmap functions. i'll have a go to at it.

code:

SelectObject, tempDC, hBitmap

If a bitmap (hBitmap) is selected into a DC (tempDC) by SelectObject, the DC will contain the information of the bitmap right? (E.G. the color information, bitmap dimensions, etc...)

Is there a way to get the:

a. handle to this bitmap from the DC
b. color information of this bitmap from the DC

without using the original bitmap (hBitmap)?

-> Create a new bitmap based on the color information retrieved from the DC.
Posted on 2003-11-19 04:45:31 by trexxz
Yes, you can use the GetCurrentObject function and specify OBJ_BITMAP to get the bitmap currently selected into a DC.

When you select a bitmap into a DC, Windows uses ICM (color management) to convert the bitmap to the color depth of the DC so the color information is useless. If you have used the GetObject function in my procedure the color is available in the bmBitsPixel member of the BITMAP structure. You can get the current object and pass that to GetObject to retrieve the correct color depth.

When you create a compatible bitmap it already uses the color information from the DC you specify.
Posted on 2003-11-19 08:26:37 by donkey