Hi,

I desperately try to draw a line with 2 mouse clicks.
For the following code, I only try to draw a line with fixed coordinates when a button is clicked. Can anyone tell me where the problem is?

When I put this code in the WM_PAINT event it works. (with Begin and EndPaint)

Alternatively, that would be nice if you could point me to a working example. I couldn't find any on the forum.

Thanks in advance


WinMain...

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL hdc:HDC

.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_LBUTTONDOWN

            mov hdc,eax
            invoke GetStockObject,BLACK_PEN
            invoke SelectObject,hdc,eax
            invoke MoveToEx,hdc,10,25,0
            invoke LineTo,hdc,20,75
            xor eax,eax
    .ELSE
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam
        ret
.ENDIF
xor eax,eax
ret
WndProc endp
Posted on 2005-06-29 07:58:17 by RepeCmps
One problem is that you need to call InvalidateRect after you draw to the hdc to tell windows to update the window to display your changes. Also I'm not sure about the hdc you're drawing to, it may not be valid.

A better solution is to create you're own back buffer DC and bitmap and do any drawing to it. Then during the WM_PAINT message you BitBlt this to the window DC. I've attached an example of this. It constantly re-blts the back buffer to the screen as would happen in a game. To stop this behaviour simply add a Begin and EndPaint to the WM_PAINT handler.
Attachments:
Posted on 2005-06-29 10:13:24 by Eóin
Hi,

Thanks very much for the information.

besides, it seems I have difficulties downloading your file. I get a 0 byte .zip
Any suggestion?
Posted on 2005-06-29 10:32:15 by RepeCmps
I really can't explain that, it downloads fine for me. Try it from here, this link woun't remain online for too long though.
Posted on 2005-06-29 11:35:10 by Eóin
I experience that problem sometimes, save it to your harddisk first before opening the .zip file.

Hey Eoin, how would you access the pixels of the dib section? ?Instead of using GetPixel, the other method of reading from an array?
Posted on 2005-06-29 11:36:32 by drarem
Works great.
Thanks a lot E?in
Posted on 2005-06-29 11:37:23 by RepeCmps
It looks like you would use the pBb as the pointer to the array of dwords - what is the purpose of CreateFileMapping / MapViewofFile?
Posted on 2005-06-29 12:02:49 by drarem
My appologies all, the BackBufferShell is a slightly more complicated example as it uses DIBSections. The advantage of this extra complication is the extra control it gives you, specificially the ability to access the pixels through a pointer stored in pBb (as already guessed).

The following bit of code
.data
MmfName db "TestMmf",0
.data?
hMmf dd ?
pMmf1 dd ?
pMmf2 dd ?
pMmf3 dd ?
.code
mov edi,100
@@:
invoke CreateFileMappingA,-1,0,PAGE_READWRITE,0,1000h,addr MmfName
mov hMmf,eax
invoke MapViewOfFile,eax,FILE_MAP_WRITE,0,0,0
mov pMmf1,eax
invoke MapViewOfFile,eax,FILE_MAP_WRITE,0,0,0
mov pMmf2,eax
invoke MapViewOfFile,eax,FILE_MAP_WRITE,0,0,0
mov pMmf3,eax

invoke UnmapViewOfFile,pMmf3
invoke UnmapViewOfFile,pMmf2
invoke UnmapViewOfFile,pMmf1
invoke CloseHandle,hMmf
dec edi
jnz @b

Appears to be me doing some sort of benchmarking, it can be removed.

The code I was ment to post uses a regular Bitmap instead of a DIBSection which is easier to setup. It doesn't give you access to the pixel bits, but if you only want to use GDI commands for doing any drawing then that doesn't matter of course.

Unfortunatly I seem to have misplaced it, or, more likely, I never put it together as a Shell program because it offers no advantage over the DIBSection menthod  ;) .

Posted on 2005-06-29 19:29:22 by Eóin
I loaded a bitmap to a DDB and blit'ed it to your bDc (dib dc),
then  I tried accessing the pBb pointer and it kept crashing. VS 2003 net debug said the address of the pointer was 0000000.

I have this:

mov edx, pBb  ;<========= (after DIB section is created and a bitmap is blitted to it's dc).
mov ecx, 2
imul ecx, width
shl ecx,2

mov eax,     ;<==== crash, edx = 0000000

Posted on 2005-06-29 20:19:31 by drarem
drarem, I'm a bit confused by what code you're using. If you post it I might be able to help.
Posted on 2005-07-01 12:56:46 by Eóin
GetPixel is way too slow, I need to be able to read the colors from an array or pointer to the data.

Here I played with your code and added GetDibits at the bottom. When I try to read from the pBitmapBits dword, it crashes.



InitDoubleBuffer Proc
;LOCAL bih:BITMAPINFOHEADER

invoke DeleteDC, bDc
invoke DeleteObject, hBm

invoke CreateCompatibleDC, hDc
mov bDc, eax

mov bmi.bmiHeader.biSize, sizeof(BITMAPINFOHEADER)
mov eax, rect.right
mov bmi.bmiHeader.biWidth, eax
mov eax, rect.bottom
mov bmi.bmiHeader.biHeight, eax
mov bmi.bmiHeader.biPlanes, 1
mov bmi.bmiHeader.biBitCount, 32
mov bmi.bmiHeader.biCompression, BI_RGB
mov bmi.bmiHeader.biSizeImage, 0
mov bmi.bmiHeader.biXPelsPerMeter, 0
mov bmi.bmiHeader.biYPelsPerMeter, 0
mov bmi.bmiHeader.biClrUsed, 0
mov bmi.bmiHeader.biClrImportant, 0

invoke CreateDIBSection, bDc, addr bmi, DIB_RGB_COLORS, addr pBb, NULL, 0
mov hBm, eax

invoke SelectObject, bDc, hBm
invoke SetTextColor, bDc, 0FFCCCCh
invoke SetBkColor, bDc, 0h

invoke GetDIBits,bDc,hBm,0, bmi.bmiHeader.biHeight,,addr bmi,DIB_RGB_COLORS



ret
InitDoubleBuffer EndP


Here is where I read the data from:

invoke BitBlt,bDc,0,0,600,534,workDC,0,0,SRCCOPY

mov edi,55
xor ecx,ecx
@@:
xor edx,edx
lea edx, pBitmapBits  ;<=== when is a global variable not a global variable?  edx loaded with 0's
;              mov edx,pBitmapBits  ;same effect - crash, boing
add ecx, 1               
imul ecx,600
shl ecx,2
mov eax,0

; invoke GetPixel,bDc,0,0  <==== this of course works as expected but too slow
RGB 0,0,0
mov eax,   <=== this crashes as edx = 000000000
GetRValue eax
.if eax==(255)
invoke PostQuitMessage,0;
.endif
dec edi
jnz @b


And before all that, I did this in the INIT_DIALOG part:


invoke GetProcessHeap
invoke HeapAlloc,eax,HEAP_ZERO_MEMORY,52512000 * sizeof(BITMAPINFOHEADER)  ;512 * 32 (size of MSPR pointer)
mov ,eax

invoke LoadImage,hInstance,addr sfName,IMAGE_BITMAP,0,0,LR_LOADFROMFILE Or LR_CREATEDIBSECTION
mov savBMP,eax
; invoke GetObject,savBMP, sizeof BITMAP, addr bm
invoke SelectObject,workDC,savBMP

invoke GetClientRect, hWnd, addr rect

call InitDoubleBuffer
Posted on 2005-07-01 14:38:45 by drarem
Well pBb should hold a pointer to the bits. Try putting the following code in

invoke CreateDIBSection, bDc, addr bmi, DIB_RGB_COLORS, addr pBb, NULL, 0
mov hBm, eax

mov edx,pBb
mov ,0FFFFFFh


And then display this DC (without bltting your workDC to it) If you see a white pixel in the bottom-left corner then everything should be working.
Posted on 2005-07-01 15:13:25 by Eóin
Thanks alot Eoin, that was it - DIBs are upside down and I was going past the end of the bitmap instead of going backwards.  And it is definitely WAY faster than getpixel/setpixel... you people should check it out =)  Right now I'm going thru my large loaded bitmap blit'ed to the DIB and replacing every black pixel with red - so my original bitmap looks like it has a red background - in real time at 695+ FPS. I tried this with getpixel only, was topping about 3 fps.

I'll add you to my credit list Eoin if that is ok - to my lib project. You want some other name in there or is Eoin ok?

Here is my test code:


mov ecx,ndXY
imul ecx,dword
mov edx,pBb
@@:
mov eax,
.if (eax==0)
RGB 0,255,0
.endif
mov , eax
sub ecx,4
cmp ecx,0
jnz @b
Posted on 2005-07-01 17:46:51 by drarem
Thats great to hear drarem, glad you got it working. And Eoin is grand, it's my name after all :) .
Posted on 2005-07-01 20:04:45 by Eóin