0

I have custom progress bar (is a progress bar with text)

Custom progressbar code:

public enum ProgressBarDisplayText
    {
        Percentage,
        CustomText
    }

    public class CustomProgressBar : ProgressBar
    {


        [DllImportAttribute("uxtheme.dll")]
        private static extern int SetWindowTheme(IntPtr hWnd, string appname, string idlist);

        protected override void OnHandleCreated(EventArgs e)
        {
            SetWindowTheme(this.Handle, "", "");
            base.OnHandleCreated(e);
        }

        //Property to set to decide whether to print a % or Text
        public ProgressBarDisplayText DisplayStyle { get; set; }

        //Property to hold the custom text
        public String CustomText { get; set; }

        public CustomProgressBar()
        {
            // Modify the ControlStyles flags
            //http://msdn.microsoft.com/en-us/library/system.windows.forms.controlstyles.aspx
            SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            Rectangle rect = ClientRectangle;
            Graphics g = e.Graphics;

            ProgressBarRenderer.DrawHorizontalBar(g, rect);
            rect.Inflate(-3, -3);
            if (Value > 0)
            {
                // As we doing this ourselves we need to draw the chunks on the progress bar
                Rectangle clip = new Rectangle(rect.X, rect.Y, (int)Math.Round(((float)Value / Maximum) * rect.Width), rect.Height);
                ProgressBarRenderer.DrawHorizontalChunks(g, clip);
            }

            // Set the Display text (Either a % amount or our custom text
            int percent = (int)(((double)this.Value / (double)this.Maximum) * 100);
            string text = DisplayStyle == ProgressBarDisplayText.Percentage ? percent.ToString() + '%' : CustomText;

            //string text = DisplayStyle == ProgressBarDisplayText.Percentage ? Value.ToString() + '%' : CustomText;


            using (Font f = new Font(FontFamily.GenericSerif, 10, FontStyle.Bold))
            {

                SizeF len = g.MeasureString(text, f);
                // Calculate the location of the text (the middle of progress bar)
                // Point location = new Point(Convert.ToInt32((rect.Width / 2) - (len.Width / 2)), Convert.ToInt32((rect.Height / 2) - (len.Height / 2)));
                Point location = new Point(Convert.ToInt32((Width / 2) - len.Width / 2), Convert.ToInt32((Height / 2) - len.Height / 2));
                // The commented-out code will centre the text into the highlighted area only. This will centre the text regardless of the highlighted area.
                // Draw the custom text
                g.DrawString(text, f, Brushes.Black, location);
            }

        }
    }

Now I want to change color of progress bar so I saw this solution

So I try to add to my code

  [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
  static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr w, IntPtr l);
    public static void SetState(this ProgressBar pBar, int state)
    {
        SendMessage(pBar.Handle, 1040, (IntPtr)state, IntPtr.Zero);
    }

But as you can see this code is for an extension method, but my current CustomProgressBar inherits ProgressBar and it does not permit to use static classes. So it throw me:

Extension method must be defined in a non-generic static class

how can I add this method to my current class? Regards

Jesus
  • 79
  • 2
  • 9
  • Extension methods must be defined in a `static` class. Normally I just create a `public static class Extensions { }` and add them there. If you want to add them to your current class, you can just remove `this` from the first argument and then pass in an instance of your control. – Rufus L Aug 18 '20 at 22:07

1 Answers1

1

That's an extension method and those need to go in a static class. If you want to just make it work in your existing non-static class, just get rid of the this on the first parameter:

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr w, IntPtr l);

public static void SetState(ProgressBar pBar, int state)
{
    SendMessage(pBar.Handle, 1040, (IntPtr)state, IntPtr.Zero);
}

The parameter can still be of type ProgressBar since CustomProgressBar inherits from it.

itsme86
  • 19,266
  • 4
  • 41
  • 57
  • I copy paste your code and it works but I don't understand why? What do you mean when you say get rid of `this`, I see your code same as mine, what is the difference? – Jesus Aug 18 '20 at 22:53
  • Yours has `this ProgressBar pBar` and mine just has `ProgressBar pBar`. – itsme86 Aug 18 '20 at 23:08