【发布时间】:2017-01-19 23:47:08
【问题描述】:
我在我的 C#(桌面)应用程序中嵌入了 WindowsMediaPlayer,并希望在其上放置一个透明的 Panel 或 PictureBox。
由于Panel 或PictureBox 都没有TransparencyKey 属性,我不能使用BackColor=TransparencyKey=Color.Magenta 方法。
我尝试将Panel 的BackColor 设置为Color.Transparent。它似乎不起作用。 [或者可能确实如此,但 WMP 视频根本无法通过(透明)面板显示。]
(最终)目标是防止用户直接与 WMP 交互,并且理想情况下,有一个叠加层,可以将“有用”信息传达给用户。
有人成功地做到了这样的事情吗?我对如何解决这个问题的大多数想法持开放态度。
编辑:
使用 'How to Make a UserControls BackColor Transparent in C#?' 中的示例,我创建了“我自己的”面板,如下所示:
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
这实现了制作覆盖 WMP 的“不可见”面板的目标,同时允许 WMP 显示通过。但是,我仍然需要在 WMP 窗口的顶部(前面)显示一些信息。
我曾尝试直接在此透明面板上“绘制”,[请参阅 OnPaint() 中“// 显示覆盖信息”的代码块],但这没有显示。但是,如果我“隐藏()”WMP 窗口,文字会显示(当然,WMP 不会显示)。如果我让我的透明面板只覆盖一半屏幕并添加一个“常规”面板(带有 BackgroundImage),它会显示,除非它的任何部分与透明面板重叠,在这种情况下它不会显示。
我已经注意到有关父级绘制面板背景的 cmets。我不明白这一点,但是让我的透明面板的 Parent 成为 WMP (TP.Parent = WMP;) 没有任何区别。
我准备相信我在这里遗漏了一些基本的东西,因为我对表单/控件的了解充其量只是初级的。尽管如此,我真的很想了解我缺少什么,以便我可以将其添加到我的知识库中,在这里解决我的问题,然后继续前进。
[祝福George Birbilis,没有他,我仍然站在第一方! :-)]
【问题讨论】:
-
我认为您可以禁用 WMP ti 上的控件以防止用户与之交互。当您放置一个透明控件(通过更改不透明度)时,您可以单击它,所以我怀疑您是否会通过透明控件实现您的目标
-
您可以禁用/隐藏可见控件(我有),但不能在屏幕上右键单击显示操作列表。无论如何,尝试使用透明覆盖的其他原因之一是允许在其上显示信息(作为补充数据)“覆盖”正在运行的视频。
-
您还可以添加这些的后代类并覆盖它们用于绘制自己的方法,以不擦除背景和/或不绘制任何东西
-
您可能需要使用另一个顶级窗口并处理所有交互,以便最终用户显示为一个表单。也许它可以与某些第三方控件一起使用,但不能与标准控件一起使用。
-
WMP 使用什么类/控件?
标签: c# winforms panel transparency windows-media-player