ToolBarButton.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / 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.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK