非矩形(所有者绘制)工具提示控件周围的透明度?

发布于 2024-08-04 03:01:23 字数 1161 浏览 4 评论 0原文

我通过响应 Draw 事件来自定义 WinForms 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 的非自定义工具提示是具有正确透明度的非矩形。

谁能建议解决这个问题?

I'm customizing the appearance of a WinForms ToolTip control by responding to the Draw event. I just want some of the ToolTip's corners to be rounded. I've got everything working such that the first time the ToolTip is displayed, everything looks perfect. On subsequent displays, however, the unfilled areas of my rounded rectangle continue to have what was in the background the first time the ToolTip was displayed.

Screen shot of problem (I don't have rights to put inline apparently):
http://tinypic.com/r/30xa3w9/3

In the picture, you can see the left-over artifacts in the upper-left corner where I would like it to just be transparent (showing the gray background), like this:

tinypic.com/r/mvn8eo/3 (nor rights to add more than one link)

Here is the drawing code:

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

The GetRoundedRectangle function (not included) just calculates the appropriate GraphicsPath for the rounded geometry that I want.

I tried adding a call to args.DrawBackground after setting the BackColor to Color.Transparent, but that just filled in the area with the dark gray of the form's background rather than actually being transparent, which I think is the typical "simulated" transparency of WinForms.

As a side note, an non-customized ToolTip with IsBalloon set to true is non-rectangular with correct transparency.

Can anyone suggest a fix for this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鸩远一方 2024-08-11 03:01:23

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

Control.Region is what you are looking for. You need to tell the window manager the shape of the tooltip, so background is properly redrawn.

秋叶绚丽 2024-08-11 03:01:23

这是一个解决方案,尽管不完美。它使用 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;
    }

Here is a solution, though imperfect. It uses Graphics.CopyFromScreen to copy the area under the tooltip into the background. Of course, getting the location of the tooltip isn't simple -- hence the reflection and PInvoke call to GetWindowRect.

A remaining glitch is that the background might be wrong while the the tooltip fades out. For example, if you have a button that is colored when the mouse is over it, the tooltip will still have that colored background when you move the mouse off while it fades away. Setting ToolTip.UseFading to false seems to change the frequency of background paints such that it is worse than the fading problem. If the user has disabled eye candy at the OS level, that might also trigger the same paint glitches as having UseFading set to 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;
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文