非矩形(所有者绘制)ToolTip控件周围的透明度?

时间:2009-09-04 23:14:31

标签: c# winforms tooltip gdi+ ownerdrawn

我通过响应Draw事件来自定义WinForms ToolTip控件的外观。我只是希望将一些ToolTip的角落四舍五入。我已经完成了所有工作,这样第一次显示工具提示时,一切看起来都很完美。但是,在后续显示中,我的圆角矩形的未填充区域将继续显示第一次显示工具提示时的背景内容。

问题的屏幕截图(我没有权利显示内联): http://tinypic.com/r/30xa3w9/3

在图片中,您可以看到左上角的遗留物,我希望它只是透明(显示灰色背景),如下所示:

tinypic.com/r/mvn8eo/3(也无权添加多个链接)

这是绘图代码:

private void ToolTip_Draw(object sender, DrawToolTipEventArgs args)
{
    args.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    var rect = new RectangleF(0, 0, args.Bounds.Width, args.Bounds.Height);
    using (var backBrush = new LinearGradientBrush(rect, Color.Silver, this.BackColor, 90))
    {
        using (var path = GetRoundedRectangle(rect, 10, 4, 4, 1))
        {
            args.Graphics.FillPath(backBrush, path);
            args.DrawText();
        }
    }
}

GetRoundedRectangle函数(未包含)只为我想要的圆角几何体计算适当的GraphicsPath。

我尝试在将BackColor设置为Color.Transparent之后添加对args.DrawBackground的调用,但是只填充了窗体背景的深灰色而不是实际透明的区域,我认为这是典型的“模拟” “WinForms的透明度。

作为旁注,IsBalloon设置为true的非自定义工具提示是非矩形的,具有正确的透明度。

有人可以建议修复此问题吗?

2 个答案:

答案 0 :(得分:1)

Control.Region正是您要找的。您需要告诉窗口管理器工具提示的形状,以便正确地重新绘制背景。

答案 1 :(得分:1)

这是一个解决方案,虽然不完美。它使用Graphics.CopyFromScreen将工具提示下的区域复制到背景中。当然,获取工具提示的位置并不简单 - 因此反射和PInvoke调用GetWindowRect。

剩下的故障是工具提示淡出时背景可能错误。例如,如果您有一个按钮,当鼠标悬停在该按钮上时,当您将鼠标移开时,工具提示仍将具有该彩色背景。将ToolTip.UseFading设置为false似乎会改变背景颜料的频率,使其比褪色问题更糟糕。如果用户在操作系统级别禁用了眼睛糖果,那么也可能触发与将UseFading设置为false相同的油漆故障。

    private void ToolTip_Draw2(object sender, DrawToolTipEventArgs args)
    {
        var graphics = args.Graphics;
        var bounds = args.Bounds;
        graphics.SmoothingMode = SmoothingMode.AntiAlias;
        var windowRect = GetWindowRect();
        graphics.CopyFromScreen(windowRect.Left, windowRect.Top, 0, 0, new Size(bounds.Width, bounds.Height));

        using (var backBrush = new LinearGradientBrush(bounds, C.Color_LogitechGray2, this.BackColor, 90))
        {
            using (var path = GetRoundedRectangle(bounds, 10, 4, 4, 1))
            {
                args.Graphics.FillPath(backBrush, path);
                args.DrawText();
            }
        }
    }

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);

    private Rectangle GetWindowRect()
    {
        RECT rect = new RECT();
        var window = typeof(ToolTip).GetField("window", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this) as NativeWindow;
        GetWindowRect(window.Handle, ref rect);
        return rect;
    }