Shimmering colours

Shimmering colours

davidgraham's picture

I am displaying 256 boxes on a dialog using FillRec.
When the dialog is first displayed the whole dialog shimmers, but if I move the dialog it stops and is the display is OK.

Any ideas how I can stop this?

Thanks,

David

4 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
davidgraham's picture

Jugoslav,

Here is the code for drawing the 256 colours (in fact 16 colours drawn 16 times at present). The main call are CreateSolidBrush, FillRect & DeteObject - all the rest is drawing the rectangles in the correct place.

grad_inc & the *.gcb files contain global variables.

Regards,

David

integer*4 function SetColourProc(hwnd, message, wParam, lParam) !********************************************************** !MS$ATTRIBUTES STDCALL, ALIAS : '_SetColourProc@16' :: SetColourProc use dfwin use grad_inc include 'resource.fd' include 'rgbcol.gcb' ! api_rgb,api_rgbc,api_lsc include 'apipar.gcb' ! hdc,x/yClientView,yClientOffset,hpen common/SetColourc/jSetColour integer*2 jSetColour TYPE(T_RECT) rect1,rectC,rectD,rectB integer*4 hwnd, message, wParam, lParam integer*4 iret,hdcDlg,iCtrl,hdcClr,hbr,col,row,hColours,CWidth,CHeight integer*4 XColour,YColour integer*4 hSR integer*2 c,r,b real*4 width,height logical*4 lret ! Unreferenced variables lparam = lparam select case (message) case (#0053) ! WM_HELP call help case (WM_INITDIALOG) hdcDlg=GetDC(hWnd) SetColourProc=1 return case (WM_SHOWWINDOW) if (wParam) then iret=ShowCursor(.TRUE.) hColours=GetDlgItem(hwnd,IDC_COLOURS) endif SetColourProc = 1 return case (WM_PAINT) lret=GetWindowRect(hColours,rectC) lret=GetWindowRect(hwnd,rectD) hdcClr = GetDC (hwnd) lret=GetClientRect(hwnd,rect1) col=16 row=16 XColour=rectC%left-rectD%left YColour=rectC%top-rectD%top CWidth=rectC%right-rectC%left-7 CHeight=rectC%bottom-rectC%top-15 width=real(CWidth)/(real(col)+(real(col)+1.0)/2.0) height=real(CHeight)/(real(row)+(real(row)+1.0)/2.0) do b=1,256 ! 256 colours c=imod(b-1,col)+1 ! column r=int2((b-1)/row)+1 ! row rect1%left=(int4(c)*(1.5)-1.0)*width+Xcolour rect1%right=rect1%left+width rect1%top=(int4*(1.5)-1.0)*height+Ycolour-10 rect1%bottom=rect1%Top+height hbr = CreateSolidBrush (RGB(api_rgb(1,c),api_rgb(2,c),api_rgb(3,c))) lret = FillRect (hdcClr, rect1, hbr) lret = DeleteObject (hbr) end do case (WM_COMMAND) ! message: received a command iCtrl=LoWord(wParam) select case (iCtrl) case (IDOK) ! OK lret=EndDialog(hWnd,1) SetColourProc = 1 case (IDCANCEL) ! System menu close command? lret = EndDialog(hWnd, 0) SetColourProc = 1 end select case default SetColourProc=0 end select return end function SetColourProc
Jugoslav Dujic's picture

IMO it's quite incommon to do the drawing directly on
dialog's hDC. Even as you wrote it, its atypical for standard
WM_PAINT handling. You can try two things:

1) Add

type(T_PAINSTRUCT) ps ... IF (GetUpdateRect(hWnd,Rect,.FALSE.)) THEN hdcClr=BeginPaint(hWnd,ps) ... bSt=EndPaint(hWnd,ps) END IF


(also remove line hDcClr=GetDC(...))

I think that dialog shimmers because noone has ever
validated the update region, so Windows keep on
sending WM_PAINT until the region is validated another
way. ValidateRect documentation says that, quote,

"The BeginPaint function automatically validates the entire client area. Neither the ValidateRect nor ValidateRgn function should be called if a portion of the update region must be validated before the next WM_PAINT message is generated. Windows continues to generate WM_PAINT messages until the current update region is validated."

b) Nevertheless, I think it's clearer to do the drawing in an owner-
drawn static control. So, make IDC_COLOURS an owner-drawn static control
Unfortunately, Visual Studio 5 (nor 6, as I checked) does not have "Owner drawn" check-box for static control on property sheet. You have to edit .rc file manually later - add SS_OWNERDRAW style to your control:

CONTROL "",IDC_COLOURS,"Static",SS_OWNERDRAW,11,16,116,120

then, instead of WM_PAINT, process WM_DRAWITEM in SetColourProc:

TYPE(T_DRAWITEMSTRUCT):: DIS; POINTER(pDIS,DIS) ... CASE(WM_DRAWITEM) pDIS=lParam hdcClr=DIS%hDC ...



and leave the rest of the code more or less the same.
Owner-drawn controls are very powerful for obtaining nice
effects with controls.

HTH

Jugoslav

Jugoslav www.xeffort.com
davidgraham's picture

Thanks, I used the BeginPaint / EndPaint and the colours are now OK.

David

Login to leave a comment.