The MASM Forum

General => The Campus => Topic started by: gelatine1 on June 29, 2014, 04:48:03 AM

Title: Difference in WM_PAINT messages ?
Post by: gelatine1 on June 29, 2014, 04:48:03 AM
As some may know I am currently writing my text editor but I got once again a problem I am not sure of how to solve.

Currently if the user is currently writing on line 3 then I simply make sure my program only repaints line 3. Line 1 and 2 still remain on the screen. But once the user resizes the window then there is also a WM_PAINT message getting sent but this time the bErase is true which causes the whole window to getting cleared. After that line 3 is painted again on the screen but 1 and 2 are gone.

Now my question is how should I determine whether the WM_PAINT message was sent by a keypress (using the InvalidateRect function) or by the resize of my window?

Thanks in advance,
Jannes
Title: Re: Difference in WM_PAINT messages ?
Post by: dedndave on June 29, 2014, 05:05:13 AM
WM_PAINT is very tricky   :(

you will find it challenging to learn, at first
one of the things you'll learn about is double-buffering (drawing to a memory DC, then blitting to the display DC)
this prevents flicker - nice smooth transitions

that having been said......

when you InvalidateRect (or InvalidateRegion/ValidateRect/ValidateRegion)
or when windows needs to update the window (sized/moved or some other window removed from on top),
the "update region" is modified

when windows gets around to sending a WM_PAINT message....
you call BeginPaint and EndPaint, and windows clears the update region for your window

you can see what the update region is by examining the RECT in the PAINTSTRUCT that is filled by BeginPaint
other than that, there is no way to know where the update requirement came from
Title: Re: Difference in WM_PAINT messages ?
Post by: dedndave on June 29, 2014, 05:25:16 AM
here is what i suggest when you get a WM_PAINT message....

1 ) BeginPaint - this fills in a PAINTSTRUCT for you
2 ) create a "compatible" DC (memory DC) - it should be compatible with the display DC - CreateCompatibleDC
3 ) create a compatible bitmap (also compatible with the display DC) - CreateCompatibleBitmap
make it the same size as the client area of your window
4 ) select the compatible bitmap into the compatible DC - SelectObject - save the old value that's returned in EAX
5 ) do all your drawing into this memory DC
you can update the entire client area (memory DC updates are usually very fast)
6 ) use the PAINTSTRUCT rcPaint RECT to determine what part of the client area to update
you convert the RECT coordinates from <left,top,right,bottom> into <left,top,width,height>
width = right-left and height = bottom-top
7 ) blitter the update area from the memory DC into the display DC - BitBlt
updating the display DC is not as fast as updating a memory DC
but, you are only updating the area required by rcPaint

now - you have to do some cleanup....

8 ) undo step 4 by selecting the original bitmap back into the memory DC (SelectObject again)
9 ) undo step 3 by deleting the bitmap - DeleteObject
10 ) undo step 2 by deleting the memory DC - DeleteDC
11 ) undo step 1 by calling EndPaint

there are many ways to make improvements, but you will find this works pretty well
whenever you change the properties of a DC, you want to restore them before deleting it
so - you SelectObject, save the old value and restore it before deleting the DC
this also applies to fonts, background colors, etc
you can simplify that whole "setup/restore" process with SaveDC and RestoreDC (works sort of like PUSH/POP)
Title: Re: Difference in WM_PAINT messages ?
Post by: dedndave on June 29, 2014, 06:46:25 AM
i don't like to create LOCAL's inside WndProc, so i usually write a paint proc and create them there
this is not tested, but should work   :P

at beginning of program....

WndProc PROTO :HWND,:UINT,:WPARAM,:LPARAM
wmPaint PROTO :HWND


then in the .CODE section, WndProc....

WndProc PROC hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

    mov     eax,uMsg
    .if eax==WM_PAINT
        INVOKE  wmPaint,hWnd
        xor     eax,eax

    .elseif eax==

;......

    .else
        INVOKE  DefWindowProc,hWnd,uMsg,wParam,lParam

    .endif
    ret

WndProc ENDP


and wmPaint...

wmPaint PROC USES EBX ESI EDI hWnd:HWND

;--------------------------------

    LOCAL   ps              :PAINTSTRUCT
    LOCAL   rcClient        :RECT
    LOCAL   nSavedDC        :UINT
    LOCAL   hbmpMem         :HBITMAP

;--------------------------------

    INVOKE  BeginPaint,hWnd,addr ps
    INVOKE  CreateCompatibleDC,eax
    xchg    eax,esi                                                          ;ESI = hdcMem
    INVOKE  GetClientRect,hWnd,addr rcClient
    INVOKE  SaveDC,esi
    mov     nSavedDC,eax
    INVOKE  CreateCompatibleBitmap,ps.hdc,rcClient.right,rcClient.bottom
    mov     hbmpMem,eax
    INVOKE  SelectObject,esi,eax

;do all your selecting and drawing into hdcMem (ESI)

;.....

;now, update the display

    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                                                          ;EDX = height
    INVOKE  BitBlt,ps.hdc,edi,ebx,ecx,edx,esi,edi,ebx,SRCCOPY

;and clean-up

    INVOKE  RestoreDC,esi,nSavedDC
    INVOKE  DeleteObject,hbmpMem
    INVOKE  DeleteDC,esi
    INVOKE  EndPaint,hWnd,addr ps
    ret

wmPaint ENDP


you actually don't have to save nSavedDC in this case
you can just call

    INVOKE  RestoreDC,esi,-1

and it will use the most recently saved DC


BeginPaint
http://msdn.microsoft.com/en-us/library/dd183362%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/dd183362%28v=vs.85%29.aspx)

PAINTSTRUCT
http://msdn.microsoft.com/en-us/library/dd162768%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/dd162768%28v=vs.85%29.aspx)

EndPaint
http://msdn.microsoft.com/en-us/library/dd162598%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/dd162598%28v=vs.85%29.aspx)

GetClientRect
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633503%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633503%28v=vs.85%29.aspx)

SaveDC
http://msdn.microsoft.com/en-us/library/dd162945%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/dd162945%28v=vs.85%29.aspx)

RestoreDC
http://msdn.microsoft.com/en-us/library/dd162929%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/dd162929%28v=vs.85%29.aspx)

CreateCompatibleDC
http://msdn.microsoft.com/en-us/library/dd183489%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/dd183489%28v=vs.85%29.aspx)

DeleteDC
http://msdn.microsoft.com/en-us/library/dd183533%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/dd183533%28v=vs.85%29.aspx)

CreateCompatibleBitmap
http://msdn.microsoft.com/en-us/library/dd183488%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/dd183488%28v=vs.85%29.aspx)

SelectObject
http://msdn.microsoft.com/en-us/library/dd162957%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/dd162957%28v=vs.85%29.aspx)

DeleteObject
http://msdn.microsoft.com/en-us/library/dd183539%28v=vs.85%29.aspx

BitBlt
http://msdn.microsoft.com/en-us/library/dd183370%28v=vs.85%29.aspx
Title: Re: Difference in WM_PAINT messages ?
Post by: gelatine1 on June 29, 2014, 07:07:05 AM
Wow, thank you very much Dave! I like how you're giving me so much explanation, examples and even references!
Once again so much new information but I'll try to process it :)

Just one more question, What in fact is a DC ? It's an device context right ? I am not sure what it actually is...  :redface:
Title: Re: Difference in WM_PAINT messages ?
Post by: dedndave on June 29, 2014, 07:25:01 AM
right - a device context

and - you can read documentation until you turn blue and still not know the answer to that   :lol:

i have seen some analogies that compare it to a "canvas" for painting
i think it's more like the easel   :P

there are 2 primary types of DC's - memory DC's and device DC's
the display DC is very different from the memory DC
another one is a printer DC - again, very different from a memory DC
the display and printer are real physical devices that have specific properties
the memory DC has the properties that you assign to it

but - the DC is essentially a structure that is hidden somewhere in memory, used by the OS
it holds all sorts of information about the device attributes, what has been selected into it, and so on

at this point, try not to be too concerned with knowing what it is
after you see how DC's are used in different ways, you will grow to have a better understanding
Title: Re: Difference in WM_PAINT messages ?
Post by: Tedd on June 29, 2014, 10:39:38 PM
You don't strictly need to know where the update came from, you only need to know WHAT should be redrawn.
Each time you receive WM_PAINT, it is because there is an invalidated region that needs to updated. Calling GetUpdateRect will give you the smallest rectangle that covers the invalidated region; and that's all you need to redraw.
So, when a text line is modified, instead of invalidating the entire window, you can call InvalidateRect with just the rectangle that covers the line itself. Then when WM_PAINT arrives, you only need to draw the part that's changed, and the other lines are left alone (unless you're wrapping lines, and then the following lines may get shifted along/down.)

As for what is a DC, consider it as a box that holds the resources (pens, brushes, fonts, color palette, canvas, settings, etc) to be used with its associated device. When windows draws to a display device (screen, printer, holographic projector) it uses the tools in the associated box (DC) for drawing operations on that device; other devices have their own box which may contain a different set of tools.
Title: Re: Difference in WM_PAINT messages ?
Post by: gelatine1 on June 30, 2014, 06:36:35 AM
Right now I have implemented the codes as you explained. My code compiled, it doesn't crash, but it still doesn't actually work as I exptected it to work  :(

Basically what I do now is once the WM_PAINT message is received then I create this memoryDC and I write all lines into this memoryDC then the next I do is I blitter this memoryDC to the DisplayDC (only the Update Region) like you told me to do.

Although once I resize the screen it doesn't work anyway. All previous lines get removed and only the currently is getting displayed.

Another thing I noticed is that I am still getting some flickering effect when I keep pressing the backspace key the background of the currentline is flashing white and black. (windows background is in fact white but the texts background is black)

So I was wondering whether I used this memoryDC correctly or if I am just missing something?

My full code in an attachment. (it was a .rar file and I just changed the extension to .zip since the forum doesn't allow .rar ? If you can't extract it just change the extension again)

My WM_PAINT code:

cmp eax,WM_PAINT
jnz __cont0

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
mov hOld,eax

;paint into memoryDC
invoke SelectObject,memdc,hFontMsg
mov hFontHdc,eax

invoke SetBkColor,memdc,0
invoke SetTextColor,memdc,00FFFFFFh

mov edx,[FirstLine]
__NextLine:
mov eax,edx
mov ecx,[BytesPerLine]
mov ebx,eax
shl ebx,7
push edx
mul [LineHeight]
pop edx
;mov edx,[CurrentLine]
add ebx,[pmem]
push edx
invoke ExtTextOut, memdc,3,eax,ETO_OPAQUE or ETO_NUMERICSLATIN,addr rect,ebx,[ecx+4*edx],NULL
pop edx
inc edx
mov eax,[LastLine]
cmp eax,edx
jns __NextLine


invoke SelectObject,memdc,hFontHdc

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

jmp __cont


Oh and one more questionn, You used BitBlt like this:
invoke BitBlt,hdc,edi,ebx,ecx,edx,memdc,edi,ebx,SRCCOPY

But I was not really sure about those the 2 parameters before the last. It says the upper left-corner of the source rectangle. isn't this always just (0,0) ?

Thanks in advance,
Jannes

EDIT: for some reason I am quite convinced that the error is somewhere in this BitBlt function. If I debug this code in OllyDbg then I see that the ExtTextOut function is executed exactly the equal amount of times as the number of lines I currently have.
Title: Re: Difference in WM_PAINT messages ?
Post by: dedndave on June 30, 2014, 06:55:15 AM
my fault for not testing the code, first

what i normally do is to use WNDCLASSEX.hbrBackground = NULL
this prevents the background from being re-drawn each time WM_PAINT is sent

in WM_CREATE, i create a brush of the desired background color and store the handle in a global dword
        INVOKE  CreateSolidBrush,0FFFFFFh ;white
        mov     hbrBackGnd,eax


http://msdn.microsoft.com/en-us/library/dd183518%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/dd183518%28v=vs.85%29.aspx)

you should delete that object in WM_DESTROY
        INVOKE  DeleteObject,hbrBackGnd

then, before i draw things into the memory DC, i fill it with the background brush

    INVOKE  SelectObject,esi,hbrBackGnd
    xor     ecx,ecx
    INVOKE  PatBlt,esi,ecx,ecx,rcClient.right,rcClient.bottom,PATCOPY


pattern blit is very fast into a memory DC
http://msdn.microsoft.com/en-us/library/dd162778%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/dd162778%28v=vs.85%29.aspx)

next - i update the entire window in the memory DC
i.e., you have to draw all visible text

this process, combined with double-buffering, totally eliminates flicker

when it comes time to BitBlt, you use the update coordinates from rcPaint for both the source and destination
let's say that windows wants to update the RECT <10,15,20,25>  (10x10 pixels, upper left = 10,15)
you want to use the 10x10 section from the memory DC, starting at 10,15
and draw it to the window DC, starting at 10,15

when you do it this way, you can size/move the window,
or move other windows in front of it and move them around
you will see the update is very fast and no flickering
Title: Re: Difference in WM_PAINT messages ?
Post by: dedndave on June 30, 2014, 07:06:23 AM
as i mentioned before, there are several ways to improve this
for example, you can just create and re-draw the desired rectangle in the memory DC
the code gets a little hairy, but it can be done

another way to improve it is to use a 256-color DIB section (whenever 256 colors is enough)
rather than calling CreateCompatibleBitmap, you call CreateDIBSection

drawing into a DC with a 256-color bitmap is super fast   :biggrin:

however - that is a lot of effort
and - you will find that it works pretty well without all that extra coding
Title: Re: Difference in WM_PAINT messages ?
Post by: gelatine1 on June 30, 2014, 07:46:23 AM
I am impressed by such quick replies! :) Thank you a lot!

Although I applied the changes you mentioned I am still getting some white flickering when I keep the backspace button down and after a resize I still lose the previous lines :( and I am quite sure those lines are actually written to the memoryDC.

I have my new code in an attachment in case anyone would want to take a look at it. I am going to sleep now, goodnight!

Title: Re: Difference in WM_PAINT messages ?
Post by: dedndave on June 30, 2014, 10:53:34 PM
i am looking over the code you posted
i will make some edits and get back to you

a couple things i notice right away......

first, in WM_CREATE, you call BeginPaint and EndPaint to get an hDC
if i'm not mistaken, BeginPaint/EndPaint should not be called outside WM_PAINT

many functions require a DC, sometimes even when you're not drawing anything
to get an hDC, you can use GetDC or GetWindowDC (depends on what you're doing)
when you're done using it, use ReleaseDC

http://msdn.microsoft.com/en-us/library/dd144871%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/dd144871%28v=vs.85%29.aspx)
http://msdn.microsoft.com/en-us/library/dd144947%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/dd144947%28v=vs.85%29.aspx)
http://msdn.microsoft.com/en-us/library/dd162920%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/dd162920%28v=vs.85%29.aspx)


another issue is font height/line height

(http://i.msdn.microsoft.com/dynimg/IC444269.png)

you use GetTextMetric, so use the values on the left
to get line spacing, add tmHeight + tmExternalLeading

i guess it's better to use GetOutlineTextMetrics for true-type fonts (values on the right)
so, you'd use otmMacAscent + otmMacDescent + otmMacLineGap

http://msdn.microsoft.com/en-us/library/dd145122%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/dd145122%28v=vs.85%29.aspx)
http://msdn.microsoft.com/en-us/library/dd144906%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/dd144906%28v=vs.85%29.aspx)
http://msdn.microsoft.com/en-us/library/dd162755%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/dd162755%28v=vs.85%29.aspx)

i am looking into the flicker issue.....
Title: Re: Difference in WM_PAINT messages ?
Post by: RuiLoureiro on June 30, 2014, 11:37:18 PM
Dave,         
         «i am looking into the flicker issue.....»
          you may solve it cretating a memo DC ...
Title: Re: Difference in WM_PAINT messages ?
Post by: gelatine1 on July 01, 2014, 12:15:43 AM
Thank you a lot Dave :)

I am getting some weird (or just unexpected) output for this GetOutlineTextMetrics.

I use this little piece of code now in the WM_CREATE message:

invoke GetDC,hWnd
mov    hdc,eax

invoke SelectObject,hdc,hFontMsg
mov hFontHdc,eax

invoke GetOutlineTextMetrics,hdc,SIZEOF OUTLINETEXTMETRIC,offset outtxt
mov eax,outtxt.otmMacAscent
add eax,outtxt.otmMacDescent
add eax,outtxt.otmMacLineGap
mov [LineHeight],eax

invoke SelectObject,hdc,hFontHdc
invoke ReleaseDC,hWnd,hdc


My text got pasted onto each other so there was something wrong.. I checked the debugger and I figured out that
outtxt.otmMacAscent = -3
outtxt.otmMacDescent = 13
outtxt.otmMacLineGap = -3

these values don't really make much sense huh do they ? The lineHeight would become 7 like this and I remember before that 16 was perfect. What is going wrong ?

Also this morning when I opened up the program I had send again it stopped giving any black background although I am still using this PatBlt function with the black brush. Last night I am pretty sure it was black but today somehow it was white. I don't really know what was going on :/ Do you get a black or white background in the files I sent ?

Oh andRuiLoureiro, that's exactly what I was using, still had the flicker though.
Title: Re: Difference in WM_PAINT messages ?
Post by: dedndave on July 01, 2014, 12:44:31 AM
not sure how you got anything from that function - lol
usually, if the structure requires the size to be set, and you don't set it, it fails

        .DATA?

otm OUTLINETEXTMETRIC <>

        .CODE

        mov     edx,offset otm
        mov     ecx,sizeof OUTLINETEXTMETRIC
        mov     [edx].OUTLINETEXTMETRIC.otmSize,ecx
        INVOKE  GetOutlineTextMetrics,hdc,ecx,edx


if the nmbers are negative, it is a little strange
make them positive and add them all up for 19
i'll see when i get that far

i noticed the white screen, as well
in your zip file, the EXE has a black background
but, when i re-assemble, it is white
no matter - i am working through WndProc, now
i'm sure i'll find it   :t
Title: Re: Difference in WM_PAINT messages ?
Post by: dedndave on July 01, 2014, 01:02:11 AM
in your WM_PAINT code, you use EBX and EDI without preserving them   :P
Title: Re: Difference in WM_PAINT messages ?
Post by: dedndave on July 01, 2014, 01:09:41 AM
something screwy with the text loop

to test it, i jumped around it - and the screen is black again   :P
jmp around

mov edx,[FirstLine]
__NextLine:
mov eax,edx
mov ecx,[BytesPerLine]
mov ebx,eax
shl ebx,7
push edx
mul [LineHeight]
pop edx
;mov edx,[CurrentLine]
add ebx,[pmem]
push edx
invoke ExtTextOut, memdc,3,eax,ETO_OPAQUE or ETO_NUMERICSLATIN,addr rect,ebx,[ecx+4*edx],NULL
pop edx
inc edx
mov eax,[LastLine]
cmp eax,edx
jns __NextLine

around:
Title: Re: Difference in WM_PAINT messages ?
Post by: gelatine1 on July 01, 2014, 01:11:41 AM
I changed the GetOutlineTextMetrics function to this

mov outtxt.otmSize,SIZEOF OUTLINETEXTMETRIC
invoke GetOutlineTextMetrics,hdc,SIZEOF OUTLINETEXTMETRIC,offset outtxt


nothing changed

I preserved ebx and edi like this:

cmp eax,WM_PAINT
jnz __cont0
push ebx
push edi

...

pop edi
pop ebx


Nothing changed :( I'm kinda lost in all this

And okay  :t I'll find what's going wrong in the text loop
Title: Re: Difference in WM_PAINT messages ?
Post by: gelatine1 on July 01, 2014, 01:22:15 AM
This ETO_OPAQUE flag in the ExtTextOut function messed everything up.
I have a black background again  :biggrin: But... this happens:

(http://s26.postimg.org/v63341xv9/blackwhite.jpg?noCache=1404141625)

i set the text to red so it doesn't get hidden in the backgrounds :p

What is this ? another flag that should be altered ? or um oh right I need to use SetBkgndColor to black I guess ?

EDIT: SetBkColor did the thing :) although there is still something wrong with the LineHeight now. Can't seem to get it right
Title: Re: Difference in WM_PAINT messages ?
Post by: dedndave on July 01, 2014, 01:28:10 AM
even though you filled in the bitmap with all black, you still have to set the background color for ExtTextOut
invoke  SetBkColor,memdc,0

http://msdn.microsoft.com/en-us/library/dd162713%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/dd162713%28v=vs.85%29.aspx)

QuoteThe ExtTextOut function draws text using the currently selected font, background color,
and text color. You can optionally provide dimensions to be used for clipping, opaquing, or both.
Title: Re: Difference in WM_PAINT messages ?
Post by: dedndave on July 01, 2014, 01:29:44 AM
the line height thing is probably a clipping issue
to test that theory, try it without clipping

but, i think your clipping rectangle isn't moving with your text
Title: Re: Difference in WM_PAINT messages ?
Post by: gelatine1 on July 01, 2014, 01:44:19 AM
May I ask , what is clipping? Do you know any article about it ?

Thanks in advance, I hope I'm not bothering you too much
Title: Re: Difference in WM_PAINT messages ?
Post by: dedndave on July 01, 2014, 01:57:39 AM
well - clipping is like "not drawing outside this rectangle"
for example - your text is wider than the area you want to display it - you clip it
in this case, you are not using clipping - you don't have that flag set in ExtTextOut
so - you don't really need a rectangle pointer, either (also used for opaquing)

but - that's not where the problem lies
the problem lies here, with the calculation of the top of the rect for InvalidateRect   :biggrin:

mov ecx,[CurrentLine]
shl ecx,7
mov edx,[pmem]
add edx,ecx

mov ecx,[CurrentLine]
mov ebx,[BytesPerLine]
mov ebx,[ebx+4*ecx]

mov [edx+ebx],eax

inc ebx
mov edx,[BytesPerLine]
mov [edx+4*ecx],ebx

mov rect.left,0
shl ecx,4
mov rect.top,ecx
mov rect.right,4FFh
add ecx,16
mov rect.bottom,ecx
invoke InvalidateRect,hWnd,offset rect,0
Title: Re: Difference in WM_PAINT messages ?
Post by: dedndave on July 01, 2014, 02:01:31 AM
you can test it very easily....

type 4 lines of text - notice that each line is shorter   :P

now, minimize the window - then restore it
this causes the OS to send a WM_PAINT message with the entire client area as the update region
Title: Re: Difference in WM_PAINT messages ?
Post by: dedndave on July 01, 2014, 02:05:01 AM
you have to use the LineHeight variable in that calculation   :t
Title: Re: Difference in WM_PAINT messages ?
Post by: dedndave on July 01, 2014, 03:24:44 AM
try this one.....
Title: Re: Difference in WM_PAINT messages ?
Post by: gelatine1 on July 01, 2014, 04:46:22 AM
Thanks a lot once again dave. You have been really helpful so thank you for all of that :) I finally got everything working well again.
Title: Re: Difference in WM_PAINT messages ?
Post by: Tedd on July 02, 2014, 03:09:45 AM
A few suggestions..

mov dword ptr [esi+4],CS_HREDRAW or CS_VREDRAW
This can actually be zeroed -- these flags cause the WHOLE window to be redrawn every time the size changes, which will result in flicker.

Using the BLACK_BRUSH for the window background is perfectly fine, flicker is caused by the background being cleared unnecessarily. Specifically, when you call InvalidateRect, the last parameter is true/false to say whether you want the background cleared in the invalidated rectangle; setting it to false means it won't be cleared, which is fine as long as you're drawing entirely over the area so no previous pixels remain - which you are, with BitBlt.


invoke GlobalAlloc,GHND,65535
mov hmem,eax
invoke GlobalLock,hmem
mov pmem,eax

can simply be:

invoke GlobalAlloc,GPTR,65535
mov pmem,eax

and to free:
invoke GlobalFree,pmem
Equally for BytesPerLine.
There's no need to lock/unlock, it's a left-over from windows 3.