Home All Groups Group Topic Archive Search About
Author
24 Feb 2009 4:33 PM
Lorin
I am trying to put a gradient on a form that has labels on it.
I am using StretchDIBits to write the gradient to the form.
This all works, except that the labels are overwritten and not visible.
So I added .Refresh to all lables and now they show but they do not have
transparent backgrounds as instructed by setting BackStyle = Transparent. 
This seems to be ignored.  The label background is the form background but
not the gradient.
How do I get this VB6 app to do it correctly?
Also, if after all is written and refreshed individually (lables), I add a
Me.Refresh, the gradient is erased and labels are there and their background
is transparent.  Maybe a clue.
I also tried using the Bring To Front to no avail.
Something else I have always wondered about, in this situation, no matter
how many times I click Bring To Front, the Bring To Front button never
indicates that it is all the way to the front by going disabled.

Author
24 Feb 2009 4:55 PM
mayayana
You're applying an image with StretchBlt? I don't
know why you'd do that for a gradient. The following
sub seems to work fine. You just give it the form,
scalewidth, and scaleheight. This sample has the colors
hard coded and goes from upper left to lower right.
I think there are also some VB sample of form gradients
online. It's a fairly common routine.

'--------------------------------------------
Public Sub ColorBack(Frm As Form, LWidth As Single, LHeight As Single)
  '--color gradient on backgrounds, left top dark to bottom right light.
  '--Before calling: first change form scalemode to pixels. This version
  '-- will only go from 0,0 out.
  '--WIDTH MUST BE GREATER THAN HEIGHT!!
  Dim R1 As Integer, R2 As Integer, G1 As Integer, G2 As Integer
  Dim B1 As Integer, B2 As Integer
  Dim PtS As Single, PtE As Single, CurPt As Single, Pt2 As Single
  Dim DifB As Single, DifR As Single, DifG As Single
  Dim LTot As Single
   On Error Resume Next
   '--dark colors:
   B1 = 71
   G1 = 59
   R1 = 35
   '--light colors:
   B2 = 255
   G2 = 139
   R2 = 28

      '--total number of lines:
   LTot = LWidth + (LHeight * 2)

     '--get difference between each line:
   DifB = (B2 - B1) / LTot
   DifG = (G2 - G1) / LTot
   DifR = (R2 - R1) / LTot

   With Frm
     .DrawStyle = vbInsideSolid
     .DrawMode = vbCopyPen
     .DrawWidth = 1
   End With

   '--go down left side, up diagonally:
   For PtS = 1 To LHeight
       Frm.Line (0, PtS)-(PtS, 0), RGB( _
         (R1 + (PtS * DifR)), (G1 + (PtS * DifG)), (B1 + (PtS * DifB)))
   Next

   '--go along top, down diagonally:

   For PtS = LHeight To LWidth
         Frm.Line (PtS, 1)-((PtS - LHeight), LHeight), RGB( _
          (R1 + (PtS * DifR)), (G1 + (PtS * DifG)), (B1 + (PtS * DifB)))
   Next

   '--go along right down to bottom:
   CurPt = (LWidth - LHeight)
    For PtS = 1 To LHeight
      PtE = LWidth + PtS
         Frm.Line (LWidth, PtS)-((CurPt + PtS), LHeight), RGB( _
           (R1 + (PtE * DifR)), (G1 + (PtE * DifG)), (B1 + (PtE * DifB)))
    Next

       Frm.ScaleMode = vbTwips
       Frm.Refresh
End Sub
Author
24 Feb 2009 8:16 PM
Mike Williams
"Lorin" <Lo***@discussions.microsoft.com> wrote in message
news:5715DE24-E3B0-407A-804F-2C16A9BBE921@microsoft.com...

> I am trying to put a gradient on a form that has labels on
> it. I am using StretchDIBits to write the gradient to the
> form. This all works, except that the labels are overwritten
> and not visible. So I added .Refresh to all lables and now
> they show but they do not have transparent backgrounds
> as instructed by setting BackStyle = Transparent.

VB always draws a background rectangle for the Label whether it's BackStyle
property is set to transparent or not and, in the absence of either a valid
Picture property or an Autoredraw bitmap for its container, that drawn
background rectangle will be a solid block of the container's back colour.
This will cause the backgound rectangle to overwrite anything you have drawn
to the Form unless you take steps to make the background persistent. You can
solve this problem in various different ways, perhaps by drawing the text
yourself in code instead of using a Label, but for Label controls perhaps
the easiest way, and certainly the most efficient way in terms of speed and
processor usage (although not in terms of memory) is to simply set your
Form's Autoredraw property to True before you draw your gradient.

Incidentally, why are you using StretchBlt to draw your gradient? If it is a
complex gradient then of course that is one way of doing it (although there
are others), but if it is a simple gradient, such as a rectangular or
triangular gradient, then you can draw it very quickly using the
GradientFill function in the msimg32 library, which should be present by
default on Win98 onwards (except perhaps on various versions of NT). At one
time I think this function had a memory leak, but I'm sure that was fixed
some years ago. Anybody know for sure? Anyway, here is an example:

Option Explicit
Private Type GRADIENT_RECT
   UpperLeft As Long
   LowerRight As Long
End Type
Private Type TRIVERTEX
   X As Long
   Y As Long
   Red As Integer
   Green As Integer
   Blue As Integer
   Alpha As Integer
End Type
Private Const GRADIENT_FILL_RECT_H = 0 ' horizontal
Private Const GRADIENT_FILL_RECT_V = 1 ' vertical
Private Declare Function GradientFillRect _
  Lib "msimg32" Alias "GradientFill" _
  (ByVal hDC As Long, pVertex As TRIVERTEX, _
  ByVal dwNumVertex As Long, pMesh As GRADIENT_RECT, _
  ByVal dwNumMesh As Long, ByVal dwMode As Long) As Long

Private Sub Form_Load()
Me.WindowState = vbMaximized
Me.Show
Me.AutoRedraw = True
Me.Cls
Call Gradient(Me, RGB(0, 150, 250), RGB(0, 50, 100))
End Sub

Private Sub Gradient(z As Object, c1 As Long, c2 As Long)
' A single Gradient Filled rectangle
' Note: The RGB colours required by the various API
' routine that require the Trivertex Type (for example
' GradientFill) all need each colour to be expressed
' as a two byte Integer but with the Hi byte (rather
' than the Lo Byte)representing the colour value (in
' other words a "high endian" Integer. For example,
' full Red as a Byte would be 255 (or &H00FF) whereas
' Trivertex would want the two byte integer &HFF00.
Dim rectangles(1 To 1) As GRADIENT_RECT ' 1 rectangle
Dim trivrex(1 To 2) As TRIVERTEX ' start and end colours
z.ScaleMode = vbPixels
With rectangles(1)
  .UpperLeft = 0
  .LowerRight = 1
End With
With trivrex(1)
  .X = 0
  .Y = 0
  .Red = (c1 And &H7F&) * &H100
  If (c1 And &H80&) Then
    .Red = .Red Or &H8000
  End If
  .Green = c1 And &H7F00&
  If (c1 And &H8000&) Then
    .Green = .Green Or &H8000
  End If
  .Blue = (c1 And &H7F0000) \ &H100
  If (c1 And &H800000) Then
    .Blue = .Blue Or &H8000
  End If
End With
With trivrex(2)
  .X = z.ScaleWidth + 1
  .Y = z.ScaleHeight + 1
  .Red = (c2 And &H7F&) * &H100
  If (c2 And &H80&) Then
    .Red = .Red Or &H8000
  End If
  .Green = c2 And &H7F00&
  If (c2 And &H8000&) Then
    .Green = .Green Or &H8000
  End If
  .Blue = (c2 And &H7F0000) \ &H100
  If (c2 And &H800000) Then
    .Blue = .Blue Or &H8000
  End If
End With
GradientFillRect z.hDC, trivrex(1), 2, _
    rectangles(1), 1, GRADIENT_FILL_RECT_H
End Sub
Author
25 Feb 2009 3:41 AM
Lorin
Thank you both for some insights.
I will give it a try tomorrow.
I just finished helping my 94 year old father move to a senior living
facility and I am exhausted.
I am only 66.

Show quoteHide quote
"Lorin" <Lo***@discussions.microsoft.com> wrote in message
news:5715DE24-E3B0-407A-804F-2C16A9BBE921@microsoft.com...
>I am trying to put a gradient on a form that has labels on it.
> I am using StretchDIBits to write the gradient to the form.
> This all works, except that the labels are overwritten and not visible.
> So I added .Refresh to all lables and now they show but they do not have
> transparent backgrounds as instructed by setting BackStyle = Transparent.
> This seems to be ignored.  The label background is the form background but
> not the gradient.
> How do I get this VB6 app to do it correctly?
> Also, if after all is written and refreshed individually (lables), I add a
> Me.Refresh, the gradient is erased and labels are there and their
> background
> is transparent.  Maybe a clue.
> I also tried using the Bring To Front to no avail.
> Something else I have always wondered about, in this situation, no matter
> how many times I click Bring To Front, the Bring To Front button never
> indicates that it is all the way to the front by going disabled.
>