編集コントロール テキストの操作

システムは、ユーザーが開始したすべてのテキスト操作を自動的に処理し、操作が完了したときにアプリケーションに通知します。

これ以降のトピックでは、ユーザーが開始するテキスト操作とアプリケーションの応答について説明します。

編集コントロールを選択する

ユーザーは、コントロールをマウスでクリックするか、Tab キーを押してコントロールに移動することで、編集コントロールを選択できます。 タブで移動する方法は、システムが提供する定義済みのキーボード インターフェイスの一部です。 このインターフェイスの詳細な説明については、「ダイアログ ボックス」を参照してください。 ユーザーが編集コントロールを選択すると、システムはそのコントロールにキーボード フォーカスを与え (「キーボード入力の概要」の「キーボード フォーカスとアクティブ化」を参照)、反転ビデオを使用してテキストを強調表示します。

テキストを設定および取得する

アプリケーションでは、SetWindowText 関数または SetDlgItemText 関数を使用するか、コントロールに WM_SETTEXT メッセージを送信することで、編集コントロールのテキストを設定できます。

編集コントロールからすべてのテキストを取得するには、まず GetWindowTextLength 関数または WM_GETTEXTLENGTH メッセージを使用して、テキストを格納するのに必要なバッファーのサイズを決定します。 次に、GetWindowText 関数、GetDlgItemText 関数、または WM_GETTEXT メッセージを使用して、テキストを取得します。

テキストを選択する

編集コントロールを選択した後で、ユーザーはマウスまたはキーボードを使用してコントロール内のテキストを選択できます。 アプリケーションは、コントロールに EM_GETSEL メッセージを送信することで、編集コントロールでの現在の選択範囲について、開始文字位置と終了文字位置を取得できます。 終了位置の戻り値は、選択範囲の末尾の文字より 1 大きい値 (つまり最後に選択された文字に続く最初の文字の位置) です。

アプリケーションでは、選択範囲の開始文字と終了文字のインデックスを指定した EM_SETSEL メッセージをコントロールに対して送信することで、編集コントロール内のテキストを選択することもできます。 たとえば、アプリケーションで EM_SETSELEM_REPLACESEL を使用することで、編集コントロールからテキストを削除できます。

これらの 3 つのメッセージは、単一行編集コントロールと複数行編集コントロールの両方に適用されます。

テキストを置換する

アプリケーションで、置換テキストへのポインターを指定した EM_REPLACESEL メッセージをコントロールに対して送信することで、編集コントロール内の選択されたテキストを置換できます。 現在選択が行われていない場合は、EM_REPLACESEL によって挿入ポイントに置換テキストが挿入されます。 置換テキストが使用可能なメモリを超過する場合、アプリケーションは EN_ERRSPACE 通知コードを受け取る可能性があります。 このメッセージは、単一行編集コントロールと複数行編集コントロールの両方に適用されます。

アプリケーションで EM_REPLACESEL を使用して、編集コントロールのテキストの一部を置換するか、またはSetDlgItemText 関数を使用してすべてのテキストを置換することができます。

編集コントロールで使用されるフォントを変更する

アプリケーションで WM_SETFONT メッセージを送信することで、編集コントロールで使用するフォントを変更できます。 ほとんどのアプリケーションでは、WM_INITDIALOG メッセージの処理中にこれを実行します。 フォントを変更しても編集コントロールのサイズは変更されません。WM_SETFONT メッセージを送信するアプリケーションでは、テキストのフォント メトリックを取得して編集コントロールのサイズを再計算する必要が生じる可能性があります。 フォントとフォント メトリックの詳細については、「フォントとテキスト」を参照してください。

切り取り、コピー、貼り付け、クリア操作

編集コントロールとクリップボードの間でテキストを移動するためのメッセージは 4 つ用意されています。 WM_COPY メッセージは、編集コントロールでの現在の選択内容 (選択されている場合) を、編集コントロールから削除せずにクリップボードにコピーします。 WM_CUT メッセージは、編集コントロールでの現在の選択内容 (選択されている場合) を削除し、削除したテキストをクリップボードにコピーします。 WM_CLEAR メッセージは、編集コントロールでの現在の選択内容 (選択されている場合) を削除しますが、ユーザーが Shift キーを押さなかった場合はクリップボードにコピーしません。 WM_PASTE メッセージは、クリップボードから編集コントロールの挿入ポイントにテキストをコピーします。 これらの 4 つのメッセージは、単一行編集コントロールと複数行編集コントロールの両方に適用されます。

Microsoft Windows NT 4.0 以降: 編集コントロールには、ユーザーが編集コントロールとクリップボードの間でテキストを簡単に移動できるようにする、組み込みのコンテキスト メニューが含まれています。 コンテキスト メニューは、ユーザーがコントロールを右クリックすると表示されます。 このコンテキスト メニューのコマンドには、[元に戻す]、[切り取り]、[コピー]、[貼り付け]、[削除]、[すべて選択] があります。

テキストを変更する

ユーザーは、編集コントロール内のテキストを選択、削除、または移動できます。 システムは、コントロールの内容が変更されたかどうかを示す内部フラグを、編集コントロールごとに保持します。 システムは、コントロールを作成するときにこのフラグをクリアし、コントロール内のテキストが変更されるたびにフラグを設定します。 アプリケーションは、コントロールに EM_GETMODIFY メッセージを送信することで、この変更フラグを取得できます。 その後で、アプリケーションはコントロールに EM_SETMODIFY メッセージを送信することで、変更フラグを設定またはクリアできます。 これらのメッセージは、単一行編集コントロールと複数行編集コントロールの両方に適用されます。

ユーザー入力テキストを制限する

ユーザーが編集コントロールに入力できるテキストの量に対する既定の制限は、32 KB です。 アプリケーションでは、コントロールに EM_SETLIMITTEXT メッセージを送信することで、この既定の制限を変更できます。 このメッセージにより、ユーザーが編集コントロールに入力できるバイト数にハード制限が設定されますが、メッセージが送信された時点で既にコントロールに存在していたテキストと、SetDlgItemText 関数または WM_SETTEXT メッセージによってコントロールにコピーされたテキストのどちらにも影響しません。 たとえば、アプリケーションで SetDlgItemText 関数を使用して編集コントロールに 500 バイトを配置する場合、ユーザーも 500 バイトを入力できます (合計 1,000 バイト)。 その後にアプリケーションで EM_SETLIMITTEXT メッセージを送信し、ユーザー入力テキストを 300 バイトに制限した場合、編集コントロールに既に存在している 1,000 バイトはそのまま保持され、ユーザーはそれ以上テキストを追加できません。 それに対し、アプリケーションで EM_SETLIMITTEXT メッセージを送信してユーザー入力テキストを 1,300 バイトに制限した場合は、1,000 バイトはそのまま保持されますが、ユーザーはさらに 300 バイトを追加できます。

ユーザーの入力が編集コントロールの文字制限に達すると、システムはアプリケーションに対して EN_MAXTEXT 通知コードを含む WM_COMMAND メッセージを送信します。 この通知コードは、メモリが使い果たされたという意味ではなく、ユーザー入力テキストの制限に達したことを意味します。ユーザーはそれ以上テキストを入力できません。 この制限を変更するには、アプリケーションで、より高い制限を指定した新しい EM_SETLIMITTEXT メッセージをコントロールに送信する必要があります。

EM_SETLIMITTEXTEN_MAXTEXT の使用例として、編集コントロールでユーザーが 4 文字を超えて入力しないように、アプリケーションで制限する必要があるとします。 アプリケーションで EM_SETLIMITTEXT を使用して、4 文字の制限を指定します。 ユーザーが 5 文字目を入力しようとすると、システムがアプリケーションに対して EN_MAXTEXT 通知コードを送信します。

文字と行の操作

編集コントロール内の文字と行に関する情報を返すメッセージがいくつか用意されています。 ほとんどのメッセージは、文字または行を参照するインデックス (通常はゼロから始まる数値) を返します。 たとえば、n 文字を含む単一行編集コントロールでは、行インデックスは 0 で、文字のインデックスは 0 から n-1 までになります。 m 行と n 文字を含む複数行編集コントロールでは、行のインデックスは 0 から m-1 まで、文字のインデックスは 0 から n-1 までになります。 文字のインデックス作成では改行が無視されることに注意してください。

アプリケーションで編集コントロールに WM_GETTEXTLENGTH メッセージを送信することで、編集コントロール内の文字数を判別できます。 このメッセージは、単一行または複数行の編集コントロール内のテキストの長さを、(末尾の null 文字を含まない) 文字数で返します。 EM_LINELENGTH メッセージは、行内の 1 文字の文字インデックスで指定された行の長さを、文字数で返します。 返される長さには、選択された文字は含まれません。 アプリケーションは、単一行または複数行の編集コントロールでこれらのメッセージを使用できます。

EM_GETFIRSTVISIBLELINE メッセージは、複数行編集コントロールの場合は、表示されている一番上の行の、ゼロから始まるインデックスを返します。または、単一行編集コントロールの場合は、表示されている最初の文字の、ゼロから始まるインデックスを返します。 アプリケーションでは、編集コントロールに EM_GETLINE メッセージを送信することで、編集コントロールからバッファーに行をコピーできます。 この行は行インデックスで指定されます。受信バッファーの最初の単語には、バッファーにコピーされる最大バイト数が含まれます。 戻り値は、コピーされたバイト数です。 このメッセージも、単一行または複数行の編集コントロールで使用できます。

複数行編集コントロール内の行に関する情報を返すために使用できる、固有のメッセージが用意されています。 EM_GETLINECOUNT メッセージは、編集コントロール内の行数を返します。 EM_LINEFROMCHAR メッセージは、指定された文字インデックスを含む行のインデックスを返します。 EM_LINEINDEX メッセージは、指定された行の最初の文字のインデックスを返します。

編集コントロール内のテキストをスクロールする

編集コントロールにスクロールを実装するには、「編集コントロールの種類とスタイル」で説明されている自動スクロール バー スタイルを使用するか、編集コントロールに対して明示的にスクロール バーを追加します。 水平スクロール バーを追加するには、WS_HSCROLL スタイルを使用します。垂直スクロール バーを追加するには、WS_VSCROLL スタイルを使用します。 スクロール バーを含む編集コントロールは、固有のスクロール バー メッセージを処理します。 編集コントロールへのスクロール バーの追加の詳細については、「スクロール バー」を参照してください。

スクロール バーを含む編集コントロールに対してアプリケーションが送信できるメッセージは 3 つ用意されています。 EM_LINESCROLL メッセージを使用すると、複数行編集コントロールを水平方向と垂直方向の両方にスクロールできます。 lParam パラメーターで、現在の行から何行分を垂直方向にスクロールするかを指定します。また、wParam パラメーターで、現在の文字から何も自分を水平方向にスクロールするかを指定します。 編集コントロールに ES_CENTER スタイルまたは ES_RIGHT スタイルが設定されている場合、コントロールは水平スクロール メッセージを確認しません。 EM_LINESCROLL メッセージは、複数行編集コントロールにのみ適用されます。

EM_SCROLL メッセージを使用すると、複数行編集コントロールが垂直方向にスクロールされます。 wParam パラメーターで、スクロール アクションを指定します。 EM_SCROLL メッセージは、複数行編集コントロールにのみ適用されます。 EM_SCROLL は、WM_VSCROLL メッセージと同じ効果があります。

EM_SCROLLCARET メッセージを使用すると、編集コントロール内でキャレットが表示されるまでスクロールします。

タブ位置と余白を設定する

アプリケーションでは、EM_SETTABSTOPS メッセージを使用することで、複数行編集コントロール内のタブ位置を設定できます。 (タブ位置の既定値は 8 文字です)。アプリケーションが編集コントロールにテキストを追加するときに、テキスト内のタブ文字によって、次のタブ位置までのスペースが自動的に生成されます。 EM_SETTABSTOPS メッセージでは、システムが自動的にテキストを再描画することはありません。 これを行うためには、アプリケーションで InvalidateRect 関数を呼び出します。 EM_SETTABSTOPS メッセージは、複数行編集コントロールにのみ適用されます。

アプリケーションで EM_SETMARGINS メッセージを使用することで、編集コントロールの左余白と右余白の幅を設定できます。 このメッセージを送信した後に、システムが編集コントロールを再描画して新しい余白設定を反映します。 アプリケーションで EM_GETMARGINS メッセージを送信することで、左余白または右余白の幅を取得できます。 既定では、編集コントロールの余白は、編集コントロールで使用されている現在のフォントで最も大きい文字の水平方向のオーバーハング (マイナスの ABC 幅) がちょうど収まる程度の幅に設定されます。

ユーザー入力を隠す

アプリケーションで、編集コントロールでのパスワード文字を使用することで、ユーザー入力を隠すことができます。 パスワード文字を設定すると、ユーザーが入力する個々の文字の代わりにパスワード文字が表示されます。 パスワード文字を削除すると、ユーザーが入力する文字がコントロールに表示されます。 アプリケーションで ES_PASSWORD スタイルを使用して単一行編集コントロールを作成する場合、既定のパスワード文字はアスタリスク (*) です。 アプリケーションで EM_SETPASSWORDCHAR メッセージを使用して、パスワード文字を削除するか、別のパスワード文字を定義することができます。または EM_GETPASSWORDCHAR メッセージを使用して、現在のパスワード文字を取得することができます。 これらのメッセージは、単一行編集コントロールにのみ適用されます。

整数を使用する

数字のみを受け付けるように設計された編集コントロールの場合、整数変換関数が 2 つ用意されています。 SetDlgItemInt 関数は、指定された整数 (符号付きまたは符号なし) の文字列表現を作成し、その文字列を編集コントロールに送信します。 SetDlgItemInt は値を返しません。 GetDlgItemInt 関数は、編集コントロール内の文字列表現から整数 (符号付きまたは符号なし) を作成します。 GetDlgItemInt は整数 (またはエラー値) を返します。

テキスト操作を取り消す

すべての編集コントロールで、その編集コントロールでの直近の操作をアプリケーションが元に戻すことができるかどうかを示す、元に戻すフラグが保持されます (たとえばテキストの削除を元に戻すなど)。 編集コントロールは、元に戻すフラグを設定することで、操作を元に戻せることを示し、フラグをリセットすることで、操作を元に戻せないことを示します。 アプリケーションでコントロールに対して EM_CANUNDO メッセージを送信することで、元に戻すフラグの設定状況を判別できます。

アプリケーションでコントロールに対して EM_UNDO メッセージを送信することで、直近の操作を元に戻すことができます。 編集コントロールで他の操作が先に行われていない場合は、操作を元に戻すことができます。 たとえば、ユーザーは、テキストを削除してからテキストを置換し (削除を元に戻し)、その後でテキストを再び削除する (置換を元に戻す) ことができます。 EM_UNDO メッセージは、単一行と複数行の両方の編集コントロールに適用され、単一行編集コントロールでは常に機能します。

アプリケーションでコントロールに対して EM_EMPTYUNDOBUFFER メッセージを送信することで、編集コントロールの元に戻すフラグをリセットできます。 編集コントロールが EM_SETHANDLE メッセージまたは WM_SETTEXT メッセージを受信すると常に、元に戻すフラグはシステムによって自動的にリセットされます。 SetDlgItemText 関数は、WM_SETTEXT メッセージを送信します。

折り返しと改行を処理する

アプリケーションでは、複数行編集コントロールで折り返し関数を使用することで、次の行に折り返す必要がある単語または単語のフラグメントを見つけることができます。 システムで提供されている既定の折り返し関数を使用すると、行末は常に単語間のスペースになります。 アプリケーションでは、EditWordBreakProc 折り返し関数を使用し、EM_SETWORDBREAKPROC メッセージを編集コントロールに対して送信することで、独自の折り返し関数を指定できます。 アプリケーションでコントロールに対して EM_GETWORDBREAKPROC メッセージを送信することで、現在の折り返し関数のアドレスを取得できます。

アプリケーションでは、折り返されたテキスト行の末尾にソフト改行文字 (2 個の復帰と 1 個の改行) を自動的に追加または削除するように、複数行の編集コントロールに指示できます。 アプリケーションで編集コントロールに対して EM_FMTLINES メッセージを送信することで、この機能をオンまたはオフにできます。 このメッセージは、複数行編集コントロールにのみ適用され、ハード改行 (1 個の復帰とユーザーが入力した 1 個の改行) で終わる行には影響しません。 また、複数行コントロールでは、アプリケーションで ES_WANTRETURN スタイルを指定することで、ユーザーが編集コントロールで Enter キーを押したときに復帰を挿入するようにシステムに要求することもできます。

ポイントと文字を取得する

編集コントロールのクライアント領域の指定されたポイントに最も近い文字を判別するには、EM_CHARFROMPOS メッセージをコントロールに対して送信します。 このメッセージは、ポイントに最も近い文字の文字インデックスと行インデックスを返します。 同様に、EM_POSFROMCHAR メッセージを送信することで、指定された文字のクライアント領域座標を取得できます。 このメッセージは、指定された文字の左上隅の x 座標と y 座標を返します。

文字列のオートコンプリート

オートコンプリートは、編集コントロールで部分的に入力された文字列を完全な文字列に拡張します。 たとえば、Windows Internet Explorer ツール バーに埋め込まれているアドレス編集コントロールにユーザーが URL を入力し始めると、オートコンプリートによって、既存の部分文字列と一致する 1 つ以上の完全な URL に文字列が拡張されます。 "mic" のような部分文字列は、"https://www.microsoft.com" または "https://www.microsoft.com/windows" に拡張される可能性があります。 オートコンプリートは通常、編集コントロール、または編集コントロールが埋め込まれたコントロールで使用されます。

詳細については、IAutoComplete および IAutoComplete2 のインターフェイス ドキュメントを参照してください。

編集コントロールでの複雑なスクリプト

複雑なスクリプトとは、印刷出力を単純な方法で生成できない言語のことです。 たとえば、複雑なスクリプトでは、双方向レンダリング、コンテキストに応じた字形の形成、文字の組み合わせが許可されている場合があります。 標準の編集コントロールは、多言語テキストと複雑なスクリプトをサポートするように拡張されています。 これには、入力と表示だけでなく、文字クラスター上での正しいカーソル移動も含まれます (タイ語やデーヴァナーガリー スクリプトなど)。

適切に記述されたアプリケーションであれば、変更なしでこのサポートが自動的に適用されます。 それでも、右から左への読み取り順序や右揃えのサポートを追加することを検討する必要があります。 この場合は、次の例に示すように、編集コントロール ウィンドウの拡張スタイル フラグを切り替えて、これらの属性を制御します。

// ID_EDITCONTROL is the control ID in the resource file.
HANDLE hWndEdit = GetDlgItem(hDlg, ID_EDITCONTROL);
LONG lAlign = GetWindowLong(hWndEdit, GWL_EXSTYLE) ;

// To toggle alignment
lAlign ^= WS_EX_RIGHT ;

// To toggle reading order
lAlign ^= WS_EX_RTLREADING ;

lAlign 値を設定した後で、編集コントロール ウィンドウの拡張スタイルを以下のように設定することで、新しい表示を有効にします。

// This assumes your edit control is in a dialog box. If not, 
// get the edit control handle from another source.

SetWindowLong(hWndEdit, GWL_EXSTYLE, lAlign);
InvalidateRect(hWndEdit, NULL, FALSE);

Uniscribe は、複雑なスクリプトを処理するための細かな制御を提供する別の関数セットです。 詳細については、「Uniscribe」を参照してください。