追加質問のようなので、解決済みマークを一旦外しておきます。 ■No33006に返信(きっずさんの記事) > こちらの意図した動きになりました。 No33005 のサンプルコードは簡易実装です。 受け渡された引数を無視して常に「return 0;」としていますので、 ダブルクリック時には、単語単位の選択が行えず、 カーソルが先頭に戻ってしまうという弊害があります。 必要に応じて、適宜修正してみて下さい。 > 何故上記の内容を記述することで意図した動きに変わったのでしょうか? 今回使用した EM_SETWORDBREAKPROC メッセージというのは、 単語の区切りをカスタマイズするためのものです。 これにより、今回問題としていた『テキストの折り返し位置』の他、 [Ctrl](+[Shift])+[→]キー、あるいはダブルクリックでの 『文字列選択』の動作が上書きされることになります。 この EM_SETWORDBREAKPROC では、単語の区切りをカスタマイズするために、 EditWordBreakProc というコールバック関数を受け渡す必要があります。 今回は無条件に 0 を return するようにしていますが、本来は 引数に応じた値を return せねばなりません。このコールバック関数の 具体的な仕様については、下記の URL を参照してみてください。 https://msdn.microsoft.com/ja-jp/library/cc410811.aspx なお EditWordBreakProc が働くのは、次回以降の入力・選択に対してです。 既に入力されている文字列の折り返し位置までは変更されないため、先のコードでは Text プロパティに別の文字列を再設定することで、設定が即時反映されるようにしています。 (なお TextBox は、'\0' 以降の文字列を切り捨てる仕様なため、結果として同じ) 参考までに、コールバック関数にどのような値が渡されるのかを監視できるようにしてみました。 // using System.Runtime.InteropServices; private enum WorkBreak { WB_LEFT = 0, WB_RIGHT = 1, WB_ISDELIMITER = 2, WB_CLASSIFY = 3, // WB_MOVEWORDLEFT = 4, // WB_MOVEWORDRIGHT = 5, // WB_LEFTBREAK = 6, // WB_RIGHTBREAK = 7, WB_MOVEWORDPREV = 4, WB_MOVEWORDNEXT = 5, WB_PREVBREAK = 6, WB_NEXTBREAK = 7, } [Flags] private enum WordBreakFlags { WBF_CLASS = 0x0F, WBF_ISWHITE = 0x10, // 空白文字 WBF_BREAKLINE = 0x20, // 区切り文字 WBF_BREAKAFTER = 0x40, // この文字の後での改行を許可 } [DllImport("user32")] private static extern IntPtr SendMessage(IntPtr hWnd, int msgId, IntPtr wParam, EditWordBreakProc lParam); private delegate int EditWordBreakProc(IntPtr ipch, int ichCurrent, int cch, WorkBreak code); private int EditWordBreak(IntPtr ipch, int ichCurrent, int cch, WorkBreak code) { var srcText = Marshal.PtrToStringAuto(ipch, cch); var currentChar = (ichCurrent >= srcText.Length) ? "" : "(" + srcText[ichCurrent] + ")"; var msg = string.Format("モード={0}, 切分位置={1}{2}, 文字列={3}", code, ichCurrent, currentChar, srcText); this.listBox1.TopIndex = this.listBox1.Items.Add(msg); return 0; // 本来は 0 固定ではなく、引数に応じた値を返すように実装する // // code == WB_ISDELIMITER の場合:区切り文字なら 1、それ以外なら 0 を返す // code == WB_CLASSIFY の場合:WBF_系のフラグ値を返す // code が上記以外:単語の開始点のインデックスを返す } private void Form1_Load(object sender, EventArgs e) { const int EM_SETWORDBREAKPROC = 0xD0; SendMessage(this.textBox1.Handle, EM_SETWORDBREAKPROC, IntPtr.Zero, this.EditWordBreak); this.textBox1.Text += '\0'; }
■No33004に返信(きっずさんの記事) > textbox1.Multiline = True; Textbox1.Multiline = True ' VB (or Visual Studio プロパティ画面) textbox1.Multiline = true; // C# textbox1.Multiline = True; ??? > テキストボックスの端で折れてほしいのですが > 意図しない場所で改行が入ってしまいます。 これでどうでしょう。 [System.Runtime.InteropServices.DllImport("user32")] private static extern IntPtr SendMessage(IntPtr hWnd, int msgId, IntPtr wParam, EditWordBreakProc lParam); private delegate int EditWordBreakProc(IntPtr ipch, int ichCurrent, int cch, int code); private void Form1_Load(object sender, EventArgs e) { const int EM_SETWORDBREAKPROC = 0xD0; SendMessage(this.textBox1.Handle, EM_SETWORDBREAKPROC, IntPtr.Zero, delegate { return 0; }); this.textBox1.Text = this.textBox1.Text + '\0'; }