Hi
I have flickering in a static box that displays a timer that is updated every 25 milliseconds.
Q how do I go about preventing this flicker?
any help would be appreciated
Regards
John
maybe give us a sample code ?
the flicker may be due to your video card or drivers
so - first step is to isolate the problem
find out if it is the program or the machine
alternately, try the program on a different machine
Is this a dialog?
Is the WS_CLIPCHILDREN style bit set?
John,
at 25 MS intervals, it is being updated 40 times a second, thats why its flickering. Seperate the data update from the display update and reduce the interval, say for example, every 250 MS and most of the flicker will be gone.
There is also this tut (not of mine)
[attachment deleted by admin]
In my tests synchronizing the control update with vertical blank eliminated the flicker, even with the dialog window positioned at the top of the screen and the vertical refresh frequency set to the maximum. There are probably other equally effective methods that do not depend on DirectX, but I suspect that they would be significantly more difficult to implement.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
include \masm32\include\ddraw.inc
includelib \masm32\lib\ddraw.lib
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
DD_OK EQU 0
DDO_GetScanLine EQU 64
DDERR_INVALIDPARAMS EQU E_INVALIDARG
DDERR_UNSUPPORTED EQU E_NOTIMPL
DDERR_INVALIDOBJECT EQU ((1 shl 31) or (876h shl 16) or ( 130 ))
DDERR_VERTICALBLANKINPROGRESS EQU ((1 shl 31)or(876h shl 16)or(537))
DDGetScanLine PROTO scanLine:DWORD
WaitForVerticalBlank PROTO
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
hInst dd 0
ctr dd 0
lpdd_1 dd 0
sync dd 0
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
DialogProc proc hwndDlg:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL rc:RECT
LOCAL ps:PAINTSTRUCT
SWITCH uMsg
CASE WM_INITDIALOG
; ------------------------------------
; Create a default DirectDraw object.
; ------------------------------------
invoke DirectDrawCreate,NULL,ADDR lpdd_1,NULL
.IF eax
MsgBox 0,"DirectDrawCreate failed",0,0
.ENDIF
invoke SetTimer, hwndDlg, 1, 25, NULL
CASE WM_TIMER
inc ctr
.IF sync
call WaitForVerticalBlank
.ENDIF
invoke SetDlgItemText, hwndDlg, 100, hex$(ctr)
CASE WM_COMMAND
SWITCH wParam
CASE 101
invoke IsDlgButtonChecked, hwndDlg, 101
.IF eax
mov sync, 1
.ELSE
mov sync, 0
.ENDIF
CASE IDCANCEL
invoke KillTimer, hwndDlg, 1
invoke EndDialog, hwndDlg, NULL
ENDSW
CASE WM_CLOSE
invoke KillTimer, hwndDlg, 1
invoke EndDialog, hwndDlg, NULL
ENDSW
return 0
DialogProc endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
invoke GetModuleHandle, NULL
mov hInst, eax
Dialog "TEST",\
"Courier New Bold",24,\
WS_OVERLAPPEDWINDOW or DS_CENTER,\
2,0,0,70,10,1024
DlgStatic 0, WS_BORDER, 3, 1, 34, 8, 100
DlgCheck "Sync:",BS_LEFTTEXT,40,1,26,8,101
CallModalDialog hInst,0,DialogProc,NULL
ret
exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
DDGetScanLine proc lpScanLine:DWORD
push lpScanLine
push lpdd_1
mov eax, lpdd_1
mov eax, [eax]
call DWORD PTR[eax+DDO_GetScanLine]
ret
DDGetScanLine endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
WaitForVerticalBlank proc
LOCAL localScanLine:DWORD
invoke DDGetScanLine, ADDR localScanLine
; -------------------------------
; Wait until not vertical blank.
; -------------------------------
.WHILE (eax == DDERR_VERTICALBLANKINPROGRESS)
invoke DDGetScanLine, ADDR localScanLine
.ENDW
; ---------------------------
; Wait until vertical blank.
; ---------------------------
.WHILE (eax != DDERR_VERTICALBLANKINPROGRESS)
invoke DDGetScanLine, ADDR localScanLine
.ENDW
ret
WaitForVerticalBlank endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
JayPee,
Other alternative which hasn't been mentioned is to draw the text in the static control (or any control) using a bitmap with a off-screen HDC and BitBlt it.
Relvinian
lots of good stuff here for a n00b to learn - this is why i am here
Thank You All
- Dave
Do you actually need to update this fast, or is it 'just in case' to catch something that may change?
How about checking whether the thing you're displaying has actually changed, and only update when it has - your program will run a lot smoother and there will be no flicker.
All you need to do is keep a copy of the previous value, then on the next update-cycle get the new value and check that against the old, if they're different do a redraw and update the 'old' value to this new one; if they're the same you don't need to do anything.
good point - a person can only read and comprehend about 10 changes a second (guessing, there)
if the information was going to a file record or to be used for calculation - different story
Hi everyone
Thank you very much for your replies.
I have fixed the problem by using the ExtTextOut function- works very well without using double buffering.
I created a DC at creation time and call the function every 25 Milliseconds
After extensive testing I haven't experienced any flicker at all.
ToutEnMasm - Thanks for pointing me to the flicker tutorial, found it most informative.
Hutch - I agree with your comments however as a learner I am using this as a learning exercise in making code run as efficient as possible :bg
Kind Regards
John