2016-12-03 71 views
6

我有一个ProgressBar控制,如以下两个:反转文本颜色取决于背景色

enter image description here

首先是正确画。正如你所看到的,第二个只有一个0,它应该有两个,但另一个不能被看到,因为ProgressBar的ForeColorTextColor相同。有什么方法可以将下面的ProgressBar画在石灰上,并在背景是黑色时将石灰画在石灰上,这样我可以将文本涂成黑色?

+0

哪个进度条吧?它是内置的还是您正在使用一些自定义或第三方控件? – vendettamit

+0

@vendettamit对不起,忘了指定,我正在使用https://www.codeproject.com/tips/645899/csharp-alternative-progressbar –

+1

如果文本是一个部分,它是不可能的,除非你会使用位图并切换像素。如果你可以把它分成两部分,你需要确定分割是否需要分割字符。在任何方面都不太容易。哦,但对于旧的xor-ing绘制模式..我看到的唯一便宜且容易的解决方案是在颜色上妥协并且不为条和文本选择相同(亮度)。 – TaW

回答

11

你可以先绘制背景和文本,然后绘制使用PatBlt方法的前景石灰矩形PATINVERT参数前景绘制背景绘画相结合:

enter image description here

enter image description here

using System; 
using System.Drawing; 
using System.Runtime.InteropServices; 
using System.Windows.Forms; 
public class MyProgressBar : Control 
{ 
    public MyProgressBar() 
    { 
     DoubleBuffered = true; 
     Minimum = 0; Maximum = 100; Value = 50; 
    } 
    public int Minimum { get; set; } 
    public int Maximum { get; set; } 
    public int Value { get; set; } 
    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 
     Draw(e.Graphics); 
    } 
    private void Draw(Graphics g) 
    { 
     var r = this.ClientRectangle; 
     using (var b = new SolidBrush(this.BackColor)) 
      g.FillRectangle(b, r); 
     TextRenderer.DrawText(g, this.Value.ToString(), this.Font, r, this.ForeColor); 
     var hdc = g.GetHdc(); 
     var c = this.ForeColor; 
     var hbrush = CreateSolidBrush(((c.R | (c.G << 8)) | (c.B << 16))); 
     var phbrush = SelectObject(hdc, hbrush); 
     PatBlt(hdc, r.Left, r.Y, (Value * r.Width/Maximum), r.Height, PATINVERT); 
     SelectObject(hdc, phbrush); 
     DeleteObject(hbrush); 
     g.ReleaseHdc(hdc); 
    } 
    public const int PATINVERT = 0x005A0049; 
    [DllImport("gdi32.dll")] 
    public static extern bool PatBlt(IntPtr hdc, int nXLeft, int nYLeft, 
     int nWidth, int nHeight, int dwRop); 
    [DllImport("gdi32.dll")] 
    public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj); 
    [DllImport("gdi32.dll", EntryPoint = "DeleteObject")] 
    public static extern bool DeleteObject(IntPtr hObject); 
    [DllImport("gdi32.dll")] 
    public static extern IntPtr CreateSolidBrush(int crColor); 
} 

注意:这些控件仅用于演示绘画逻辑。对于真实世界的应用程序,您需要在MinimumMaximumValue属性上添加一些验证。

+2

好的一个!感觉就像过去一样.. – TaW

+0

这正是我需要的!谢谢! –

+0

不客气:) –