I'm using a picture box simply as a container for a specific set of controls
on my form (I have to keep it like this), but I have a problem.
My form contains 1 big picture as a bg and the picture box's bg is not
letting the bg pic come through.
In other words even though I've set the fill style property of my picture
box to transparent, all it does is make my picturebox have an opaque white
background.
Is there anyway I can get the picturebox's bg to be true transparent??
Thanks
Ivar
The Code:
Option Explicit
Private Declare Function BitBlt Lib "gdi32" _
(ByVal hDestDC As Long, ByVal x As Long, _
ByVal y As Long, ByVal nWidth As Long, _
ByVal nHeight As Long, ByVal hSrcDC As Long, _
ByVal xSrc As Long, ByVal ySrc As Long, _
ByVal dwRop As Long) As Long
Private Sub Command1_Click()
Me.ScaleMode = vbPixels
With Picture1
.Visible = False
DoEvents
.ScaleMode = vbPixels
.BorderStyle = 0
.AutoRedraw = True
'BitBlt .hDC, 0, 0, .ScaleWidth, .ScaleHeight, _
Me.hDC, .Left, .Top, vbSrcCopy
.PaintPicture Me.Picture, 0, 0, .ScaleWidth, _
.ScaleHeight, .Left, .Top, .ScaleWidth, .ScaleHeight
.Visible = True
.Refresh
End With
End Sub
> I'm using a picture box simply as a container for a specific set
> of controls on my form (I have to keep it like this), but I have
> a problem. My form contains 1 big picture as a bg and the picture
> box's bg is not letting the bg pic come through. In other words
> even though I've set the fill style property of my picture box to
> transparent, all it does is make my picturebox have an opaque
> white background.
A VB PictureBox does not natively support transparency. The PictureBox's
FillStyle property has nothing to do with the style of the PictureBox
itself. It simply controls the fill style of any graphics (circles, boes,
ect) that your code draws into the PictureBox at runtime.
There are various different ways to achieve transparency in a PictureBox,
but choosing the most suitable method depends on what else you are using
your PictureBox for. Post again telling us exactly what you are doing. For
example, how are you creating your Form's background image? Are you simply
assigning a Picture to its Picture property, or have you set your Form's
Autoredraw property to True and are you then drawing (stretching) a picture
into it at the appropriate size using PaintPicture or some other method? And
what else are you doing in your Picture Box? Is it simply used as a
container for some Controls (and are some of those Controls Labels?) or are
you also drawing stuff into it (lines, circles, rectangles or whatever)?
Post as much detail as you can and we'll be able to post some suitable code
for you.
Mike
The only possible downside I see to this method is if there is a control (or
worse yet, part of a control) underneath the PictureBox, it (or that part of
it) will remain hidden after your code is run. Below is a routine I've
posted in the past which cuts away that part of the form where no controls
exists. Doing this will expose everything underneath the PictureBox for
viewing or, in the case of a control, making use of. Using the code is
simplicity itself.... once placed into the project, all one needs to do is
this (for the case of the PictureBox, but the code should work on any object
that can contain controls - including even a form).
Rick
Private Type POINTAPI
X As Long
Y As Long
End Type
Private Declare Function CreateRectRgn _
Lib "gdi32" _
(ByVal X1 As Long, _
ByVal Y1 As Long, _
ByVal X2 As Long, _
ByVal Y2 As Long) _
As Long
Private Declare Function CreatePolygonRgn _
Lib "gdi32" _
(lpPoint As POINTAPI, _
ByVal nCount As Long, _
ByVal nPolyFillMode As Long) _
As Long
Private Declare Function CombineRgn _
Lib "gdi32" _
(ByVal hDestRgn As Long, _
ByVal hSrcRgn1 As Long, _
ByVal hSrcRgn2 As Long, _
ByVal CombineMode As Long) _
As Long
Private Declare Function SetWindowRgn _
Lib "user32" _
(ByVal hWnd As Long, _
ByVal hRgn As Long, _
ByVal bRedraw As Long) _
As Long
Private Declare Function DeleteObject _
Lib "gdi32" _
(ByVal hObject As Long) _
As Long
Private Const RGN_OR = 2
Private Const ALTERNATE = 1
Public Sub MakeContainerTransparent(TheContainerObject As Object)
Dim TPPx As Long
Dim TPPy As Long
Dim Ctrl As Control
Dim CtrlShape(3) As POINTAPI
Dim ComboReg As Long
Dim TempReg As Long
Dim ReturnVal As Long
Dim ContainObj As Object
Dim NotFirstControl As Boolean
If TypeOf TheContainerObject Is Form Then
Set ContainObj = TheContainerObject
Else
Set ContainObj = TheContainerObject.Parent
End If
TPPx = Screen.TwipsPerPixelX
TPPy = Screen.TwipsPerPixelY
On Error Resume Next
For Each Ctrl In ContainObj.Controls
If Err.Number <> 438 Then
If Ctrl.Container Is TheContainerObject And Ctrl.Visible Then
With Ctrl
CtrlShape(0).X = .Left \ TPPx
CtrlShape(0).Y = .Top \ TPPy
CtrlShape(1).X = (.Left + .Width) \ TPPx
CtrlShape(1).Y = .Top \ TPPy
CtrlShape(2).X = (.Left + .Width) \ TPPx
CtrlShape(2).Y = (.Top + .Height) \ TPPy
CtrlShape(3).X = .Left \ TPPx
CtrlShape(3).Y = (.Top + .Height) \ TPPy
If NotFirstControl Then
TempReg = CreatePolygonRgn&(CtrlShape(0), 4&, ALTERNATE)
ReturnVal = CombineRgn(ComboReg, ComboReg, TempReg, RGN_OR)
DeleteObject TempReg
Else
ComboReg = CreatePolygonRgn&(CtrlShape(0), 4&, ALTERNATE)
NotFirstControl = True
End If
End With
End If
End If
Next
On Error GoTo 0
Set Ctrl = Nothing
Set ContainObj = Nothing
SetWindowRgn TheContainerObject.hWnd, ComboReg, True
DeleteObject ComboReg
End Sub
> Below is a routine I've posted in the past which cuts away that
> part of the form [PictureBox] where no controls exists. Doing this
> will expose everything underneath the PictureBox for viewing or,
> in the case of a control, making use of.
That's the second of the two methods I was going to suggest after the OP
posted back with details of his project, which of course he hasn't yet done.
The other was Ivar's method, or a variation of it depending on exactly how
the OP was creating his Form's background image. I like both methods myself,
and I use them both in my various different projects. Both methods have
their advantages and their limitations, as you've already pointed out Rick,
but (as I often say) it's "horses for courses" and I usually choose
whichever method suits me best for any specific set of circumstances.
As you've already pointed out, the background in Ivar's method is not really
transparent (although the conditions under which that will become a problem
are rare). Regarding your own suggested method you'll find that there is a
problem with Labels in the PictureBox, which always show up as opaque
regardless of their BackStyle property.
You can overcome that problem in a couple of different ways. One way would
be to set any contained Labels to be invisible and to instead draw the
Label's text onto the underlying Form, but if you do that then you'll need
to add extra code to account for the loss of the Label's Click and other
events. My own favourite method is to deliberately fail to "punch a non
transparent hole in the otherwise transparent container" (so that the PicBox
is still transparent in the area of the Label) and to then change the
Label's Container to its Container's Container (usually the Form) and to
adjust its Left and Top properties accordingly to maintain its correct
position in relation to the PictureBox. This method allows the user to still
be able to click the Label.
Here is a modification of your own code, Rick, which does just that. I
haven't added any extra code to take account of different possible scale
modes, because your own original code assumes that both are twips, but it is
of course possible to do so if required.
Mike
Public Sub MakeContainerTransparent _
(TheContainerObject As Object)
Dim TPPx As Long
Dim TPPy As Long
Dim Ctrl As Control
Dim CtrlShape(3) As POINTAPI
Dim ComboReg As Long
Dim TempReg As Long
Dim ReturnVal As Long
Dim ContainObj As Object
Dim NotFirstControl As Boolean
If TypeOf TheContainerObject Is Form Then
Set ContainObj = TheContainerObject
Else
Set ContainObj = TheContainerObject.Parent
End If
TPPx = Screen.TwipsPerPixelX
TPPy = Screen.TwipsPerPixelY
On Error Resume Next
For Each Ctrl In ContainObj.Controls
If Err.Number <> 438 Then
If Ctrl.Container Is TheContainerObject And Ctrl.Visible Then
With Ctrl
If TypeName(Ctrl) = "Label" Then
.Left = .Left + .Container.Left
.Top = .Top + .Container.Top
Set .Container = .Container.Container
Else
CtrlShape(0).X = .Left \ TPPx
CtrlShape(0).Y = .Top \ TPPy
CtrlShape(1).X = (.Left + .Width) \ TPPx
CtrlShape(1).Y = .Top \ TPPy
CtrlShape(2).X = (.Left + .Width) \ TPPx
CtrlShape(2).Y = (.Top + .Height) \ TPPy
CtrlShape(3).X = .Left \ TPPx
CtrlShape(3).Y = (.Top + .Height) \ TPPy
If NotFirstControl Then
TempReg = CreatePolygonRgn&(CtrlShape(0), 4&, ALTERNATE)
ReturnVal = CombineRgn(ComboReg, ComboReg, TempReg, RGN_OR)
DeleteObject TempReg
Else
ComboReg = CreatePolygonRgn&(CtrlShape(0), 4&, ALTERNATE)
NotFirstControl = True
End If
End If
End With
End If
End If
Next Ctrl
Except if the Label on the PictureBox was located over top of a control on
its container's container, in which case it would then fall behind the
control when its container was swapped. I guess there is not just one
perfect solution out there. As you said, you pretty much have to know your
project and how whatever method you choose is impacted by it. Of course,
that could be said of programming in general as well.
Rick
> Except if the Label on the PictureBox was located over top of a
> control on its container's container, in which case it would then
> fall behind the control when its container was swapped.
Yep. That might be a problem in certain circumstances, but so would the
problem of a transparent Label being opaque, which would happen if you
didn't take that action. And of course any Labels in a container that you
wish to make transparent are themselves likely to be required to be
transparent. You can of course overcome the problem in various ways, but . .
.
> I guess there is not just one perfect solution out there.
Exactly. As I've said, it's "horses for courses". In most circumstances I
usually choose whichever method works for me for a specific set of
circumstances and then modify it in order to overcome any of its limitations
that become a problem in my own specific project.
> As you said, you pretty much have to know your project and
> how whatever method you choose is impacted by it. Of course, that could be
> said of programming in general as well.
Yep. That's the problem with trying to post general purpose solutions on the
group. If in any specific case the OP doesn't know how to solve his problem
(which of course he doesn't or he would not have posted his question!) then
he is unlikely to know how to overcome the limitations of some of the
solutions he receives. Add to that the likelihood that many of the
professional programmers here will be only too pleased to pick you up on any
little "mistakes" you make in your newsgroup responses, especially if you're
an amateur like me, and it can be a scary place at times ;-)
Mike
Really appreciate your help.
Rgds
"Mike Williams" <mi...@whiskyandCoke.com> wrote in message
news:uUl$o6jJI...@TK2MSFTNGP05.phx.gbl...