容器透明(如PictureBox)

一次做个小小的程序,在一个小小的问题上卡壳了,就是这个关于容器透明的问题。我要达到的目的是这样的:PictureBox上放一张透明的GIF图片,我要PictureBox在GIF图片透明的部分透明,主要是因为我在PictureBox下面还有其他图像,这样如果GIF图片透明的部分不透明就会是一块方块状的容器,显示特别难看。然而查一般情况下做为容器的控件不具有BackStyle这样的属性,而Label,Image等这样的控件都是有的。这里贴出代码和大家分享。VB6代码,Google搜索所得,没仔细看也看不懂,我只知道怎么用。用法如下:
Dim TempCls As clsTransForm
Set TempCls = New clsTransForm
TempCls.ShapeMe RGB(255, 255, 255), True, , PictureBox1
这样PictureBox1容器就透明了,当然PictureBox1的背景颜色最好也设置成和RGB(255, 255, 255)这个参数一样的颜色,具体参数是什么意义请看代码中的具体说明。
下面是这个类模块中的代码:
ContractedBlock.gif ExpandedBlockStart.gif clsTransForm
None.gifOption Explicit
None.gif
'Doug Gaede
None.gif'
October 31, 2000
None.gif'
----------------------------------------------------------
None.gif'
Notes:
None.gif'
Originally based on code by Chris Yates (Automatic Form Shaper) from www.planetsourcecode.com,
None.gif'
but modified completely and only shares about 5 lines of code with the original.  This version runs
None.gif'
much faster and will work on either a Form or PictureBox (for making custom-shaped controls).
None.gif'
Should work with any object that has an hDC, but I have restricted it for my own use.
None.gif'
My test form image (not the one in Form1 now, but about the same size and complexity) took
None.gif'
~35 seconds to create on a PIII-650 with Chris's code.
None.gif'
I cut it down to ~3 seconds (10X gain) by cutting the CombineRgn calls down from many, many thousands
None.gif'
to a few hundred in many cases.
None.gif'
This was done by searching for adjacent points and combining them into one line.
None.gif'
I also replaced the code to move the form because it didn't work in NT.
None.gif'
I have only tested this code in NT4, SP4.
None.gif

None.gif
'You are free to use, modify and distribute this code.
None.gif'
Email me at dgaede@home.com with comments or questions.
None.gif'
----------------------------------------------------------
None.gif

None.gif
'This module causes a Form or PictureBox to become shaped depending on the picture
None.gif'
that is assigned to the Picture property.  One color in the picture
None.gif'
will become the transparent color, depending on the color values passed to ShapeMe.
None.gif'
The DragForm sub allows the user to drag a form that doesn't have a title bar.
None.gif

None.gif
'Note that you MUST set the Form or PictureBox's BorderStyle property
None.gif'
equal to 0, manually.  This can not be set in code because it is read-only at runtime.
None.gif

None.gif
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As LongAs Long
None.gif
Private Declare Function SetWindowRgn Lib "user32" (ByVal hwnd As Long, ByVal hRgn As Long, ByVal bRedraw As BooleanAs Long
None.gif
Private Declare Function CreateRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As LongAs Long
None.gif
Private Declare Function CombineRgn Lib "gdi32" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As LongAs Long
None.gif
Private Declare Sub ReleaseCapture Lib "user32" ()
None.gif
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
None.gif
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As LongAs Long
None.gif
None.gif
Private Const RGN_DIFF = 4
None.gif
None.gif
Dim CurRgn As Long, TempRgn As Long  ' Region variables
None.gif

None.gif
'For dragging the form
None.gif
Private Const WM_NCLBUTTONDOWN = &HA1
None.gif
Private Const HTCAPTION = 2
None.gif
None.gif
Public Sub ShapeMe(Color As Long, HorizontalScan As Boolean, Optional Name1 As Form = Nothing, Optional Name2 As PictureBox = Nothing)
None.gif
None.gif
'Color = the color to convert to transparent (easiest to use RGB function to pass in this value)
None.gif'
HorizontalScan = scan for transparent lines horizonally or vertically.  Try both during development and pick the fastest one.
None.gif'
Name1 = a Form name.  If used, leave Name2 blank.
None.gif'
Name2 = a PictureBox name.  If used, leave Name1 blank.
None.gif

None.gif
Dim X As Integer, Y As Integer 'points on form
None.gif
Dim dblHeight As Double, dblWidth As Double 'height and width of object
None.gif
Dim lngHDC As Long 'the hDC property of the object
None.gif
Dim booMiddleOfSet As Boolean 'used during the gathering of transparent points
None.gif
Dim colPoints As Collection 'this will hold all usrPoints
None.gif
Set colPoints = New Collection
None.gif
Dim Z As Variant 'used during iteration through collection
None.gif
Dim dblTransY As Double 'these 3 variables hold each point that will be made transparent
None.gif
Dim dblTransStartX As Double
None.gif
Dim dblTransEndX As Double
None.gif
Dim Name As Object 'will hold the name of the object.  Late-bound and slower, but allows different types (in this case Form or PictureBox)
None.gif

None.gif
'check out the name or names passed into the subroutine
None.gif
If Name1 Is Nothing Xor Name2 Is Nothing Then 'we know there is a name in one of them
None.gif
    If Name1 Is Nothing Then 'set the name
None.gif
        Set Name = Name2
None.gif    
Else
None.gif        
Set Name = Name1
None.gif    
End If
None.gif
Else 'both or none hold valid names
None.gif
    MsgBox "Must pass in the name of either a Form OR a PictureBox.  TransForm received NONE or BOTH.  Function failed.", vbOKOnly, "ShapeMe Subroutine"
None.gif    
Exit Sub
None.gif
End If
None.gif
None.gif
'initialization
None.gif
With Name
None.gif    .AutoRedraw 
= True 'object must have this setting
None.gif
    .ScaleMode = 3 'object must have this setting
None.gif
    lngHDC = .hdc 'faster to use a variable; VB help recommends using the property, but I didn't encounter any problems
None.gif
    If HorizontalScan = True Then 'look for lines of transparency horizontally
None.gif
        dblHeight = .ScaleHeight 'faster to use a variable
None.gif
        dblWidth = .ScaleWidth 'faster to use a variable
None.gif
    Else 'look vertically (note that the names "dblHeight" and "dblWidth" are non-sensical now, but this was an easy way to do this
None.gif
        dblHeight = .ScaleWidth 'faster to use a variable
None.gif
        dblWidth = .ScaleHeight 'faster to use a variable
None.gif
    End If 'HorizontalScan = True
None.gif
End With
None.gifbooMiddleOfSet 
= False
None.gif
None.gif
'gather all points that need to be made transparent
None.gif
For Y = 0 To dblHeight  ' Go through each column of pixels on form
None.gif
    dblTransY = Y
None.gif    
For X = 0 To dblWidth  ' Go through each line of pixels on form
None.gif
        'note that using GetPixel appears to be faster than using VB's Point
None.gif
        If TypeOf Name Is Form Then 'check to see if this is a form and use GetPixel function which is a little faster
None.gif
            If GetPixel(lngHDC, X, Y) = Color Then  ' If the pixel's color is the transparency color, record it
None.gif
                If booMiddleOfSet = False Then
None.gif                    dblTransStartX 
= X
None.gif                    dblTransEndX 
= X
None.gif                    booMiddleOfSet 
= True
None.gif                
Else
None.gif                    dblTransEndX 
= X
None.gif                
End If 'booMiddleOfSet = False
None.gif
            Else
None.gif                
If booMiddleOfSet Then
None.gif                    colPoints.Add 
Array(dblTransY, dblTransStartX, dblTransEndX)
None.gif                    booMiddleOfSet 
= False
None.gif                
End If 'booMiddleOfSet = True
None.gif
            End If 'GetPixel(lngHDC, X, Y) = Color
None.gif
         ElseIf TypeOf Name Is PictureBox Then 'if a PictureBox then use Point; a little slower but works when GetPixel doesn't
None.gif
            If Name.Point(X, Y) = Color Then
None.gif                
If booMiddleOfSet = False Then
None.gif                    dblTransStartX 
= X
None.gif                    dblTransEndX 
= X
None.gif                    booMiddleOfSet 
= True
None.gif                
Else
None.gif                    dblTransEndX 
= X
None.gif                
End If 'booMiddleOfSet = False
None.gif
            Else
None.gif                
If booMiddleOfSet Then
None.gif                    colPoints.Add 
Array(dblTransY, dblTransStartX, dblTransEndX)
None.gif                    booMiddleOfSet 
= False
None.gif                
End If 'booMiddleOfSet = True
None.gif
            End If 'Name.Point(X, Y) = Color
None.gif
        End If 'TypeOf Name Is Form
None.gif
        
None.gif    
Next X
None.gif
Next Y
None.gif
None.gifCurRgn 
= CreateRectRgn(00, dblWidth, dblHeight)  ' Create base region which is the current whole window
None.gif

None.gif
For Each Z In colPoints 'now make it transparent
None.gif
    TempRgn = CreateRectRgn(Z(1), Z(0), Z(2+ 1, Z(0+ 1)  ' Create a temporary pixel region for this pixel
None.gif
    CombineRgn CurRgn, CurRgn, TempRgn, RGN_DIFF  ' Combine temp pixel region with base region using RGN_DIFF to extract the pixel and make it transparent
None.gif
    DeleteObject (TempRgn)  ' Delete the temporary region and free resources
None.gif
Next
None.gif
None.gifSetWindowRgn Name.hwnd, CurRgn, 
True  ' Finally set the windows region to the final product
None.gif'
I do not use DeleteObject on the CurRgn, going with the advice in Dan Appleman's book:
None.gif'
once set to a window using SetWindowRgn, do not delete the region.
None.gif

None.gif
Set colPoints = Nothing
None.gif
None.gif
End Sub
None.gif
Public Sub DragForm(Who As Form, intButton As Integer)
None.gif
None.gif
On Error Resume Next
None.gif
None.gif
If intButton = vbLeftButton Then
None.gif    
'Move the borderless formdot.gif
None.gif
    Call ReleaseCapture
None.gif    
Call SendMessage(Who.hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0)
None.gif
End If
None.gif
None.gif
End Sub
None.gif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值