Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Transparent Control (Not form)

Posted on 1998-10-16
16
Medium Priority
?
562 Views
Last Modified: 2013-12-25
I know how to get a form to be transparent, but how do I get it's controls to be also transparent?
ie: a form with a text box is transparent, but the text box has the background color of the form's color.

Here is the code I use for the with a form with only one text box:

Const GWL_EXSTYLE = (-20)
Const WS_EX_TRANSPARENT = &H20&
   
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Private Sub Form_Load()
  Dim Ret As Long
    Ret = SetWindowLong(Me.hWnd, GWL_EXSTYLE, WS_EX_TRANSPARENT)
End Sub

Please, no OCX; just plain API call
0
Comment
Question by:OlivierKovacs
[X]
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
  • 6
  • 5
  • 3
  • +2
16 Comments
 

Author Comment

by:OlivierKovacs
ID: 1487715
Edited text of question
0
 
LVL 2

Expert Comment

by:schild
ID: 1487716
Hello

This is a code give you both transparent form and controls, In this example you make an elliptic transparent shape, but you can change it for any shape you need to. and place the shape in any proper loaction:


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 CreateEllipticRgn 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 Sub Form_Resize()
Const RGN_DIFF = 4

Dim outer_rgn As Long
Dim inner_rgn As Long
Dim combined_rgn As Long
Dim wid As Single
Dim hgt As Single
Dim border_width As Single
Dim title_height As Single

    If WindowState = vbMinimized Then Exit Sub
   
    ' Create the regions.
    wid = ScaleX(Width, vbTwips, vbPixels)
    hgt = ScaleY(Height, vbTwips, vbPixels)
    outer_rgn = CreateRectRgn(0, 0, wid, hgt)
   
    border_width = (wid - ScaleWidth) / 2
    title_height = hgt - border_width - ScaleHeight
    inner_rgn = CreateEllipticRgn( _
        border_width + ScaleWidth * 0.1, _
        title_height + ScaleHeight * 0.1, _
        ScaleWidth * 0.9, ScaleHeight * 0.9)

    ' Subtract the inner region from the outer.
    combined_rgn = CreateRectRgn(0, 0, 0, 0)
    CombineRgn combined_rgn, outer_rgn, _
        inner_rgn, RGN_DIFF
   
    ' Restrict the window to the region.
    SetWindowRgn hWnd, combined_rgn, True
End Sub


If you have any farther questions please let me know

Good Luck
Schild



0
 
LVL 5

Expert Comment

by:AnswerTheMan
ID: 1487717
wait a sec before u past all that code into your machine...
why do u need that transparation action for ?
if it's what i think - there is a simple way - not with that
long code.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:OlivierKovacs
ID: 1487718
Thanks for the help.  Your example is great but it is not exactly what I am looking for.  Unfortunately, I can not give you part of the points as you deserve...
Your code will cause the complete control to be transparent.  I probably should have explained better my requirements:
The control should be like a text box where the background is transparent (like the form) but still showing the text.  This will be used for a counter.
0
 
LVL 5

Expert Comment

by:AnswerTheMan
ID: 1487719
i can't quite understand what exactly your goal is.

0
 

Author Comment

by:OlivierKovacs
ID: 1487720
AnswerTheMan,

My goal is to have some text displayed on the desktop, but with a transparent background.  As an example, I saw some count-down program for the Year 2000 displayed on the desktop.  This was only showing the text, refreshing every second, but without hiding the wallpaper.  Is that feasible?
0
 
LVL 13

Expert Comment

by:Mirkwood
ID: 1487721
You owe me big time. It took me more than an hour to found out what it does in VB.

Here are the steps to make a control transparent.
1) Create a form1
2) Create a usercontrol
3) Create a new form2
4) Put a picture control on form2 (picture1)
5) Set backcolor property of picture to &h00fffffff
6) Set maskcolor of usercontrol to &h00ffffff
7) Set backstyle of usercontrol to 0 - transparent
8) Add the following code to the usercontrol
Private Sub UserControl_Initialize()
    Load Form2
    UserControl.Picture = Form2.Picture1
    UserControl.MaskPicture = Form2.Picture1
End Sub

Private Sub UserControl_Resize()
    Form2.Picture1.Move 0, 0, ScaleWidth, ScaleHeight
End Sub

Private Sub UserControl_Terminate()
    Unload Form2
End Sub
9) Add usercontrol to form1

Now you have a transparent control.
This answer would be OK but when I found the answer I read that you wanted to display a label and guess what. A transparent label  does not work on a transparent control. See KB Q179052
Here is a solution. This is worth another 25 points I guess (that's the amount of points you have tomorrow,  I guess, post a question for 25 points with Mirkwood Rules!! or something.Just kidding, I'm glad I can help.

1) Add a label to the picture control.
2) Set backstyle property = 0-transparent
3) Set font to Tahoma or another Truetype font

Now the label will work.




0
 
LVL 5

Expert Comment

by:AnswerTheMan
ID: 1487722
Got u now. ok. print the text to screen(main form) - not to any control.
0
 

Author Comment

by:OlivierKovacs
ID: 1487723
Sorry Mirkwood...   ...I can get the transparent control, but can not figure out how to get the label on the image.  When I do it, the label does not display on the first form.

Did you get it working?  How?  


0
 
LVL 5

Expert Comment

by:AnswerTheMan
ID: 1487724
First thing  declare:

Declare Function TextOut Lib "gdi32" Alias "TextOutA" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal lpString As String, ByVal nCount As Long) As Long

implimentation :
''suppose u write on a Picture (can write on a form also)
     dim StringToAdd as string
     StringToAdd= "Testing"
     dim StringLen as long
     StringLen=Len(StringToAdd)
''u wanna set the color for writing ?
     dim MyColor as long
     Picture1.ForeColor="MyColor"
 ''AND The PUNCH LINE :
     TextOut Picture1.hdc,TextCol,TextLine,StringToAdd,StringLen
  ''TextCol and TextLine are the locations for your text

0
 
LVL 13

Expert Comment

by:Mirkwood
ID: 1487725
I used a truetype font for the label and that seemed to work.
0
 
LVL 13

Expert Comment

by:Mirkwood
ID: 1487726
AnswerTheMan, TextOut want work either ofcourse. The transparent pixels ignore all printing on the same level. You must first force another drawing level. Truetypes font do that, for some internal reason.
It is true that you can use textout to write to the background window. Ans that Olivier might be an easier solution to your problem.
Here is some sample code to do that. To change the properties of how its printed you can change the DC settings. Look in the GDI api's. Or ask a quesion :-)

    Dim hdcMain As Long
    hdcMain = GetWindowDC(0)
    TextOut hdcMain, 0, 0, "00:22:30", 8
    ReleaseDC 0, hdcMain
0
 
LVL 5

Expert Comment

by:AnswerTheMan
ID: 1487727
yeah.....and you even fill as if u writing Visual C++......
0
 

Author Comment

by:OlivierKovacs
ID: 1487728
Well guys,

First, thanks to you all who tried helping me to resolve this question.
Sorry for you all, I know this question was interesting for you all (hey!  200 points!!!) but I have been able to do it with really simple coding.  Here is how:

Create a new VB project and make sure the form's AutoRedraw is set to true

In a module add the following:

-------  MODULE  START  -------
Option Explicit

Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Declare Function GetDesktopWindow Lib "user32" () As Long
Declare Function GetWindowDC Lib "user32" (ByVal hwnd As Long) As Long
Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long

Public Const SRCCOPY = &HCC0020           ' Raster Operation
Public DesktopHDC As Long    ' This variable will store the Desktop handle
Public Desktop As Long            ' This will store the Desktop device context


Public Sub drawDesktop(Dest As Form)

    Dest.Visible = False    'Need to hide the form to refresh the background

    Desktop = GetDesktopWindow()
    DesktopHDC = GetWindowDC(Desktop)
   
    Dest.Visible = True     'Show the form again

    Call BitBlt(Dest.hdc, 0, 0, Dest.Width / Screen.TwipsPerPixelX, Dest.Height / Screen.TwipsPerPixelY, DesktopHDC, Dest.Left / Screen.TwipsPerPixelX, Dest.Top / Screen.TwipsPerPixelY, SRCCOPY)

    Call ReleaseDC(Desktop, DesktopHDC)          'Free used resource

End Sub

-------  MODULE   END   -------

On the previously created form add the following code :

-------  FORM1 CODE START  -------

Private Sub Form_Initialize()
    Label1.Caption = now()
    Call drawDesktop(Form1)
End Sub

Private Sub Timer1_Timer()
    Label1.Caption = ""
    Label1.Refresh
    Call drawDesktop(Form1)

    Label1.Caption = Now()
    Label1.Refresh
End Sub

-------  FORM1 CODE END  -------

Et voila!!!

0
 

Author Comment

by:OlivierKovacs
ID: 1487729
Well guys,

First, thanks to you all who tried helping me to resolve this question.
Sorry for you all, I know this question was interesting for you all (hey!  200 points!!!) but I have been able to do it with really simple coding.  Here is how:

Create a new VB project and make sure the form's AutoRedraw is set to true

In a module add the following:

-------  MODULE  START  -------
Option Explicit

Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Declare Function GetDesktopWindow Lib "user32" () As Long
Declare Function GetWindowDC Lib "user32" (ByVal hwnd As Long) As Long
Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long

Public Const SRCCOPY = &HCC0020           ' Raster Operation
Public DesktopHDC As Long    ' This variable will store the Desktop handle
Public Desktop As Long            ' This will store the Desktop device context


Public Sub drawDesktop(Dest As Form)

    Dest.Visible = False    'Need to hide the form to refresh the background

    Desktop = GetDesktopWindow()
    DesktopHDC = GetWindowDC(Desktop)
   
    Dest.Visible = True     'Show the form again

    Call BitBlt(Dest.hdc, 0, 0, Dest.Width / Screen.TwipsPerPixelX, Dest.Height / Screen.TwipsPerPixelY, DesktopHDC, Dest.Left / Screen.TwipsPerPixelX, Dest.Top / Screen.TwipsPerPixelY, SRCCOPY)

    Call ReleaseDC(Desktop, DesktopHDC)          'Free used resource

End Sub

-------  MODULE   END   -------

On the previously created form add the following code :

-------  FORM1 CODE START  -------

Private Sub Form_Initialize()
    Label1.Caption = now()
    Call drawDesktop(Form1)
End Sub

Private Sub Timer1_Timer()
    Label1.Caption = ""
    Label1.Refresh
    Call drawDesktop(Form1)

    Label1.Caption = Now()
    Label1.Refresh
End Sub

-------  FORM1 CODE END  -------

Et voila!!!

0
 
LVL 7

Accepted Solution

by:
linda101698 earned 800 total points
ID: 1487730
I am posting the solution found by OlivierKovacs so it can be saved in the previously asked questions.  Please see your customer service question for an explanation.

Linda Gardner
Customer Service @ Experts Exchange



Comment
     From: OlivierKovacs
                                   Date: Thursday, October 22 1998 - 09:57AM PDT

     Well guys,

     First, thanks to you all who tried helping me to resolve this question.
     Sorry for you all, I know this question was interesting for you all (hey!  200
     points!!!) but I have been able to do it with really simple coding.  Here is how:


     Create a new VB project and make sure the form's AutoRedraw is set to true


     In a module add the following:

     -------  MODULE  START  -------
     Option Explicit

     Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As
     Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long,
     ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal
     dwRop As Long) As Long
     Declare Function GetDesktopWindow Lib "user32" () As Long
     Declare Function GetWindowDC Lib "user32" (ByVal hwnd As Long) As
     Long
     Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc
     As Long) As Long

     Public Const SRCCOPY = &HCC0020           ' Raster Operation
     Public DesktopHDC As Long    ' This variable will store the Desktop handle
     Public Desktop As Long            ' This will store the Desktop device context


     Public Sub drawDesktop(Dest As Form)

         Dest.Visible = False    'Need to hide the form to refresh the background

         Desktop = GetDesktopWindow()
         DesktopHDC = GetWindowDC(Desktop)
         
         Dest.Visible = True     'Show the form again

         Call BitBlt(Dest.hdc, 0, 0, Dest.Width / Screen.TwipsPerPixelX,
     Dest.Height / Screen.TwipsPerPixelY, DesktopHDC, Dest.Left /
     Screen.TwipsPerPixelX, Dest.Top / Screen.TwipsPerPixelY, SRCCOPY)

         Call ReleaseDC(Desktop, DesktopHDC)          'Free used resource

     End Sub

     -------  MODULE   END   -------

     On the previously created form add the following code :

     -------  FORM1 CODE START  -------

     Private Sub Form_Initialize()
         Label1.Caption = now()
         Call drawDesktop(Form1)
     End Sub

     Private Sub Timer1_Timer()
         Label1.Caption = "" 
         Label1.Refresh
         Call drawDesktop(Form1)

         Label1.Caption = Now()
         Label1.Refresh
     End Sub

     -------  FORM1 CODE END  -------

     Et voila!!!
0

Featured Post

[Webinar] Lessons on Recovering from Petya

Skyport is working hard to help customers recover from recent attacks, like the Petya worm. This work has brought to light some important lessons. New malware attacks like this can take down your entire environment. Learn from others mistakes on how to prevent Petya like worms.

Question has a verified solution.

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

This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
This article describes how to use a set of graphical playing cards to create a Draw Poker game in Excel or VB6.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Suggested Courses

705 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