对 CreateParams 有效使用按位运算符,是不良行为吗?

发布于 2024-09-19 03:01:28 字数 4092 浏览 5 评论 0原文

我正在为 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 上设置值之前,我应该做哪些额外的检查,或者我的按位运算(或事实上我的代码)是否正确?

感谢 Jon Skeet 的更新 能够完全修复此问题并正常工作,并通过应用 UpdateStyles() 来强制新样式根据属性中的需要 apply(),该控件现在按预期工作并经过改进:)

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一抹苦笑 2024-09-26 03:01:28

| 操作是正确的(尽管我会使用 |=),而 ^ 则不然。

这:

cp.Style = cp.Style ^ PBS_SMOOTHREVERSE;

只会反转已经存在的内容。你想要的:

cp.Style &= ~PBS_SMOOTHREVERSE;

这就是说,“用一个掩码来掩码该值,该掩码设置了除了 PBS_SMOOTHREVERSE 之外的所有位”。

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".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文