News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Flickering screen is not solved using a compatible DC?

Started by gelatine1, November 12, 2014, 03:37:59 AM

Previous topic - Next topic

gelatine1

I wrote some code that should simply draw a rectangle from a given point up to the current mouse location. Everytime the mouse moved the screen flashed white quickly in between and now I wanted to remove it by using a compatible Device context and bitmap but the flickering only got worse now. Does anyone see what is wrong with my code for the WM_PAINT message (I didn't include the code for the other messages) ?


cmp eax,WM_PAINT
jnz __cont0
push ebx
push edi

invoke BeginPaint,hWnd, ADDR ps
mov    hdc,eax

invoke CreateCompatibleDC,hdc
mov memdc,eax
invoke GetClientRect,hWnd, offset rect

invoke CreateCompatibleBitmap,hdc,rect.right,rect.bottom
mov hbm,eax
invoke SelectObject,memdc,eax ; Select the Bitmap
mov hOld,eax

;the following code paints the membc in the same background color as the window
invoke SelectObject,memdc,hbrBkgnd
invoke PatBlt,memdc,0,0,rect.right,rect.bottom,PATCOPY

;The following code draws the rectangle using a brush and a pen created in the WM_CREATE message
invoke SelectObject,memdc,hbr
mov hbrOld,eax
invoke SelectObject,memdc,hpen
mov hpenOld,eax

cmp drawrect,0
jz skiprect
invoke Rectangle,memdc,x1,y1,x2,y2
skiprect:
;Deselect brush and pen
invoke SelectObject,memdc,hbrOld
invoke SelectObject,memdc,hpenOld

; the follow code copys the image in memdc to the hdc
mov     edi,ps.rcPaint.left
mov     ebx,ps.rcPaint.top
mov     ecx,ps.rcPaint.right
mov     edx,ps.rcPaint.bottom
sub     ecx,edi                                                          ;ECX = width
sub     edx,ebx
invoke BitBlt,hdc,edi,ebx,ecx,edx,memdc,edi,ebx,SRCCOPY

;clean up
invoke SelectObject,memdc,hOld
invoke DeleteObject,hbm
invoke DeleteDC,memdc

invoke EndPaint,hWnd, ADDR ps

pop edi
pop ebx
jmp __cont
__cont0:
invoke DefWindowProc,hWnd,uMsg,wParam,lParam     ; Default message processing
ret

__cont:
xor eax,eax
ret
WndProc endp


Thanks in advance,
Jannes

redskull

Often the problem is that GDI is automatically painting your background for you.  Ensure hbrBackground is NULL when you register the window.

-r

gelatine1


Tedd

General "avoiding flicker" advice:
- don't use CS_HREDRAW or CS_VREDRAW in the class style;
- use a NULL brush for the window background (and obviously then ensure you paint the full client area);
- add WS_CLIPCHILDREN to the window style (in CreateWindowEx) of your main window (only necessary if you have children/controls in the window);
- using a back-buffer (CreateCompatibleDC) isn't necessarily required (make the above changes, then check).
Potato2

dedndave

hbrBackground = NULL solves the flicker problem, as others suggested

but, I do see a little flaw in the code
when you store the original brush that is selected into the memdc, you only need to do it the first time you replace it (when you PatBlt the background)
you do not need to store the returned value when you select the painting brush

when you restore the memdc to original state, you will have the correct brush handle
little things like that can cause GDI memory leaks