I have embedded WindowsMediaPlayer in my C# (desktop) app and want to place a transparent Panel
or PictureBox
on top of it.
Since neither Panel
or PictureBox
has the TransparencyKey
property, I can't use the, BackColor=TransparencyKey=Color.Magenta
, approach.
I've tried setting the BackColor
of the Panel
to Color.Transparent
. It doesn't seem to work. [Or maybe it does, but the WMP video is simply not showing through the (transparent) panel.]
The (ultimate) goal is to prevent users from directly interacting with the WMP and, ideally, to have an overlay on which "useful" info could be conveyed to the users.
Anyone managed to do something like this successfully? I'm open to most ideas on how to solve this.
EDIT:
Using the example from 'How to Make a UserControls BackColor Transparent in C#?', I have created "my own" Panel as follows:
class TransarentPanel : Panel {
public bool drag = false;
public bool enab = false;
private int m_opacity = 100;
private int alpha;
System.Drawing.Font drawFont;
System.Drawing.SolidBrush drawBrush;
System.Drawing.StringFormat drawFormat;
public TransarentPanel() {
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
SetStyle(ControlStyles.Opaque, true);
this.BackColor = Color.Transparent;
}
public int Opacity {
get {
if (m_opacity > 100) {
m_opacity = 100;
} else if (m_opacity < 1) {
m_opacity = 1;
}
return this.m_opacity;
}
set {
this.m_opacity = value;
if (this.Parent != null) {
Parent.Invalidate(this.Bounds, true);
}
}
}
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle = cp.ExStyle | 0x20;
return cp;
}
}
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
Rectangle bounds = new Rectangle(0, 0, this.Width - 1, this.Height - 1);
Color frmColor = this.Parent.BackColor;
Brush bckColor = default(Brush);
alpha = (m_opacity * 255) / 100;
if (drag) {
Color dragBckColor = default(Color);
if (BackColor != Color.Transparent) {
int Rb = BackColor.R * alpha / 255 + frmColor.R * (255 - alpha) / 255;
int Gb = BackColor.G * alpha / 255 + frmColor.G * (255 - alpha) / 255;
int Bb = BackColor.B * alpha / 255 + frmColor.B * (255 - alpha) / 255;
dragBckColor = Color.FromArgb(Rb, Gb, Bb);
} else {
dragBckColor = frmColor;
}
alpha = 255;
bckColor = new SolidBrush(Color.FromArgb(alpha, dragBckColor));
} else {
bckColor = new SolidBrush(Color.FromArgb(alpha, this.BackColor));
}
if (this.BackColor != Color.Transparent | drag) {
g.FillRectangle(bckColor, bounds);
}
// Display overlay info
{
drawFont = new System.Drawing.Font("Arial", 24);
drawBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Black);
drawFormat = new System.Drawing.StringFormat();
g.DrawString("Overlay", drawFont, drawBrush, this.Location.X + 50, this.Location.Y + 30, drawFormat);
drawFont.Dispose();
drawBrush.Dispose();
drawFormat.Dispose();
}
bckColor.Dispose();
g.Dispose(); // Should this object be disposed of here since it was not created here?
base.OnPaint(e);
}
protected override void OnBackColorChanged(EventArgs e)
{
if (this.Parent != null)
{
Parent.Invalidate(this.Bounds, true);
}
base.OnBackColorChanged(e);
}
protected override void OnParentBackColorChanged(EventArgs e)
{
this.Invalidate();
base.OnParentBackColorChanged(e);
}
} // end class TransparentPanel
This achieves the goal of making an "invisible" Panel that overlays the WMP while allowing the WMP display to show through. However, I still need to display some info on top of (in front of) the WMP window.
I have tried to 'Draw' directly on this transparent panel, [see the code block at '// Display overlay info' in OnPaint()], but this does not show. However, if I 'Hide()' the WMP window, the writing does show (but, of course, WMP doesn't). If I make my transparent panel only cover half the screen and add a "regular" panel (with a BackgroundImage), it shows up unless any part of it overlaps the transparent panel, in which case it does not show.
I have noted comments about the Parent drawing the Panel's background. I don't understand this, but making my transparent panel's Parent be the WMP (TP.Parent = WMP;) didn't make any difference.
I am prepared to believe I'm missing something basic here, since my knowledge of Forms/Controls is rudimentary at best. Having come this close, though, I'd really like to understand what I'm missing so I can add it to my knowledge base, fix my problem here, and move on.
[And bless George Birbilis without whom I'd still be at square one! :-) ]