ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

Visual Basic User's Clubコミュの文字キーを矢印キーとして認識

  • mixiチェック
  • このエントリーをはてなブックマークに追加
vi エディタのように文字キーを矢印キーとして使いたいのですが方法が解りません。

小文字で移動したいので、TextBox1_KeyPress に TextBox1_KeyDown(sender, Keys.Left) を呼び出したのですが、2番目の引数ではじかれました。

TextBox1.SelectionStart = TextBox1.SelectionStart - 1
としたのですが、どうしても改行のところで躓いてしまいます。
(改行を判定することが出来ません。変数に改行を入力して格納したのですが、if文で vbCrLf,vbCr,vbLf,"\n",0A と比べても無理でした。)

TextBox1_KeyDown でキャップスロックキーが押されていないときに文字キーを押したら矢印キーとして認識するようにしたいと思いましたが、

e.KeyCode = Keys.Left

KeyCode が読み取り専用で値を代入することが出来ませんでした。

どのようにすればスムースにカーソル移動することが出来るのでしょうか。

よろしくお願いします。

コメント(12)

VBのバージョンを記載されておられないので、VB2005と仮定してカキコさせていただきます。

改行判定はどうやってやってます?
TextBoxに改行だけを入力し、その.TextとvbNewLineを比較したら判定できました。
vbNewLine(復帰+改行)は当然のことながら、2文字ですので、Len(Me.TextBox1.Text)とすると2が帰ってきます。
.Textの一部を比較するときに、1文字で比較してませんか?
Mid(Me.TextBox1.Text, 1, 2) のようにして、2文字で比較すればいけると思いますが・・・

あと、やりたいことをしようとした時に、私なら、TextBoxから継承されたカスタムコントロールをつくり、その中で、ProcessCmdKeyあたりで処理します。
ProcessCmdKeyをオーバーライドさせ、ご自分がやりたい処理を行ってから、Return Trueすると、小文字の入力自体はTextBoxへは送られませんので、案外楽に処理できると思います。

ヘルプに、『Visual BasicによるWindowsフォームコントロールからの継承』というトピックがありますので、そこを参照してください。
過去ログだと、このあたりに・・・
http://mixi.jp/view_bbs.pl?id=10520784&comm_id=925
> 1: hiro_ozzy_5150
> VBのバージョンを記載されておられないので、VB2005と仮定してカキコさせていただきます。

失礼しました。
OS:WindowsXP
VB:2005

です。
1文字で比較していました。

abc
d

矢印キーだと、「c」にカールがあり、右矢印を押すと一回押しただけで「d」の左側に来ますが、文字で
TextBox1.SelectionStart = TextBox1.SelectionStart - 1
とすると、「c」のさらに右側に移動してしまうのです。

過去ログの URL までリンクはつけていただきありがとうございます。

熟読します。
ありがとうございました。
> 1: hiro_ozzy_5150
> ヘルプに、『Visual BasicによるWindowsフォームコントロールからの継承』というトピックがありますので、そこを参照してください。
> 過去ログだと、このあたりに・・・
> http://mixi.jp/view_bbs.pl?id=10520784&comm_id=925

これはすばらしい。
・・・と思う。
難しいですが、モノにします。

継承で作成した場合に Releaseビルドで .dll が作成されました。
一緒に配布するのは邪魔くさいですが、自動で生成してくれるあたりは便利ですね。


> あと、やりたいことをしようとした時に、私なら、TextBoxから継承されたカスタムコントロールをつくり、その中で、ProcessCmdKeyあたりで処理します。

この難題に挑戦します。

ありがとうございました。
ちなみに・・・・TextBoxから派生させて、エンターキーで次のコントロールにTABで飛ばすサンプルを・・・

Public Class myTextBox

Private WM_KEYDOWN As Integer = &H100

Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean

If msg.Msg = WM_KEYDOWN Then
Dim keyCode As Keys = CType(msg.WParam.ToInt32(), Keys) And Keys.KeyCode
Dim uModifiers As Keys = (keyData And Keys.Modifiers)
If keyCode = Keys.Enter Then
If MyBase.Multiline = True Then
Select Case uModifiers
Case Keys.Control
Exit Select
Case Keys.Shift
Exit Select
Case Not (Keys.Control OrElse Keys.Shift) 'エンターオンリー
System.Windows.Forms.SendKeys.Send("{TAB}")
Return True
End Select
Else
System.Windows.Forms.SendKeys.Send("{TAB}")
Return True
End If
End If
End If

Return False

End Function

End Class
> 4: hiro_ozzy_5150
> ちなみに・・・・TextBoxから派生させて、エンターキーで次のコントロールにTABで飛ばすサンプルを・・・

継承したからには一つ一つプログラミングしないと駄目だって事ですかね。


> TextBoxから継承されたカスタムコントロールをつくり

の時点で足踏みしていますが、がんばります。
> 1: hiro_ozzy_5150
> 私なら、TextBoxから継承されたカスタムコントロールをつくり、その中で、ProcessCmdKeyあたりで処理します。

継承も理解したので組み込むことに成功しました。
ProcessCmdKeyあたりで処理させることにも成功しました。

しかし、
> ProcessCmdKeyをオーバーライドさせ、

の部分で躓いております。

Public Class ProcessCmdKey
  Inherits ValueTextBox
  Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
    Dim Key_Instance As New KeyEventArgs(keyData)
    If keyData = Keys.H Then
      Return True ' キーを受け付けない
    ElseIf keyData = Keys.L Then ' 右矢印
      Return True ' キーを受け付けない
    End If
    Return MyBase.ProcessCmdKey(msg, keyData)
  End Function
End Class

上記の ProcessCmdKey でプログラムを処理させています。
しかし、オーバーライドさせることが出来ません。
スーパークラスである、Public Class ValueTextBox に Overridable をつけた ProcessCmdKey を作成しようと思いましたが出来ませんでした。

スーパークラス(ValueTextBox)に作成:
  Protected Overridable Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
  End Function

サブクラス(ProcessCmdKey)に作成:
  Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
  End Function

Form1 のクラスで、サブクラスの ProcessCmdKey を読み取りました(スーパークラスに作成した ProcessCmdKey は削除しています)。

作成できないエラー内容:
警告 1 function 'ProcessCmdKey' は、ベース class 'ContainerControl' のオーバーライド可能なメソッドに 'Shadows' を実行します。ベース メソッドをオーバーライドするには、このメソッドは 'Overrides' に宣言されていなければなりません。 H:\TextEditor\ValueTextBoxLib\ValueTextBox.vb 27 36 ValueTextBoxLib


また、ProcessCmdKey(テキストボックス) を Form1 に貼り付けているのですが、貼り付けたテキストボックスをダブルクリックすると、ProcessCmdKey1 が作成されます。
ProcessCmdKey1 にプログラムを書いても無視されるのは何故でしょうか。

自作していない、コマンドボタンやテキストボックスのような扱いをすることが出来ません。

ご教授よろしくお願いします。
(プログラムのインデントは全角のスペースです)
Class名にProcessCmdKeyってのはあんまりよろしくないかと^^;;

ValueTextBoxを作って、また派生させてProcessCmdKeyというコントロールを作るのは、あんまり意味がないのでは???^^;;

フォーム内でサブクラスを作って、ValueTextBoxから継承してコード記入するなら、わざわざValueTextBoxを作る意味がないように思いますが・・・・直接TextBoxから派生させて記述するのが通常な手順では?

カスタムコントロールを作る意味は、同一の動作をするコントロールを作成しておけば、いろんなプログラム・フォームで同じ動作をするカスタムTextBoxを作成できるということです。

フォーム内で継承して作るなら、
Public Class Form1

End Class
Partial Class xxtextbox
Inherits System.Windows.Forms.TextBox
Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
If keyData = Keys.A Then
MyBase.BackColor = Color.Aqua
Else
MyBase.BackColor = Color.White
End If
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
End Class
のように作って、一度ビルドすると、ツールボックス内にxxTextBoxってコントロールができますので、そのxxTextBoxを配置して実行し、キー『A』を押すと、バックカラーが変わりますよ。

ValueTextBoxにもProcessCmdKeyにも Return MyBase.ProcessCmdKey(msg, keyData) の記述が見当たりませんが・・・省略してることによって、もしかしたら、Return Trueと同じ動作になってるのかも??

まず簡単な動作から順番に動作確認していきましょう。
ってか、
スーパークラス(ValueTextBox)に作成:
  Protected Overridable Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
  End Function

サブクラス(ProcessCmdKey)に作成:
  Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
  End Function

上はOverridable
下はOverrides
になってますよ(笑)
7-8: hiro_ozzy_5150

> Class名にProcessCmdKeyってのはあんまりよろしくないかと^^;;
> フォーム内で継承して作るなら、

了解しました。フォームないで継承することにし、違う名前にします。

> Return MyBase.ProcessCmdKey(msg, keyData)

これは、Public Class ProcessCmdKey に書いているので大丈夫ですよね。

> 上はOverridable
> 下はOverrides
> になってますよ(笑)

逆にしても同じエラーが出たので、両方 Overrides にするべきだと言うことですね。

ひとつひとつ簡単な構成にして勉強します。
ありがとうございました。
> 7: hiro_ozzy_5150
> フォーム内で継承して作るなら、

今のところ全然継承する必要がないことを理解したのですが、今後のためにフォーム内で継承することにしています。
ちょっとお試しで色々いじりましたが、フォーム内の継承だけでも便利だと実感しています。

話はトピックの題名になるのですが、ずっと調べてきましたが全然解りません。

入力した文字キーコードを矢印キーとして認識させるにはどのようにすればよいのでしょうか。

文字を矢印キーとして認識させたいときと,させたくないときがあります。

以下のソースコードにある MsgBox で表示される文字コードは矢印のコードになっていますが、文字のコードとしてテキストボックスに反映されてしまいます。

Partial Class xxtextbox
  Inherits System.Windows.Forms.TextBox

  Dim i As Integer = 0

  Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
    If keyData = Keys.I Then
      i = 1
    End If

    If keyData = Keys.Escape Then
      i = 0
    End If

    If i = 0 Then
      If keyData = Keys.K Then
        keyData = Keys.Up
        MsgBox("キー変換" & keyData & "成功")
      End If
    End If

    Return MyBase.ProcessCmdKey(msg, keyData)
  End Function
End Class

お願いします。
こんにちは〜〜

やり方は色々あるとおもいます。

方法としては、ProcessCmdKeyでは、何の文字が入力されたかではなく、どのキーが押されたかになりますので、Caps LockとShiftキーの押されてる状態を判断する必要があると思いますよ。

それと、keyData = Keys.Upのように押されたキーを入替ようとしてますが、それではうまくいかないような気がします。
System.Windows.Forms.SendKeys.Send("{UP}")
センドキーでキー自体を押されたようにした方が、カーソル移動の計算とか、復帰改行のとこの移動とかを、全てシステム側が勝手にやってくれるので、楽だと思います。

例)
Public Class Form6
  Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
    Return MyBase.ProcessCmdKey(msg, keyData)
  End Function
End Class
Public Class xxtextbox
  Inherits System.Windows.Forms.TextBox
  Private WM_KEYDOWN As Integer = &H100
  Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
    If msg.Msg = WM_KEYDOWN Then
      Dim keyCode As Keys = CType(msg.WParam.ToInt32(), Keys) And Keys.KeyCode
      Dim uModifiers As Keys = (keyData And Keys.Modifiers)
      If System.Console.CapsLock = True Then
        Select Case uModifiers
          Case Keys.Shift
            If keyCode = Keys.D Then
              System.Windows.Forms.SendKeys.Send("{RIGHT}")
              Return True
            End If
            Exit Select
        End Select
      Else
        Select Case uModifiers
          Case Not (Keys.Shift OrElse Keys.Control OrElse Keys.Alt)
            If keyCode = Keys.D Then
              System.Windows.Forms.SendKeys.Send("{RIGHT}")
              Return True
            End If
            Exit Select
        End Select
      End If
    End If

    Return MyBase.ProcessCmdKey(msg, keyData)
  End Function
End Class

SendKeyを使ってしまうと、CapsLockがかかってる状態で、Shiftを押されながら"D"を入力されると、Shift+→状態になってしまうところは問題になるかも^^;
あと、System.Console.CapsLockはWindowsME以前だとサポートされてないみたいです。(VB2005で開発されてるなら、ME以前での実行はしないですよね??)

がんばってください^^v
> 11: hiro_ozzy_5150

こんにちは。
ソースにインデントまでつけていただき、お手数おかけします。

> System.Windows.Forms.SendKeys.Send("{UP}")

VB も奥が深いですね。
入門書には全然ふれられない命令です。

> SendKeyを使ってしまうと、CapsLockがかかってる状態で、Shiftを押されながら"D"を入力されると、Shift+→状態になってしまうところは問題になるかも^^;

この問題も
2006年12月06日 01:10 10番目の書き込み
を流用して解決しましたが・・・。

> ME以前での実行はしないですよね??

ソフトが一通り完成したらソースコード込みで公開する予定です。
ですので・・・WinXP のみ稼働という仕様にします。

> がんばってください^^v

ありがとうございます。
これからもがんばります。
むしろ、これからもよろしくお願いします。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

Visual Basic User's Club 更新情報

Visual Basic User's Clubのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング