none
Formが起動した直後に、Textboxにフォーカスがあって、日本語入力がONになっている状態にしたい RRS feed

  • 質問

  • 初めて投稿させて頂きます。

    Textboxが1個だけがあるFormを作って、起動した直後にそのTextboxにフォーカスがあって、日本語入力がONになっている状態にしたいと思っています。

     

    TextboxのIMEModeをOnやHiraganaにしても起動時のTextboxは半角英語の状態です。他のツール上でIMEをONにしていても強制的に半角英語になります。

    ImeModeChangedで捕まえてみると結局何が設定されていてもIMEModeはOffになってしまっています。

     

    ImmSetOpenStatusを呼べばフォーカスがあっていない状態で起動します。フォーカスを合わせれば日本語入力はONになります。

    フォーカスがあっていない原因はImmSetOpenStatusが例外を発生させるからでした。但し例外をキャッチすると日本語入力はOFFになってしまいます。

     

    ImmSetOpenStatusを呼ぶソースを記載しておきます。

            [DllImport("CoreDll.Dll")]
            private extern static int ImmSetOpenStatus(IntPtr hMMC, int fOpen);
            private void Form1_Load(object sender, EventArgs e)
            {
                ImmSetOpenStatus(IntPtr.Zero, 1);
            }

    因みに[DllImport("Imm32.dll")]では日本語入力はONになりませんでした。

     

    起動した直後にそのTextboxにフォーカスがあって、日本語入力がONになっている状態にする方法を御存じの方はお教えて頂ければと思います。

     

    当方の開発環境はWindows7,64bit Visual C# 2010 Expressです。

    2010年12月11日 12:06

回答

  • Azuleanさんと同じ環境のマシンである、Windows 7 (x64) Ultimate + .NET Framework 4 + Office 2010(x64)、Microsoft Office IME 2010 の環境で試してみましたが、問題は発生しませんでした。IMEを入れ直したということはなく、Office 2010を入れただけです。私専用の開発マシンなので間違いありません。
    というわけで、必ずしも

    >皆さんの話を総合するとWindows 7 (x64)のMicrosoft Office IMEが駄目。それ以外のIMEであれば問題なし。

    というわけではなく、何かしら他の影響も関係しているのではないかと思います。例えばIMEの設定や、他のアプリケーションの影響などです。
    ちなみに試したプログラムはフォームにTextBoxが一つあるだけの単純なものです。載せるまでもないかとは思いますが、行き違いがないことを確認するためにも、一応コードを載せておきます。

    public partial class ImeOnTest : Form
    {
       public ImeOnTest()
       {
         InitializeComponent();
       }
    
    }
    
    partial class ImeOnTest
    {
       /// <summary>
       /// Required designer variable.
       /// </summary>
       private System.ComponentModel.IContainer components = null;
    
       /// <summary>
       /// Clean up any resources being used.
       /// </summary>
       /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
       protected override void Dispose(bool disposing)
       {
         if (disposing && (components != null))
         {
            components.Dispose();
         }
         base.Dispose(disposing);
       }
    
       #region Windows Form Designer generated code
    
       /// <summary>
       /// Required method for Designer support - do not modify
       /// the contents of this method with the code editor.
       /// </summary>
       private void InitializeComponent()
       {
         this.textBox1 = new System.Windows.Forms.TextBox();
         this.SuspendLayout();
         // 
         // textBox1
         // 
         this.textBox1.ImeMode = System.Windows.Forms.ImeMode.On;
         this.textBox1.Location = new System.Drawing.Point(43, 71);
         this.textBox1.Name = "textBox1";
         this.textBox1.Size = new System.Drawing.Size(100, 19);
         this.textBox1.TabIndex = 0;
         // 
         // ImeOnTest
         // 
         this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
         this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
         this.ClientSize = new System.Drawing.Size(284, 262);
         this.Controls.Add(this.textBox1);
         this.Name = "ImeOnTest";
         this.Text = "ImeOnTest";
         this.ResumeLayout(false);
         this.PerformLayout();
    
       }
    
       #endregion
    
       private System.Windows.Forms.TextBox textBox1;
    }
    

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    • 回答としてマーク 山本春海 2010年12月28日 2:09
    2010年12月14日 1:26
    モデレータ
  • ご指摘ありがとうございます。

    trapemiyaさんの検証から、僕のだした「Windows 7 (x64)のMicrosoft Office IMEが駄目。それ以外のIMEであれば問題なし。」という結論は間違っていたようです。

     

    念のためtrapemiyaさんのソースをそのまま使って

    Windows 7 (x64) Professional+ .NET Framework 4 + Office 2007、Microsoft Office IME 2010

    で試したみましたが、僕の環境下では駄目でした。


    ここから先は色々な環境下での検証数をあげていき絞っていくのが一番良いだと思いますが、個人では難しいかなと思います。

    とりあえず、IMEの設定や他のソフトなど思いついたところから試していこうと思います。

    ありがとうございます。


    • 回答としてマーク 山本春海 2010年12月28日 2:09
    2010年12月14日 14:58

すべての返信

  • TextboxのIMEModeをOnやHiraganaにしても起動時のTextboxは半角英語の状態です。


    通常はImeModeプロパティで制御できるはずですが、何か特殊なことをされているのでしょうか? 私の方では問題なく制御できています。

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    2010年12月11日 12:55
    モデレータ
  • trapemiyaさん。返信有難うございます。

    デバッグとして、新たにFormを作って、テキストボックスを1つ置いて、ImeModeをHiraganaにだけしました。ソースは1行も書いていません。

    この状態で起動しても半角英語の状態になってしまいます。

    Windows7,64bit Visual C# 2010 Express以外では試していませんが、動作環境なども同じでしょうか?


    2010年12月11日 13:04
  • あと問題になり得るのは使用している IME の問題ですが。

    とりあえず、Windows 7 64bit / ATOK 2009 / .NET Framework 4 では問題ないですね。

    2010年12月11日 13:14
  • 当方のIMEはMicrosoftOfficeIME2007です。これが問題なのでしょうか?

    起動した状態ではIME上の入力モードは、半角英語です。

    手動で変えればもちろん日本語ひらがなには出来ます。

    ただやりたいことは、この手動の一手間をなくしたいと思っております。

    それで、手動で変えないでプログラムでやる方法としてImmSetOpenStatusを呼ぶという方法を取りました。

    これで、ワンクリックすれば日本語ひらがなになってくれます。

    しかし、このワンクリックもなくしたいと思っています。

    なくすためには例外が発生しているので、今度はtry-catchで囲むと、また最初の状況のように半角英語になってしまいます。

    起動時に手動がなく日本語ひらがなに出来ればOKなのですが、MicrosoftIMEでは出来ないのでしょうか?
    2010年12月11日 13:27
  • 手元にATOKはないので、試せませんでしたが、GoogleIMEをいれたところ希望どおりの動作になりました。

    しかしやはりユーザーの最も多いMicrosoftIMEでやりたいと思いますが、今のところ上手くいっていません。

    2010年12月11日 13:35
  •  本筋ではないところにくっつけますが。。。

    それで、手動で変えないでプログラムでやる方法としてImmSetOpenStatusを呼ぶという方法を取りました。
    これで、ワンクリックすれば日本語ひらがなになってくれます。
    しかし、このワンクリックもなくしたいと思っています。
    なくすためには例外が発生しているので、今度はtry-catchで囲むと、また最初の状況のように半角英語になってしまいます。

    よくわかりません。
    クリックが必要というのは、そういったコードを書いたからですよね。
    クリックをなくすために例外が発生したとありますが、これはどういったコードを書いたんでしょうか。

    ご自身ではよく理解されているので端折られているのかもしれませんが、第三者から見ると何をやってどのように失敗したのか見えません。
    それなのに、「できないのでしょうか?」と聞かれても、答えようがありません。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    2010年12月11日 14:38
    モデレータ
  • ご指摘ありがとうございます。コードは一番最初に書いたのでは、自分だけの理解ではしょってしまいましたが、

    おっしゃられる通り第三者に分かりづらい記述になってしまいました。

    もう1度流れに沿って詳細に記載します。


    Formを作って、テキストボックスを1つ置いて、ImeModeをHiraganaにします。

    次にLoad時のイベントにコードを書きます。

    [DllImport("CoreDll.Dll")]

            private extern static int ImmSetOpenStatus(IntPtr hMMC, int fOpen);
            private void Form1_Load(object sender, EventArgs e)
            {
                ImmSetOpenStatus(IntPtr.Zero, 1);
            }

    この状態で起動すると、テキストボックスにフォーカスがあっていない状態で起動します。そして手動でテキストボックスをクリックしてフォーカスを合わせた時は

    日本語入力はONになっています。

     

    なぜテキストボックスにフォーカスがあっていないのかを追っていたときにコードのImmSetOpenStatusの後の}にブレイクポイントを置いたところ、ブレイクでとまりませんでした。

    そこで、

               try
                {
                    ImmSetOpenStatus(IntPtr.Zero, 1);
                }
                catch(Exception)
                {
                    MessageBox.Show("例外");
                }
    としたところ例外というメッセージボックスが出ました。この時も日本語入力はONです。

     

    しかし、

               try
                {
                    ImmSetOpenStatus(IntPtr.Zero, 1);
                }
                catch(Exception)
                {
                    //MessageBox.Show("例外");
                }

    こうすると再び日本語入力はOFFになってしまいます。

    結果望みの挙動になっていない状態です。

    何か方法をご存知の方がいれば教えていただければ幸いと思います。

    2010年12月11日 15:10
  • 私が試した環境は、Windows 7 32bit / IME 2007 / .NET Framework 4 です。この環境で問題なく動いています。

    ところでどのような例外が出ているのでしょうか?

    Catch(Exception e)
    {

    }

    などとして、eの内容を調べてみて下さい。

    また、そのテキストボックスのFocusメソッドを実行し、そのテキストボックスのEnterイベントでImeModeを設定するとうまく行きますでしょうか?

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    2010年12月11日 15:42
    モデレータ
  • trapemiyaさんのところではIMEでも動くのですね。

    となると僕のローカル環境化だけで起きている可能性もありますね。

    先ほどIMEを2010にしてみましたが、結果は同じでした。

     

    例外は「"DLL 'CoreDll.Dll' を読み込めません: 指定されたモジュールが見つかりません。」です。

    この例外は

    [DllImport("Imm32.dll")]

    private extern static int ImmSetOpenStatus(IntPtr hMMC, int fOpen);

    とインポートするdllを変更すると出なくなります。

    ところが、Imm32.dllにするとやはり起動時は半角英語になります。

     

    またEnterイベントでImeModeを設定する方法でも結果は同じで半角英語のままです。


    2010年12月12日 1:28
  • 追記です。ImmSetOpenStatusはどうも関係ないようです。

     

    private void Form1_Load(object sender, EventArgs e)
            {
               MessageBox.Show("aa");
            }

    で、MessageBoxを出た後に、テキストボックスをクリックすれば日本語入力になりました。

     

    この点からいろいろ試してみたところ、最初に別の場所にフォーカスがあって、次にテキストボックスにフォーカスを合わせれば日本語入力はONになることはわかりました。

     

    しかし僕がやりたいのは最初にテキストボックスにフォーカスがあって、なおかつ日本語入力ONです。これはうまくいっておりません。


    2010年12月12日 1:59
  • 例外は「"DLL 'CoreDll.Dll' を読み込めません: 指定されたモジュールが見つかりません。」です。

    CoreDll.dll は Windows Mobile など、携帯端末向けの Windows の場合に使うものであり、普通の Windows XP などでは Imm32.dll を利用します。

    呼んだ結果、うまく動かないからと言って全く違うコードに変えてはいけません。

    ところが、Imm32.dllにするとやはり起動時は半角英語になります。

    当面は「この入力モードが変わらないのはなぜか?」か、「回避策はないか?」で考えるべきでしょう。

     

    ところで、ImmSetOpenStatus の第 1 引数に IntPtr.Zero (NULL) って何か定義があるのでしょうか?
    さくっとは見つからなかったので、少し引っかかった点です。(原因とは異なる可能性があります)


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    2010年12月12日 2:08
    モデレータ
  • 軽く再現性を見てみました。

    Windows 7 (x64) Ultimate + .NET Framework 4 + Office 2010(x64)、Microsoft Office IME 2010 の環境で、x86/x64 の両方のプラットフォーム構成で ImeMode プロパティの効果がないようです。
    また、ImmSetOpenStatus を TextBox の Enter イベントのタイミングで呼ぶようにすると、最初のフォーム表示時は反映されませんが、別のコントロールにフォーカスを移し、再度 TextBox にフォーカスを当てると IME が有効になりました。
    この再現する環境に ATOK を入れればどうなるかについては見ていません。

    また、手元の Windows 7 (x86) + .NET Framework 4 上の ATOK 2010 と Microsoft IME (10.1.7600.0) では問題ありませんでした。

    これらの実験結果から、x64 環境の Microsoft IME という風に因子が絞られつつあるかなと見立てていますが、これより先はまだ窺ってません。

    追記
    前述の Windows 7 (x64) の環境で Microsoft IME (10.1.7600.0) を追加し直して、デフォルトに設定してどうなるかを見ると、ひらがなが有効な状態で開きました。Office 付属の IME が怪しいんでしょうか?


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    2010年12月12日 3:38
    モデレータ
  • IME 2007にはサービスパックが出ていますので、ひょっとしてその関係かもしれません。ちなみに私の環境では最新のサービスパックが当たっていました。

    Office IME 2007 で入力した文字を漢字に変換できない場合の対処方法
    http://support.microsoft.com/kb/932102/ja

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    2010年12月12日 4:26
    モデレータ
  • ご指摘ありがとうございます。調べているときにCoreDLL.DLLのヒット数が多かったため、こちらが正しいという先入観を持ってしまっていました。

    おっしゃられるとおり、なんとなく上手くいっているだけの何の意味もないコードです。

    この掲示板を読む人にとっても誤解を招いてしまう記述失礼しました。ImmSetOpenStatusは「Formが起動した直後に、Textboxにフォーカスがあって、日本語入力がONになっている状態にしたい」場合には何の関係もありません。ImmSetOpenStatusを使う場合は[DllImport("CoreDLL.DLL")]ではなく[DllImport("Imm32.dll")]を使うようにする旨再度記載しておきます。

    失礼しました。

    2010年12月12日 22:40
  •  

    こちらでも、試してみましたが、同様にMicrosoft IMEではひらがな状態で開きました。

    おっしゃられるとおりWindows 7 (x64) の環境でMicrosoft Office IMEが駄目なようです。

     

    とりあえず自分の環境で試したのは、

    ×|Windows 7 (x64) |Microsoft Office IME2007|

    ×|Windows 7 (x64) |Microsoft Office IME2010|

    ○|Windows 7 (x64) |Microsoft IME|

    ○|Windows 7 (x64) |GoogleIME|

    となります。

     

    皆さんの話を総合するとWindows 7 (x64)のMicrosoft Office IMEが駄目。それ以外のIMEであれば問題なし。

    他の環境下なら大丈夫そうだけれど、検証データがないのでもしかしたらそのほかのOSの64bit版でも起きるかもといったところでしょうか。

    とりあえず、このバグが起きる環境は意外に少ないようなので、現状のTextboxのIMEModeをHiraganaでそのまま開発は続けつつ、

    今回得た情報をまとめてバグ報告をすることで終了にしようと思います。

     

    今回掲示板を使ってみて自分では検証しきれないものをみなさんのアドバイスでずいぶん助けられました。

    特に返答頂けた方には厚くお礼申しげます。ありがとうございました。


    2010年12月13日 15:16
  • Azuleanさんと同じ環境のマシンである、Windows 7 (x64) Ultimate + .NET Framework 4 + Office 2010(x64)、Microsoft Office IME 2010 の環境で試してみましたが、問題は発生しませんでした。IMEを入れ直したということはなく、Office 2010を入れただけです。私専用の開発マシンなので間違いありません。
    というわけで、必ずしも

    >皆さんの話を総合するとWindows 7 (x64)のMicrosoft Office IMEが駄目。それ以外のIMEであれば問題なし。

    というわけではなく、何かしら他の影響も関係しているのではないかと思います。例えばIMEの設定や、他のアプリケーションの影響などです。
    ちなみに試したプログラムはフォームにTextBoxが一つあるだけの単純なものです。載せるまでもないかとは思いますが、行き違いがないことを確認するためにも、一応コードを載せておきます。

    public partial class ImeOnTest : Form
    {
       public ImeOnTest()
       {
         InitializeComponent();
       }
    
    }
    
    partial class ImeOnTest
    {
       /// <summary>
       /// Required designer variable.
       /// </summary>
       private System.ComponentModel.IContainer components = null;
    
       /// <summary>
       /// Clean up any resources being used.
       /// </summary>
       /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
       protected override void Dispose(bool disposing)
       {
         if (disposing && (components != null))
         {
            components.Dispose();
         }
         base.Dispose(disposing);
       }
    
       #region Windows Form Designer generated code
    
       /// <summary>
       /// Required method for Designer support - do not modify
       /// the contents of this method with the code editor.
       /// </summary>
       private void InitializeComponent()
       {
         this.textBox1 = new System.Windows.Forms.TextBox();
         this.SuspendLayout();
         // 
         // textBox1
         // 
         this.textBox1.ImeMode = System.Windows.Forms.ImeMode.On;
         this.textBox1.Location = new System.Drawing.Point(43, 71);
         this.textBox1.Name = "textBox1";
         this.textBox1.Size = new System.Drawing.Size(100, 19);
         this.textBox1.TabIndex = 0;
         // 
         // ImeOnTest
         // 
         this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
         this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
         this.ClientSize = new System.Drawing.Size(284, 262);
         this.Controls.Add(this.textBox1);
         this.Name = "ImeOnTest";
         this.Text = "ImeOnTest";
         this.ResumeLayout(false);
         this.PerformLayout();
    
       }
    
       #endregion
    
       private System.Windows.Forms.TextBox textBox1;
    }
    

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    • 回答としてマーク 山本春海 2010年12月28日 2:09
    2010年12月14日 1:26
    モデレータ
  • ご指摘ありがとうございます。

    trapemiyaさんの検証から、僕のだした「Windows 7 (x64)のMicrosoft Office IMEが駄目。それ以外のIMEであれば問題なし。」という結論は間違っていたようです。

     

    念のためtrapemiyaさんのソースをそのまま使って

    Windows 7 (x64) Professional+ .NET Framework 4 + Office 2007、Microsoft Office IME 2010

    で試したみましたが、僕の環境下では駄目でした。


    ここから先は色々な環境下での検証数をあげていき絞っていくのが一番良いだと思いますが、個人では難しいかなと思います。

    とりあえず、IMEの設定や他のソフトなど思いついたところから試していこうと思います。

    ありがとうございます。


    • 回答としてマーク 山本春海 2010年12月28日 2:09
    2010年12月14日 14:58