views:

24

answers:

1

I am writing a wrapper for the ProgressBar control (not really a true wrapper, but implementing Vista features properly). And here is my code:

    /// <summary>
    /// Encapsulates the information needed when creating a control
    /// </summary>
    protected override CreateParams CreateParams {
        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
        get {
            CreateParams cp = base.CreateParams;
            if (SmoothReverse) {
                // Add using bitwise OR
                cp.Style = cp.Style | PBS_SMOOTHREVERSE;
            }
            else {
                // Remove using bitwise XOR
                cp.Style = cp.Style ^ PBS_SMOOTHREVERSE;
            }
            if (Vertical) {
                // Add using bitwise OR
                cp.Style = cp.Style | PBS_VERTICAL;
            }
            else {
                // Remove using bitwise XOR
                cp.Style = cp.Style ^ PBS_VERTICAL;
            }
            return cp;
        }
    }

    private bool m_SmoothReverse = false;
    /// <summary>
    /// Gets or sets a System.Boolean value indicating whether the SmoothReverse style is used
    /// </summary>
    [Category("Behavior")]
    [DefaultValue(false)]
    [Description("Gets or sets a System.Boolean value indicating whether the SmoothReverse style is used")]
    public bool SmoothReverse {
        get {
            return m_SmoothReverse;
        }
        set {
            m_SmoothReverse = value;
        }
    }

    private bool m_Vertical = false;
    /// <summary>
    /// Gets or sets a System.Boolean value indicating whether the progress bar will be rendered vertically
    /// </summary>
    [Category("Behavior")]
    [DefaultValue(false)]
    [Description("Gets or sets a System.Boolean value indicating whether the progress bar will be rendered vertically")]
    public bool Vertical {
        get {
            return m_Vertical;
        }
        set {
            m_Vertical = value;
        }
    }

The thing is though, when you drop the control on a form it starts out as Vertical, with PBS_SMOOTH. So my question is, what additional checking should I be doing before using bitwise operations to set values on CreateParams.Style, or are my bitwise operations (or my code as a matter of fact) even correct?

Update Thanks to Jon Skeet Was able to get this fully fixed and working, and with applied UpdateStyles() to force the new styles to apply() on demand in the properties, the control now works as expected and is polished :)

    /// <summary>
    /// Encapsulates the information needed when creating a control
    /// </summary>
    protected override CreateParams CreateParams {
        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
        get {
            CreateParams cp = base.CreateParams;
            if (SmoothReverse) {
                cp.Style |= PBS_SMOOTHREVERSE;
            }
            else {
                cp.Style &= ~PBS_SMOOTHREVERSE;
            }
            if (Vertical) {
                cp.Style |= PBS_VERTICAL;
            }
            else {
                cp.Style &= ~PBS_VERTICAL;
            }
            return cp;
        }
    }

    private bool m_SmoothReverse = false;
    /// <summary>
    /// Gets or sets a System.Boolean value indicating whether the SmoothReverse style is used
    /// </summary>
    [Category("Behavior")]
    [DefaultValue(false)]
    [Description("Gets or sets a System.Boolean value indicating whether the SmoothReverse style is used")]
    public bool SmoothReverse {
        get {
            return m_SmoothReverse;
        }
        set {
            m_SmoothReverse = value;
            UpdateStyles();
        }
    }

    private bool m_Vertical = false;
    /// <summary>
    /// Gets or sets a System.Boolean value indicating whether the progress bar will be rendered vertically
    /// </summary>
    [Category("Behavior")]
    [DefaultValue(false)]
    [Description("Gets or sets a System.Boolean value indicating whether the progress bar will be rendered vertically")]
    public bool Vertical {
        get {
            return m_Vertical;
        }
        set {
            m_Vertical = value;
            UpdateStyles();
        }
    }
+2  A: 

The | operations are correct (although I'd use |=) , the ^ isn't.

This:

cp.Style = cp.Style ^ PBS_SMOOTHREVERSE;

will just invert whatever was already there. You want:

cp.Style &= ~PBS_SMOOTHREVERSE;

This is saying, "mask the value with a mask which has all the bits set except PBS_SMOOTHREVERSE".

Jon Skeet
@David: Urgh - I hadn't seen it was an existing property. That's horrible - but not your fault :) Will edit out that bit.
Jon Skeet
Bad skeet! Kidding, everyone makes bloopers; no sweat! :)
David Anderson