Announcement

Collapse
No announcement yet.

Pattern brush problems

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Pattern brush problems

    Guys -
    decided to use pattern brush instead of solid and found (under Win2000) serious flashing during moving.
    Tried FillRect in WM_PAINT and WM_CTLCOLORDLG.
    Any ideas, how to prevent ?

    ------------------
    E-MAIL: [email protected]

  • #2
    No idea. Here is a test I once did - does it also flicker?
    Code:
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' PATTERN BRUSH TEST
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    #COMPILE EXE
    #INCLUDE "WIN32API.INC"
    DECLARE CALLBACK FUNCTION DlgProc() AS LONG
    DECLARE FUNCTION MakePatternBrush(BYVAL hWnd AS LONG) AS LONG
     
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' MAIN ENTRANCE - CREATE DIALOG
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    FUNCTION PBMAIN () AS LONG
      LOCAL hDlg AS LONG
      DIALOG NEW 0, "Pattern brush test",,, 240, 120, %WS_CAPTION Or %WS_SYSMENU  TO hDlg
      CONTROL ADD BUTTON, hDlg, 123, "Dummy button",  60, 30, 120, 60
      DIALOG SHOW MODAL hDlg CALL DlgProc
    END FUNCTION
     
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' MAIN DIALOG'S CALLBACK PROCEDURE
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    CALLBACK FUNCTION DlgProc() AS LONG
      SELECT CASE CBMSG
         CASE %WM_INITDIALOG
            STATIC hBrush AS LONG
            hBrush = MakePatternBrush(CBHNDL)
     
         CASE %WM_CTLCOLORDLG
            FUNCTION = hBrush 'return pattern brush
     
         CASE %WM_DESTROY
            IF hBrush THEN DeleteObject hBrush             'clean-up time
     
      END SELECT
     
    END FUNCTION
     
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' CREATE AND RETURN PATTERNED BRUSH
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    FUNCTION MakePatternBrush(BYVAL hWnd AS LONG) AS LONG
      LOCAL Loop1 AS LONG, Loop2 AS LONG, hdc AS LONG, hdcMem AS LONG, _
            hBitmap AS LONG, hBitmapOld AS LONG, rc AS RECT
     
      hdc = GetDC(hWnd)
      hdcMem = CreateCompatibleDC(hdc)
      hBitmap = CreateCompatibleBitmap(hdc, 8, 8)
      hBitmapOld = SelectObject(hdcMem, hBitmap)
     
      rc.nleft = 0 : rc.ntop = 0 : rc.nright = 8 : rc.nbottom = 8
      FillRect hdcMem, rc, GetSysColorBrush(%COLOR_INFOBK)
     
      FOR Loop1 = 0 TO 7
         FOR Loop2 = Loop1 TO 7 STEP 2
            SetPixelV hdcMem, Loop2, Loop1, RGB(128, 128, 0)
         NEXT
      NEXT
      FUNCTION = CreatePatternBrush (hBitmap)
     
      CALL SelectObject(hdcMem, hBitmapOld)
      DeleteObject hBitmap
      DeleteDC hdcMem
      ReleaseDC hWnd, hdc
     
    END FUNCTION

    ------------------


    [This message has been edited by Borje Hagsten (edited October 01, 2001).]

    Comment


    • #3
      Semen;

      I found that the best way is to create a memory DC and a Bitmap,
      fill the bitmap with the pattern and then Bitblt it into the Dialogs
      background during either WM_ERASEBKGND or WM_PAINT (no need to call
      WM_ERASEBKGND).

      ------------------
      Chris Boss
      Computer Workshop
      Developer of "EZGUI"
      http://cwsof.com
      http://twitter.com/EZGUIProGuy

      Comment


      • #4
        Semen;

        You probably already know this, but just a reminder :

        If you paint the background in WM_PAINT make sure you prevent the
        WM_ERASEBKGND message from being processed, because when
        BeginPaint is executed it sends a WM_ERASEBKGND message
        to the dialog. This is will cause serious flicker, since the
        background gets drawn twice.



        ------------------
        Chris Boss
        Computer Workshop
        Developer of "EZGUI"
        http://cwsof.com
        http://twitter.com/EZGUIProGuy

        Comment


        • #5
          Chris -
          99.99% sure that I prevented double repainting
          Borje --
          Your small window doesn't flicker. But when I resized it to full screen (1280 * 1024 * 32), happened the same like in my code.

          I used monochrome bitmap + SetTextColor/SetBkColor.
          Tried memory DC also, and to fill it manually w/o hBrush.
          Probably, this visual effect is linked with slow redrawing in Win2000 during window moving (I see white "wawes").
          Alone hope - background will be mostly covered.



          ------------------
          E-MAIL: [email protected]

          Comment


          • #6
            Just a guess---
            Is it possibly a Pallette problem?

            ------------------

            Comment


            • #7
              Also, ---may not be relevent---

              But when I resize Borje's example, I get bad flicker on edge---
              representing the (wait for vert retrace fix)---(Dos days, I don't
              know if it pertains to Windows) B.

              ------------------

              Comment


              • #8
                It seems to me I understood, what's wrong.
                I use a bitmap which creates one line with one color, next line - with another.
                If I do not make a mistake, de-facto this is CreateHatchBrush with HS_HORIZONTAL.

                Imagine that before moving, left-up corner' screen coordinates were (100, 50). After moving - (97, 43).
                If to look to one point (let's say - 102, 60), it's color will be changed.
                Before moving dark line had x = 100, 102, 104. Light line = x = 101, 103
                After moving : dark line x = 97, 99, 101, 103 ...; light - 98, 100, 102 ...

                WM_PAINT occurs a lot of times. So there is a lot of color changes ("white wave").
                I'll write more clever algorithm - will select a color of first line depends of screen coordinates.

                ------------------
                E-MAIL: [email protected]

                Comment


                • #9
                  Flicker on repaint, often depends on graphic card. Have a bunch of machines
                  to test with here and must say, most modern graphic's cards behaves very
                  strange from time to time.

                  One machine I really like to work with is actually an old IBM 120 MHz, where
                  I installed a very cheap SVGA card as replacement for IBM's own. Instant
                  repaints - beats most other, faster computers. I can see the flicker in
                  a 500 MHz machine, but not in the old IBM. They call this progress? In any
                  event interesting, because shows one can never rely on things being faster
                  or better when it comes to newer computers.

                  Yes, hatched brushes seems to base all things on screen coordiantes.
                  BTW, Semen. Flashing on move? Means dialog is visible during move, or? Have
                  seen also MS app's behave strange when system is set that way. Maybe will
                  help using several brushes with slighly adjusted patterns. Maybe even
                  two is enough, and then let GetWindowRect decide which brush to use.


                  ------------------

                  Comment


                  • #10
                    Modern graphics cards are generally much faster, if you're comparing
                    apples to apples. In practice, though, they're likely to be dealing
                    with many more pixels at much greater color depth...


                    ------------------
                    Tom Hanlin
                    PowerBASIC Staff

                    Comment


                    • #11
                      I tested my idea - doesn't work.
                      But I found that results depends, how contrast are colors.
                      If to uncomment SetTextColor - doesn't flash on my PC.

                      Code:
                         #Compile Exe
                         #Register None
                         #Dim All
                         #Include "WIN32API.INC"
                      
                         CallBack Function DlgProc
                            Select Case CbMsg
                               Case %WM_INITDIALOG
                                 Static hBrush As Long
                                 Local hBitMap As Long
                                 ReDim wWeave(7) As Word
                                 wWeave(0)=&H0F : wWeave(1)=&H8B : wWeave(2)=&HDD : wWeave(3)=&HB8
                                 wWeave(4)=&H70 : wWeave(5)=&HE8 : wWeave(6)=&HDD : wWeave(7)=&H8E
                                 hBitmap = CreateBitmap(8, 8, 1, 1, wWeave(0))
                                 hBrush = CreatePatternBrush(hBitmap)
                                 
                                 DeleteObject hBitMap
                      
                              Case %WM_CTLCOLORDLG
                                 SetTextColor CbWparam, Rgb(0, 0, 128)
                                 SetBkColor CbWparam, %WHITE
                                 
                                 'SetTextColor CbWparam, Rgb(128, 128, 128) ' doesn't flash
                                 
                                 Function = hBrush 'return pattern brush
                             Case %WM_DESTROY
                                 If hBrush Then DeleteObject hBrush             'clean-up time
                      
                           End Select
                        End Function
                      
                         
                         Function PbMain () As Long
                            Local hDlg As Long
                            Dialog New 0, "Pattern brush test",,, 240, 120, %WS_CAPTION Or %WS_SYSMENU  To hDlg
                            Control Add Button, hDlg, 123, "Dummy button",  60, 30, 120, 60
                            Dialog Show Modal hDlg Call DlgProc
                         End Function

                      ------------------
                      E-MAIL: [email protected]

                      Comment


                      • #12
                        Tom - IBM 120 MHz machine, 16-bit color cheap SVGA with 4MB memory,
                        instant repaints in almost all app's - dialogs pop up directly. Other
                        machine 500 MHz, 16-bit colors, modern graphics accelerator blah-blah,
                        blah-blah, with test values that runs in circles around old machine,
                        can sometimes see controls in dialogs being painted on popup.

                        All is about three times faster in 500MHz machine, except for repaint,
                        which gives impression it is much slower. My son tells me it's a good
                        game machine, but what games? The old IBM is much better at handling
                        Solitaire, so I tell my son he is wrong. Will spare you what my son
                        tells me then..

                        Semen, interesting. Have noticed that setting BkMode Transparent is
                        slower than using matching BkColor. Can understand that. Cannot
                        understand why setting a text color or not makes a difference.

                        Maybe playing with pen color can affect things too? Who understands
                        what a Device Context really is and look like? Seems to me there are
                        several different DC's for same window. Maybe that can explain why setting
                        text color makes a difference - Windows then has to combine several DC's..?


                        ------------------


                        [This message has been edited by Borje Hagsten (edited October 02, 2001).]

                        Comment


                        • #13
                          I believe Tom is right here... typical modern cards are MUCH faster than just a few years ago, and as a result are told to redraw the screen many more times during a window move/resize.

                          Because the redraw can theoretically be acomplished more quickly and more often, it can become more visible to the eye (unless the redraw can happen at the frame rate of the monitor or at least higher than 60hz - which is not always possible for a "tile paint" such as this topic is discussing).

                          One interesting test yourself and Semen could make would be to reduce the hardware acceleration setting (in Control Panel) to minimum. Also, does the flicker effect change with the color depth settings?

                          The results may be of interest at least...





                          ------------------
                          Lance
                          PowerBASIC Support
                          mailto:[email protected][email protected]</A>
                          Lance
                          mailto:[email protected]

                          Comment


                          • #14
                            I know, Lance. My problem is I'm too old and stupid to understand that
                            faster today means more repaints in longer total time..

                            BTW, in 256 color mode, things look better, faster here. But then, cheap
                            SVGA card also is much faster. Changing any other settings makes no real
                            visual difference in plain app's, at least not for me. Guess it mostly
                            affects performance in 3D games, etc.


                            ------------------

                            Comment


                            • #15
                              I don't know how to explain this exactly-----
                              But, when the video card refreshes the monitor--- it inter-leaves
                              the scan---so what is happening is that windows obviously in this
                              case does not care about high speed graphics---and therefore is not
                              waiting for the vertical retrace to be at zero-----there should be
                              an API that controls the wait as well as API's that will allow us to
                              hook between the repainting of the old background and the painting of the
                              new image----------as Semen taught me about hooking----

                              ------------------

                              Comment


                              • #16
                                Semen:
                                I cannot test the samples because I do not have DDT so this is only a
                                wild shot based on my own experiences. Since you are using a pattern
                                brush, try explicitly setting the brush origin during repaints to the
                                origin of the device context for the diaolg(wParam of WM_CTLCOLORDLG).

                                Brad:
                                The BeginDeferWindowPos , DeferWindowPos and EndDeferWindowPos usually
                                do a good job, at for controls.

                                [This message has been edited by Dominic Mitchell (edited October 03, 2001).]
                                Dominic Mitchell
                                Phoenix Visual Designer
                                http://www.phnxthunder.com

                                Comment


                                • #17
                                  Thanks, Dominic --------- B

                                  ------------------

                                  Comment

                                  Working...
                                  X