|
//------------------------------------------------------------------------------
// <copyright file="StatusBarPanel.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
/*
*/
namespace System.Windows.Forms {
using System.Runtime.Serialization.Formatters;
using System.Runtime.Remoting;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics;
using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.Win32;
using System.Globalization;
using System.Runtime.Versioning;
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel"]/*' />
/// <devdoc>
/// <para>
/// Stores the <see cref='System.Windows.Forms.StatusBar'/>
/// control panel's information.
/// </para>
/// </devdoc>
[
ToolboxItem(false),
DesignTimeVisible(false),
DefaultProperty("Text")
]
public class StatusBarPanel : Component, ISupportInitialize {
private const int DEFAULTWIDTH = 100;
private const int DEFAULTMINWIDTH = 10;
private const int PANELTEXTINSET = 3;
private const int PANELGAP = 2;
private string text = "";
private string name = "";
private string toolTipText = "";
private Icon icon = null;
private HorizontalAlignment alignment = HorizontalAlignment.Left;
private System.Windows.Forms.StatusBarPanelBorderStyle borderStyle = System.Windows.Forms.StatusBarPanelBorderStyle.Sunken;
private StatusBarPanelStyle style = StatusBarPanelStyle.Text;
// these are package scope so the parent can get at them.
//
private StatusBar parent = null;
private int width = DEFAULTWIDTH;
private int right = 0;
private int minWidth = DEFAULTMINWIDTH;
private int index = 0;
private StatusBarPanelAutoSize autoSize = StatusBarPanelAutoSize.None;
private bool initializing = false;
private object userData;
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.StatusBarPanel"]/*' />
/// <devdoc>
/// <para>
/// Initializes a new default instance of the <see cref='System.Windows.Forms.StatusBarPanel'/> class.
/// </para>
/// </devdoc>
public StatusBarPanel() {
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.Alignment"]/*' />
/// <devdoc>
/// <para>
/// Gets or sets the <see cref='System.Windows.Forms.StatusBarPanel.Alignment'/>
/// property.
///
/// </para>
/// </devdoc>
[
SRCategory(SR.CatAppearance),
DefaultValue(HorizontalAlignment.Left),
Localizable(true),
SRDescription(SR.StatusBarPanelAlignmentDescr)
]
public HorizontalAlignment Alignment {
get {
return alignment;
}
set {
//valid values are 0x0 to 0x2
if (!ClientUtils.IsEnumValid(value, (int)value, (int)HorizontalAlignment.Left, (int)HorizontalAlignment.Center)){
throw new InvalidEnumArgumentException("value", (int)value, typeof(HorizontalAlignment));
}
if (alignment != value) {
alignment = value;
Realize();
}
}
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.AutoSize"]/*' />
/// <devdoc>
/// <para>
/// Gets or sets the <see cref='System.Windows.Forms.StatusBarPanel.AutoSize'/>
/// property.
///
/// </para>
/// </devdoc>
[
SRCategory(SR.CatAppearance),
DefaultValue(StatusBarPanelAutoSize.None),
RefreshProperties(RefreshProperties.All),
SRDescription(SR.StatusBarPanelAutoSizeDescr)
]
public StatusBarPanelAutoSize AutoSize {
get {
return this.autoSize;
}
set {
//valid values are 0x1 to 0x3
if (!ClientUtils.IsEnumValid(value, (int)value, (int)StatusBarPanelAutoSize.None, (int)StatusBarPanelAutoSize.Contents)){
throw new InvalidEnumArgumentException("value", (int)value, typeof(StatusBarPanelAutoSize));
}
if (this.autoSize != value) {
this.autoSize = value;
UpdateSize();
}
}
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.BorderStyle"]/*' />
/// <devdoc>
/// <para>
/// Gets or sets the <see cref='System.Windows.Forms.StatusBarPanel.BorderStyle'/>
///
/// property.
///
/// </para>
/// </devdoc>
[
SRCategory(SR.CatAppearance),
DefaultValue(System.Windows.Forms.StatusBarPanelBorderStyle.Sunken),
DispId(NativeMethods.ActiveX.DISPID_BORDERSTYLE),
SRDescription(SR.StatusBarPanelBorderStyleDescr)
]
public StatusBarPanelBorderStyle BorderStyle {
get {
return borderStyle;
}
set {
//valid values are 0x1 to 0x3
if (!ClientUtils.IsEnumValid(value, (int)value, (int)StatusBarPanelBorderStyle.None, (int)StatusBarPanelBorderStyle.Sunken)){
throw new InvalidEnumArgumentException("value", (int)value, typeof(StatusBarPanelBorderStyle));
}
if (this.borderStyle != value) {
this.borderStyle = value;
Realize();
if (Created)
this.parent.Invalidate();
}
}
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.Created"]/*' />
/// <devdoc>
/// </devdoc>
/// <internalonly/>
internal bool Created {
get {
return this.parent != null && this.parent.ArePanelsRealized();
}
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.Icon"]/*' />
/// <devdoc>
/// <para>
/// Gets or sets the <see cref='System.Windows.Forms.StatusBarPanel.Icon'/>
/// property.
///
/// </para>
/// </devdoc>
[
SRCategory(SR.CatAppearance),
DefaultValue(null),
Localizable(true),
SRDescription(SR.StatusBarPanelIconDescr)
]
public Icon Icon {
[ResourceExposure(ResourceScope.Machine)]
get {
// unfortunately we have no way of getting the icon from the control.
return this.icon;
}
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
set {
if (value != null && (((Icon)value).Height > SystemInformation.SmallIconSize.Height || ((Icon)value).Width > SystemInformation.SmallIconSize.Width)) {
this.icon = new Icon(value, SystemInformation.SmallIconSize);
}
else {
this.icon = value;
}
if (Created) {
IntPtr handle = (this.icon == null) ? IntPtr.Zero : this.icon.Handle;
this.parent.SendMessage(NativeMethods.SB_SETICON, (IntPtr)GetIndex(), handle);
}
UpdateSize();
if (Created) {
this.parent.Invalidate();
}
}
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.Index"]/*' />
/// <devdoc>
/// <para>
/// Expose index internally
/// </para>
/// </devdoc>
internal int Index
{
get
{
return index;
}
set
{
index = value;
}
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.MinWidth"]/*' />
/// <devdoc>
/// <para>
/// Gets or sets the minimum width the <see cref='System.Windows.Forms.StatusBarPanel'/> can be within the <see cref='System.Windows.Forms.StatusBar'/>
/// control.
///
/// </para>
/// </devdoc>
[
SRCategory(SR.CatBehavior),
DefaultValue(DEFAULTMINWIDTH),
Localizable(true),
RefreshProperties(RefreshProperties.All),
SRDescription(SR.StatusBarPanelMinWidthDescr)
]
public int MinWidth {
get {
return this.minWidth;
}
set {
if (value < 0) {
throw new ArgumentOutOfRangeException("MinWidth", SR.GetString(SR.InvalidLowBoundArgumentEx, "MinWidth", value.ToString(CultureInfo.CurrentCulture), (0).ToString(CultureInfo.CurrentCulture)));
}
if (value != this.minWidth) {
this.minWidth = value;
UpdateSize();
if (this.minWidth > this.Width) {
Width = value;
}
}
}
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.Name"]/*' />
/// <devdoc>
/// <para>
/// Gets or sets the name of the panel.
/// </para>
/// </devdoc>
[
SRCategory(SR.CatAppearance),
Localizable(true),
SRDescription(SR.StatusBarPanelNameDescr)
]
public string Name {
get {
return WindowsFormsUtils.GetComponentName(this, name);
}
set {
name = value;
if(Site!= null) {
Site.Name = name;
}
}
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.Parent"]/*' />
/// <devdoc>
/// <para>
/// Represents the <see cref='System.Windows.Forms.StatusBar'/>
/// control which hosts the
/// panel.
///
/// </para>
/// </devdoc>
[Browsable(false)]
public StatusBar Parent {
get {
return parent;
}
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.ParentInternal"]/*' />
/// <devdoc>
/// <para>
/// Expose a direct setter for parent internally
/// </para>
/// </devdoc>
internal StatusBar ParentInternal
{
set
{
parent = value;
}
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.Right"]/*' />
/// <devdoc>
/// <para>
/// Expose right internally
/// </para>
/// </devdoc>
internal int Right
{
get
{
return right;
}
set
{
right = value;
}
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.Style"]/*' />
/// <devdoc>
/// <para>
/// Gets or sets the style of the panel.
///
/// </para>
/// </devdoc>
[
SRCategory(SR.CatAppearance),
DefaultValue(StatusBarPanelStyle.Text),
SRDescription(SR.StatusBarPanelStyleDescr)
]
public StatusBarPanelStyle Style {
get { return style;}
set {
//valid values are 0x1 to 0x2
if (!ClientUtils.IsEnumValid(value, (int)value, (int)StatusBarPanelStyle.Text, (int)StatusBarPanelStyle.OwnerDraw)){
throw new InvalidEnumArgumentException("value", (int)value, typeof(StatusBarPanelStyle));
}
if (this.style != value) {
this.style = value;
Realize();
if (Created) {
this.parent.Invalidate();
}
}
}
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.Tag"]/*' />
[
SRCategory(SR.CatData),
Localizable(false),
Bindable(true),
SRDescription(SR.ControlTagDescr),
DefaultValue(null),
TypeConverter(typeof(StringConverter)),
]
public object Tag {
get {
return userData;
}
set {
userData = value;
}
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.Text"]/*' />
/// <devdoc>
/// <para>
/// Gets or sets the text of the panel.
/// </para>
/// </devdoc>
[
SRCategory(SR.CatAppearance),
Localizable(true),
DefaultValue(""),
SRDescription(SR.StatusBarPanelTextDescr)
]
public string Text {
get {
if (text == null) {
return "";
}
else {
return text;
}
}
set {
if (value == null) {
value = "";
}
if (!Text.Equals(value)) {
if (value.Length == 0) {
this.text = null;
}
else {
this.text = value;
}
Realize();
UpdateSize();
}
}
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.ToolTipText"]/*' />
/// <devdoc>
/// <para>
/// Gets
/// or sets the panel's tool tip text.
/// </para>
/// </devdoc>
[
SRCategory(SR.CatAppearance),
Localizable(true),
DefaultValue(""),
SRDescription(SR.StatusBarPanelToolTipTextDescr)
]
public string ToolTipText {
get {
if (this.toolTipText == null) {
return "";
}
else {
return this.toolTipText;
}
}
set {
if (value == null) {
value = "";
}
if (!ToolTipText.Equals(value)) {
if (value.Length == 0) {
this.toolTipText = null;
}
else {
this.toolTipText = value;
}
if (Created) {
parent.UpdateTooltip(this);
}
}
}
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.Width"]/*' />
/// <devdoc>
/// <para>
/// Gets or sets the width of the <see cref='System.Windows.Forms.StatusBarPanel'/> within the <see cref='System.Windows.Forms.StatusBar'/>
/// control.
///
/// </para>
/// </devdoc>
[
Localizable(true),
SRCategory(SR.CatAppearance),
DefaultValue(DEFAULTWIDTH),
SRDescription(SR.StatusBarPanelWidthDescr)
]
public int Width {
get {
return this.width;
}
set {
if (!initializing && value < this.minWidth)
throw new ArgumentOutOfRangeException("Width", SR.GetString(SR.WidthGreaterThanMinWidth));
this.width = value;
UpdateSize();
}
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.BeginInit"]/*' />
/// <devdoc>
/// Handles tasks required when the control is being initialized.
/// </devdoc>
public void BeginInit() {
initializing = true;
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.Dispose"]/*' />
/// <internalonly/>
/// <devdoc>
/// </devdoc>
protected override void Dispose(bool disposing) {
if (disposing) {
if (parent != null) {
int index = GetIndex();
if (index != -1) {
parent.Panels.RemoveAt(index);
}
}
}
base.Dispose(disposing);
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.EndInit"]/*' />
/// <devdoc>
/// Called when initialization of the control is complete.
/// </devdoc>
public void EndInit() {
initializing = false;
if (Width < MinWidth) {
Width = MinWidth;
}
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.GetContentsWidth"]/*' />
/// <internalonly/>
/// <devdoc>
/// Gets the width of the contents of the panel
/// </devdoc>
internal int GetContentsWidth(bool newPanel) {
string text;
if (newPanel) {
if (this.text == null)
text = "";
else
text = this.text;
}
else
text = Text;
Graphics g = this.parent.CreateGraphicsInternal();
Size sz = Size.Ceiling(g.MeasureString(text, parent.Font));
if (this.icon != null) {
sz.Width += this.icon.Size.Width + 5;
}
g.Dispose();
int width = sz.Width + SystemInformation.BorderSize.Width*2 + PANELTEXTINSET*2 + PANELGAP;
return Math.Max(width, minWidth);
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.GetIndex"]/*' />
/// <internalonly/>
/// <devdoc>
/// Returns the index of the panel by making the parent control search
/// for it within its list.
/// </devdoc>
private int GetIndex() {
return index;
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.Realize"]/*' />
/// <internalonly/>
/// <devdoc>
/// Sets all the properties for this panel.
/// </devdoc>
internal void Realize() {
if (Created) {
string text;
string sendText;
int border = 0;
if (this.text == null) {
text = "";
}
else {
text = this.text;
}
HorizontalAlignment align = alignment;
// Translate the alignment for Rtl apps
//
if (parent.RightToLeft == RightToLeft.Yes) {
switch (align) {
case HorizontalAlignment.Left:
align = HorizontalAlignment.Right;
break;
case HorizontalAlignment.Right:
align = HorizontalAlignment.Left;
break;
}
}
switch (align) {
case HorizontalAlignment.Center:
sendText = "\t" + text;
break;
case HorizontalAlignment.Right:
sendText = "\t\t" + text;
break;
default:
sendText = text;
break;
}
switch (borderStyle) {
case StatusBarPanelBorderStyle.None:
border |= NativeMethods.SBT_NOBORDERS;
break;
case StatusBarPanelBorderStyle.Sunken:
break;
case StatusBarPanelBorderStyle.Raised:
border |= NativeMethods.SBT_POPOUT;
break;
}
switch (style) {
case StatusBarPanelStyle.Text:
break;
case StatusBarPanelStyle.OwnerDraw:
border |= NativeMethods.SBT_OWNERDRAW;
break;
}
int wparam = GetIndex() | border;
if (parent.RightToLeft == RightToLeft.Yes) {
wparam |= NativeMethods.SBT_RTLREADING;
}
int result = (int) UnsafeNativeMethods.SendMessage(new HandleRef(parent, parent.Handle), NativeMethods.SB_SETTEXT, (IntPtr)wparam, sendText);
if (result == 0)
throw new InvalidOperationException(SR.GetString(SR.UnableToSetPanelText));
if (this.icon != null && style != StatusBarPanelStyle.OwnerDraw) {
this.parent.SendMessage(NativeMethods.SB_SETICON, (IntPtr)GetIndex(), this.icon.Handle);
}
else {
this.parent.SendMessage(NativeMethods.SB_SETICON, (IntPtr)GetIndex(), IntPtr.Zero);
}
if (style == StatusBarPanelStyle.OwnerDraw) {
NativeMethods.RECT rect = new NativeMethods.RECT();
result = (int) UnsafeNativeMethods.SendMessage(new HandleRef(parent, parent.Handle), NativeMethods.SB_GETRECT, (IntPtr)GetIndex(), ref rect);
if (result != 0) {
this.parent.Invalidate(Rectangle.FromLTRB(rect.left, rect.top, rect.right, rect.bottom));
}
}
}
}
private void UpdateSize() {
if (this.autoSize == StatusBarPanelAutoSize.Contents) {
ApplyContentSizing();
}
else {
if (Created) {
parent.DirtyLayout();
parent.PerformLayout();
}
}
}
private void ApplyContentSizing() {
if (this.autoSize == StatusBarPanelAutoSize.Contents &&
parent != null) {
int newWidth = GetContentsWidth(false);
if (newWidth != this.Width) {
this.Width = newWidth;
if (Created) {
parent.DirtyLayout();
parent.PerformLayout();
}
}
}
}
/// <include file='doc\StatusBarPanel.uex' path='docs/doc[@for="StatusBarPanel.ToString"]/*' />
/// <devdoc>
/// <para>
/// Retrieves a string that contains information about the
/// panel.
/// </para>
/// </devdoc>
public override string ToString() {
return "StatusBarPanel: {" + Text + "}";
}
}
}
|