none
TextBox.GetPositionFromCharIndexがうまく機能しない RRS feed

  • 質問

  • TextBox.SelectionStart() にて取得したインデックスを用いて(正常に動作していることは確認)、

    TextBox.GetPositionFromCharIndex(int _index) を実行しても必ずX=0,Y=0となります。

    この結果に対する原因は、現在不明です。

    TextChanged イベントにて確認したものです。

    お手数ですが、お分かりの方ご返事お待ちしております。

    よろしくお願いいたします。

    //-----------------------

    TextBox のプロパティ:
    MulthLine = True
    ScrollBars = Both
    WordWrap = False

    環境:
    VC#2010EE
    windows7 64bit Professional sp1

    .Net Framework 環境
    (http://www.atmarkit.co.jp/fwin2k/win2ktips/246checkvdnfw/checkvdnfw.html):
    *:****>checkvdnfw
    ----- ローカル・コンピュータ(****) -----
    .NET Framework 2.0 Service Pack 2 がインストール済みです
     日本語Language Pack(Service Pack 2)がインストール済みです
    .NET Framework 3.0 Service Pack 2 がインストール済みです
     日本語Language Pack(Service Pack 2)がインストール済みです
    .NET Framework 3.5 Service Pack 1 がインストール済みです
     日本語Language Pack(Service Pack 1)がインストール済みです
    .NET Framework 4 (フル版)がインストール済みです
     日本語Language Packがインストール済みです



    • 編集済み Sura4849 2012年6月23日 15:37
    2012年6月23日 15:28

回答

  • テキストボックスにフォーカスがある状態なら Win32API の GetCaretPos 関数を使うのも手かと。
    時間が不足していたので動作検証不足となってしまいましたが、実験していたコードを貼り付けます。
    このコードは、文末で改行すると数値が変になります。。。

    [DllImport("user32.dll")]
    private static extern bool GetCaretPos(out Point point);
    
    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        Point apiPoint;
        GetCaretPos(out apiPoint);
    
        int charIndex = textBox1.GetCharIndexFromPosition(apiPoint);
        int r = textBox1.GetLineFromCharIndex(charIndex);
        int c = charIndex - textBox1.GetFirstCharIndexOfCurrentLine();
    
        var sb = new StringBuilder();
        sb.AppendFormat("GetCaretPos({0}, {1})", apiPoint.X, apiPoint.Y);
        sb.AppendFormat("RC({0}, {1})", r, c);
        Text = sb.ToString();
    }

    • 回答としてマーク Sura4849 2012年6月24日 1:28
    2012年6月23日 23:54
    モデレータ

すべての返信

  • 入力されている文字列の最後にカーソルがあると、0,0 になりますね。途中だと 0 以外の数字が入ってくるようです。
    2012年6月23日 16:33
  • ご確認有難うございます。

    私の環境も同じ結果を得ました。

    こうなると、地道に Text プロパティ内の'\n', '\r'を検査して算出するしかないのでしょうか?

    上手い方法があると嬉しいのですが。

    ちなみに、ドットベースの座標ではなくカーソル(キャレット)の行と列を取得する方法はあるのでしょうか。


    • 編集済み Sura4849 2012年6月23日 17:00
    2012年6月23日 16:58
  • テキストボックスにフォーカスがある状態なら Win32API の GetCaretPos 関数を使うのも手かと。
    時間が不足していたので動作検証不足となってしまいましたが、実験していたコードを貼り付けます。
    このコードは、文末で改行すると数値が変になります。。。

    [DllImport("user32.dll")]
    private static extern bool GetCaretPos(out Point point);
    
    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        Point apiPoint;
        GetCaretPos(out apiPoint);
    
        int charIndex = textBox1.GetCharIndexFromPosition(apiPoint);
        int r = textBox1.GetLineFromCharIndex(charIndex);
        int c = charIndex - textBox1.GetFirstCharIndexOfCurrentLine();
    
        var sb = new StringBuilder();
        sb.AppendFormat("GetCaretPos({0}, {1})", apiPoint.X, apiPoint.Y);
        sb.AppendFormat("RC({0}, {1})", r, c);
        Text = sb.ToString();
    }

    • 回答としてマーク Sura4849 2012年6月24日 1:28
    2012年6月23日 23:54
    モデレータ
  • ご返答有難うございます。

    ドットベースのキャレット座標を求めるには GetCaretPos 関数を用いるほうが良さそうです。

    ただ、得られた座標から GetCharIndexFromPosition メソッドを用いると1インデックス足りなく、さらに1加えるかもしくは直接 SelectionStart プロパティを用いる必要がありました。

    以上を以て解決と致します。

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


    • 編集済み Sura4849 2012年6月24日 1:33
    2012年6月24日 1:33