I've spent a long time trying to figure this out but haven't got very far really.

I have a dialog with a button and an Image box (the kind of image box you can make in RadASM)
In the image box I would like to display a circle using the Ellipse API. I've managed to get a back buffer working which lets me do this, the problem arises when I try to implement the code within the WM_PRINT message. Here is my non working code:



mov eax,uMsg
.if eax==WM_INITDIALOG
invoke GetDlgItem,hWin,ImageBox
mov hwndImage,eax
;invoke GetDC,eax
;mov hImageDC,eax
invoke CreateCompatibleDC,hImageDC
mov hMemDC,eax
invoke GetClientRect,hwndImage,addr rect
invoke CreateCompatibleBitmap,hMemDC,rect.right,rect.bottom
mov hBitmap,eax
invoke SelectObject,hMemDC,hBitmap

.elseif eax==WM_COMMAND

.elseif eax==WM_PAINT
;invoke BeginPaint,hWin,addr ps
;mov hDC,eax
invoke GetDC,hwndImage
mov hImageDC,eax
invoke Ellipse,hMemDC,100,100,120,120
invoke BitBlt,hImageDC,0,0,rect.right,rect.bottom,hMemDC,0,0,SRCCOPY
;invoke EndPaint,hWin,addr ps
.elseif eax==WM_CLOSE
invoke DeleteDC,hMemDC
invoke DeleteObject,hBitmap
invoke EndDialog,hWin,0
.else
mov eax,FALSE
ret
.endif


I have found that if I do not use BeginPaint and EndPaint the program runs very slow and CPU untilisation rises to 100% and the image box doesn't repaint properly. But if I do use Begin and EndPaint then the Image box is not drawn at all.

I would like both the device context of the main window and the device context of the image box to be correctly redrawn after the window has been hidden or partially hidden. What is the correct way to do this?
Posted on 2004-06-06 11:39:04 by DeX
I cant solve your problem right now but you should ReleaseDC obtained by GetDC
Posted on 2004-06-06 15:03:09 by AceEmbler
I`ve a question about WM_paint too:
I paint a text without background. How can I erase it? The previous text disappear only when I cover it with another window.
I`ve try the InvalidateRect , doesn`t help. That is, without it there is no text at all.
;*******
.elseif uMsg == WM_PAINT ; itt kezdodok a gubanc

invoke BeginPaint,hWin,addr ps ;ez a resz egy bitmap-et rak ki hatternek, OK.
mov hdc,eax
invoke CreateCompatibleDC,hdc
mov hMemoryDC2ch4,eax
invoke SelectObject,hMemoryDC2ch4,hBitmapch4
mov hOldBmp2ch4,eax
invoke GetObject,hBitmapch4,sizeof BITMAP,addr bitmap2ch4
invoke StretchBlt,hdc,0,0,250,510,hMemoryDC2ch4,0,0,bitmap2ch4.bmWidth,bitmap2ch4.bmHeight,SRCCOPY
invoke SelectObject,hMemoryDC2ch4,hOldBmp2ch4
invoke DeleteDC,hMemDC2ch4
invoke EndPaint,hWin,addr ps
invoke InvalidateRect,hChild4,NULL,FALSE ;enelkul nincs felirat,de miert?
;*******
What should I do?
Posted on 2004-06-08 15:54:04 by ola_dina
try InvalidateRect,hChild4,NULL,TRUE
Posted on 2004-06-09 14:34:42 by AceEmbler
Well, it helps. Only the background image disappears. And I`ve spend a week to show a bitmap.
Posted on 2004-06-09 15:14:20 by ola_dina
maybe the whole descrption helps:

.elseif uMsg == WM_PAINT ; itt kezdodok a gubanc
invoke BeginPaint,hWin,addr ps ;ez a resz
mov hdc,eax
invoke CreateCompatibleDC,hdc
mov hMemoryDC2ch4,eax
invoke SelectObject,hMemoryDC2ch4,hBitmapch4
mov hOldBmp2ch4,eax
invoke GetObject,hBitmapch4,sizeof BITMAP,addr bitmap2ch4
invoke StretchBlt,hdc,0,0,250,510,hMemoryDC2ch4,0,0,bitmap2ch4.bmWidth,bitmap2ch4.bmHeight,SRCCOPY
invoke SelectObject,hMemoryDC2ch4,hOldBmp2ch4
invoke DeleteDC,hMemDC2ch4
invoke EndPaint,hWin,addr ps
invoke InvalidateRect,hChild4,NULL,FALSE; if I set this TRUE, there is no background pic.
szText wrt,"it's the drawtext function",0
szText wrt2,"ooooooops..... :))) ",0
test ooops,00000011b ;ooops set in the main window
jnz oops
mov rwrt,offset wrt
call r_draw
jmp nooops
oops: mov rwrt,offset wrt2
call r_draw
nooops: invoke InvalidateRect,hChild4,NULL,TRUE ;this call is indifferent
.endif
****
r_draw:
invoke BeginPaint,hWin,ADDR ps
mov hdc,eax
invoke SetTextColor,hdc,0A00Ah
invoke SetBkColor,hdc,022cch
invoke SetBkMode,hdc,TRANSPARENT
invoke GetClientRect,hWin, ADDR rect
invoke DrawText,hdc,rwrt,-1,ADDR rect,DT_SINGLELINE or DT_CENTER or DT_VCENTER
invoke EndPaint,hWin,ADDR ps
ret
;so, that is. I can`t imagin, what`s wrong.
Posted on 2004-06-09 15:27:35 by ola_dina
Maybe using RedrawWindow? :confused:

EDIT: Never mind that, I've read your code a little more.

It's the OS's normal behavior to repaint only when needed (ie when you cover your window with another one). Unless you want to do some animations that should be fine, if not then call RedrawWindow or InvalidateRect when the proper event is triggered (for example, a timer).

In any case, DON'T call InvalidateRect or RedrawWindow from your WM_PAINT handler... that's likely to cause an infinite loop since this two functions will cause more WM_PAINT messages to be generated. :(

If your text (or background) is not showing then the problem must be somewhere else... my bet would be a DC you're not releasing properly, or calling BeginPaint/EndPaint more than once for a single WM_PAINT message. Try loading your program from OllyDbg, and see if some function is throwing an error.

Let us know if you got it working :)
Posted on 2004-06-09 15:39:09 by QvasiModo
Indeed:



.elseif uMsg == WM_PAINT ; itt kezdodok a gubanc
[b]invoke BeginPaint,hWin,addr ps ;ez a resz [/b]
mov hdc,eax
invoke CreateCompatibleDC,hdc
mov hMemoryDC2ch4,eax
invoke SelectObject,hMemoryDC2ch4,hBitmapch4
mov hOldBmp2ch4,eax
invoke GetObject,hBitmapch4,sizeof BITMAP,addr bitmap2ch4
invoke StretchBlt,hdc,0,0,250,510,hMemoryDC2ch4,0,0,bitmap2ch4.bmWidth,bitmap2ch4.bmHeight,SRCCOPY
invoke SelectObject,hMemoryDC2ch4,hOldBmp2ch4
invoke DeleteDC,hMemDC2ch4
[b]invoke EndPaint,hWin,addr ps[/b]
invoke InvalidateRect,hChild4,NULL,FALSE; if I set this TRUE, there is no background pic.
szText wrt,"it's the drawtext function",0
szText wrt2,"ooooooops..... :))) ",0
test ooops,00000011b ;ooops set in the main window
jnz oops
mov rwrt,offset wrt
[b]call r_draw[/b]
jmp nooops
oops: mov rwrt,offset wrt2
[b]call r_draw[/b]
nooops: invoke InvalidateRect,hChild4,NULL,TRUE ;this call is indifferent
.endif
****
[b]r_draw:[/b]
[b]invoke BeginPaint,hWin,ADDR ps[/b]
mov hdc,eax
invoke SetTextColor,hdc,0A00Ah
invoke SetBkColor,hdc,022cch
invoke SetBkMode,hdc,TRANSPARENT
invoke GetClientRect,hWin, ADDR rect
invoke DrawText,hdc,rwrt,-1,ADDR rect,DT_SINGLELINE or DT_CENTER or DT_VCENTER
[b]invoke EndPaint,hWin,ADDR ps[/b]
ret


Calling BeginPaint will reset the update region (the part of your window that needs to be redrawn). So if you call it again, drawing will have no effect at all since (supposedly) there are no pixels in your window that need to be repainted.
Posted on 2004-06-09 15:58:49 by QvasiModo
I can draw only in the BeginPaint, so I must call it again.
Simplify the problem: how can I draw a line and then clear the text?
QvasiModo : if I don`t call Invalidaterect RIGHT AFTER putting out the bitmap, there is no text at all.
Posted on 2004-06-09 16:45:36 by ola_dina
He call InvalidateRect for hchild4 so when he subclass window there is no problem with infinite loop.

If you want paint removable text on the background/bitmaps/stuff then you should paint it on a transparent window (without a background) and this one put on window with background and stuff.
Posted on 2004-06-10 04:05:26 by AceEmbler
@ola_dina: I'm afraid it's an OS limitation, you have to call BeginPaint only once for each message. You can always use GetWindowDC, but IMHO it should be more efficient to restructure your paint routines to do all drawing between a single pair of BeginPaint/EndPaint calls. :)

@AceEmbler: You're right of course, I didn't realize that InvalidateRect was being called on another window... :o
Posted on 2004-06-10 12:27:31 by QvasiModo
Maybe it would be a good idea to use the WS_CLIPCHILDREN style for the parent window?
Posted on 2004-06-10 12:29:47 by Sephiroth3
I will try your suggestions.
What I still do not understand: if I cover it with another applications window, the old text disappear and everything looks fine. So the OS knows what to do just doesn`t know when.
Posted on 2004-06-10 15:10:00 by ola_dina
I`ve put it between a single pair Begin-EndPaint as follows:
......
.elseif uMsg == WM_PAINT ; itt kezdodok a gubanc
invoke BeginPaint,hWin,addr ps ;ez a resz egy bitmap-et rak ki hatternek, OK.
mov hdc,eax
invoke CreateCompatibleDC,hdc
mov hMemoryDC2ch4,eax
invoke SelectObject,hMemoryDC2ch4,hBitmapch4
mov hOldBmp2ch4,eax
invoke GetObject,hBitmapch4,sizeof BITMAP,addr bitmap2ch4
invoke StretchBlt,hdc,0,0,250,510,hMemoryDC2ch4,0,0,bitmap2ch4.bmWidth,bitmap2ch4.bmHeight,SRCCOPY
invoke SelectObject,hMemoryDC2ch4,hOldBmp2ch4
invoke DeleteDC,hMemDC2ch4
szText wrt,"it's the drawtext function",0
szText wrt2,"ooooooops..... :))) ",0
test ooops,00000011b ;ezt a valtozot a parent w-ban allitom be
jnz oops
mov rwrt,offset wrt
call r_draw
jmp nooops
oops:
mov rwrt,offset wrt2
call r_draw
nooops:
invoke EndPaint,hWin,addr ps
invoke InvalidateRect,hChild4,NULL,FALSE ;enelkul nincs felirat,de miert?
.endif
invoke DefWindowProc,hWin,uMsg,wParam,lParam
ret
r_draw: invoke SetTextColor,hdc,0A00Ah
invoke SetBkColor,hdc,022cch
invoke SetBkMode,hdc,TRANSPARENT
invoke GetClientRect,hWin, ADDR rect
invoke DrawText,hdc,rwrt,-1,ADDR rect,DT_SINGLELINE or DT_CENTER or DT_VCENTER
ret

The result almost exactly the same as before: the text changes only if I cover it. (difference: doesn`t put the new text on the old)
Posted on 2004-06-10 15:27:37 by ola_dina
WS_CLIPCHILDREN and RedrawWindow doesn`t help.
Posted on 2004-06-10 15:41:57 by ola_dina
I'm kinda lost... you want to draw this text in response to what event? :confused:

If the problem is that the text's background is not transparent, you have to use a whole different approach. Using regions should work, but AceEmbler's suggestion will probably be easier to implement: just create a transparent window with the text you want.

(or maybe I totally misunderstood the problem :o)
Posted on 2004-06-11 17:27:00 by QvasiModo
Yes, at first it looks easier. And every now and than when I want to change the text, I should close the transparent window, and create again. I`m sure it will work just don`t like it.
The annoying thing is that the Windows KNOWS what I want, just doesn`t do it until I didn`t change/move something in the window. Tomorrow I`ll send the code.
Thx your attentions
Posted on 2004-06-13 16:29:32 by ola_dina
I`ve find a solution: I hide the window then show it again (ShowWindow). Not elegant but works.
Posted on 2004-06-15 14:27:38 by ola_dina
You have to use InvalidateRect when the text changes.
Posted on 2004-06-15 14:49:52 by Sephiroth3
InvalidateRect doesn`t help.
Here I send a short version of my program. The interesting part is in the winproc_ch4.inc.
This is a working version. Try it without ShowWindow (it is in the wndproc_par.inc , to respond the WM_COMMAND)
Posted on 2004-06-16 13:56:55 by ola_dina