Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Transparent picture boxes?
#8
Sorry i just formatted my PC i'm reinstalling VB right now and i'll post it. Smile

[Edit]

Okay so i add this to the form load, for instance.

Code:
' Load the image
    Set pic(1) = Picture1.Image
    
    Picture1.picture = pic(1)

    ' Scan the image
    Call rgnBasic.ScanPicture(pic(1))

    ' Offset the Shape to allow for the form header.
    Call rgnBasic.OffsetHeader(Me)

    Me.picture = pic(1) ' Set the Form Background
    Call rgnBasic.ApplyRgn(Me.hWnd) ' Set the Form Shape
    CurrentRgn = rgnBasic.hndRegion ' Set the Current Shape

These are declared at the top (globals... NOT inside the sub...)

Code:
Dim rgnBasic As New Region
Dim rgnExtended As New Region
Dim CurrentRgn As Long
Dim pic(0 To 1) As New StdPicture

Then this was a class file (apparently, i didn't use an API...)

Code:
Option Explicit

Public hndRegion As Long
Private DIB As New cDIBSection
Private Declare Function timeGetTime Lib "winmm.dll" () As Long
Private Declare Function OffsetRgn Lib "gdi32" (ByVal hRgn As Long, ByVal x As Long, ByVal y As Long) As Long

Private Sub Class_Terminate()
    If hndRegion  0 Then Call DeleteObject(hndRegion)
End Sub

Public Sub ApplyRgn(ByVal hWnd As Long)
'
'   When the setWinowRgn function gets a handle to a region it applies and
'   deletes the region.  Therefore you cannot call the function twice with
'   the handle to the same region.  Therefore I make a copy of the region
'   for windows to apply and delete.
'
    Dim hndRegionCopy As Long
    
    hndRegionCopy = CreateRectRgn(0, 0, 0, 0) ' Create a blank region

    Call CombineRgn(hndRegionCopy, hndRegion, hndRegionCopy, RGN_OR) ' Copy the region
    Call SetWindowRgn(hWnd, hndRegionCopy, True)
End Sub

Public Sub ScanPicture(ByVal picture As StdPicture, Optional transColor As Long = vbNull)
On Error Resume Next
    Dim Rgn2 As Long
    
    hndRegion = CreateRectRgn(0, 0, 0, 0)
    
    Dim x As Long, y As Long
    Dim SPos As Long, EPos As Long
    Dim Wid As Long, Hgt As Long
    Dim bDib() As Byte
    Dim tSA As SAFEARRAY2D
      
    'get the picture size of the form
    Call DIB.CreateFromPicture(picture)
    
    Wid = DIB.Width
    Hgt = DIB.Height
    
    ' have the local matrix point to bitmap pixels
    With tSA
        .cbElements = 1
        .cDims = 2
        .Bounds(0).lLbound = 0
        .Bounds(0).cElements = DIB.Height
        .Bounds(1).lLbound = 0
        .Bounds(1).cElements = DIB.BytesPerScanLine
        .pvData = DIB.DIBSectionBitsPtr
    End With
    
    Call CopyMemory(ByVal VarPtrArray(bDib), VarPtr(tSA), 4)
    
    ' if there is no transColor specified, use the first pixel as the transparent color
    If transColor = vbNull Then transColor = RGB(bDib(0, 0), bDib(1, 0), bDib(2, 0))
    
    For y = 0 To DIB.Height - 1 'line scan
        x = -3
        Do
            Rgn2 = 0
            x = x + 3
            
            While RGB(bDib(x, y), bDib(x + 1, y), bDib(x + 2, y)) = transColor And (x < DIB.Width * 3 - 3)
                x = x + 3 'skip the transparent point
            Wend
            
            SPos = x / 3
            
            While RGB(bDib(x, y), bDib(x + 1, y), bDib(x + 2, y))  transColor And (x < DIB.Width * 3 - 3)
                x = x + 3 'skip the nontransparent point
            Wend
            
            EPos = x / 3
            
            'combine the region
            If SPos = DIB.Width * 3 - 3
    Next y
    
    Call CopyMemory(ByVal VarPtrArray(bDib), 0&, 4)
End Sub

Public Sub OffsetHeader(ByRef tmpForm As Form)
    With tmpForm
        If .BorderStyle  0 Then
            Dim xoff As Long, yoff As Long
            
            .ScaleMode = vbPixels
            
            xoff = (.ScaleX(.Width, vbTwips, vbPixels) - .ScaleWidth) / 2
            yoff = .ScaleY(.Height, vbTwips, vbPixels) - .ScaleHeight - xoff
    
            Call OffsetRgn(hndRegion, xoff, yoff)
        End If
    End With
End Sub

That'll work... the color that is transparent is whatever the pixel at 0,0 is (i believe...), then basically you just create a picture box (i just left it as picture1), hide it off of the form, then it just loads the transparent stuff and puts it as the background of my form afterwards... it's hard to explain but you'll see... it works pretty well, but i'm sure there are much faster/nicer ways of doing it.
Reply


Messages In This Thread

Forum Jump:


Users browsing this thread: 1 Guest(s)