Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / WinForms / Managed / System / WinForms / ToolBarButton.cs / 1305376 / ToolBarButton.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
/*
*/
namespace System.Windows.Forms {
using System.Runtime.Serialization.Formatters;
using System.Runtime.InteropServices;
using System.Runtime.Remoting;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics;
using System;
using System.Drawing;
using System.Text;
using System.Drawing.Design;
using Marshal = System.Runtime.InteropServices.Marshal;
using System.Windows.Forms;
using Microsoft.Win32;
using System.Globalization;
///
///
///
/// Represents a Windows toolbar button.
///
[
Designer("System.Windows.Forms.Design.ToolBarButtonDesigner, " + AssemblyRef.SystemDesign),
DefaultProperty("Text"),
ToolboxItem(false),
DesignTimeVisible(false),
]
public class ToolBarButton : Component {
string text;
string name = null;
string tooltipText;
bool enabled = true;
bool visible = true;
bool pushed = false;
bool partialPush = false;
private int commandId = -1; // the cached command id of the button.
private ToolBarButtonImageIndexer imageIndexer;
ToolBarButtonStyle style = ToolBarButtonStyle.PushButton;
object userData;
// These variables below are used by the ToolBar control to help
// it manage some information about us.
///
///
/// If this button has a string, what it's index is in the ToolBar's
/// internal list of strings. Needs to be package protected.
///
///
internal IntPtr stringIndex = (IntPtr)(-1);
///
///
/// Our parent ToolBar control.
///
///
internal ToolBar parent;
///
///
/// For DropDown buttons, we can optionally show a
/// context menu when the button is dropped down.
///
internal Menu dropDownMenu = null;
///
///
/// Initializes a new instance of the class.
///
public ToolBarButton() {
}
///
///
/// [To be supplied.]
///
public ToolBarButton(string text) : base() {
this.Text = text;
}
// We need a special way to defer to the ToolBar's image
// list for indexing purposes.
internal class ToolBarButtonImageIndexer : ImageList.Indexer {
private ToolBarButton owner;
public ToolBarButtonImageIndexer(ToolBarButton button) {
owner = button;
}
public override ImageList ImageList {
get {
if ((owner != null) && (owner.parent != null)) {
return owner.parent.ImageList;
}
return null;
}
set { Debug.Assert(false, "We should never set the image list"); }
}
}
internal ToolBarButtonImageIndexer ImageIndexer {
get {
if (imageIndexer == null) {
imageIndexer = new ToolBarButtonImageIndexer(this);
}
return imageIndexer;
}
}
///
///
///
/// Indicates the menu to be displayed in
/// the drop-down toolbar button.
///
[
DefaultValue(null),
TypeConverterAttribute(typeof(ReferenceConverter)),
SRDescription(SR.ToolBarButtonMenuDescr)
]
public Menu DropDownMenu {
get {
return dropDownMenu;
}
set {
//The dropdownmenu must be of type ContextMenu, Main & Items are invalid.
//
if (value != null && !(value is ContextMenu)) {
throw new ArgumentException(SR.GetString(SR.ToolBarButtonInvalidDropDownMenuType));
}
dropDownMenu = value;
}
}
///
///
/// Indicates whether the button is enabled or not.
///
[
DefaultValue(true),
Localizable(true),
SRDescription(SR.ToolBarButtonEnabledDescr)
]
public bool Enabled {
get {
return enabled;
}
set {
if (enabled != value) {
enabled = value;
if (parent != null && parent.IsHandleCreated) {
parent.SendMessage(NativeMethods.TB_ENABLEBUTTON, FindButtonIndex(),
enabled ? 1 : 0);
}
}
}
}
///
///
/// Indicates the index
/// value of the image assigned to the button.
///
[
TypeConverterAttribute(typeof(ImageIndexConverter)),
Editor("System.Windows.Forms.Design.ImageIndexEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
DefaultValue(-1),
RefreshProperties(RefreshProperties.Repaint),
Localizable(true),
SRDescription(SR.ToolBarButtonImageIndexDescr)
]
public int ImageIndex {
get {
return ImageIndexer.Index;
}
set {
if (ImageIndexer.Index != value) {
if (value < -1)
throw new ArgumentOutOfRangeException("ImageIndex", SR.GetString(SR.InvalidLowBoundArgumentEx, "ImageIndex", (value).ToString(CultureInfo.CurrentCulture), -1));
ImageIndexer.Index = value;
UpdateButton(false);
}
}
}
///
///
/// Indicates the index
/// value of the image assigned to the button.
///
[
TypeConverterAttribute(typeof(ImageKeyConverter)),
Editor("System.Windows.Forms.Design.ImageIndexEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
DefaultValue(""),
Localizable(true),
RefreshProperties(RefreshProperties.Repaint),
SRDescription(SR.ToolBarButtonImageIndexDescr)
]
public string ImageKey {
get {
return ImageIndexer.Key;
}
set {
if (ImageIndexer.Key != value) {
ImageIndexer.Key = value;
UpdateButton(false);
}
}
}
///
///
/// Name of this control. The designer will set this to the same
/// as the programatic Id "(name)" of the control - however this
/// property has no bearing on the runtime aspects of this control.
///
[Browsable(false)]
public string Name {
get {
return WindowsFormsUtils.GetComponentName(this, name);
}
set {
if (value == null || value.Length == 0) {
name = null;
}
else {
name = value;
}
if(Site!= null) {
Site.Name = name;
}
}
}
///
///
/// Indicates the toolbar control that the toolbar button is assigned to. This property is
/// read-only.
///
[
Browsable(false),
]
public ToolBar Parent {
get {
return parent;
}
}
///
///
///
/// Indicates whether a toggle-style toolbar button
/// is partially pushed.
///
[
DefaultValue(false),
SRDescription(SR.ToolBarButtonPartialPushDescr)
]
public bool PartialPush {
get {
if (parent == null || !parent.IsHandleCreated)
return partialPush;
else {
if ((int)parent.SendMessage(NativeMethods.TB_ISBUTTONINDETERMINATE, FindButtonIndex(), 0) != 0)
partialPush = true;
else
partialPush = false;
return partialPush;
}
}
set {
if (partialPush != value) {
partialPush = value;
UpdateButton(false);
}
}
}
///
///
/// Indicates whether a toggle-style toolbar button is currently in the pushed state.
///
[
DefaultValue(false),
SRDescription(SR.ToolBarButtonPushedDescr)
]
public bool Pushed {
get {
if (parent == null || !parent.IsHandleCreated)
return pushed;
else {
return GetPushedState();
}
}
set {
if (value != Pushed) { // Getting property Pushed updates pushed member variable
pushed = value;
UpdateButton(false, false, false);
}
}
}
///
///
/// Indicates the bounding rectangle for a toolbar button. This property is
/// read-only.
///
public Rectangle Rectangle {
get {
if (parent != null) {
NativeMethods.RECT rc = new NativeMethods.RECT();
UnsafeNativeMethods.SendMessage(new HandleRef(parent, parent.Handle), NativeMethods.TB_GETRECT, FindButtonIndex(), ref rc);
return Rectangle.FromLTRB(rc.left, rc.top, rc.right, rc.bottom);
}
return Rectangle.Empty;
}
}
///
///
/// Indicates the style of the
/// toolbar button.
///
[
DefaultValue(ToolBarButtonStyle.PushButton),
SRDescription(SR.ToolBarButtonStyleDescr),
RefreshProperties(RefreshProperties.Repaint)
]
public ToolBarButtonStyle Style {
get {
return style;
}
set {
//valid values are 0x1 to 0x4
if (!ClientUtils.IsEnumValid(value, (int)value, (int)ToolBarButtonStyle.PushButton, (int)ToolBarButtonStyle.DropDownButton)){
throw new InvalidEnumArgumentException("value", (int)value, typeof(ToolBarButtonStyle));
}
if (style == value) return;
style = value;
UpdateButton(true);
}
}
///
[
SRCategory(SR.CatData),
Localizable(false),
Bindable(true),
SRDescription(SR.ControlTagDescr),
DefaultValue(null),
TypeConverter(typeof(StringConverter)),
]
public object Tag {
get {
return userData;
}
set {
userData = value;
}
}
///
///
/// Indicates the text that is displayed on the toolbar button.
///
[
Localizable(true),
DefaultValue(""),
SRDescription(SR.ToolBarButtonTextDescr)
]
public string Text {
get {
return(text == null) ? "" : text;
}
set {
if (String.IsNullOrEmpty(value)) {
value = null;
}
if ( (value == null && text != null) ||
(value != null && (text == null || !text.Equals(value)))) {
text = value;
// 94943 VSWhidbey Adding a mnemonic requires a handle recreate.
UpdateButton(WindowsFormsUtils.ContainsMnemonic(text), true, true);
}
}
}
///
///
///
/// Indicates
/// the text that appears as a tool tip for a control.
///
[
Localizable(true),
DefaultValue(""),
SRDescription(SR.ToolBarButtonToolTipTextDescr)
]
public string ToolTipText {
get {
return tooltipText == null ? "" : tooltipText;
}
set {
tooltipText = value;
}
}
///
///
///
/// Indicates whether the toolbar button
/// is visible.
///
[
DefaultValue(true),
Localizable(true),
SRDescription(SR.ToolBarButtonVisibleDescr)
]
public bool Visible {
get {
return visible;
}
set {
if (visible != value) {
visible = value;
UpdateButton(false);
}
}
}
///
///
/// This is somewhat nasty -- by default, the windows ToolBar isn't very
/// clever about setting the width of buttons, and has a very primitive
/// algorithm that doesn't include for things like drop down arrows, etc.
/// We need to do a bunch of work here to get all the widths correct. Ugh.
///
///
internal short Width {
get {
Debug.Assert(parent != null, "Parent should be non-null when button width is requested");
int width = 0;
ToolBarButtonStyle style = Style;
Size edge = SystemInformation.Border3DSize;
if (style != ToolBarButtonStyle.Separator) {
// COMPAT: this will force handle creation.
// we could use the measurement graphics, but it looks like this has been like this since Everett.
using (Graphics g = this.parent.CreateGraphicsInternal()) {
Size buttonSize = this.parent.buttonSize;
if (!(buttonSize.IsEmpty)) {
width = buttonSize.Width;
}
else {
if (this.parent.ImageList != null || !String.IsNullOrEmpty(Text)) {
Size imageSize = this.parent.ImageSize;
Size textSize = Size.Ceiling(g.MeasureString(Text, parent.Font));
if (this.parent.TextAlign == ToolBarTextAlign.Right) {
if (textSize.Width == 0)
width = imageSize.Width + edge.Width * 4;
else
width = imageSize.Width + textSize.Width + edge.Width * 6;
}
else {
if (imageSize.Width > textSize.Width)
width = imageSize.Width + edge.Width * 4;
else
width = textSize.Width + edge.Width * 4;
}
if (style == ToolBarButtonStyle.DropDownButton && this.parent.DropDownArrows) {
width += ToolBar.DDARROW_WIDTH;
}
}
else
width = this.parent.ButtonSize.Width;
}
}
}
else {
width = edge.Width * 2;
}
return(short)width;
}
}
///
///
///
///
protected override void Dispose(bool disposing) {
if (disposing) {
if (parent != null) {
int index = FindButtonIndex();
if (index != -1) {
parent.Buttons.RemoveAt(index);
}
}
}
base.Dispose(disposing);
}
///
///
/// Finds out index in the parent.
///
///
private int FindButtonIndex() {
for (int x = 0; x < parent.Buttons.Count; x++) {
if (parent.Buttons[x] == this) {
return x;
}
}
return -1;
}
// VSWhidbey 177016: This is necessary to get the width of the buttons in the toolbar,
// including the width of separators, so that we can accurately position the tooltip adjacent
// to the currently hot button when the user uses keyboard navigation to access the toolbar.
internal int GetButtonWidth() {
// Assume that this button is the same width as the parent's ButtonSize's Width
int buttonWidth = Parent.ButtonSize.Width;
NativeMethods.TBBUTTONINFO button = new NativeMethods.TBBUTTONINFO();
button.cbSize = Marshal.SizeOf(typeof(NativeMethods.TBBUTTONINFO));
button.dwMask = NativeMethods.TBIF_SIZE;
int buttonID = (int)UnsafeNativeMethods.SendMessage(new HandleRef(Parent, Parent.Handle), NativeMethods.TB_GETBUTTONINFO, commandId, ref button);
if (buttonID != -1) {
buttonWidth = button.cx;
}
return buttonWidth;
}
private bool GetPushedState()
{
if ((int)parent.SendMessage(NativeMethods.TB_ISBUTTONCHECKED, FindButtonIndex(), 0) != 0) {
pushed = true;
}
else {
pushed = false;
}
return pushed;
}
///
///
/// Returns a TBBUTTON object that represents this ToolBarButton.
///
internal NativeMethods.TBBUTTON GetTBBUTTON(int commandId) {
NativeMethods.TBBUTTON button = new NativeMethods.TBBUTTON();
button.iBitmap = ImageIndexer.ActualIndex;
// set up the state of the button
//
button.fsState = 0;
if (enabled) button.fsState |= NativeMethods.TBSTATE_ENABLED;
if (partialPush && style == ToolBarButtonStyle.ToggleButton) button.fsState |= NativeMethods.TBSTATE_INDETERMINATE;
if (pushed) button.fsState |= NativeMethods.TBSTATE_CHECKED;
if (!visible) button.fsState |= NativeMethods.TBSTATE_HIDDEN;
// set the button style
//
switch (style) {
case ToolBarButtonStyle.PushButton:
button.fsStyle = NativeMethods.TBSTYLE_BUTTON;
break;
case ToolBarButtonStyle.ToggleButton:
button.fsStyle = NativeMethods.TBSTYLE_CHECK;
break;
case ToolBarButtonStyle.Separator:
button.fsStyle = NativeMethods.TBSTYLE_SEP;
break;
case ToolBarButtonStyle.DropDownButton:
button.fsStyle = NativeMethods.TBSTYLE_DROPDOWN;
break;
}
button.dwData = (IntPtr)0;
button.iString = this.stringIndex;
this.commandId = commandId;
button.idCommand = commandId;
return button;
}
///
///
/// Returns a TBBUTTONINFO object that represents this ToolBarButton.
///
internal NativeMethods.TBBUTTONINFO GetTBBUTTONINFO(bool updateText, int newCommandId) {
NativeMethods.TBBUTTONINFO button = new NativeMethods.TBBUTTONINFO();
button.cbSize = Marshal.SizeOf(typeof(NativeMethods.TBBUTTONINFO));
button.dwMask = NativeMethods.TBIF_IMAGE
| NativeMethods.TBIF_STATE | NativeMethods.TBIF_STYLE;
// Comctl on Win98 interprets null strings as empty strings, which forces
// the button to leave space for text. The only workaround is to avoid having comctl
// update the text.
if (updateText) {
button.dwMask |= NativeMethods.TBIF_TEXT;
}
button.iImage = ImageIndexer.ActualIndex;
if (newCommandId != commandId) {
commandId = newCommandId;
button.idCommand = newCommandId;
button.dwMask |= NativeMethods.TBIF_COMMAND;
}
// set up the state of the button
//
button.fsState = 0;
if (enabled) button.fsState |= NativeMethods.TBSTATE_ENABLED;
if (partialPush && style == ToolBarButtonStyle.ToggleButton) button.fsState |= NativeMethods.TBSTATE_INDETERMINATE;
if (pushed) button.fsState |= NativeMethods.TBSTATE_CHECKED;
if (!visible) button.fsState |= NativeMethods.TBSTATE_HIDDEN;
// set the button style
//
switch (style) {
case ToolBarButtonStyle.PushButton:
button.fsStyle = NativeMethods.TBSTYLE_BUTTON;
break;
case ToolBarButtonStyle.ToggleButton:
button.fsStyle = NativeMethods.TBSTYLE_CHECK;
break;
case ToolBarButtonStyle.Separator:
button.fsStyle = NativeMethods.TBSTYLE_SEP;
break;
}
if (text == null) {
button.pszText = Marshal.StringToHGlobalAuto("\0\0");
}
else {
string textValue = this.text;
PrefixAmpersands(ref textValue);
button.pszText = Marshal.StringToHGlobalAuto(textValue);
}
return button;
}
private void PrefixAmpersands(ref string value) {
// Due to a comctl32 problem, ampersands underline the next letter in the
// text string, but the accelerators don't work.
// So in this function, we prefix ampersands with another ampersand
// so that they actually appear as ampersands.
//
// Sanity check parameter
//
if (value == null || value.Length == 0) {
return;
}
// If there are no ampersands, we don't need to do anything here
//
if (value.IndexOf('&') < 0) {
return;
}
// Insert extra ampersands
//
StringBuilder newString = new StringBuilder();
for(int i=0; i < value.Length; ++i) {
if (value[i] == '&') {
if (i < value.Length - 1 && value[i+1] == '&') {
++i; // Skip the second ampersand
}
newString.Append("&&");
}
else {
newString.Append(value[i]);
}
}
value = newString.ToString();
}
///
///
///
///
public override string ToString() {
return "ToolBarButton: " + Text + ", Style: " + Style.ToString("G");
}
///
///
/// When a button property changes and the parent control is created,
/// we need to make sure it gets the new button information.
/// If Text was changed, call the next overload.
///
internal void UpdateButton(bool recreate) {
UpdateButton(recreate, false, true);
}
///
///
/// When a button property changes and the parent control is created,
/// we need to make sure it gets the new button information.
///
private void UpdateButton(bool recreate, bool updateText, bool updatePushedState) {
// It looks like ToolBarButtons with a DropDownButton tend to
// lose the DropDownButton very easily - so we need to recreate
// the button each time it changes just to be sure.
//
if (style == ToolBarButtonStyle.DropDownButton && parent != null && parent.DropDownArrows) {
recreate = true;
}
// we just need to get the Pushed state : this asks the Button its states and sets
// the private member "pushed" to right value..
// this member is used in "InternalSetButton" which calls GetTBBUTTONINFO(bool updateText)
// the GetButtonInfo method uses the "pushed" variable..
//rather than setting it ourselves .... we asks the button to set it for us..
if (updatePushedState && parent != null && parent.IsHandleCreated) {
GetPushedState();
}
if (parent != null) {
int index = FindButtonIndex();
if (index != -1)
parent.InternalSetButton(index, this, recreate, updateText);
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
/*
*/
namespace System.Windows.Forms {
using System.Runtime.Serialization.Formatters;
using System.Runtime.InteropServices;
using System.Runtime.Remoting;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics;
using System;
using System.Drawing;
using System.Text;
using System.Drawing.Design;
using Marshal = System.Runtime.InteropServices.Marshal;
using System.Windows.Forms;
using Microsoft.Win32;
using System.Globalization;
///
///
///
/// Represents a Windows toolbar button.
///
[
Designer("System.Windows.Forms.Design.ToolBarButtonDesigner, " + AssemblyRef.SystemDesign),
DefaultProperty("Text"),
ToolboxItem(false),
DesignTimeVisible(false),
]
public class ToolBarButton : Component {
string text;
string name = null;
string tooltipText;
bool enabled = true;
bool visible = true;
bool pushed = false;
bool partialPush = false;
private int commandId = -1; // the cached command id of the button.
private ToolBarButtonImageIndexer imageIndexer;
ToolBarButtonStyle style = ToolBarButtonStyle.PushButton;
object userData;
// These variables below are used by the ToolBar control to help
// it manage some information about us.
///
///
/// If this button has a string, what it's index is in the ToolBar's
/// internal list of strings. Needs to be package protected.
///
///
internal IntPtr stringIndex = (IntPtr)(-1);
///
///
/// Our parent ToolBar control.
///
///
internal ToolBar parent;
///
///
/// For DropDown buttons, we can optionally show a
/// context menu when the button is dropped down.
///
internal Menu dropDownMenu = null;
///
///
/// Initializes a new instance of the class.
///
public ToolBarButton() {
}
///
///
/// [To be supplied.]
///
public ToolBarButton(string text) : base() {
this.Text = text;
}
// We need a special way to defer to the ToolBar's image
// list for indexing purposes.
internal class ToolBarButtonImageIndexer : ImageList.Indexer {
private ToolBarButton owner;
public ToolBarButtonImageIndexer(ToolBarButton button) {
owner = button;
}
public override ImageList ImageList {
get {
if ((owner != null) && (owner.parent != null)) {
return owner.parent.ImageList;
}
return null;
}
set { Debug.Assert(false, "We should never set the image list"); }
}
}
internal ToolBarButtonImageIndexer ImageIndexer {
get {
if (imageIndexer == null) {
imageIndexer = new ToolBarButtonImageIndexer(this);
}
return imageIndexer;
}
}
///
///
///
/// Indicates the menu to be displayed in
/// the drop-down toolbar button.
///
[
DefaultValue(null),
TypeConverterAttribute(typeof(ReferenceConverter)),
SRDescription(SR.ToolBarButtonMenuDescr)
]
public Menu DropDownMenu {
get {
return dropDownMenu;
}
set {
//The dropdownmenu must be of type ContextMenu, Main & Items are invalid.
//
if (value != null && !(value is ContextMenu)) {
throw new ArgumentException(SR.GetString(SR.ToolBarButtonInvalidDropDownMenuType));
}
dropDownMenu = value;
}
}
///
///
/// Indicates whether the button is enabled or not.
///
[
DefaultValue(true),
Localizable(true),
SRDescription(SR.ToolBarButtonEnabledDescr)
]
public bool Enabled {
get {
return enabled;
}
set {
if (enabled != value) {
enabled = value;
if (parent != null && parent.IsHandleCreated) {
parent.SendMessage(NativeMethods.TB_ENABLEBUTTON, FindButtonIndex(),
enabled ? 1 : 0);
}
}
}
}
///
///
/// Indicates the index
/// value of the image assigned to the button.
///
[
TypeConverterAttribute(typeof(ImageIndexConverter)),
Editor("System.Windows.Forms.Design.ImageIndexEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
DefaultValue(-1),
RefreshProperties(RefreshProperties.Repaint),
Localizable(true),
SRDescription(SR.ToolBarButtonImageIndexDescr)
]
public int ImageIndex {
get {
return ImageIndexer.Index;
}
set {
if (ImageIndexer.Index != value) {
if (value < -1)
throw new ArgumentOutOfRangeException("ImageIndex", SR.GetString(SR.InvalidLowBoundArgumentEx, "ImageIndex", (value).ToString(CultureInfo.CurrentCulture), -1));
ImageIndexer.Index = value;
UpdateButton(false);
}
}
}
///
///
/// Indicates the index
/// value of the image assigned to the button.
///
[
TypeConverterAttribute(typeof(ImageKeyConverter)),
Editor("System.Windows.Forms.Design.ImageIndexEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
DefaultValue(""),
Localizable(true),
RefreshProperties(RefreshProperties.Repaint),
SRDescription(SR.ToolBarButtonImageIndexDescr)
]
public string ImageKey {
get {
return ImageIndexer.Key;
}
set {
if (ImageIndexer.Key != value) {
ImageIndexer.Key = value;
UpdateButton(false);
}
}
}
///
///
/// Name of this control. The designer will set this to the same
/// as the programatic Id "(name)" of the control - however this
/// property has no bearing on the runtime aspects of this control.
///
[Browsable(false)]
public string Name {
get {
return WindowsFormsUtils.GetComponentName(this, name);
}
set {
if (value == null || value.Length == 0) {
name = null;
}
else {
name = value;
}
if(Site!= null) {
Site.Name = name;
}
}
}
///
///
/// Indicates the toolbar control that the toolbar button is assigned to. This property is
/// read-only.
///
[
Browsable(false),
]
public ToolBar Parent {
get {
return parent;
}
}
///
///
///
/// Indicates whether a toggle-style toolbar button
/// is partially pushed.
///
[
DefaultValue(false),
SRDescription(SR.ToolBarButtonPartialPushDescr)
]
public bool PartialPush {
get {
if (parent == null || !parent.IsHandleCreated)
return partialPush;
else {
if ((int)parent.SendMessage(NativeMethods.TB_ISBUTTONINDETERMINATE, FindButtonIndex(), 0) != 0)
partialPush = true;
else
partialPush = false;
return partialPush;
}
}
set {
if (partialPush != value) {
partialPush = value;
UpdateButton(false);
}
}
}
///
///
/// Indicates whether a toggle-style toolbar button is currently in the pushed state.
///
[
DefaultValue(false),
SRDescription(SR.ToolBarButtonPushedDescr)
]
public bool Pushed {
get {
if (parent == null || !parent.IsHandleCreated)
return pushed;
else {
return GetPushedState();
}
}
set {
if (value != Pushed) { // Getting property Pushed updates pushed member variable
pushed = value;
UpdateButton(false, false, false);
}
}
}
///
///
/// Indicates the bounding rectangle for a toolbar button. This property is
/// read-only.
///
public Rectangle Rectangle {
get {
if (parent != null) {
NativeMethods.RECT rc = new NativeMethods.RECT();
UnsafeNativeMethods.SendMessage(new HandleRef(parent, parent.Handle), NativeMethods.TB_GETRECT, FindButtonIndex(), ref rc);
return Rectangle.FromLTRB(rc.left, rc.top, rc.right, rc.bottom);
}
return Rectangle.Empty;
}
}
///
///
/// Indicates the style of the
/// toolbar button.
///
[
DefaultValue(ToolBarButtonStyle.PushButton),
SRDescription(SR.ToolBarButtonStyleDescr),
RefreshProperties(RefreshProperties.Repaint)
]
public ToolBarButtonStyle Style {
get {
return style;
}
set {
//valid values are 0x1 to 0x4
if (!ClientUtils.IsEnumValid(value, (int)value, (int)ToolBarButtonStyle.PushButton, (int)ToolBarButtonStyle.DropDownButton)){
throw new InvalidEnumArgumentException("value", (int)value, typeof(ToolBarButtonStyle));
}
if (style == value) return;
style = value;
UpdateButton(true);
}
}
///
[
SRCategory(SR.CatData),
Localizable(false),
Bindable(true),
SRDescription(SR.ControlTagDescr),
DefaultValue(null),
TypeConverter(typeof(StringConverter)),
]
public object Tag {
get {
return userData;
}
set {
userData = value;
}
}
///
///
/// Indicates the text that is displayed on the toolbar button.
///
[
Localizable(true),
DefaultValue(""),
SRDescription(SR.ToolBarButtonTextDescr)
]
public string Text {
get {
return(text == null) ? "" : text;
}
set {
if (String.IsNullOrEmpty(value)) {
value = null;
}
if ( (value == null && text != null) ||
(value != null && (text == null || !text.Equals(value)))) {
text = value;
// 94943 VSWhidbey Adding a mnemonic requires a handle recreate.
UpdateButton(WindowsFormsUtils.ContainsMnemonic(text), true, true);
}
}
}
///
///
///
/// Indicates
/// the text that appears as a tool tip for a control.
///
[
Localizable(true),
DefaultValue(""),
SRDescription(SR.ToolBarButtonToolTipTextDescr)
]
public string ToolTipText {
get {
return tooltipText == null ? "" : tooltipText;
}
set {
tooltipText = value;
}
}
///
///
///
/// Indicates whether the toolbar button
/// is visible.
///
[
DefaultValue(true),
Localizable(true),
SRDescription(SR.ToolBarButtonVisibleDescr)
]
public bool Visible {
get {
return visible;
}
set {
if (visible != value) {
visible = value;
UpdateButton(false);
}
}
}
///
///
/// This is somewhat nasty -- by default, the windows ToolBar isn't very
/// clever about setting the width of buttons, and has a very primitive
/// algorithm that doesn't include for things like drop down arrows, etc.
/// We need to do a bunch of work here to get all the widths correct. Ugh.
///
///
internal short Width {
get {
Debug.Assert(parent != null, "Parent should be non-null when button width is requested");
int width = 0;
ToolBarButtonStyle style = Style;
Size edge = SystemInformation.Border3DSize;
if (style != ToolBarButtonStyle.Separator) {
// COMPAT: this will force handle creation.
// we could use the measurement graphics, but it looks like this has been like this since Everett.
using (Graphics g = this.parent.CreateGraphicsInternal()) {
Size buttonSize = this.parent.buttonSize;
if (!(buttonSize.IsEmpty)) {
width = buttonSize.Width;
}
else {
if (this.parent.ImageList != null || !String.IsNullOrEmpty(Text)) {
Size imageSize = this.parent.ImageSize;
Size textSize = Size.Ceiling(g.MeasureString(Text, parent.Font));
if (this.parent.TextAlign == ToolBarTextAlign.Right) {
if (textSize.Width == 0)
width = imageSize.Width + edge.Width * 4;
else
width = imageSize.Width + textSize.Width + edge.Width * 6;
}
else {
if (imageSize.Width > textSize.Width)
width = imageSize.Width + edge.Width * 4;
else
width = textSize.Width + edge.Width * 4;
}
if (style == ToolBarButtonStyle.DropDownButton && this.parent.DropDownArrows) {
width += ToolBar.DDARROW_WIDTH;
}
}
else
width = this.parent.ButtonSize.Width;
}
}
}
else {
width = edge.Width * 2;
}
return(short)width;
}
}
///
///
///
///
protected override void Dispose(bool disposing) {
if (disposing) {
if (parent != null) {
int index = FindButtonIndex();
if (index != -1) {
parent.Buttons.RemoveAt(index);
}
}
}
base.Dispose(disposing);
}
///
///
/// Finds out index in the parent.
///
///
private int FindButtonIndex() {
for (int x = 0; x < parent.Buttons.Count; x++) {
if (parent.Buttons[x] == this) {
return x;
}
}
return -1;
}
// VSWhidbey 177016: This is necessary to get the width of the buttons in the toolbar,
// including the width of separators, so that we can accurately position the tooltip adjacent
// to the currently hot button when the user uses keyboard navigation to access the toolbar.
internal int GetButtonWidth() {
// Assume that this button is the same width as the parent's ButtonSize's Width
int buttonWidth = Parent.ButtonSize.Width;
NativeMethods.TBBUTTONINFO button = new NativeMethods.TBBUTTONINFO();
button.cbSize = Marshal.SizeOf(typeof(NativeMethods.TBBUTTONINFO));
button.dwMask = NativeMethods.TBIF_SIZE;
int buttonID = (int)UnsafeNativeMethods.SendMessage(new HandleRef(Parent, Parent.Handle), NativeMethods.TB_GETBUTTONINFO, commandId, ref button);
if (buttonID != -1) {
buttonWidth = button.cx;
}
return buttonWidth;
}
private bool GetPushedState()
{
if ((int)parent.SendMessage(NativeMethods.TB_ISBUTTONCHECKED, FindButtonIndex(), 0) != 0) {
pushed = true;
}
else {
pushed = false;
}
return pushed;
}
///
///
/// Returns a TBBUTTON object that represents this ToolBarButton.
///
internal NativeMethods.TBBUTTON GetTBBUTTON(int commandId) {
NativeMethods.TBBUTTON button = new NativeMethods.TBBUTTON();
button.iBitmap = ImageIndexer.ActualIndex;
// set up the state of the button
//
button.fsState = 0;
if (enabled) button.fsState |= NativeMethods.TBSTATE_ENABLED;
if (partialPush && style == ToolBarButtonStyle.ToggleButton) button.fsState |= NativeMethods.TBSTATE_INDETERMINATE;
if (pushed) button.fsState |= NativeMethods.TBSTATE_CHECKED;
if (!visible) button.fsState |= NativeMethods.TBSTATE_HIDDEN;
// set the button style
//
switch (style) {
case ToolBarButtonStyle.PushButton:
button.fsStyle = NativeMethods.TBSTYLE_BUTTON;
break;
case ToolBarButtonStyle.ToggleButton:
button.fsStyle = NativeMethods.TBSTYLE_CHECK;
break;
case ToolBarButtonStyle.Separator:
button.fsStyle = NativeMethods.TBSTYLE_SEP;
break;
case ToolBarButtonStyle.DropDownButton:
button.fsStyle = NativeMethods.TBSTYLE_DROPDOWN;
break;
}
button.dwData = (IntPtr)0;
button.iString = this.stringIndex;
this.commandId = commandId;
button.idCommand = commandId;
return button;
}
///
///
/// Returns a TBBUTTONINFO object that represents this ToolBarButton.
///
internal NativeMethods.TBBUTTONINFO GetTBBUTTONINFO(bool updateText, int newCommandId) {
NativeMethods.TBBUTTONINFO button = new NativeMethods.TBBUTTONINFO();
button.cbSize = Marshal.SizeOf(typeof(NativeMethods.TBBUTTONINFO));
button.dwMask = NativeMethods.TBIF_IMAGE
| NativeMethods.TBIF_STATE | NativeMethods.TBIF_STYLE;
// Comctl on Win98 interprets null strings as empty strings, which forces
// the button to leave space for text. The only workaround is to avoid having comctl
// update the text.
if (updateText) {
button.dwMask |= NativeMethods.TBIF_TEXT;
}
button.iImage = ImageIndexer.ActualIndex;
if (newCommandId != commandId) {
commandId = newCommandId;
button.idCommand = newCommandId;
button.dwMask |= NativeMethods.TBIF_COMMAND;
}
// set up the state of the button
//
button.fsState = 0;
if (enabled) button.fsState |= NativeMethods.TBSTATE_ENABLED;
if (partialPush && style == ToolBarButtonStyle.ToggleButton) button.fsState |= NativeMethods.TBSTATE_INDETERMINATE;
if (pushed) button.fsState |= NativeMethods.TBSTATE_CHECKED;
if (!visible) button.fsState |= NativeMethods.TBSTATE_HIDDEN;
// set the button style
//
switch (style) {
case ToolBarButtonStyle.PushButton:
button.fsStyle = NativeMethods.TBSTYLE_BUTTON;
break;
case ToolBarButtonStyle.ToggleButton:
button.fsStyle = NativeMethods.TBSTYLE_CHECK;
break;
case ToolBarButtonStyle.Separator:
button.fsStyle = NativeMethods.TBSTYLE_SEP;
break;
}
if (text == null) {
button.pszText = Marshal.StringToHGlobalAuto("\0\0");
}
else {
string textValue = this.text;
PrefixAmpersands(ref textValue);
button.pszText = Marshal.StringToHGlobalAuto(textValue);
}
return button;
}
private void PrefixAmpersands(ref string value) {
// Due to a comctl32 problem, ampersands underline the next letter in the
// text string, but the accelerators don't work.
// So in this function, we prefix ampersands with another ampersand
// so that they actually appear as ampersands.
//
// Sanity check parameter
//
if (value == null || value.Length == 0) {
return;
}
// If there are no ampersands, we don't need to do anything here
//
if (value.IndexOf('&') < 0) {
return;
}
// Insert extra ampersands
//
StringBuilder newString = new StringBuilder();
for(int i=0; i < value.Length; ++i) {
if (value[i] == '&') {
if (i < value.Length - 1 && value[i+1] == '&') {
++i; // Skip the second ampersand
}
newString.Append("&&");
}
else {
newString.Append(value[i]);
}
}
value = newString.ToString();
}
///
///
///
///
public override string ToString() {
return "ToolBarButton: " + Text + ", Style: " + Style.ToString("G");
}
///
///
/// When a button property changes and the parent control is created,
/// we need to make sure it gets the new button information.
/// If Text was changed, call the next overload.
///
internal void UpdateButton(bool recreate) {
UpdateButton(recreate, false, true);
}
///
///
/// When a button property changes and the parent control is created,
/// we need to make sure it gets the new button information.
///
private void UpdateButton(bool recreate, bool updateText, bool updatePushedState) {
// It looks like ToolBarButtons with a DropDownButton tend to
// lose the DropDownButton very easily - so we need to recreate
// the button each time it changes just to be sure.
//
if (style == ToolBarButtonStyle.DropDownButton && parent != null && parent.DropDownArrows) {
recreate = true;
}
// we just need to get the Pushed state : this asks the Button its states and sets
// the private member "pushed" to right value..
// this member is used in "InternalSetButton" which calls GetTBBUTTONINFO(bool updateText)
// the GetButtonInfo method uses the "pushed" variable..
//rather than setting it ourselves .... we asks the button to set it for us..
if (updatePushedState && parent != null && parent.IsHandleCreated) {
GetPushedState();
}
if (parent != null) {
int index = FindButtonIndex();
if (index != -1)
parent.InternalSetButton(index, this, recreate, updateText);
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TypeExtension.cs
- AxisAngleRotation3D.cs
- typedescriptorpermission.cs
- Helper.cs
- XPathBinder.cs
- ContentControl.cs
- FrameworkContentElement.cs
- Point3D.cs
- RootBrowserWindowAutomationPeer.cs
- Transform3DGroup.cs
- DataGridRow.cs
- SpecularMaterial.cs
- TrackPointCollection.cs
- NumericExpr.cs
- QueryCacheKey.cs
- SinglePageViewer.cs
- PrintingPermissionAttribute.cs
- DisplayClaim.cs
- MimeTypeAttribute.cs
- WebServicesDescriptionAttribute.cs
- SEHException.cs
- FontTypeConverter.cs
- WebPartVerbCollection.cs
- WebPartConnectionsEventArgs.cs
- ApplicationProxyInternal.cs
- TraceProvider.cs
- ExceptionUtil.cs
- XmlIterators.cs
- WriteFileContext.cs
- TextRunProperties.cs
- DesignerDataConnection.cs
- InvalidMessageContractException.cs
- XmlExceptionHelper.cs
- CopyAction.cs
- PolyQuadraticBezierSegment.cs
- Interfaces.cs
- IisTraceListener.cs
- _AcceptOverlappedAsyncResult.cs
- QuaternionConverter.cs
- StringFunctions.cs
- GPRECT.cs
- GeometryDrawing.cs
- WebPartCatalogAddVerb.cs
- ActivityValidationServices.cs
- AssemblyFilter.cs
- RepeatBehaviorConverter.cs
- MetabaseServerConfig.cs
- PriorityQueue.cs
- SelectedDatesCollection.cs
- ScriptMethodAttribute.cs
- HtmlInputFile.cs
- BinaryUtilClasses.cs
- UserUseLicenseDictionaryLoader.cs
- InstanceDescriptor.cs
- EventTask.cs
- AssemblyFilter.cs
- ListViewDeletedEventArgs.cs
- glyphs.cs
- PrinterSettings.cs
- entitydatasourceentitysetnameconverter.cs
- XmlSchemaElement.cs
- StackOverflowException.cs
- EntityChangedParams.cs
- LogReserveAndAppendState.cs
- DataTableReader.cs
- SizeConverter.cs
- QilReplaceVisitor.cs
- XPathScanner.cs
- AttributeCollection.cs
- SpecialTypeDataContract.cs
- DiffuseMaterial.cs
- ManagedCodeMarkers.cs
- ParserStreamGeometryContext.cs
- TypeDescriptionProvider.cs
- ByteAnimation.cs
- SmiSettersStream.cs
- SingleAnimationBase.cs
- Propagator.cs
- SqlGenericUtil.cs
- TypeHelpers.cs
- XMLSyntaxException.cs
- _ScatterGatherBuffers.cs
- SingleObjectCollection.cs
- Stopwatch.cs
- XmlChildEnumerator.cs
- CommonBehaviorsSection.cs
- MimeMapping.cs
- SqlFlattener.cs
- GeometryCollection.cs
- DecimalAnimationUsingKeyFrames.cs
- Duration.cs
- MarginsConverter.cs
- StorageEntityTypeMapping.cs
- FontSizeConverter.cs
- CoTaskMemUnicodeSafeHandle.cs
- JournalEntryListConverter.cs
- ConnectionStringSettingsCollection.cs
- FormsIdentity.cs
- Rule.cs
- AbstractDataSvcMapFileLoader.cs