【问题标题】:Non-overlapped transparent control非重叠透明控件
【发布时间】:2011-09-07 10:08:31
【问题描述】:

我正在尝试为我的视频播放器制作工具提示。我在 c# (AxWMPLib.AxWindowsMediaPlayer) 上使用嵌入到我的 winform 应用程序中的 windows 媒体播放器来播放视频。我创建了一个显示媒体当前位置的控件。这个控件是透明的。控件代码如下:

namespace player.Controls
{
public partial class TransparentToolTip : System.Windows.Forms.UserControl
{
    public enum PointerLocation : byte { ... }

    #region Private data
     // ...
    #endregion

    Timer Wriggler = new Timer();
    int iInterval = 100;
    protected void TickHandler(object sender, EventArgs e)
    {
        this.InvalidateEx();
    } 

    private void _SetStyle()
    {
        this.SetStyle((ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.CacheText | ControlStyles.ContainerControl), true);
        this.SetStyle(ControlStyles.Selectable, false);
        this.SetStyle(ControlStyles.SupportsTransparentBackColor | ControlStyles.Opaque, true);            
        this.UpdateStyles();
    }
    private void _SetTimer(int _Interval)
    {
        Wriggler.Tick += new EventHandler(TickHandler);
        this.Wriggler.Interval = _Interval;
        this.Wriggler.Enabled = true;
    }    

    public TransparentToolTip()
    {            
        InitializeComponent();
        _SetStyle();
        _SetTimer(iInterval);                    
    }
    public TransparentToolTip(System.ComponentModel.IContainer container)
    {               
        container.Add(this);             
        InitializeComponent();            
        _SetStyle();
        _SetTimer(iInterval); 
    }        

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= (0x00000020 | 0x00000008); // WS_EX_TRANSPARENT  = 0x00000020, WS_EX_TOPMOST = 0x00000008              
            return cp;
        }
    }
    #region Extra Properties
    // ...
    #endregion

    // Drawing            
    protected void InvalidateEx()
    {
        if (Parent == null)
            return;
        Rectangle rc = new Rectangle(this.Location, this.Size);
        Parent.Invalidate(rc, true);
    }
    protected override void OnPaintBackground(PaintEventArgs pevent)
    {

    }
    protected override void OnPaint(PaintEventArgs pe)
    {           
        pe.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
        pe.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
        pe.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
        pe.Graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;

        Rectangle rect = new Rectangle(this.ClientRectangle.X, this.ClientRectangle.Y, this.ClientRectangle.Width - 1, this.ClientRectangle.Height - 1);            
        SolidBrush brushBackground = new SolidBrush(ColorBackground);
        SolidBrush brushBorder = new SolidBrush(ColorBorder);
        using (GraphicsPath graphicsPath = ToolTipBody(...))
        {
            using (Pen p = new Pen(brushBorder, BorderSize))
            {
                pe.Graphics.FillPath(brushBackground, graphicsPath); // background
                pe.Graphics.DrawPath(p, graphicsPath); // borders
            }
        }            

        TextFormatFlags flags = // some flags;
        TextRenderer.DrawText(pe.Graphics, ToolTipText, Font, new Rectangle(this.ClientRectangle.X, this.ClientRectangle.Y, this.ClientRectangle.Width, this.ClientRectangle.Height - TriangleSizeSide), ToolTipColor, System.Drawing.Color.Transparent, flags);
        brushBorder.Dispose();
        brushBackground.Dispose();

        base.OnPaint(pe);
    }
    // Form mapping tips
    private GraphicsPath ToolTipBody(...)
    { 
        // some code
        return graphicsPath;
    }
}

我尝试在 axWindowsMediaPlayer 对象上显示此工具提示。但我的控制与媒体播放器重叠。我尝试使用 SetWindowPos 但这不起作用:

static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
const int SWP_NOSIZE = 0x0001;
const int SWP_NOMOVE = 0x0002;
const int SWP_SHOWWINDOW = 0x0040;
//...
 [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
 [return: MarshalAs(UnmanagedType.Bool)]
  public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, int flags);
//...
SetWindowPos(transparentToolTip1.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);

注意:如果不更改新控件的 CreateParams,它将在媒体播放器上绘制。但它变得不透明。

使用 是否有正确的想法?

【问题讨论】:

  • 请编辑您的问题并提供一个有意义的标题。
  • 请修正题名/
  • 对不起。已经完成了。
  • 这不适用于媒体播放器。无论如何,工具提示应该是顶级窗口。很容易获得:从 Form 派生您的类,而不是使用 FormBorderStyle = None。使用 TransparencyKey 属性,透明度现在很简单。会太大,请在 Load 事件中调整它的大小。
  • 这个方法是我考虑的第二种方法(第一种是自定义控件)。它工作得很好。 Tnx。

标签: winforms c# winforms transparency topmost axwindowsmediaplayer


【解决方案1】:

我的猜测是透明的事情正在发生,因为您将控件样式定义为ControlStyles.Opaque。然后,将标志设置为WS_EX_TRANSPARENT,您将再次将其设置为透明样式。

关于重叠问题:如果您使用 Visual Studio Windows 窗体设计器设计了表单,那么您的控件可能会向下排列 AxWMPLib.AxWindowsMediaPlayer 组件。在显示之前尝试在您的控件集合中使用bring to frontcontrol the ChildrenIndex

希望对你有帮助。

【讨论】:

猜你喜欢
  • 2016-02-15
  • 1970-01-01
  • 1970-01-01
  • 2019-04-21
  • 2014-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多