2016-12-03 72 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

不客氣:) –