Announcement

Collapse
No announcement yet.

sdk transparent labels on gradient bkgrnd

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

    sdk transparent labels on gradient bkgrnd

    I can't figure out why the following code doesn't produce a transparent sdk label since I use the ws_ex_transparent style. I paint the background with a gradient.

    First, am I doing the 'static' control correctly. Secondly, is it required to use a null_brush in the dialog call back to get it to go transparent?

    I've started looking at ownerdrawn but don't see how I can remove the drawtext or textout output.

    Code:
    #DIM ALL
    #REGISTER ALL
    #INCLUDE "win32api.inc"
    
    GLOBAL ghMain AS DWORD
    
    CALLBACK FUNCTION dlgMain 
      SELECT CASE CBMSG
        CASE %WM_PAINT
          CALL PaintBg(CBHNDL,0,0,0)
      END SELECT    
    END FUNCTION
    
    
    FUNCTION PBMAIN
        %LBL_LABEL = 1001
        DIM hWndControl AS DWORD,szControlText AS STRING
    
        DIALOG NEW 0, "Transparent sdk style label ", 0,0,150,170, %WS_OVERLAPPEDWINDOW OR %DS_CENTER TO ghMain
        szControlText = "Sample Text"
        hWndControl = CreateWindowEx(%WS_EX_TRANSPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING , _
                                     "Static", _  ' window class name
                                     BYCOPY szControlText, _    ' window caption
                                     %SS_LEFT OR %WS_CHILD OR %WS_VISIBLE OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN, _
                                     10, 10, 150, 15, _
                                     ghMain, %LBL_LABEL, GetModuleHandle(BYVAL 0&), BYVAL %Null)
        DIALOG SHOW MODAL ghMain CALL dlgMain
    
    END FUNCTION
    FUNCTION SetColor (BYVAL tCOLOR AS BYTE) AS WORD
        ' the windows api GradientFill routine wants r/g/b colors to be
        ' 16 bit words with the 8 bit color values left shifted 8 bits.
        ' this takes care of that.
        LOCAL clr AS WORD
        clr = tCOLOR
        SHIFT LEFT clr, 8
        FUNCTION = clr
    END FUNCTION
    SUB PaintBg(BYVAL hDialog AS LONG, BYVAL r AS LONG, BYVAL g AS LONG, BYVAL b AS LONG)
         ' this is to paint the background of the dialog
         ' it's all straight out of the MSDN help file.  We can change the values
         ' if we like.
         LOCAL ps AS PAINTSTRUCT
         LOCAL rc AS Rect
         LOCAL hDc AS DWORD
         LOCAL Xin&
         LOCAL Yin&,Temp&,cRed&,cGreen&,cBlue&
         DIM vert(1) AS TRIVERTEX
         DIM gRect AS GRADIENT_RECT
         hDC = BeginPaint(hDialog, ps)
           ' Tile the background
         GetClientRect hdialog, rc
         Xin = rc.nRight - rc.nLeft
         Yin = rc.nBottom - rc.nTop
         Xin = rc.nRight - rc.nLeft
         Yin = rc.nBottom - rc.nTop
         Temp& = RGB(205,214,255)
         IF Temp& <> 0 THEN
           cRed&   = Temp& MOD 256
           cGreen& = (Temp& \ 256) MOD 256
           cBlue&  = ((Temp& \ 256) \ 256) MOD 256
         ELSE
           cRed&   = 192
           cGreen& = 224
           cBlue&  = 192
         END IF
         vert(0).x      = 0
         vert(0).y      = 0
         vert(0).Red    = SetColor(cRed& - 90)
         vert(0).Green  = SetColor(cGreen& - 90)
         vert(0).Blue   = SetColor(cBlue& - 90)
         vert(0).Alpha  = &h0000
         vert(1).x      = xin
         vert(1).y      = yin
         vert(1).Red    = SetColor(cRed&)
         vert(1).Green  = SetColor(cGreen&)
         vert(1).Blue   = SetColor(cBlue&)
         vert(1).Alpha  = &h0000
         gRect.UpperLeft  = 0
         gRect.LowerRight = 1
         GradientFill hDc, vert(0), 2, gRect, 1, %GRADIENT_FILL_RECT_v
         EndPaint hDialog, ps
    END SUB

    #2
    Here is your code with the problem fixed. They key is handling the WM_CTLCOLORSTATIC message properly.

    Code:
    #DIM ALL
    #REGISTER ALL
    #INCLUDE "win32api.inc"
    GLOBAL ghMain AS DWORD
    CALLBACK FUNCTION dlgMain
      SELECT CASE CBMSG
        CASE %WM_ERASEBKGND
             FUNCTION=1
             EXIT FUNCTION
        CASE %WM_SIZE
             InvalidateRect CBHNDL, BYVAL %NULL,1
        CASE %WM_CTLCOLORSTATIC
             SetBKMode CBWPARAM, %TRANSPARENT
             FUNCTION=GetStockObject(%NULL_BRUSH)
             EXIT FUNCTION
        CASE %WM_PAINT
          CALL PaintBg(CBHNDL,0,0,0)
          FUNCTION=1    ' required for dialog procedure
          EXIT FUNCTION
      END SELECT
    END FUNCTION
     
    FUNCTION PBMAIN
        %LBL_LABEL = 1001
        DIM hWndControl AS DWORD,szControlText AS STRING
        DIALOG NEW 0, "Transparent sdk style label ", 0,0,150,170, %WS_OVERLAPPEDWINDOW OR %DS_CENTER OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN TO ghMain
        szControlText = "Sample Text"
        hWndControl = CreateWindowEx(%WS_EX_TRANSPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING , _
                                     "Static", _  ' window class name
                                     BYCOPY szControlText, _    ' window caption
                                     %SS_LEFT OR %WS_CHILD OR %WS_VISIBLE OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN, _
                                     10, 10, 150, 15, _
                                     ghMain, %LBL_LABEL, GetModuleHandle(BYVAL 0&), BYVAL %Null)
        DIALOG SHOW MODAL ghMain CALL dlgMain
    END FUNCTION
    FUNCTION SetColor (BYVAL tCOLOR AS BYTE) AS WORD
        ' the windows api GradientFill routine wants r/g/b colors to be
        ' 16 bit words with the 8 bit color values left shifted 8 bits.
        ' this takes care of that.
        LOCAL clr AS WORD
        clr = tCOLOR
        SHIFT LEFT clr, 8
        FUNCTION = clr
    END FUNCTION
    SUB PaintBg(BYVAL hDialog AS LONG, BYVAL r AS LONG, BYVAL g AS LONG, BYVAL b AS LONG)
         ' this is to paint the background of the dialog
         ' it's all straight out of the MSDN help file.  We can change the values
         ' if we like.
         LOCAL ps AS PAINTSTRUCT
         LOCAL rc AS Rect
         LOCAL hDc AS DWORD
         LOCAL Xin&
         LOCAL Yin&,Temp&,cRed&,cGreen&,cBlue&
         DIM vert(1) AS TRIVERTEX
         DIM gRect AS GRADIENT_RECT
         hDC = BeginPaint(hDialog, ps)
           ' Tile the background
         GetClientRect hdialog, rc
         Xin = rc.nRight - rc.nLeft
         Yin = rc.nBottom - rc.nTop
         Xin = rc.nRight - rc.nLeft
         Yin = rc.nBottom - rc.nTop
         Temp& = RGB(205,214,255)
         IF Temp& <> 0 THEN
           cRed&   = Temp& MOD 256
           cGreen& = (Temp& \ 256) MOD 256
           cBlue&  = ((Temp& \ 256) \ 256) MOD 256
         ELSE
           cRed&   = 192
           cGreen& = 224
           cBlue&  = 192
         END IF
         vert(0).x      = 0
         vert(0).y      = 0
         vert(0).Red    = SetColor(cRed& - 90)
         vert(0).Green  = SetColor(cGreen& - 90)
         vert(0).Blue   = SetColor(cBlue& - 90)
         vert(0).Alpha  = &h0000
         vert(1).x      = xin
         vert(1).y      = yin
         vert(1).Red    = SetColor(cRed&)
         vert(1).Green  = SetColor(cGreen&)
         vert(1).Blue   = SetColor(cBlue&)
         vert(1).Alpha  = &h0000
         gRect.UpperLeft  = 0
         gRect.LowerRight = 1
         GradientFill hDc, vert(0), 2, gRect, 1, %GRADIENT_FILL_RECT_v
         EndPaint hDialog, ps
    END SUB
    Last edited by Chris Boss; 15 Feb 2008, 11:38 PM.
    Chris Boss
    Computer Workshop
    Developer of "EZGUI"
    http://cwsof.com
    http://twitter.com/EZGUIProGuy

    Comment


      #3
      There is another problem you might have to deal with. If the window is resizeable, add the following code right after the DIALOG NEW statement.
      Code:
       SetClassLong ghMain, %GCL_STYLE, GetClassLong(ghMain, %GCL_STYLE) OR %CS_HREDRAW OR %CS_VREDRAW
      Click the maximize image(button) in the caption to see why.
      Dominic Mitchell
      Phoenix Visual Designer
      http://www.phnxthunder.com

      Comment


        #4
        Another solution to the redrawing of the gradient background when resizing:

        Code:
            CASE %WM_SIZE
                 InvalidateRect CBHNDL, BYVAL %NULL,1
        Forces the entire client area to be redrawn, when ever reiszed.

        I fixed the code I posted above to reflect this fix.
        Chris Boss
        Computer Workshop
        Developer of "EZGUI"
        http://cwsof.com
        http://twitter.com/EZGUIProGuy

        Comment


          #5
          Bitmap question

          Somehow off topic here , but i wanted to rephrase my question here to EZGUI
          User to user discussions of third-party addons and user-recommended links to related web sites. Advertisements are permitted only in this forum, for products designed to work with and enhance PowerBASIC compilers.

          Comment


            #6
            Code:
            CASE %WM_CTLCOLORSTATIC
                     SetBKMode CBWPARAM, %TRANSPARENT
                     FUNCTION=GetStockObject(%NULL_BRUSH)
                     EXIT FUNCTION
            Works here because only one control is sending WM_CTLCOLORSTATIC. In general you'd want to trap to which control the notification message applies...
            Code:
            CASE %WM_CTLCOLORSTATIC
            [b]  IF GetDlgCtlId(CBLPARAM) = %LBL_LABEL THEN [/b]
                     SetBKMode CBWPARAM, %TRANSPARENT
                     FUNCTION=GetStockObject(%NULL_BRUSH)
                     EXIT FUNCTION
            [b]  END IF  [/b]
            GetDlgCtlID(CBLPARAM) "might" equal CBCTL, but I'm not a DDT guy and don't feel like testing it myself.
            Michael Mattias
            Tal Systems (retired)
            Port Washington WI USA
            [email protected]
            http://www.talsystems.com

            Comment


              #7
              Michael is correct about the color message. I was in a hurry to demonstrate the key method to make it work, not to handle multiple controls.

              Now to handle multiple controls it may be good to not test for control ID's but simply test for the WS_EX_TRANSPARENT extended window style of the control. This way multiple static controls could be used and the ones which are transparent would be handled correctly.
              Chris Boss
              Computer Workshop
              Developer of "EZGUI"
              http://cwsof.com
              http://twitter.com/EZGUIProGuy

              Comment


                #8
                Frank,

                I would suggest that using a brush is not the best way to go there.

                You need to be able to draw a Bitmap which has transparent pixels.
                Your graphic tool should be able to do this, I would think.

                Using the API, you can use ImageLists, since they can draw bitmaps with transparent pixels (one unique RGB color is used to define the trasnparent pixels)

                Another technique is to BitBlt a Bitmap, but use a round cliiping region to draw only within the region. This can be done to draw a round image.

                Another technique is to use something like PB's GETBITs commands to get the pixels of the background and an image and then pixel by pixel combine them and then copy the pixels back.
                Chris Boss
                Computer Workshop
                Developer of "EZGUI"
                http://cwsof.com
                http://twitter.com/EZGUIProGuy

                Comment


                  #9
                  Static sdk labels work DDT label has a little problem

                  The following code takes some of the suggestions and tests a DDT label (which is why I started to learn about the SDK version) against SDK ones. I set an SDK label before the Dialog Show Modeless. Then I add a DDT label and an SDK label after the Dialog Show Modeless but before the message loop. I then add 4 more labels based on a button click. I tried to make the DDT LABEL work with the same styles, but as you can see it doesn't turn transparent. (I know about the -1,-2 approach prior to the Dialog Show Modeless but in my testing, this doesn't work on labels placed after the Dialog Show Modeless. A separate InvalidateRect is required for the DDT labels. Only the SDK labels work the way I want them too.
                  Code:
                  #DIM ALL
                  #REGISTER ALL
                  #INCLUDE "win32api.inc"
                  
                  GLOBAL ghMain AS DWORD,hFontCap AS LONG
                      %LBL_LABEL = 1001
                      %LBL_AFTER = 1002
                      %LBL_DDT   = 1003
                      %NEW_LBL1  = 1004
                      %NEW_LBL2  = 1005
                      %NEW_LBL3  = 1006
                      %NEW_LBL4  = 1007
                      %BUT_DDT   = 2001
                  
                  FUNCTION MakeFont(BYVAL CFont AS STRING, BYVAL PointSize AS LONG) AS LONG
                  
                    LOCAL hDC      AS LONG
                    LOCAL CyPixels AS LONG
                  
                    hDC = GetDC(%HWND_DESKTOP)
                    CyPixels  = GetDeviceCaps(hDC, %LOGPIXELSY)
                    ReleaseDC %HWND_DESKTOP, hDC
                  
                    PointSize = (PointSize * CyPixels) \ 72
                    FUNCTION = CreateFont(0 - PointSize, 0, 0, 0, %FW_NORMAL, 0, 0, 0, _
                              %ANSI_CHARSET, %OUT_TT_PRECIS, %CLIP_DEFAULT_PRECIS, _
                              %DEFAULT_QUALITY, %FF_DONTCARE, BYCOPY CFONT)
                  END FUNCTION 
                  
                  CALLBACK FUNCTION dlgMain
                    LOCAL szNewStaticText AS STRING 
                    DIM hWndControl AS DWORD
                    SELECT CASE CBMSG
                        hFontCap = MakeFont("Ms Sans Serif",10)   
                      CASE %WM_CTLCOLORSTATIC
                        SELECT CASE GetDlgCtrlId(CBLPARAM) 
                          CASE %LBL_LABEL TO %NEW_LBL4      'in case other labels need different handling
                            SelectObject CBWPARAM, hFontCap
                            SetBkMode CBWPARAM,%Transparent
                           FUNCTION = GetStockObject(%NULL_BRUSH)
                        END SELECT    
                      CASE %WM_PAINT
                        CALL PaintBg(CBHNDL,0,0,0)
                      CASE %WM_COMMAND
                        SELECT CASE CBCTL
                          CASE %BUT_DDT
                            szNewStaticText = "New Label 1"
                            hWndControl = CreateWindowEx(%WS_EX_TRANSPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING , _
                                                   "Static", _  ' window class name
                                                   BYCOPY szNewStaticText, _    ' window caption
                                                   %SS_LEFT OR %WS_CHILD OR %WS_VISIBLE OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN, _
                                                   10, 64, 150, 18, _
                                                   ghMain, %NEW_LBL1, GetModuleHandle(BYVAL 0&), BYVAL %NULL)
                            szNewStaticText = "New Label 2"
                            hWndControl = CreateWindowEx(%WS_EX_TRANSPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING , _
                                                   "Static", _  ' window class name
                                                   BYCOPY szNewStaticText, _    ' window caption
                                                   %SS_LEFT OR %WS_CHILD OR %WS_VISIBLE OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN, _
                                                   10, 84, 150, 18, _
                                                   ghMain, %NEW_LBL2, GetModuleHandle(BYVAL 0&), BYVAL %NULL)
                            szNewStaticText = "New Label 3"
                            hWndControl = CreateWindowEx(%WS_EX_TRANSPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING , _
                                                   "Static", _  ' window class name
                                                   BYCOPY szNewStaticText, _    ' window caption
                                                   %SS_LEFT OR %WS_CHILD OR %WS_VISIBLE OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN, _
                                                   10, 104, 150, 18, _
                                                   ghMain, %NEW_LBL3, GetModuleHandle(BYVAL 0&), BYVAL %NULL)
                            szNewStaticText = "New Label 4"
                            hWndControl = CreateWindowEx(%WS_EX_TRANSPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING , _
                                                   "Static", _  ' window class name
                                                   BYCOPY szNewStaticText, _    ' window caption
                                                   %SS_LEFT OR %WS_CHILD OR %WS_VISIBLE OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN, _
                                                   10, 124, 150, 18, _
                                                   ghMain, %NEW_LBL4, GetModuleHandle(BYVAL 0&), BYVAL %NULL)
                            
                        END SELECT  
                    END SELECT    
                  END FUNCTION
                  
                  FUNCTION PBMAIN
                      DIM hWndControl AS DWORD,szControlText AS STRING,cnt AS LONG
                  
                      DIALOG NEW 0, "Transparent sdk style label ",,,200,170,%WS_SYSMENU TO ghMain
                  
                      szControlText = "Before Show ghMain"
                      hWndControl = CreateWindowEx(%WS_EX_TRANSPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING , _
                                                   "Static", _  ' window class name
                                                   BYCOPY szControlText, _    ' window caption
                                                   %SS_LEFT OR %WS_CHILD OR %WS_VISIBLE OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN, _
                                                   10, 10, 150, 18, _
                                                   ghMain, %LBL_LABEL, GetModuleHandle(BYVAL 0&), BYVAL %Null)
                      DIALOG SHOW MODELESS ghMain CALL dlgMain
                      
                      szControlText = "After Show ghMain"
                      hWndControl = CreateWindowEx(%WS_EX_TRANSPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING , _
                                                   "Static", _  ' window class name
                                                   BYCOPY szControlText, _    ' window caption
                                                   %SS_LEFT OR %WS_CHILD OR %WS_VISIBLE OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN, _
                                                   10, 30, 150, 18, _
                                                   ghMain, %LBL_AFTER, GetModuleHandle(BYVAL 0&), BYVAL %NULL)
                  
                      CONTROL ADD LABEL, ghMain,%LBL_DDT,"After Show ghMain DDT",7,30,60,10,%SS_LEFT OR %WS_CHILD OR %WS_VISIBLE _
                                                                                 OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN, _
                                                                                 %WS_EX_TRANSPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING
                      CONTROL ADD BUTTON, ghMain,%BUT_DDT,"Add more labels",120,130,60,14                                                                                                                                 
                      DO
                        DIALOG DOEVENTS TO cnt      
                      LOOP UNTIL cnt = 0
                  END FUNCTION
                  
                  FUNCTION SetColor (BYVAL tCOLOR AS BYTE) AS WORD
                      ' the windows api GradientFill routine wants r/g/b colors to be
                      ' 16 bit words with the 8 bit color values left shifted 8 bits.
                      ' this takes care of that.
                      LOCAL clr AS WORD
                      clr = tCOLOR
                      SHIFT LEFT clr, 8
                      FUNCTION = clr
                  END FUNCTION 
                  
                  SUB PaintBg(BYVAL hDialog AS LONG, BYVAL r AS LONG, BYVAL g AS LONG, BYVAL b AS LONG)
                       ' this is to paint the background of the dialog
                       ' it's all straight out of the MSDN help file.  We can change the values
                       ' if we like.
                       LOCAL ps AS PAINTSTRUCT
                       LOCAL rc AS Rect
                       LOCAL hDc AS DWORD
                       LOCAL Xin&
                       LOCAL Yin&,Temp&,cRed&,cGreen&,cBlue&
                       DIM vert(1) AS TRIVERTEX
                       DIM gRect AS GRADIENT_RECT
                       hDC = BeginPaint(hDialog, ps)
                         ' Tile the background
                       GetClientRect hdialog, rc
                       Xin = rc.nRight - rc.nLeft
                       Yin = rc.nBottom - rc.nTop
                       Xin = rc.nRight - rc.nLeft
                       Yin = rc.nBottom - rc.nTop
                       Temp& = RGB(205,214,255)
                       IF Temp& <> 0 THEN
                         cRed&   = Temp& MOD 256
                         cGreen& = (Temp& \ 256) MOD 256
                         cBlue&  = ((Temp& \ 256) \ 256) MOD 256
                       ELSE
                         cRed&   = 192
                         cGreen& = 224
                         cBlue&  = 192
                       END IF
                       vert(0).x      = 0
                       vert(0).y      = 0
                       vert(0).Red    = SetColor(cRed& - 90)
                       vert(0).Green  = SetColor(cGreen& - 90)
                       vert(0).Blue   = SetColor(cBlue& - 90)
                       vert(0).Alpha  = &h0000
                       vert(1).x      = xin
                       vert(1).y      = yin
                       vert(1).Red    = SetColor(cRed&)
                       vert(1).Green  = SetColor(cGreen&)
                       vert(1).Blue   = SetColor(cBlue&)
                       vert(1).Alpha  = &h0000
                       gRect.UpperLeft  = 0
                       gRect.LowerRight = 1
                       GradientFill hDc, vert(0), 2, gRect, 1, %GRADIENT_FILL_RECT_v
                       EndPaint hDialog, ps
                  END SUB

                  Comment


                    #10
                    DDT has some quirks re returning values directly, as required by the handling of WM_CTLCOLORSTATIC, specifcially you can't return the value zero. If GetStockObject(%NULL_BRUSH) = 0 (which it might well be), that will never get thru... a zero return gets read by DDT as "do default stuff" which is exactly what you are trying to NOT do.

                    No, I don't know how to get around that other than using SDK-style coding syntax for the dialog.
                    Michael Mattias
                    Tal Systems (retired)
                    Port Washington WI USA
                    [email protected]
                    http://www.talsystems.com

                    Comment


                      #11
                      The following works if placed right after the CONTROL ADD LABEL statement if this statement is being executed after the Dialog Show Modeless.

                      Code:
                          CONTROL SHOW STATE ghMain,%LBL_DDT,%SW_HIDE                                                               
                          CONTROL SHOW STATE ghMain,%LBL_DDT,%SW_SHOW
                      Last edited by BOB MECHLER; 16 Feb 2008, 05:37 PM. Reason: More info

                      Comment


                        #12
                        I think using a brush in this situation won't work. I put a little sleep 300 in between putting 23 new labels on the screen and this is how it proceeded. It started by putting rectangles with no text of the dialog's original color (before the gradient), After it created these empty rectangles, it placed the text and the transparent effect only when it hit a messagbox or a textbox.

                        I'm going now in the direction of transparent bits as Chris suggested. I need the ability to put the text on the screen with a transparent background without the intermediate steps. This particular program has 259 fields that come into view with information based on buttons I provide. The problem of course is not there if I abandon the gradient effect and make the labels have the same background color as the dialog.

                        I thought I had the problem licked with the SDK labels but in practice they acted very much like the DDT labels if I drew enough of them at one time.

                        BOB MECHLER

                        Comment


                          #13
                          Hi Bob,

                          You mentioned in one of your posts the "-1, -2 method", but that it doesn't work for DDT controls placed after the SHOW MODELESS. I'm guessing that the method you are referring to is CONTROL SET COLOR ? If so, then that does appear to work after the SHOW statement, but you need to force a redraw. i.e. if you add these two lines:
                          Code:
                          CONTROL SET COLOR ghMain, %LBL_DDT, -1, -2
                          CONTROL REDRAW ghMain, %LBL_DDT
                          After the CONTROL ADD LABEL, then it appears to work fine.

                          Not sure if that helps any, and I get the sneaking feeling I'm missing something, but this appears to work...

                          Regards,

                          Pete.

                          Comment


                            #14
                            I tried that Peter but with as many labels as I draw at one time, going from screen to screen removing and then adding up 40 labels the redraw causes an unacceptable flicker. I'm playing with loading a bitmap and it seems to work just fine. What I want to do is create a gradient bitmap and load it as you would from a resource file to allow the user to choose their own starting color. I'm in the process of trying to find some code that will create the gradient bitmap and then how to transfer it to the dialog.

                            Bob Mechler

                            Comment


                              #15
                              Try the modified version of your code shown below.
                              The old version had a serious memory leak because a new font was created with each invocation of dlgMain.
                              Also, your old code did not have the modification to WM_ERASEBKGND suggested by Chris.
                              Unfortunately, even with that modification you will still get streaks when a window is dragged across your dialog.

                              This modified version paints the background during WM_CTLCOLORDLG, adds an hDC parameter to the PaintBg procedure, and drops BeginPaint/EndPaint.
                              Also, the font is created and destroyed during WM_INITDIALOG and WM_DESTROY respectively.

                              Code:
                              #DIM ALL
                              #REGISTER ALL
                              #INCLUDE "win32api.inc"
                              
                              GLOBAL ghMain AS DWORD,hFontCap AS LONG
                                  %LBL_LABEL = 1001
                                  %LBL_AFTER = 1002
                                  %LBL_DDT   = 1003
                                  %NEW_LBL1  = 1004
                                  %NEW_LBL2  = 1005
                                  %NEW_LBL3  = 1006
                                  %NEW_LBL4  = 1007
                                  %BUT_DDT   = 2001
                              
                              FUNCTION MakeFont(BYVAL CFont AS STRING, BYVAL PointSize AS LONG) AS LONG
                              
                                LOCAL hDC      AS LONG
                                LOCAL CyPixels AS LONG
                              
                                hDC = GetDC(%HWND_DESKTOP)
                                CyPixels  = GetDeviceCaps(hDC, %LOGPIXELSY)
                                ReleaseDC %HWND_DESKTOP, hDC
                              
                                PointSize = (PointSize * CyPixels) \ 72
                                FUNCTION = CreateFont(0 - PointSize, 0, 0, 0, %FW_NORMAL, 0, 0, 0, _
                                          %ANSI_CHARSET, %OUT_TT_PRECIS, %CLIP_DEFAULT_PRECIS, _
                                          %DEFAULT_QUALITY, %FF_DONTCARE, BYCOPY CFONT)
                              END FUNCTION 
                              
                              CALLBACK FUNCTION dlgMain
                                LOCAL szNewStaticText AS STRING 
                                DIM hWndControl AS DWORD
                                SELECT CASE CBMSG 
                                  CASE %WM_INITDIALOG
                                    hFontCap = MakeFont("Ms Sans Serif",10) 
                              
                                  CASE %WM_DESTROY
                                    DeleteObject hFontCap
                                    
                                  CASE %WM_CTLCOLORSTATIC
                                    SELECT CASE GetDlgCtrlID(CBLPARAM) 
                                      CASE %LBL_LABEL TO %NEW_LBL4      'in case other labels need different handling
                                        SelectObject CBWPARAM, hFontCap
                                        SetBkMode CBWPARAM,%TRANSPARENT
                                       FUNCTION = GetStockObject(%NULL_BRUSH)
                                    END SELECT 
                              
                                  CASE %WM_CTLCOLORDLG
                                    CALL PaintBg(CBHNDL,CBWPARAM,0,0,0)      
                                    FUNCTION = GetStockObject(%NULL_BRUSH)
                              
                                  CASE %WM_COMMAND
                                    SELECT CASE CBCTL
                                      CASE %BUT_DDT
                                        szNewStaticText = "New Label 1"
                                        hWndControl = CreateWindowEx(%WS_EX_TRANSPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING , _
                                                               "Static", _  ' window class name
                                                               BYCOPY szNewStaticText, _    ' window caption
                                                               %SS_LEFT OR %WS_CHILD OR %WS_VISIBLE OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN, _
                                                               10, 64, 150, 18, _
                                                               ghMain, %NEW_LBL1, GetModuleHandle(BYVAL 0&), BYVAL %NULL)
                                        szNewStaticText = "New Label 2"
                                        hWndControl = CreateWindowEx(%WS_EX_TRANSPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING , _
                                                               "Static", _  ' window class name
                                                               BYCOPY szNewStaticText, _    ' window caption
                                                               %SS_LEFT OR %WS_CHILD OR %WS_VISIBLE OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN, _
                                                               10, 84, 150, 18, _
                                                               ghMain, %NEW_LBL2, GetModuleHandle(BYVAL 0&), BYVAL %NULL)
                                        szNewStaticText = "New Label 3"
                                        hWndControl = CreateWindowEx(%WS_EX_TRANSPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING , _
                                                               "Static", _  ' window class name
                                                               BYCOPY szNewStaticText, _    ' window caption
                                                               %SS_LEFT OR %WS_CHILD OR %WS_VISIBLE OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN, _
                                                               10, 104, 150, 18, _
                                                               ghMain, %NEW_LBL3, GetModuleHandle(BYVAL 0&), BYVAL %NULL)
                                        szNewStaticText = "New Label 4"
                                        hWndControl = CreateWindowEx(%WS_EX_TRANSPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING , _
                                                               "Static", _  ' window class name
                                                               BYCOPY szNewStaticText, _    ' window caption
                                                               %SS_LEFT OR %WS_CHILD OR %WS_VISIBLE OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN, _
                                                               10, 124, 150, 18, _
                                                               ghMain, %NEW_LBL4, GetModuleHandle(BYVAL 0&), BYVAL %NULL)
                                        
                                    END SELECT  
                                END SELECT    
                              END FUNCTION
                              
                              FUNCTION PBMAIN
                                  DIM hWndControl AS DWORD,szControlText AS STRING,cnt AS LONG
                              
                                  DIALOG NEW 0, "Transparent sdk style label ",,,200,170,%WS_SYSMENU TO ghMain
                              
                                  szControlText = "Before Show ghMain"
                                  hWndControl = CreateWindowEx(%WS_EX_TRANSPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING , _
                                                               "Static", _  ' window class name
                                                               BYCOPY szControlText, _    ' window caption
                                                               %SS_LEFT OR %WS_CHILD OR %WS_VISIBLE OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN, _
                                                               10, 10, 150, 18, _
                                                               ghMain, %LBL_LABEL, GetModuleHandle(BYVAL 0&), BYVAL %NULL)
                                  DIALOG SHOW MODELESS ghMain CALL dlgMain
                                  
                                  szControlText = "After Show ghMain"
                                  hWndControl = CreateWindowEx(%WS_EX_TRANSPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING , _
                                                               "Static", _  ' window class name
                                                               BYCOPY szControlText, _    ' window caption
                                                               %SS_LEFT OR %WS_CHILD OR %WS_VISIBLE OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN, _
                                                               10, 30, 150, 18, _
                                                               ghMain, %LBL_AFTER, GetModuleHandle(BYVAL 0&), BYVAL %NULL)
                              
                                  CONTROL ADD LABEL, ghMain,%LBL_DDT,"After Show ghMain DDT",100,30,130,18,%SS_LEFT OR %WS_CHILD OR %WS_VISIBLE _
                                                                                             OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN, _
                                                                                             %WS_EX_TRANSPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING
                              
                                  CONTROL ADD BUTTON, ghMain,%BUT_DDT,"Add more labels",120,130,60,14                                                                                                                                 
                                  DO
                                    DIALOG DOEVENTS TO cnt      
                                  LOOP UNTIL cnt = 0
                              END FUNCTION
                              
                              FUNCTION SetColor (BYVAL tCOLOR AS BYTE) AS WORD
                                  ' the windows api GradientFill routine wants r/g/b colors to be
                                  ' 16 bit words with the 8 bit color values left shifted 8 bits.
                                  ' this takes care of that.
                                  LOCAL clr AS WORD
                                  clr = tCOLOR
                                  SHIFT LEFT clr, 8
                                  FUNCTION = clr
                              END FUNCTION 
                              
                              SUB PaintBg(BYVAL hDialog AS LONG, BYVAL hDC AS DWORD, BYVAL r AS LONG, BYVAL g AS LONG, BYVAL b AS LONG)
                                   ' this is to paint the background of the dialog
                                   ' it's all straight out of the MSDN help file.  We can change the values
                                   ' if we like.
                                   LOCAL rc AS Rect
                              
                                   LOCAL Xin&
                                   LOCAL Yin&,Temp&,cRed&,cGreen&,cBlue&
                                   DIM vert(1) AS TRIVERTEX
                                   DIM gRect AS GRADIENT_RECT
                              
                                     ' Tile the background
                                   GetClientRect hdialog, rc
                                   Xin = rc.nRight - rc.nLeft
                                   Yin = rc.nBottom - rc.nTop
                                   Xin = rc.nRight - rc.nLeft
                                   Yin = rc.nBottom - rc.nTop
                                   Temp& = RGB(205,214,255)
                                   IF Temp& <> 0 THEN
                                     cRed&   = Temp& MOD 256
                                     cGreen& = (Temp& \ 256) MOD 256
                                     cBlue&  = ((Temp& \ 256) \ 256) MOD 256
                                   ELSE
                                     cRed&   = 192
                                     cGreen& = 224
                                     cBlue&  = 192
                                   END IF
                                   vert(0).x      = 0
                                   vert(0).y      = 0
                                   vert(0).Red    = SetColor(cRed& - 90)
                                   vert(0).Green  = SetColor(cGreen& - 90)
                                   vert(0).Blue   = SetColor(cBlue& - 90)
                                   vert(0).Alpha  = &H0000
                                   vert(1).x      = xin
                                   vert(1).y      = yin
                                   vert(1).Red    = SetColor(cRed&)
                                   vert(1).Green  = SetColor(cGreen&)
                                   vert(1).Blue   = SetColor(cBlue&)
                                   vert(1).Alpha  = &H0000
                                   gRect.UpperLeft  = 0
                                   gRect.LowerRight = 1
                                   GradientFill hDc, vert(0), 2, gRect, 1, %GRADIENT_FILL_RECT_V
                              
                              END SUB
                              Dominic Mitchell
                              Phoenix Visual Designer
                              http://www.phnxthunder.com

                              Comment


                                #16
                                I moved the relevant changes you proposed to my production code and it works absolutely great. I can now happily erase and/or replace all the controls on my gradient background dialog as much as I want and no flicker.

                                Thanks Dominic!! As a bonus I used Chris's suggestion of loading a bitmap into the dialog and that also works well too. Great,great,great!

                                Thanks,

                                Bob Mechler

                                Comment


                                  #17
                                  Forgot to mention that this approach allowed the CONTROL ADD LABEL statements to work fine. I didn't need to go to SDK.

                                  Bob Mechler

                                  Comment


                                    #18
                                    Very interesting. Is there a way to convert the paint structure so that it
                                    will paint background of textbox instead of dialog? I get too much flicker
                                    when editing text in textbox over a bitmap, which is rendered on a
                                    graphic control. Thought, maybe just paint a gradient background for
                                    textbox control and do away with graphic control. Should not be any
                                    flicker?

                                    Comment


                                      #19
                                      Don't know myself but I've seen code where it works for a static label to draw a gradient on it's background. I felt the non-flickering transparent effect on the static label with a gradient dialog background was good enough for now. Interested to see the answer myself.

                                      Bob Mechler

                                      Comment


                                        #20
                                        Using Dominic's code and getting the dimensions of my textbox, it will
                                        paint gradient background for textbox and I can edit text with no flicker!
                                        Problem is that the rest of the dialog is transparent and shows desktop?
                                        I guess I need some help on how to just paint a region the size of textbox and not entire dialog?

                                        Comment

                                        Working...
                                        X
                                        😀
                                        🥰
                                        🤢
                                        😎
                                        😡
                                        👍
                                        👎