2009-09-04 63 views
1

我正在通过响应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的非自定义工具提示是非正方形且具有正确的透明度。

任何人都可以提出一个解决这个问题?

回答

1

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

+0

工具提示不是控件,但它只是一个组件,所以它没有Region属性。有没有这样做的间接方式? – 2009-09-08 19:15:42

+0

@Eric Smith,嗯,它有一个Handle属性,你可以使用SetWindowRgn(参见pinvoke.net)。在NativeWindow类的帮助下,完全托管代码可能会做到这一点,但它可能比它值得的工作更多。 – 2009-09-12 09:37:16

+0

我尝试了SetWindowRgn方法并使其工作。最大的问题是该地区不平滑,所以工具提示有不愉快的锯齿边缘。从我读到的其他地方看,平滑一个地区可能是不可能的。 – 2009-09-24 15:07:00

1

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

其余的小故障是背景可能是错误的,而工具提示淡出。例如,如果您的鼠标悬停时有一个按钮被着色,那么当您将鼠标移开时,该工具提示仍将具有该彩色背景。将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; 
    } 
相关问题