|
-
Jan 28th, 2010, 11:40 AM
#1
[VB6] Fake Transparency for PictureBox
There are several workarounds to faking transparency for a picturebox. The code below is about as simple as it gets to provide basic transparency-like effect. Thought I just throw it out there should someone be able to use it.
What is copied over and what isn't. Container means what the picturebox is on: Form, frame, another picturebox, etc.
1. Any windowless controls (labels, image controls, shapes, lines) behind the picturebox, while still in the picturebox's container, are transferred even if other controls are between that windowless control and the picturebox.
2. The container's backcolor is transferred
3. If the container is custom drawn (i.e., gradients). Container's AutoRedraw must be true for that to be transferred too.
4. Windowed controls are not, but since the picturebox is above the windowed controls you wouldn't be able to click them anyway.
Advantages: Simple for simple purposes.
Disadvantages:
1. Option buttons/checkboxes within the picturebox can have their background color set to container's backcolor, but any custom drawing (i.e., gradients) within the container won't show thru since those controls do not have a "Transparent" background setting.
2. As mentioned above, any windowed controls behind the picturebox won't show thru.
3. You cannot "click thru" the picturebox, it is not transparent.
4. This may not work if placing picturebox in some compiled usercontrol unless that usercontrol exposes an hWnd property and handles the WM_Paint message the same as VB does.
5. If user changes system colors that effect the container's backcolor, the container will repaint but the picturebox won't unless tracked in Form/Container's Paint event. If container has AutoRedraw=True, no Paint events are triggered for that object. You will have to "refresh" by calling the below code again.
Code:
Option Explicit
Private Type POINTAPI
X As Long
Y As Long
End Type
Private Declare Function SetViewportOrgEx Lib "gdi32.dll" (ByVal hDC As Long, ByVal nX As Long, ByVal nY As Long, ByRef lpPoint As POINTAPI) As Long
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
Private Declare Function ScreenToClient Lib "user32.dll" (ByVal hWnd As Long, ByRef lpPoint As POINTAPI) As Long
Private Declare Function ClientToScreen Lib "user32.dll" (ByVal hWnd As Long, ByRef lpPoint As POINTAPI) As Long
Private Const WM_PAINT As Long = &HF&
Private Sub Command1_Click()
Dim vPt As POINTAPI
With Picture1
ClientToScreen .hWnd, vPt ' convert 0,0 to screen coords
ScreenToClient .Container.hWnd, vPt ' convert that to container's coords
SetViewportOrgEx .hDC, -vPt.X, -vPt.Y, vPt ' offset the picbox DC
SendMessage .Container.hWnd, WM_PAINT, .hDC, ByVal 0& ' tell VB to repaint
SetViewportOrgEx .hDC, vPt.X, vPt.Y, vPt ' reset picbox DC
If .AutoRedraw = True then .Refresh
End With
End Sub
Additional tweaks could be made using other drawing APIs. For example, one can have a hidden picturebox (AutoRedraw=True), send WM_Paint to that picturebox, then use AlphaBlend to fade/combine the real picturebox's graphics with the containers background. Would require a tad bit of work, but not overly difficult.
Last edited by LaVolpe; Jan 28th, 2010 at 03:33 PM.
Reason: wording
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|