2016-12-03 74 views
6

bağlı aşağıdaki ikisi gibi bir ProgressBar kontrole sahip. Gördüğünüz gibi, ikincisinin sadece bir tane 0 var, iki tane olması gerekiyor ama diğeri görülemiyor çünkü ProgressBar'ın ForeColor'u TextColor ile aynı. Aşağıdaki resimde ProgressBar Kireç içinde boyandığında ve arka plan siyahken kireçteki metni boyadığında metni siyah olarak boyamanın bir yolu var mı?ters çevir Metin Rengi BackColor

+0

Bu ilerleme çubuğu nedir? Yerleşik mi yoksa bazı özel veya üçüncü taraf kontrolü kullanıyor musunuz? – vendettamit

+0

@vendettamit Üzgünüz, belirtmeyi unuttuysanız, https://www.codeproject.com/tips/645899/csharp-alternative-progressbar kullanıyorum –

+1

Metin bir parçaysa, bitmap kullanmazsanız mümkün olmaz ve pikselleri değiştir. Eğer iki bölüm halinde bölebilirseniz, bölmenin karakterleri bölmek için gerekip gerekmediğine karar vermeniz gerekecektir. Hiçbir şekilde tam olarak kolay değil. Oh ama eski xor-ing çekme modları için .. Gördüğüm tek ucuz ve kolay bir çözüm, renk üzerinde uzlaşma ve bar ve metin için aynı (parlaklık) seçim değil .. – TaW

cevap

11

Önce arka plan ve metin çizebilir, sonra arka plan çizim ile ön plan çizim birleştirmek PATINVERT parametresi PatBlt yöntemi kullanarak ön plan kireç dikdörtgen çizin:

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); 
} 

Not: Kontroller sadece boya mantığını göstermek içindir. Gerçek bir dünya uygulaması için, Minimum, Maximum ve Value özelliklerinde bazı doğrulama eklemeniz gerekir.

+2

Nice one! Eski günlerdeki gibi hissediyor .. – TaW

+0

Tam olarak ihtiyacım olan şey bu! Teşekkür ederim! –

+0

Rica ederim :) –