Solved

Transparent Control (Not form)

Posted on 1998-10-16
16
549 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
  • 6
  • 5
  • 3
  • +2
16 Comments
 

Author Comment

by:OlivierKovacs
Comment Utility
Edited text of question
0
 
LVL 2

Expert Comment

by:schild
Comment Utility
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
Comment Utility
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
 

Author Comment

by:OlivierKovacs
Comment Utility
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
Comment Utility
i can't quite understand what exactly your goal is.

0
 

Author Comment

by:OlivierKovacs
Comment Utility
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
Comment Utility
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
Comment Utility
Got u now. ok. print the text to screen(main form) - not to any control.
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 

Author Comment

by:OlivierKovacs
Comment Utility
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
Comment Utility
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
Comment Utility
I used a truetype font for the label and that seemed to work.
0
 
LVL 13

Expert Comment

by:Mirkwood
Comment Utility
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
Comment Utility
yeah.....and you even fill as if u writing Visual C++......
0
 

Author Comment

by:OlivierKovacs
Comment Utility
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
Comment Utility
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 200 total points
Comment Utility
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

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
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.
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
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…

772 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now