エディットコントロールの操作

エディットコントロールの基本的な操作は前ページを参照してください。

通知コード

エディットコントロールを操作するとWM_COMMANDメッセージが発行され、WPARAMの上位ワードに以下の通知コードが送られてきます。

通知コード 説明
EN_SETFOCUS フォーカスを受け取ったとき。
EN_KILLFOCUS フォーカスを失ったとき。
EN_CHANGE テキストが変更される可能性のある操作をしたとき。
テキストの再描画後に送信される。
EN_UPDATE テキストの再描画が行われるとき。
テキストの再描画前に送信される。
EN_ERRSPACE メモリ割り当てエラーで操作に失敗したとき。
EN_MAXTEXT 文字数制限を超えてテキストを入力しようとしたとき。
文字の切り捨てが発生したことを知らせるもので、EM_LIMITTEXTで設定される文字数を超えたときのほか、ES_AUTOHSCROLLスタイルを持たない単一行エディットコントロールにおいてテキストがコントロールの横幅を超えた場合などにも送信される。
EN_HSCROLL 水平スクロールを操作したとき。
スクロールバーの矢印ボタン、または矢印ボタンとスクロールボックスの間の領域のクリック、およびキーボードによるスクロール操作(HOME、END、矢印キー、改行など)により通知コードが送られる。
スクロールボックスの操作では送信されない。
EN_VSCROLL 垂直スクロールを操作したとき。
通知コードが送られる条件は水平スクロールバーと同じ。

メッセージ

エディットコントロールでは以下のメッセージを使用して様々な操作が可能です。

メッセージについてはSendMessage関数を参照してください。

メッセージ WPARAM LPARAM 戻り値
EM_GETSEL 選択範囲の開始位置を受け取るDWORD型のポインタ
(NULLでも可)
選択範囲の終了位置を受け取るDWORD型のポインタ
(NULLでも可)
下位ワード:選択範囲の開始位置
上位ワード:選択範囲の終了位置
現在の選択範囲を取得する。
戻り値は16ビットずつに分かれるので、65535を超える長さは取得できない。
(WPARAM、LPARAMに格納される値は32ビットなのでこの問題はない)
EM_SETSEL 選択開始位置 選択終了位置 なし
選択範囲を設定する。
選択開始位置を0、選択終了位置を-1に設定するとすべてのテキストを選択する。
開始位置を-1に設定すると選択を解除する。
両方を同じ値にすることでキャレットを移動することができ、両方を-1に設定すると末尾にキャレットを置く。
EM_REPLACESEL 置き換え操作をEM_UNDOで元に戻せるか否か
(TRUE/FALSE)
置き換える文字列 なし
選択中のテキストを別のテキストで置き換える。
選択テキストがない場合はキャレットの位置に挿入される。
メッセージ WPARAM LPARAM 戻り値
EM_GETLINECOUNT 0 0 現在の行数
(1以上)
複数行エディットコントロールの行数を取得する。
空のエディットコントロールでも戻り値が1未満になることはない。
EM_GETLINE 行番号の指定
(最初の行は0)
テキストを格納する文字列バッファへのポインタ 取得した文字数

テキストを一行取得する。
取得した文字列の終端にNULL文字は含まれない。

このメッセージの送信前に、文字列バッファ(LPARAM)の先頭ワードにはバッファサイズをあらかじめ格納しておく必要がある。
(Unicodeの場合は文字数、ANSIの場合はバイト数)
この値はバッファへの文字列のコピーにより上書きされる。

EM_GETFIRSTVISIBLELINE 0 0 現在最も上端に表示されている行番号
(最初の行は0)
複数行のエディットコントロールで、現在最も上端に表示されている行番号を取得する。
テキストの一行目が一番上端に表示されている場合は0を、一行分スクロールしている場合は1を取得する。
EM_SCROLL 定数
(説明を参照)
0 上位ワード:成功した場合にTRUE
下位ワード:スクロールした行数
複数行エディットコントロールで、垂直方向へスクロールする。
WPARAMには以下の定数のいずれかを指定する。
SB_LINEDOWN:一行下にスクロール
SB_LINEUP:一行上にスクロール
SB_PAGEDOWN:一ページ下にスクロール
SB_PAGEUP:一ページ上にスクロール
EM_LINESCROLL 水平方向にスクロールする文字数 垂直方向にスクロールする行数 複数行エディットコントロールに送信した場合はTRUE
単一行エディットコントロールに送信した場合はFALSE
複数行エディットコントロールで、テキストをスクロールする。
EM_SCROLLCARET 0 0 なし
キャレットが現在の表示領域に含まれるようにスクロールする。
EM_GETTHUMB 0 0 スクロールボックスの位置
複数行エディットコントロールで、垂直スクロールバーのスクロールボックス(つまみ)の位置を取得する。
メッセージ WPARAM LPARAM 戻り値
EM_LIMITTEXT
EM_SETLIMITTEXT
入力可能な文字数の最大値
(NULL文字含む)
0 なし
ユーザーが入力可能な文字数を制限する。
WPARAMはANSIではバイト数、Unicodeでは文字数。
既定ではエディットコントロールは32767文字の入力が可能。
EM_GETLIMITTEXT 0 0 入力可能なテキストの最大値
ユーザーが入力可能な文字数の制限を取得する。
WPARAMはANSIではバイト数、Unicodeでは文字数。
EM_SETTABSTOPS LPARAMの配列の要素数 タブ文字幅の配列 全てのタブ幅が設定されている場合はTRUE

複数行エディットコントロールで、タブ文字の幅を設定する。
WPARAMが0の場合はデフォルトの幅(32)に設定され、LPARAMは無視される。
WPARAMが1の場合はすべてのタブ幅にLPARAMの先頭の要素の値が使用される。
WPARAMが2以上の場合はタブ幅にLPARAMの配列の値が順番に適用される。

WPARAMが2以上の場合に指定するLPARAMの各要素は、前のタブ幅との合計である。
例えば3つのタブ幅をそれぞれ「10,15,20」に設定する場合の各要素の値は「10,25,45」となる。
この時、4つ目以降のタブ文字の幅は最後の要素の値が使用される。

EM_SETPASSWORDCHAR 代替文字 0 なし
パスワード入力用に、テキストの表示をWPARAMで指定した文字に置き換える。
(表示のみで実際の内容は変更されない)
WPARAMに0を指定すると置き換えを解除する。
なお、WPARAMに指定するのは文字列ではなく文字型であるので注意。
EM_GETPASSWORDCHAR 0 0 代替文字
設定されていない場合はNULL
パスワード入力用に設定されている代替文字を取得する。
(既定はアスタリスク(*))
EM_SETREADONLY TRUE:読み取り専用に設定
FALSE:読み取り専用を解除
0 成功した場合は0以外、失敗した場合は0
テキストの読み取り専用スタイルを設定/解除する。
EM_FMTLINES TRUE:ソフト改行を挿入する
FALSE:ソフト改行を挿入しない
0 WPARAMで指定した値
WM_GETTEXTメッセージで取得される文字列、およびEM_GETHANDLEメッセージで取得されるバッファの文字列に、ソフト改行を含めるか否かを設定する。
ソフト改行とは、テキストの自動折り返しにより発生する改行のこと。
ソフト改行は「\r\r\n」で表される。
(ちなみに通常の改行コードはハード改行と言う)
メッセージ WPARAM LPARAM 戻り値
EM_GETRECT 0 RECT構造体のポインタ なし
テキストの描画可能領域を取得しLPARAMに格納する。
EM_SETRECT 0 RECT構造体のポインタ
(NULLも可)
なし
テキストの描画可能領域を設定する。
複数行エディットコントロールでのみ有効。
LPARAMにNULLを指定すると既定値に設定される。
EM_SETRECTNP 0 RECT構造体のポインタ
(NULLも可)
なし
テキストの描画可能領域を設定する。
複数行エディットコントロールでのみ有効。
LPARAMにNULLを指定すると既定値に設定される。
EM_SETRECTメッセージとの違いは、設定後にエディットコントロールを再描画しない点。
EM_SETMARGINS 定数
(説明を参照)
下位ワード:左余白
上位ワード:右余白
(ピクセル単位)
なし
左右の余白を設定する。
WPARAMには以下の定数の組み合わせを指定する。
(定数で指定しない場合、LPARAMに値をセットしても無視される)
EC_LEFTMARGIN:左余白を設定する。
EC_RIGHTMARGIN:右余白を設定する。
EC_USEFONTINFO:リッチエディットコントロール用
(エディットコントロールでは使用しない)
EM_GETMARGINS 0 0 下位ワード:左余白
上位ワード:右余白
(ピクセル単位)
左右の余白を取得する。
メッセージ WPARAM LPARAM 戻り値
EM_LINEINDEX 行番号 0 文字インデックス
無効な行番号を指定した場合は-1

複数行エディットコントロールで、行番号で指定した行の先頭の文字のインデックスを取得する。
(文字インデックス=テキスト全体の何文字目か。最初の文字は0)

行番号に「-1」を指定すると、現在キャレットのある行が指定される。

EM_LINELENGTH 文字インデックス 0 一行の文字数
無効なインデックスを指定した場合は0

指定した文字インデックスが含まれる行の文字数を取得する。
(行番号の指定ではなく、テキスト全体の何文字目かの指定)
戻り値に改行文字は含まれない。

文字インデックスに「-1」を指定すると、現在選択中のテキストが含まれる行の、選択されていない文字の文字数が返される。

EM_LINEFROMCHAR 文字インデックス 0 行番号

指定した文字インデックスが含まれる行の行番号を取得する。

文字インデックスに「-1」を指定すると、現在キャレットがある行が指定される。
現在選択中のテキストがある場合は、選択範囲の先頭がある行が指定される。

EM_POSFROMCHAR 文字インデックス 0 クライアント領域上の座標
下位ワード:X座標
上位ワード:Y座標

指定した文字インデックスのクライアント領域上の座標を取得する。
なお、「クライアント領域」は親ウィンドウではなくコントロール自身が持つクライアント領域なので注意。

EM_CHARFROMPOS 0 クライアント領域上の座標
下位ワード:X座標
上位ワード:Y座標
下位ワード:文字インデックス
上位ワード:行番号

指定した座標に最も近い位置にある文字の情報を取得する。
戻り値の下位ワードは文字インデックス。
上位ワードはその文字が含まれる行の行番号。
なお、「クライアント領域」は親ウィンドウではなくコントロール自身が持つクライアント領域なので注意。

メッセージ WPARAM LPARAM 戻り値
EM_UNDO 0 0 単一行では、常にTRUE
複数行では、成功した場合はTRUE、失敗した時はFALSE
編集操作の取り消し(アンドゥ)
EM_CANUNDO 0 0 アンドゥが可能なら0以外を返す
編集操作の取り消し(アンドゥ)が可能か否かを返す。
EM_EMPTYUNDOBUFFER 0 0 なし
編集操作の取り消し(アンドゥ)の履歴を空にする。
(アンドゥをできなくする)
EM_GETMODIFY 0 0 テキストが変更されている場合は0以外
テキストの変更フラグの状態を取得する。
テキスト変更フラグは、ユーザーがテキストを編集すると自動でオンになる。
EM_SETMODIFY TRUE:変更フラグをオン
FALSE:変更フラグをオフ
0 なし
テキストの変更フラグの状態を設定する。

その他のウィンドウメッセージ

エディットコントロールは以下のクリップボード操作のウィンドウメッセージも使用できます。

メッセージ WPARAM LPARAM 戻り値
WM_CUT 0 0 なし
選択中のテキストを削除し、クリップボードにコピーする。
WM_COPY 0 0 成功した場合は0以外
失敗した場合は0
選択中のテキストをクリップボードにコピーする。
WM_PASTE 0 0 なし
クリップボードからテキストをコピーする。
WM_CLEAR 0 0 なし
選択中のテキストを削除する。

その他、WM_SETTEXTメッセージなどでテキストを取得/設定することも可能です。

サンプル

エディットコントロールの操作サンプルです。


#include <windows.h>

//ウィンドウの生成等は省略

#define STR_LENGTH 1024

#define IDC_EDIT1 100
#define IDC_EDIT2 101
#define IDC_BUTTON1 200
#define IDC_BUTTON2 201
#define IDC_BUTTON3 202
#define IDC_BUTTON4 203

//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static HWND hEdit, hEditCopy;
	WCHAR buf[STR_LENGTH];
	int n1, n2;

	switch (message)
	{
	case WM_CREATE: //ウィンドウ作成
		hEdit = CreateWindowEx(
			WS_EX_CLIENTEDGE,
			L"EDIT", 0,
			WS_CHILD | WS_VISIBLE |
			ES_MULTILINE | WS_VSCROLL | ES_NOHIDESEL,
			0, 0, 250, 200,
			hWnd, (HMENU)IDC_EDIT1, hInst, NULL);
		hEditCopy = CreateWindowEx(
			WS_EX_CLIENTEDGE,
			L"EDIT", 0,
			WS_CHILD | WS_VISIBLE |
			ES_MULTILINE | WS_VSCROLL | ES_READONLY,
			250, 0, 250, 200,
			hWnd, (HMENU)IDC_EDIT2, hInst, NULL);

		CreateWindow(
			L"BUTTON", L"Cut",
			WS_CHILD | WS_VISIBLE,
			0, 210, 60, 25,
			hWnd, (HMENU)IDC_BUTTON1, hInst, NULL);
		CreateWindow(
			L"BUTTON", L"Copy",
			WS_CHILD | WS_VISIBLE,
			60, 210, 60, 25,
			hWnd, (HMENU)IDC_BUTTON2, hInst, NULL);
		CreateWindow(
			L"BUTTON", L"Paste",
			WS_CHILD | WS_VISIBLE,
			120, 210, 60, 25,
			hWnd, (HMENU)IDC_BUTTON3, hInst, NULL);
		CreateWindow(
			L"BUTTON", L"Undo",
			WS_CHILD | WS_VISIBLE,
			0, 240, 60, 25,
			hWnd, (HMENU)IDC_BUTTON4, hInst, NULL);
		break;

	case WM_COMMAND: //コントロール操作
		switch (LOWORD(wParam))
		{
		case IDC_EDIT1: //左エディット
			switch (HIWORD(wParam))
			{
			case EN_UPDATE:	//画面更新
				GetWindowText(hEdit, buf, STR_LENGTH);
				SetWindowText(hEditCopy, buf);
				//break;	//←画面更新後に垂直スクロールも更新
			case EN_VSCROLL: //垂直スクロール
				n1 = SendMessage(hEdit, EM_GETFIRSTVISIBLELINE, 0, 0);
				n2 = SendMessage(hEditCopy, EM_GETFIRSTVISIBLELINE, 0, 0);
				SendMessage(hEditCopy, EM_LINESCROLL, 0, (LPARAM)(n1 - n2));
				break;
			}			
			break;

		case IDC_BUTTON1:	//Cut
			SendMessage(hEdit, WM_CUT, 0, 0);
			break;
		case IDC_BUTTON2:	//Copy
			SendMessage(hEdit, WM_COPY, 0, 0);
			break;
		case IDC_BUTTON3:	//Paste
			SendMessage(hEdit, WM_PASTE, 0, 0);
			break;
		case IDC_BUTTON4:	//Undo
			SendMessage(hEdit, EM_UNDO, 0, 0);
			break;
		}
		break;

	case WM_DESTROY: //ウィンドウの破棄
		PostQuitMessage(0);
		break;

	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

このコードは左側のエディットコントロールに入力した文字を、即座に右側の読み取り専用エディットコントロールに反映させます。
左側のスクロールも右側に同期させます。
下部のボタンでは「カット」「コピー」「ペースト」「アンドゥ」の操作が可能です。
エディットコントロールの操作サンプル

なお、サンプルコードなので入力可能なテキストの最大値は1024で決め打ちしています。
実際にプログラムを作る場合はGetWindowTextLength関数などで文字数を取得し、C言語のmalloc関数などでバッファを確保してからテキストを取得する処理を行います。