Non-overlapped transparent control
Asked Answered
E

1

2

I'm trying to make a tooltip for my video player. I use a windows media player embedded into my winform's app on c# (AxWMPLib.AxWindowsMediaPlayer) for playing video. And I have created a control that shows a current position of a media. This control is transparent. Control's code is below:

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;
    }
}

I try to show this tooltip over the axWindowsMediaPlayer object. But my control is overlapped by the media player. I've tried to use SetWindowPos but this does not work:

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);

Note: If do not change CreateParams of a new control it draws over the media player. But it becomes opaque.

Is any ideas to do it correct using ?

Entirely answered 7/9, 2011 at 10:8 Comment(5)
Please edit your question and provide a meaningful title.Extravert
Please fix the title of the question/Stamey
Sorry. Has already been done.Entirely
This isn't going to work well with a media player. Tooltips should be toplevel windows anyway. Easy to get one: derive your class from Form instead using FormBorderStyle = None. Transparency is now simple with the TransparencyKey property. It will be too big, adjust its size in the Load event.Mccallum
This method is the second of those that I considered (the first one is a custom control). It works very well. Tnx.Entirely
L
1

My guess is that the transparent thing is happening because you're defining the control style as ControlStyles.Opaque. Then, setting the flag to WS_EX_TRANSPARENT you're setting it to transparent style again.

About the overlapped issue: If you designed the form using the Visual Studio Windows Forms designer, maybe your control is zOrdered down the AxWMPLib.AxWindowsMediaPlayer component. Try to bring to front or control the ChildrenIndex in your control collection before show it.

Hope it helps.

Lipophilic answered 7/9, 2011 at 13:57 Comment(1)
Methods Control.BringToFront and Control.ControlCollection.SetChildIndex do not solve the problem. Custom control is still behind the video. So I've decided to use a custom form with set properties TransparencyKey and Opacity instead of using a custom controlEntirely

© 2022 - 2024 — McMap. All rights reserved.