MaxByteLengthTextBox クラスのソースコード

スポンサーリンク

.NET Framework クラス ライブラリにある、System.Windows.Forms.TextBox クラスを継承したカスタム コントロールです。入力可能文字数を制限する MaxLength プロパティのように、全角 2 バイト、半角 1 バイトの計算で、入力可能バイト数を制限できます。

追加で用意された MaxByteLength プロパティは、MaxLength プロパティのように、手軽にデザイナ上でも扱えます。機能はこれだけですが、ホストと連携するような業務アプリケーションなどで、稀に必要とされることがあります。

ソースコード

動作の保証は致しませんので、改変はご自由に。

C# 全般
/** MaxByteLengthTextBox コントロール クラス */
using System.Windows.Forms;
using System.ComponentModel;

namespace Jeanne.Windows.Forms {

    /// ---------------------------------------------------------------------------------------
    /// <summary>
    ///     入力できる文字バイト数を制限できる TextBox コントロールを表します。
    /// </summary>
    /// ---------------------------------------------------------------------------------------

    public class MaxByteLengthTextBox : System.Windows.Forms.TextBox {

      #region コンストラクタ

        /// ---------------------------------------------------------------------------------------
        /// <summary>
        ///     MaxByteLengthTextBox コントロールの新しいインスタンスを初期化します。
        /// </summary>
        /// ---------------------------------------------------------------------------------------

        public MaxByteLengthTextBox() {
            this.MaxByteLength = 65535;
        }

      #endregion

      #region MaxByteLength プロパティ (virtual)

        private int _MaxByteLength;

        /// ---------------------------------------------------------------------------------------
        /// <summary>
        ///     ユーザーがテキスト ボックス コントロールに、
        ///     入力または貼り付けできる最大文字バイト数を取得または設定します。
        /// </summary>
        /// ---------------------------------------------------------------------------------------

        [Category("動作")]
        [DefaultValue(65535)]
        [Description("エディット コントロールに入力できる最大文字バイト数を指定します。")]
        public virtual int MaxByteLength {
            get {
                return this._MaxByteLength;
            }

            set {
                if (this._MaxByteLength != value) {
                    this._MaxByteLength = value;
                }
            }
        }

      #endregion

      #region WndProc メソッド (override)

        protected override void WndProc(ref System.Windows.Forms.Message m) {
            const int WM_CHAR  = 0x0102;
            const int WM_PASTE = 0x0302;

            switch (m.Msg) {
                case WM_CHAR:
                    KeyPressEventArgs eKeyPress = new KeyPressEventArgs((char)(m.WParam.ToInt32()));
                    this.OnChar(eKeyPress);

                    if (eKeyPress.Handled) {
                        return;
                    }

                    break;
                case WM_PASTE:
                    if (this.MaxLength * 2 > this.MaxByteLength) {
                        this.OnPaste(new System.EventArgs());
                        return;
                    }

                    break;
            }

            base.WndProc(ref m);
        }

      #endregion

      #region OnChar メソッド (virtual)

        protected virtual void OnChar(System.Windows.Forms.KeyPressEventArgs e) {
            if (char.IsControl(e.KeyChar)) {
                return;
            }

            System.Text.Encoding sjisEncoding = System.Text.Encoding.GetEncoding("Shift_JIS");
            int textByteCount = sjisEncoding.GetByteCount(this.Text);
            int inputByteCount = sjisEncoding.GetByteCount(e.KeyChar.ToString());
            int selectedTextByteCount = sjisEncoding.GetByteCount(this.SelectedText);

            if ((textByteCount + inputByteCount - selectedTextByteCount) > this.MaxByteLength) {
                e.Handled = true;
            }
        }

      #endregion

      #region OnPaste メソッド (virtual)

        protected virtual void OnPaste(System.EventArgs e) {
            object clipboardText = Clipboard.GetDataObject().GetData(System.Windows.Forms.DataFormats.Text);

            if (clipboardText == null) {
                return;
            }

            System.Text.Encoding sjisEncoding = System.Text.Encoding.GetEncoding("Shift_JIS");
            string inputText = clipboardText.ToString();
            int textByteCount = sjisEncoding.GetByteCount(this.Text);
            int inputByteCount = sjisEncoding.GetByteCount(inputText);
            int selectedTextByteCount = sjisEncoding.GetByteCount(this.SelectedText);
            int remainByteCount = this.MaxByteLength - (textByteCount - selectedTextByteCount);

            if (remainByteCount <= 0) {
                return;
            }

            if (remainByteCount >= inputByteCount) {
                this.SelectedText = inputText;
            } else {
                this.SelectedText = inputText.Substring(0, remainByteCount);
            }
        }

      #endregion

    }

}
VB.NET 全般
'/* MaxByteLengthTextBox コントロール クラス */
Imports System.Windows.Forms
Imports System.ComponentModel

Namespace Jeanne.Windows.Forms

   ''' ---------------------------------------------------------------------------------------
   ''' <summary>
   '''     入力できる文字バイト数を制限できる TextBox コントロールを表します。
   ''' </summary>
   ''' ---------------------------------------------------------------------------------------

    Public Class MaxByteLengthTextBox : Inherits System.Windows.Forms.TextBox

      #Region " コンストラクタ "

        ''' ---------------------------------------------------------------------------------------
        ''' <summary>
        '''     MaxByteLengthTextBox コントロールの新しいインスタンスを初期化します。
        ''' </summary>
        ''' ---------------------------------------------------------------------------------------

        Public Sub New()
            Me.MaxByteLength = 65535
        End Sub

      #End Region

      #Region " MaxByteLength プロパティ (Overridable) "

        Private _MaxByteLength As Integer

        ''' ---------------------------------------------------------------------------------------
        ''' <summary>
        '''     ユーザーがテキスト ボックス コントロールに、
        '''     入力または貼り付けできる最大文字バイト数を取得または設定します。
        ''' </summary>
        ''' ---------------------------------------------------------------------------------------

        <Category("動作"), _
         DefaultValue(65535), _
         Description("エディット コントロールに入力できる最大文字バイト数を指定します。")> _
        Public Overridable Property MaxByteLength() As Integer
            Get
                Return Me._MaxByteLength
            End Get

            Set
                If Me._MaxByteLength <> Value Then
                    Me._MaxByteLength = Value
                End If
            End Set
        End Property

      #End Region

      #Region " WndProc メソッド (Overrides) "

        Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
            Const WM_CHAR  As Integer = &H102
            Const WM_PASTE As Integer = &H302

            Select Case m.Msg
                Case WM_CHAR
                    Dim eKeyPress As New KeyPressEventArgs(Microsoft.VisualBasic.ChrW(m.WParam.ToInt32()))
                    Me.OnChar(eKeyPress)

                    If eKeyPress.Handled Then
                        Return
                    End If
                Case WM_PASTE
                    If Me.MaxLength * 2 > Me.MaxByteLength Then
                        Me.OnPaste(New System.EventArgs())
                        Return
                    End If
            End Select

            MyBase.WndProc(m)
        End Sub

      #End Region

      #Region " OnChar メソッド (Overridable) "

        Protected Overridable Sub OnChar(ByVal e As System.Windows.Forms.KeyPressEventArgs)
            If Char.IsControl(e.KeyChar) Then
                Return
            End If

            Dim sjisEncoding          As System.Text.Encoding = System.Text.Encoding.GetEncoding("Shift_JIS")
            Dim textByteCount         As Integer = sjisEncoding.GetByteCount(Me.Text)
            Dim inputByteCount        As Integer = sjisEncoding.GetByteCount(e.KeyChar.ToString())
            Dim selectedTextByteCount As Integer = sjisEncoding.GetByteCount(Me.SelectedText)

            If textByteCount + inputByteCount - selectedTextByteCount > Me.MaxByteLength Then
                e.Handled = True
            End If
        End Sub

      #End Region

      #Region " OnPaste メソッド (Overridable) "

        Protected Overridable Sub OnPaste(ByVal e As System.EventArgs)
            Dim clipboardText As Object = Clipboard.GetDataObject().GetData(System.Windows.Forms.DataFormats.Text)

            If clipboardText Is Nothing Then
                Return
            End If

            Dim sjisEncoding          As System.Text.Encoding = System.Text.Encoding.GetEncoding("Shift_JIS")
            Dim inputText             As String  = clipboardText.ToString()
            Dim textByteCount         As Integer = sjisEncoding.GetByteCount(Me.Text)
            Dim inputByteCount        As Integer = sjisEncoding.GetByteCount(inputText)
            Dim selectedTextByteCount As Integer = sjisEncoding.GetByteCount(Me.SelectedText)
            Dim remainByteCount       As Integer = Me.MaxByteLength -(textByteCount - selectedTextByteCount)

            If remainByteCount <= 0 Then
                Return
            End If

            If remainByteCount >= inputByteCount Then
                Me.SelectedText = inputText
            Else
                Me.SelectedText = inputText.Substring(0, remainByteCount)
            End If
        End Sub

      #End Region

   End Class

End Namespace

スポンサーリンク