2009-09-04 62 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; 
    } 
相關問題