none
TextBoxでIME入力確定と同時にフォーカスを移動させる方法 RRS feed

  • 質問

  • いつも親切に教えていただきありがとうございます。

            private void textBox1_KeyDown(object sender, KeyEventArgs e)
            {
                if (e.KeyCode == Keys.Enter)
                {
                    button1.Focus();
                }
            }
    上のコードですと,
      ア[Spaceで変換]→イ[Enterで確定]→ウ[Enterでフォーカス移動]
    となりますが,これをイの段階でbutton1にフォーカスを移動させたいのですがどの様にすれば可能でしょうか。

    2006年8月1日 2:42

回答

  • データ抽出の実行結果を見るまでに,私のコードではenterキーを3回押さねば成りません。
       ア 日本語変換確定のenter
       イ フォーカス移動のenter
       ウ 抽出実行のEnter
    それで,ennterキーを押下する回数を2回にしたいという発想なのです。


    用件を満たすか不明ですが、フォーカスアウトしたタイミング(イのあと)で検索してしまう、という手もあると思います。
    LeaveイベントでTextBoxからのフォーカスアウトを検知して、抽出実行ボタンをPerformClick()するという感じで。
    2006年8月1日 5:51

すべての返信

  • 確定はどこにいくのですか?

    そんな事をしてしまうと、かなり分かり難いオペレーションだと思いますが。

    2006年8月1日 3:26
  • TextChangedイベントでできるとは思いますが、
    囚人さんと同じく、あまりいい対応とは思いません。
    TextChangedイベントでは一言しかいれられないし、英字には対応できないし。
    どんなケースで必要なのかわかれば、ほかのアイデアもあるような気がします。

    2006年8月1日 4:06
  • 囚人さん,mars12さん,早速の対応ありがとうございます。

    textBox1:データ抽出のためのキー
    button1: データ抽出を実行するボタン
    データ抽出の実行結果を見るまでに,私のコードではenterキーを3回押さねば成りません。
       ア 日本語変換確定のenter
       イ フォーカス移動のenter
       ウ 抽出実行のEnter
    それで,ennterキーを押下する回数を2回にしたいという発想なのです。

    アの日本語変換確定のenterを察知するための簡単な方法がないのかと思って質問させていただいたというわけです。

     簡単にはいかないようですね。あきらめます。どうもありがとうございました。

     

     

     

     

    2006年8月1日 5:39
  • データ抽出の実行結果を見るまでに,私のコードではenterキーを3回押さねば成りません。
       ア 日本語変換確定のenter
       イ フォーカス移動のenter
       ウ 抽出実行のEnter
    それで,ennterキーを押下する回数を2回にしたいという発想なのです。


    用件を満たすか不明ですが、フォーカスアウトしたタイミング(イのあと)で検索してしまう、という手もあると思います。
    LeaveイベントでTextBoxからのフォーカスアウトを検知して、抽出実行ボタンをPerformClick()するという感じで。
    2006年8月1日 5:51
  • ボタンをマウスクリックにも対応させたいということで,アとイを一つの動作にしたかったのですが・・・・。

    どうもありがとうございました。

    2006年8月1日 6:58
  • ユーザーの使い勝手は置いといて、実現の考え方だけ例として示します。

    IMEの入力確定を知るには、WM_IME_COMPOSITIONを捕まえる事によって可能です。そのタイミングで独自に定義したイベントを発動し、そのイベントの引数として今変換された文字が返えるようにします。フォームでは、そのイベントプロシージャにおいて、イベントの引数から今変換された文字を取り出し、テキストボックスに既に入力されている文字列の後にくっ付けて、それで検索にいけば良いと思います。

    #日本語変換の結果で自動で検索するというようなことはやったことありませんが、例えば数字4桁のコードを入力したら自動的に検索するというようなことはやったことがあります。

    2006年8月2日 5:05
    モデレータ
  • trapemiyaさん,ありがとうございます。

    初心者の私には難しそうですが,研究してみようと思っております。

     

    2006年8月2日 21:47
  • # 皆さんも書かれていますが、使い勝手が良いとは思えませんので、
    # ユーザの要望でないのであれば、やめておいた方が無難だと思います。
    # もし、ユーザの要望であれば、如何に使い勝手の良いものでないかを、
    # きちんと説明した方がよいと思います。

     zen73 さんからの引用

    ボタンをマウスクリックにも対応させたいということで,アとイを一つの動作にしたかったのですが・・・・。

    # この場合、マウスクリックは何か関係あるのでしょうか?
    結局、この様な要件であれば、
    this.AcceptButton = button1;
    で、よいのではないでしょうか?
    または、
     zen73 さんからの引用
     
            private void textBox1_KeyDown(object sender, KeyEventArgs e)
            {
                if (e.KeyCode == Keys.Enter)
                {
    //                button1.Focus();
                    button1.PerformClick();
                }
            }

    # どちらもボタンを押す前に明示的にフォーカスをあててませんが。
    # あと、IMEがオフの場合に、
    # Enterキー1回でbutton1が押せてしまいますが、問題ないですよね?(^-^;)

    2006年8月2日 22:33
  • 辛島さん,ありがとうございました。

    多くの皆さんにお世話になっていますので簡単に自己紹介を・・・。
     ○63才のアマチュアです(北海道在住)。
     ○VS2002とVS2005の違いを勉強中の相変わらずの初心者です。

     

    2006年8月2日 23:36
  •  zen73 さんからの引用

     ○63才のアマチュアです(北海道在住)。
     ○VS2002とVS2005の違いを勉強中の相変わらずの初心者です。

    GDNJ掲示板でも、ごいっしょしましたね。(^^

    ところで、上の私の発言ですが、それを実現するテストコードを書いて見ました。 

    
    public class TextBoxImeEx : System.Windows.Forms.TextBox
    {
      const int WM_IME_ENDCOMPOSITION = 0x010E;
      const int GCS_RESULTSTR = 0x0800;
    
      [DllImport("Imm32.dll", CharSet = CharSet.Auto)]
      public static extern IntPtr ImmGetContext(IntPtr hWnd);
    
      [DllImport("Imm32.dll")]
      public static extern int ImmGetCompositionString(
        IntPtr hIMC,
        int dwIndex,
        IntPtr lpBuf,
        int dwBufLen
        );
    
      [DllImport("Imm32.dll", CharSet = CharSet.Auto)]
      public static extern bool ImmReleaseContext(IntPtr hWnd, IntPtr hIMC);
    
      [Serializable]
      public class CompositionEventArgs : EventArgs
      {
        public string ImeStr;
      }
    
      //デリゲート & イベントの定義
      public delegate void CompositionEventHandler(object sender, CompositionEventArgs e);
      public event CompositionEventHandler CompositionEvent;  //IMEの変換が確定した時に、CompositionEventを発生させる。
    
      protected override void WndProc(ref Message m)
      {
        switch (m.Msg)
        {
          case (int)WM_IME_ENDCOMPOSITION:  //IMEの変換が確定した時(変換終了)
    
              IntPtr buffer = IntPtr.Zero;
              IntPtr Imc = IntPtr.Zero;
    
              try
              {
                //変換された文字列を取得する。
                Imc = ImmGetContext(this.Handle);
                int bytes = ImmGetCompositionString(Imc, (int)GCS_RESULTSTR, IntPtr.Zero, 0);
    
                buffer = Marshal.AllocHGlobal(bytes);
                ImmGetCompositionString(Imc, (int)GCS_RESULTSTR, buffer, bytes);
                byte[] arrByte = new Byte[bytes];
                Marshal.Copy(buffer, arrByte, 0, bytes);
                string compositeStr = Encoding.GetEncoding(932).GetString(arrByte);
    
                //変換が確定した時にイベントを発動
                CompositionEventArgs args = new CompositionEventArgs();
                args.ImeStr = compositeStr;
                CompositionEvent(this, args);
              }
              finally
              {
                ImmReleaseContext(this.Handle, Imc);
                Marshal.FreeHGlobal(buffer);
              }
            break;
        }
    
        base.WndProc(ref m);
      }
    }

    使う側では、以下のように使います。
    
    private void textBoxImeEvent_Load(object sender, EventArgs e)
    {
      textBox1.CompositionEvent += new TextBoxImeEx.CompositionEventHandler(textBox1_CompositionEvent);
    }
    
    void textBox1_CompositionEvent(object sender, TextBoxImeEx.CompositionEventArgs e)
    {
      MessageBox.Show(e.ImeStr);
    }
    
    2006年8月3日 5:18
    モデレータ
  •  trapemiya さんからの引用

    GDNJ掲示板でも、ごいっしょしましたね。(^^

    やはりそうでしたか。アプリ完成まで随分と助けていただきました。
    これからもよろしくお願いいたします。

     trapemiya さんからの引用

    ところで、上の私の発言ですが、それを実現するテストコードを書いて見ました。

    ありがとうございます。以前「フリガナ取得」で苦労した苦手なところですががんばってやってみます。

     

    2006年8月3日 8:46
  • trapemiyaさんからコードを書いてくださってまで教えていただきましたが,もう少し勉強してから使わせていただきたいと思います。

    いまのところは次のようにして処理しています。

       private void Form1_Load(object sender, EventArgs e)
            {
         ・・・・・・・
                btnFilter.Enabled = false;
                btnFilterNone.Enabled = false;
            }

            private void tbxKey_TextChanged(object sender, EventArgs e)
            {
                btnFilter.Enabled = (tbxKey.Text == "") ? false : true;
                if (tbxKey.Text != "")
                {
                    btnFilter.Focus();
                }
            }

            private void tbxKey_Enter(object sender, EventArgs e)
            {
                tbxKey.SelectAll();
                btnFilter.Enabled = false;
            }

            private void tbxKey_MouseDown(object sender, MouseEventArgs e)
            {
                tbxKey.SelectAll();
                btnFilter.Enabled = false;
            }

    皆さんありがとうございました。

    2006年8月12日 11:38