1

Draw イベントに応答して、WinForms ToolTip コントロールの外観をカスタマイズしています。ツールチップの角の一部を丸くしたいだけです。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 への呼び出しを追加しようとしましたが、実際には透明ではなく、フォームの背景の濃い灰色で領域を埋めただけでした。これは、典型的な「シミュレートされた」透明度だと思いますWinフォーム。

補足として、IsBalloon が true に設定されたカスタマイズされていない ToolTip は、正しい透明度を持つ長方形ではありません。

誰でもこの問題の修正を提案できますか?

4

2 に答える 2

1

これが解決策ですが、不完全です。Graphics.CopyFromScreenを使用して、ツールチップの下の領域を背景にコピーします。もちろん、ツールチップの場所を取得するのは簡単ではありません。したがって、リフレクションとPInvokeはGetWindowRectを呼び出します。

残りの不具合は、ツールチップがフェードアウトしているときに背景が間違っている可能性があることです。たとえば、マウスを上に置いたときに色付きのボタンがある場合、マウスをオフにしたときにツールチップの背景が色付きのままになります。ToolTip.UseFadingをfalseに設定すると、背景ペイントの頻度が変更され、フェードの問題よりも悪くなるようです。ユーザーがOSレベルでアイキャンディーを無効にした場合、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;
    }
于 2009-09-24T15:04:33.737 に答える
1

Control.Regionはあなたが探しているものです。背景が適切に再描画されるように、ウィンドウ マネージャーにツールチップの形状を伝える必要があります。

于 2009-09-05T09:17:55.577 に答える