Transparency based on color

Posted on 2003-03-19
Medium Priority
Last Modified: 2010-05-01
Is there a way to make a form and parts of controls on the form transparent based on a single color, like a green screen? Like if there is green on the form it would be transparent and if there was green in the control that would be transparent too?

I have a control that I want to put on the form and I want parts of the control to be transparent and all of the form to be transparent. The control has irregular shapes that change from time to time so a simple rectangle, etc. wouldn't work. I'm using VB6. Any help would be appreciated, but I'm a newbie so please be gentle.
Question by:nealparr
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 2
  • 2
  • +2

Accepted Solution

Shaka913 earned 1500 total points
ID: 8169893
Simple code below... notice the <-- i put in to show you where to make a change to pick a color.  The way this works is create a form, put a picture on the canvas of the form, and point it to the color you want transparent, and viola it is transparent.

Good Luck

Public Declare Function GetPixel Lib "gdi32" (ByVal hDC As Long, ByVal X As Long, ByVal Y As Long) As Long
Public Declare Function SetWindowRgn Lib "user32" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long
Public Declare Function CreateRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Public Declare Function CombineRgn Lib "gdi32" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As Long
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Declare Function ReleaseCapture Lib "user32" () As Long
Public Function MakeRegion(picSkin As Form) As Long
    hDC = picSkin.hDC
    PicWidth = picSkin.ScaleWidth
    PicHeight = picSkin.ScaleHeight
    InFirstRegion = True: InLine = False
    Transparent = GetPixel(hDC, 0, 0)  '<-- pick any pixel to make that color transparent.
    For Y = 0 To PicHeight - 1
        For X = 0 To PicWidth - 1
        If GetPixel(hDC, X, Y) = Transparent Or X = PicWidth Then
            If InLine Then
            InLine = False
            LineRegion = CreateRectRgn(LineX, Y, X, Y + 1)
                If InFirstRegion Then
                Full = LineRegion
                InFirstRegion = False
                CombineRgn Full, Full, LineRegion, 2
                End If
            End If
            If Not InLine Then
            InLine = True
            LineX = X
            End If
        End If
    MakeRegion = Full
End Function

Author Comment

ID: 8171364
To Shaka913:

How would I call this function from the form and does the form or image need to be named anything special?

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

LVL 17

Expert Comment

ID: 8172632
It is possible to map a byte array to the memory used by the image of your control and also another array to the image of the underlying form.  You can scan the array (representing your control's image) and if you find a specifc pixel value merge the pixel from the form's image at the same position.  Becuase the arrays are directly mapped to the actual memory used for the images the process is very fast.

But if you want a quick and easy way you just need some code in your control's paint event.  Capture the image of the form with the control invisible and use paintpicture to place the form's image onto your user control.  Any other controls you have should just float to the top.

Expert Comment

ID: 8173320
Here is how I would call it.

This is from the load event on the form:

Private Sub Form_Load()
Dim WindowRegion As Long
With Me
    WindowRegion = MakeRegion(frmMainForm) '<-- use the name of the form that you call it...
    SetWindowRgn .hWnd, WindowRegion, True
End With
End Sub
' This allows you to move it after the transparency operation
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    SendMessage Me.hWnd, &HA1, 2, 0&
End Sub

Expert Comment

ID: 8174231
Declare Function SetLayeredWindowAttributes lib "msimg32" (byval hWnd as Long, byval crKey as Long, byval bAlpha as Long, byval dwFlags as Long) as Long

just call
SetLayeredWindowAttributes(Me.hWnd,RGB(your color here),0,LWA_COLORKEY)

The above sample will only work on Windows 2000 or later
And you'll have to lookup the value of LWA_COLORKEY in the SDK headers (for that I don't have them here)
LVL 16

Expert Comment

ID: 8174711
LVL 16

Expert Comment

ID: 8174761
I have w2k and got an error in that function.

Expert Comment

ID: 8176716
Oops, I forgot, you also need to set the WS_EX_LAYERED extended style to your window after calling SetLayeredWindowAttributes:

Declare Function SetWindowLong alias "SetWindowLongA" lib "user32" (ByVal hWnd as Long, byval nIndex as Long, byval dwNewLong as Long) as Long

Declare Function GetWindowLong alias "GetWindowLongA" lib "user32" (ByVal hWnd as Long, byval nIndex as Long) as Long

Const GWL_EXSTYLE=(-20)
Const WS_EX_LAYERED = ??? ' Lookup value in Platform SDK headers

SetWindowLong(Me.hWnd,GWL_EXSTYLE,GetWindowLong(Me.hWnd,GWL_EXSTYLE) Or WS_EX_LAYERED)

And if you call SetLayeredWindowAttributes again after setting the exstyle, you will need to clear WS_EX_LAYERED and set it again to have the settings applied.
LVL 16

Expert Comment

ID: 8176777
The problem is with library also. That function is in user32 not msimg32.

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
This article describes how to use a set of graphical playing cards to create a Draw Poker game in Excel or VB6.
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
Suggested Courses
Course of the Month12 days, 8 hours left to enroll

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question