News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

TextOut

Started by Jackal, August 06, 2006, 04:09:32 AM

Previous topic - Next topic

TNick

SaveDC and RestoreDC appeared here because of a topic here about a statement from Win32.hlp. There it is stated, at the SelectObject function, that:

Quote
This function returns the previously selected object of the specified type. An application should always replace a new object with the original, default object after it has finished drawing with the new object.

jojo sugested the use of SaveDC and RestoreDC to avoid selecting the old object back in thet DC. I considered this a good sugestion and I used this method ever sience.

Well, this is the story of SaveDC and RestoreDC as I know it  ::) ....

Nick

asmfan

IMHO, there's no necessary in using Save/Restore because Memory Context is used and deleted by you only and when you need it only. System doesnt share so no need even to save cuz finally U delete it, as i said, by your own hands. It's only useful to select back the resource if the deletion sequence is strict: e.g. Created Brush->mem DC. the first of all you delete Brush then mem DC. But what if you use ony Stock objects->you dont have to delete them only delete mem DC->not need to Save/Restore. Just my opinion on what microsoft recommends...
Russia is a weird place

Jackal

Ok i stripped out most the code of my app and left what makes my apps design as in the gui. I also turned up the timer to make it more visible of my problem. If i dont expand the DC accross the listview i dont get the green but the items will still blink. I tried to put the listview on the DC in memory but could not get it working when i tried to do that. Any help would be appreciated..

[attachment deleted by admin]

Tedd

Your problem is caused by the fact that every time you call InvalidateRect, it causes the entire window to be cleared and then its components are redrawn. For the listview this means its entire area is erased to window background and then redrawn over that - since these two colours are different, you see the flicker as the listview redraws itself.
Simple solution - don't erase the entire window, just the parts that will change and need updating.
Assuming this is just the info boxes (the listview redraws itself), modify your code like so:


(in WndProc)..

    cmp uMsg, WM_TIMER
    jne @F

      mov rect.top, 20
      mov rect.bottom, 40
      mov rect.left, 6
      mov rect.right, 185
;**these rectangles don't need to be drawn again - nothing to do with your problem, but still ;)
;      Invoke Rectangle, hDCBack, rect.left, rect.top, rect.right, rect.bottom
;** invalidate just the info box area
;** this could be reduced to just the text line - since that's what actually changes
;** erase-background is false here
:**  if you draw a long string and then a short one, you will still see the tail of the long one
;**  making it TRUE will fix that, but can also cause a flicker
invoke InvalidateRect, hWnd, ADDR rect, FALSE
      Invoke DrawText,hDCBack, addr AppName,-1,ADDR rect,DT_CENTER or DT_SINGLELINE or DT_VCENTER
      mov rect.top, 120
      mov rect.bottom, 140
      mov rect.left, 6
      mov rect.right, 185
;      Invoke Rectangle, hDCBack, rect.left, rect.top, rect.right, rect.bottom
invoke InvalidateRect, hWnd, ADDR rect, FALSE
      Invoke DrawText,hDCBack, addr FB,-1,ADDR rect,DT_CENTER or DT_SINGLELINE or DT_VCENTER
      mov rect.top, 70
      mov rect.bottom, 90
      mov rect.left, 6
      mov rect.right, 185
;      Invoke Rectangle, hDCBack, rect.left, rect.top, rect.right, rect.bottom
invoke InvalidateRect, hWnd, ADDR rect, FALSE
      Invoke DrawText,hDCBack, addr nTime,-1,ADDR rect,DT_CENTER or DT_SINGLELINE or DT_VCENTER
      mov rect.top, 170
      mov rect.bottom, 192
      mov rect.left, 6
      mov rect.right, 185
;      Invoke Rectangle, hDCBack, rect.left, rect.top, rect.right, rect.bottom
invoke InvalidateRect, hWnd, ADDR rect, FALSE
      Invoke DrawText,hDCBack, addr mNone,-1,ADDR rect,DT_CENTER or DT_SINGLELINE or DT_VCENTER
      mov rect.top, 220
      mov rect.bottom, 240
      mov rect.left, 6
      mov rect.right, 185
;      Invoke Rectangle, hDCBack, rect.left, rect.top, rect.right, rect.bottom
invoke InvalidateRect, hWnd, ADDR rect, FALSE
      Invoke DrawText,hDCBack, addr mChange,-1,ADDR rect,DT_CENTER or DT_SINGLELINE or DT_VCENTER

;** don't need to redraw the WHOLE window anymore - yay
;      invoke InvalidateRect, hWnd, 0, FALSE

     jmp Return

No snowflake in an avalanche feels responsible.

Jackal

ok i see now. Ill play with it and see if i can get it working like i want.  Thank you for the help.. I knew there had to be a way to do just parts but i couldnt figure it out and maybe i misunderstood msdn. again thx to everyone who helped  :bg

Jackal

ok its working perfectly now  :bg  I still have the rectangle api in there to redraw over any strings that may be longer than the the new one. Also instead of using the invalidaterect api i just did the entire left side at the end of the timer.