Допустимое использование побитовых операторов для CreateParams, нежелательное поведение? - PullRequest
0 голосов
/ 11 сентября 2010

Я пишу оболочку для элемента управления ProgressBar (на самом деле не настоящая оболочка, но правильно реализующая функции Vista). А вот и мой код:

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

Дело в том, что когда вы отбрасываете элемент управления в форме, он начинается как вертикальный, с PBS_SMOOTH. Поэтому мой вопрос заключается в том, какую дополнительную проверку я должен выполнить перед использованием побитовых операций для установки значений в CreateParams.Style, или мои побитовые операции (или мой код на самом деле) даже правильны?

Обновление благодаря Джону Скиту Был в состоянии получить это полностью исправленным и работающим, и с примененным UpdateStyles (), чтобы заставить новые стили применять () по требованию в свойствах, элемент управления теперь работает как ожидалось и отполирован:)

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

1 Ответ

4 голосов
/ 11 сентября 2010

Операции | правильные (хотя я бы использовал |=), ^ - нет.

Это:

cp.Style = cp.Style ^ PBS_SMOOTHREVERSE;

просто инвертирует всебыл уже там.Вы хотите:

cp.Style &= ~PBS_SMOOTHREVERSE;

Это говорит: "замаскируйте значение маской, в которой установлены все биты , за исключением PBS_SMOOTHREVERSE".

...