【问题标题】:Transparent Panel of PictureBox on top of WindowsMediaPlayerWindows Media Player 顶部的 PictureBox 透明面板
【发布时间】:2017-01-19 23:47:08
【问题描述】:

我在我的 C#(桌面)应用程序中嵌入了 WindowsMediaPlayer,并希望在其上放置一个透明的 PanelPictureBox

由于PanelPictureBox 都没有TransparencyKey 属性,我不能使用BackColor=TransparencyKey=Color.Magenta 方法。

我尝试将PanelBackColor 设置为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


【解决方案1】:

块引用

在加载的形式中,将PictureBox1的背景指定为透明,然后将PictureBox1指定为PictureBox2容器的父级,就可以实现在PictureBox2中与PictureBox1的背景透明透明。 VB2010环境。 代码如下:附屏幕左边是运行效果,右边是编程环境,希望这个效果你会满意

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    PictureBox1.BackColor = Color.Transparent
    PictureBox2.Parent = PictureBox1

或 gdi+

添加绘画事件

 Dim g As Graphics = Me.CreateGraphics

【讨论】:

  • 我相信如果我使用两个 PictureBox 实例,这可能会奏效。不幸的是,我的底层“图像生成器”是一个嵌入式 COM 对象,所以我不完全确定如何应用您的建议。
【解决方案2】:

在designer.cs文件中添加这个语句,this.YOURWINDOWSMEDIAPLAYER.Controls.Add(this.YOURTRANSPARENTPANEL);

控件的顺序取决于你在designer.cs中添加子控件的顺序。

希望这将有助于解决您的问题,虽然有点晚了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-05
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    相关资源
    最近更新 更多