サンプルについて

タグの編集
投稿者 おさむ  (高校生) 投稿日時 2011/6/22 08:44:31
VB6.0以前欄にある「サンプル」ページにあるテキストボックスの、入力出来る文字制限のプログラムは、.NETでも使えますか?
使えない場合は.NET版プログラムを教えてください。
投稿者 ヴァン  (社会人) 投稿日時 2011/6/22 09:54:49
googleで「vb テキストボックス 入力制限」で検索してみましょう。
投稿者 とくま  (社会人) 投稿日時 2011/6/22 11:51:30
Visual Basic.NET の欄にある「サンプル」ページを見ればいいのでは?

条件は多少違いますけどね。
投稿者 おさむ  (高校生) 投稿日時 2011/6/22 12:39:00
さっそく返答ありがとうございます。
私が知りたいのは、数字だけとか、ひらがなだけとか細かく制限する方法です。
.NET欄のサンプルでは、全角とか制限の幅がちょっと大きすぎます。

またネットで調べてみたところ、数字だけの制限は解りましたが、ひらがなだけの制限がわかりませんでした。

投稿者 shu  (社会人) 投稿日時 2011/6/22 12:59:13
多分、最近ではローマ字打ちの人の方が多いのではと思うので
サンプルにあるようにKeyPressで判断するのは少し手間がいると
思います。

例えば
b a と打たれたら 『ば』になるのでbだけで駄目と判断は出来ません。
g y a と打たれたら 『ぎゃ』になるので g yだけで駄目と判断は出来ません。

というようになるので複数のキーの組み合わせでどのひらがなになるのかという表を
持って文字の組み合わせで変換をしてあげると良いと思います。
母音を除く部分は各行でほぼ同じなので母音を除く文字でまとめて管理すると良いかと思います。

New String(,) {
    {"", "あ", "い", "う", "え", "お"}
      , {"b", "ば", "び", "ぶ", "べ", "ぼ"}
      , {"by", "びゃ", "びぃ", "びゅ", "びぇ", "びょ"}

   ・・・・
      , {"zy", "じゃ", "じぃ", "じゅ", "じぇ", "じょ"}}

例えばこんな感じの配列を使うとよいと思います。


投稿者 魔界の仮面弁士  (社会人) 投稿日時 2011/6/22 22:51:17
おさむさん:
>> VB6.0以前欄にある「サンプル」ページにあるテキストボックスの、入力出来る文字制限のプログラムは
それは
http://homepage1.nifty.com/rucio/main/Samples/vbsample030.htm
の事でしょうか?


>> ひらがなだけの制限がわかりませんでした。
Private Sub TextBox1_KeyPress(ByVal sender As ObjectByVal e As KeyPressEventArgs) Handles TextBox1.KeyPress
    If Not System.Text.RegularExpressions.Regex.IsMatch(e.KeyChar, "\p{IsHiragana}"Then
        e.Handled = True
    End If
End Sub




shuさん:
>> サンプルにあるようにKeyPressで判断するのは少し手間がいると思います。
>> g y a と打たれたら 『ぎゃ』になるので g yだけで駄目と判断は出来ません。
あれ? KeyPress イベントでその動作が発生するのは、どういう時なのでしょうか?

私の認識では:

IME が無効な状態で [g][y][o] の 3 つのキーが入力された場合、
KeyPress イベントは "g", "y", "o" の 3 回発生し、TextBox には『gyo』と書かれる。

IME が有効な状態で [g][y][o][Enter] の 4 つのキーが入力された場合、
KeyPress イベントは "ぎ", "ょ" の 2 回発生し、TextBox には『ぎょ』と書かれる。

だったので手元の環境で再確認してみたのですが、動作はやはり上記の通りで、
ローマ字入力であっても『ぎょ』の入力時に g y が KeyPress に入る事は
ありませんでした。それとも、OS によっては異なる動作になるのでしょうか。




いずれにしても、KeyPress / KeyDown / KeyUp 等の
「キーボード系イベント」だけでは、入力制限としては不十分です。

これはたとえば、「マウス右クリックからの貼り付け」操作や、
「タブレットPCにおいて、文字列がペン入力された場合」には
キーボード系のイベントが一切発生しないためです。

ですから、キーボードからの入力制御は、あくまでも補助的な物として扱い、
最終的には入力後の検証の仕組みも併せて実装しておく必要があるでしょう。
投稿者 (削除されました)  () 投稿日時 2011/6/23 07:50:59
(削除されました)
投稿者 shu  (社会人) 投稿日時 2011/6/23 08:27:23
> あれ? KeyPress イベントでその動作が発生するのは、どういう時なのでしょうか?
Imeを使用不可の状態にでもしておいてローマ字がそろったら変換するような
方法を考えてました。というか当方ではそういうコントロールを作って使ってます。
会社で作ったものなのでソース公開は出来ませんが、ヒントということで載せました。
ImeがOnだと確定動作が発生してしまうのでひらがなコントロールとしては余計かなと
思ってます。確かにOnの場合は確定動作が行われるまで発生しないし文字毎に
発生しますね。  
投稿者 おさむ  (高校生) 投稿日時 2011/7/5 14:01:18
みなさんたくさんの回答をありがとうございます。
しばらくネットがつながらなかったので返事が遅れました。

すいません。

それでもう少し質問なんですが、完全にひらがなしか入力できないテキストボックスと
ボタンをクリックしたときにひらがなかどうか確認するプログラムを教えてください。
投稿者 shu  (社会人) 投稿日時 2011/7/5 22:00:12
ImeON状態、入力チェックについては魔界の仮面弁士が示されているように
RegularExpressionsでひらがなかチェックすればよいです。

Disableでローマ字入力限定版でのサンプルです。変換マップはかなり歯抜けに
なってますので埋めて下さい。アルファベットの昇順で定義しないとちゃんと動きません。
会社で使っているものとは別に作りましたので動作はそれほどでしっかりしていません。
キーボードからのローマ字入力限定です。

Public Class RomanTextBox
    Inherits TextBox

    Private RomanMap(,) As String = {{"", "あ", "い", "う", "え", "お"},
                        {"GY", "ぎゃ", "", "ぎゅ", "", "ぎょ"},
                        {"K", "か", "き", "く", "け", "こ"},
                        {"N", "な", "に", "ぬ", "ね", "の"},
                        {"S", "さ", "し", "す", "せ", "そ"},
                        {"T", "た", "ち", "つ", "て", "と"}}

    Public Sub New()
        MyBase.New()
        MyBase.ImeModeBase = Windows.Forms.ImeMode.Disable
        MyBase.CharacterCasing = Windows.Forms.CharacterCasing.Upper
    End Sub

    Protected Overrides Property ImeModeBase As System.Windows.Forms.ImeMode
        Get
            Return MyBase.ImeModeBase
        End Get
        Set(ByVal value As System.Windows.Forms.ImeMode)
            MyBase.ImeModeBase = ImeMode.Disable
        End Set
    End Property

    Private Sub RomanTextBox_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
        Select Case e.KeyChar
            Case "A"c, "a"c
                e.KeyChar = TransRoman(1)
            Case "I"c, "i"c
                e.KeyChar = TransRoman(2)
            Case "U"c, "u"c
                e.KeyChar = TransRoman(3)
            Case "E"c, "e"c
                e.KeyChar = TransRoman(4)
            Case "O"c, "o"c
                e.KeyChar = TransRoman(5)
            Case "N"c, "n"c
                If IsNN Then
                    e.KeyChar = "ん"c
                End If
            Case "A"c To "Z"c, "a"c To "z"c
            Case vbBack
            Case Else
                e.Handled = True
        End Select
    End Sub

    Private Function TransRoman(ByVal idx As Integer) As Char
        Dim SelSt = MyBase.SelectionStart
        Dim SelLen = MyBase.SelectionLength
        Dim Bef = If(SelSt > 0, MyBase.Text.Substring(0, SelSt), MyBase.Text)
        Dim Aft = If(SelSt + SelLen < TextLength, MyBase.Text.Substring(SelSt + SelLen), "")

        Dim Trg As String = ""

        If Bef <> "" Then
            For Each chr1 In Bef
                Select Case chr1
                    Case "A"c To "Z"c, "a"c To "z"c
                        Trg &= chr1.ToString.ToUpper
                End Select
            Next
            If Trg.Length > 0 Then
                Bef = Bef.Substring(0, Bef.Length - Trg.Length)
            End If
        End If

投稿者 shu  (社会人) 投稿日時 2011/7/5 22:00:32
        If Trg = "" Then
            TransRoman = RomanMap(0, idx)
        Else
            Dim RomanMapNum = RomanMap.GetUpperBound(0)
            Dim idxLast = -1
            For idxm = 1 To RomanMapNum - 1
                If Trg.EndsWith(RomanMap(idxm, 0)) Then
                    idxLast = idxm
                End If
            Next
            If idxLast >= 0 And idxLast < RomanMapNum Then
                Dim ret = RomanMap(idxLast, idx)

                '『っ』の判断
                If ret <> "" Then
                    Dim TrStr = RomanMap(idxLast, 0)
                    If TrStr.Length < Trg.Length Then
                        Trg = Trg.Substring(Trg.Length - TrStr.Length - 1, 1)
                        If TrStr.StartsWith(Trg) Then
                            Bef &= "っ"
                        End If
                    End If
                End If
                '2文字以上の場合最後の文字より前をBefに連結
                If ret.Length > 1 Then
                    Bef &= ret.Substring(0, ret.Length - 1)
                    ret = ret.Substring(ret.Length - 1)
                End If
                TransRoman = ret
            Else
                TransRoman = ""
            End If
            MyBase.Text = Bef & Aft
            MyBase.SelectionLength = 0
            MyBase.SelectionStart = Bef.Length
        End If

    End Function

    Private Function IsNN() As Boolean
        Dim SelSt = MyBase.SelectionStart
        Dim SelLen = MyBase.SelectionLength
        Dim Bef = If(SelSt > 0, MyBase.Text.Substring(0, SelSt), MyBase.Text)
        Dim Aft = If(SelSt + SelLen < TextLength, MyBase.Text.Substring(SelSt + SelLen), "")
        Dim ret = False

        If Bef.EndsWith("N") Then
            Bef = Bef.Substring(0, Bef.Length - 1)
            ret = True
        End If

        If ret Then
            MyBase.Text = Bef & Aft
            MyBase.SelectionLength = 0
            MyBase.SelectionStart = Bef.Length
        End If

        Return ret
    End Function
End Class
投稿者 shu  (社会人) 投稿日時 2011/7/6 07:49:36
追記:
RomanMapの定義順ですがアルファベットの昇順ではなく
文字数の少ないものが前にくるようにした方がよかったです。
例)GYA と YA は同時にマッチしますが長いほうを優先したいので。
投稿者 おさむ  (高校生) 投稿日時 2011/7/7 13:29:29
みなさんありがとうございました。
無事解決しました。