Допустимое использование побитовых операторов для CreateParams, нежелательное поведение?
Я пишу оболочку для элемента управления 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 ответ
|
операции правильные (хотя я бы использовал |=
), ^
нет.
Это:
cp.Style = cp.Style ^ PBS_SMOOTHREVERSE;
будет просто инвертировать все, что уже было там. Ты хочешь:
cp.Style &= ~PBS_SMOOTHREVERSE;
Это говорит: "замаскируйте значение маской, в которой установлены все биты, кроме PBS_SMOOTHREVERSE".