Really Transparent Controls needed.

isilrion

Member
Joined
Aug 30, 2003
Messages
20
Hello.

I need to display some data on top of a video, but I need the containers to be transparent (i.e: no grey box around the letters of the label control, just the letters). The BackColor=Color.Transparent solution seems to work only if the background is a still image.

So far, the best thing Ive managed to do (dont laugh, I know it cant be right) is to put the to be transparent controls on top of a transparent form on top of the video... Not a nice solution.

Any idea?

Isilrion
 
Is DoubleBuffer enabled on the controls? If you DoubleBuff and still have problems, DrawString directly to the movie surface without a label.
 
DoubleBuffer?

1- What is DoubleBuffer?

2- Enabled on what control?
(Im playing the video with the AudioVideoPlayback class from DirectX 9, if doubleBuffer refers to the use of a back surface and flip, I just dont know if the audioVideoPlayback uses it)

3- How do I enable it?

4- Draw directly to the video surface? Wont the next frame erase the drawing?

Thanks.

Isilrion.
 
I set the DoubleBuffer in a control I inherited from UserControl. (onPaint and onPaintBackground methods overriden, and doing nothing). The control is just a black rectangle sitting in front of the video. (No transparency).

Without overriding the two methods, the control shows the from background, not the video. (I need to see the video through the control).
 
Put this in the constructor of your control:

this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.UserPaint, true);

Yes, DoubleBuffer refers to drawing to a backsurface first. However, you dont need to handle all that jazz when you draw in OnPaint after you use the code above.

The control is probably black because you forgot to put
base.OnPaint(e); in OnPaint.

For transparency in your control put

this.SetStyle(ControlStyles.SupportsTransparentColor, true);

in your constructor as well. Im not sure if I wrote that just right. But youll see it in the list or ControlStyles.

To Paint the control transparent paint the background color with
Color.FromArgb(0,0,0,0);

You can also just paint directly to the video screen control with your text, overriding OnPaint and then you must always call the base.OnPaint(e); method, either before your code or after. And yes, it will erase in the next frame but will redraw because it is in OnPaint.
 
Hmm. This is weird. I havent tried painting directly on the video, but I dont think it will work. The OnPaint method of my control doesnt get called after every frame (I added a MessageBox.Show to my OnPaint and OnPaintBackground methods to see when they get called - it only shows when I force it to repaint (like covering the window with another).

Even then, the painting is erratic. If I enable the doublebuffer like you did, the background gets painted of black *after* leaving the OnPaint method (my guess: backbuffer is black and it never changed color?). Ive tried painting the background with the Color.Transparent and the Color.fromARGB(0,0,0,0) in my OnPaint -still all black. But, right before the OnPaint finishes, I *almost* get what Im looking for (the debug messageBox is the last instruction on my OnPaint).

If I dont use the DoubleBuffer style, I almost get what Im looking for (the same *almost*). When I hide the window (not minimize, not covering with another window, but moving the control off-screen and then moving it back in quickly), I get the desired effect on some random regions of the control. On the rest of the control, I either get the same black or grey background, or the form background, whatever is behind the form (usually a piece of the VS.NET IDE).

Ah, the effect is exactly the same wether I call base.OnPaint/base.OnPaintBackground or not.

BTW, how do I get the graphics object asociated with a control? Im used to Javas .getGraphics().

Thanks.
 
Graphics g= control.CreateGraphics();
Are you able to post some code?
Are you overriding the video controls OnPaint or the form? You should be overriding the videos.
What are you trying to paint transparent?
Did you set the ControlsStyles to transparent also like posted above?
 
Yes, Ill post some code. I dont have it now (Im on another computer), but Ill try to post it tomorrow.

Well, I wasnt overriding the video controls OnPaint. I did, however, attach a PaintEventHandler to it, and it wasnt getting called. (can it have something to do with the fact that is DirectX/AudioVideoPlayback who is playing the video, like I said before?)

The control that Im trying to paint transparent is just a subclass of UserControl. Originaly I wanted to make a label with transparent background, now I at least want to have a way to draw text over the video.

And I set my UserControls ControlStyle like you said before my last reply.

Thanks again.
 
The Label does support transparent color. You should be able to set its Background color to Color.FromArgb(0,0,0,0); and see your movie behind it. If you cant, DirectX probably has something to do with why you cant.

I havent dealt with DirectX at all yet. There may be a factor in there that I wouldnt know the least bit about. But like I said, the label should work.
 
Im reasonably sure that AudioVideoPlayback uses DirectDraw and DirectSound so putting things over the surface(in GDI/GDI+) will not show as DirectX draws straight to the Video Card memory. You could put the control to the side rather than on the video, otherwise you could try drawing over it with DirectDraw.
 
Yes, that was my guess. Now I have a couple of questions:
1-) Is there any way to play a video to GDI/GDI+?
2-) Alternatively (and possibly better), how can I use directdraw to draw over the video? I havent managed to tell AudioVideoPlayback to draw over a DirectDraw surface, so I dont know where to paint. It draws it to Direct3D (the sample uses D3D), but not D.Draw.

thanks.
 
Ah, just in case there is a better soltion I havent thought about.
The original idea was to show a marquee on the bottom of the video, like those that appear on some movies saying This movie is copyrighted, bla bla bla, and from the beggining I was thinking on painting the text and not use labels, but right now, anything will do.
 
Are you displaying the movie in a Control or on the form? If its in a control you could just make a marquee control and stick it at the bottom of the control hosting the video.

Drawing with DirectDraw requires a lot of setting up, I didnt mean draw to the surface, I ment set the target to the Control then create a DirectDraw Device and attach it to the Control as well. Then use a loop to continously draw over the video.
 
Let me see if I got you (my english isnt nearly as good as it should be).

Im playing the movie on a panel. I have no problem with playing it on a inherited control, if thats what you mean.

Now, if I create a new DirectDraw device on that control, will it be the same as the one playing the video? (Thats what I understood from your reply). And painting the text directly there on a while(true) kind of loop (thats also what I understood)... wouldnt that be very cpu expensive, and with a lot of flickering? (I guess I can answer that question myself after I get to my computer)

And about the lot of work setting up D.Draw, I already got a marquee working on it, I just havent been able to put it on the movie.

Thanks.
Isilrion
 
What I ment is that if you have it in a panel, which you said you do, you could just put the text underneath it rather than over it.

With DirectDraw you have a Device object, if you attach it to the Panel (SetCooperativeMode) and then use a loop to continuously redraw the text it will go over everything there. It will not be the same device used by AudioVideoPlayback but it will draw over AudioVideoPlayback.
Most DirectX programs use a loop, all DirectX games certainly use a loop, because Windows can draw over DirectDraw and Direct3D so you need to continuously refresh the DirectDraw things. No it does not flicker if you do it properly, Event managing of DirectX objects is not very effective so loops are the best way to manage them.
 
Well, I think I did what you said, but nothing got displayed. I attached the DDraw device to the same control holding the video and filled a magenta rectangle in the while(true) loop. The rectangle never showed (running the prog w/o the video being rendered showed the rectangle).

In a previous post you (Ryan) mentioned to draw underneath the video. I didnt understand what you wanted to say with that, but today I was doing -another- web search, and I got to a page where a similar answer was given. I dont know exactly what they were talking about, but if thats what you meant, I think I could do some research about it. The quote is

Overlay Mixer is a Leagcy filter, but it is great, because it allow yout set a color Key ( Transparent Color). Then you can Put a normal Window behind video window. If the background of your application windows is the same of colorKey you will see the video throught the window, except in the places with another colors ( drwaings, text etc on the your window).

I also found in the samples something very similar to what I was looking for (a marquee, with transparent background, moving on the video), but it was using C++ & DirectShow. Should I search the DirectX threads for a way to use the [unmagaged] DirectShow on my app?

thnx again.
 
Ive got a similar problem and found a solution that should work.
Here a sample in C#:

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;

namespace xxx
{
public class CustomControl1 : System.Windows.Forms.Control
{
/// <summary>
/// Erforderliche Designervariable.
/// </summary>
private System.ComponentModel.Container components = null;

public CustomControl1()
{
InitializeComponent();
}

protected override void Dispose( bool disposing )
{
if( disposing )
{
if( components != null )
components.Dispose();
}
base.Dispose( disposing );
}

#region Vom Komponenten-Designer generierter Code
/// <summary>
/// Erforderliche Methode f
 
Last edited by a moderator:
Hmm... that might work.
Still trying to make it work, though (nothing is getting painted, but I just copied/pasted that, Ill take a deeper look at the code - it seems that the video is erasing it).

However, the transparency effect seems to be better than one achieved with the ControlStyles.SupportsTransparentBackColor. Thanks, Ill try to make it work, Ill let you know if it worked.

What style is 0x20?
 
Flickering

override the paint event and dont call the base. The base resets the image. of course using buffered surfaces then flipping the primary surface would avoid that but thats beyond your ?
 
Back
Top