04-12-2006, 12:25 AM
Okay, I found one working method, problem is, I can't seem to get it to work with more than one picture box.
I'm going to post the code, with a semi tut on how to implement it to get it working, but mind you, it's very simple. But also, don't forget, it only works with a single picture box at the moment.
Code:
Add this code to any form:
Create a picture box and name it picTest.
Then make sure you have an image that has something that can be transparent on it. Either change the &HFF00FF to the hex of your color, or us the RGB 255,0,255 as the color to make transparent.
Run the project, should work.
Now, what I am asking is, can someone help me get this to work with more than one picture box?
I'm going to post the code, with a semi tut on how to implement it to get it working, but mind you, it's very simple. But also, don't forget, it only works with a single picture box at the moment.
Code:
Add this code to any form:
Code:
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 CombineRgn Lib "gdi32" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode 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 Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Declare Function GetDIBits Lib "gdi32" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
Private Declare Function SetDIBits Lib "gdi32" (ByVal hdc As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
Private Type BITMAP '14 bytes
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
bmBits As Long
End Type
Private Type BITMAPINFOHEADER '40 bytes
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXPelsPerMeter As Long
biYPelsPerMeter As Long
biClrUsed As Long
biClrImportant As Long
End Type
Private Type RGBQUAD
rgbBlue As Byte
rgbGreen As Byte
rgbRed As Byte
rgbReserved As Byte
End Type
Private Type BITMAPINFO
bmiHeader As BITMAPINFOHEADER
bmiColors As RGBQUAD
End Type
Private Const DIB_RGB_COLORS = 0&
Private Const BI_RGB = 0&
Private Const pixR As Integer = 3
Private Const pixG As Integer = 2
Private Const pixB As Integer = 1
Private Sub UnRGB(ByRef color As Long, ByRef r As Byte, ByRef g As Byte, ByRef b As Byte)
r = color And &HFF&
g = (color And &HFF00&) \ &H100&
b = (color And &HFF0000) \ &H10000
End Sub
' Restrict the form to its "transparent" pixels.
Private Sub TrimPicture(ByVal pic As PictureBox, ByVal transparent_color As Long)
Const RGN_OR = 2
Dim bitmap_info As BITMAPINFO
Dim pixels() As Byte
Dim bytes_per_scanLine As Integer
Dim pad_per_scanLine As Integer
Dim transparent_r As Byte
Dim transparent_g As Byte
Dim transparent_b As Byte
Dim wid As Integer
Dim hgt As Integer
Dim X As Integer
Dim Y As Integer
Dim start_x As Integer
Dim stop_x As Integer
Dim combined_rgn As Long
Dim new_rgn As Long
' Prepare the bitmap description.
With bitmap_info.bmiHeader
.biSize = 40
.biWidth = picTest.ScaleWidth
' Use negative height to scan top-down.
.biHeight = -picTest.ScaleHeight
.biPlanes = 1
.biBitCount = 32
.biCompression = BI_RGB
bytes_per_scanLine = ((((.biWidth * .biBitCount) + 31) \ 32) * 4)
pad_per_scanLine = bytes_per_scanLine - (((.biWidth * .biBitCount) + 7) \ 8)
.biSizeImage = bytes_per_scanLine * Abs(.biHeight)
End With
' Load the bitmap's data.
wid = picTest.ScaleWidth
hgt = picTest.ScaleHeight
ReDim pixels(1 To 4, 0 To wid - 1, 0 To hgt - 1)
GetDIBits picTest.hdc, picTest.Image, _
0, picTest.ScaleHeight, pixels(1, 0, 0), _
bitmap_info, DIB_RGB_COLORS
' Break the transparent color into its components.
UnRGB transparent_color, transparent_r, transparent_g, transparent_b
' Create the PictureBox's regions.
For Y = 0 To hgt - 1
' Create a region for this row.
X = 1
Do While X < wid
start_x = 0
stop_x = 0
' Find the next non-transparent column.
Do While X < wid
If pixels(pixR, X, Y) transparent_r Or _
pixels(pixG, X, Y) transparent_g Or _
pixels(pixB, X, Y) transparent_b _
Then
Exit Do
End If
X = X + 1
Loop
start_x = X
' Find the next transparent column.
Do While X < wid
If pixels(pixR, X, Y) = transparent_r And _
pixels(pixG, X, Y) = transparent_g And _
pixels(pixB, X, Y) = transparent_b _
Then
Exit Do
End If
X = X + 1
Loop
stop_x = X
' Make a region from start_x to stop_x.
If start_x < wid Then
If stop_x >= wid Then stop_x = wid - 1
' Create the region.
new_rgn = CreateRectRgn( _
start_x, Y, stop_x, Y + 1)
' Add it to what we have so far.
If combined_rgn = 0 Then
combined_rgn = new_rgn
Else
CombineRgn combined_rgn, _
combined_rgn, new_rgn, RGN_OR
DeleteObject new_rgn
End If
End If
Loop
Next Y
' Restrict the PictureBox to the region.
SetWindowRgn pic.hWnd, combined_rgn, True
DeleteObject combined_rgn
End Sub
Private Sub pictest_Click()
Unload Me
End Sub
Private Sub Form_Load()
' Center the form.
Move (Screen.Width - Width) / 2, (Screen.Height - Height) / 2
' Move the picture on top of the other controls.
picTest.ZOrder
picTest.ScaleMode = vbPixels
picTest.AutoRedraw = True
picTest.Picture = picTest.Image
' Trim the picture.
TrimPicture picTest, &HFF00FF
End Sub
Create a picture box and name it picTest.
Then make sure you have an image that has something that can be transparent on it. Either change the &HFF00FF to the hex of your color, or us the RGB 255,0,255 as the color to make transparent.
Run the project, should work.
Now, what I am asking is, can someone help me get this to work with more than one picture box?