2019年10月13日日曜日

エディットコントロールについて

台風一過。

エディットコントロールについて調べたこと、考えたことをまとめる。

ポイント

  • 基本的なエディットコントロールの使用方法は、ユーザもしくはプログラムからテキストを範囲選択した状態で、選択範囲に対する操作をメッセージで指示すること
     
  • 全体と範囲選択に対する操作を混同してはならない
      
  • printf的な書式指定のできる出力関数を用意しておくと便利

開発・実行環境

下記の環境でコードを実行し、動作を確かめた。

プロセッサ: Intel(R) Core(TM) i5-5200U CPU @2.20GHz
メモリ: 8.00 GB
OS: Windows 8.1 (64bit)
compiler: Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x86
Visual Studio: 14.0

コード

状態指定系、範囲選択系、テキスト取得系、テキスト編集系にカテゴリ分けして、エディットコントロールへのメッセージの送り方をまとめた。
主に参考にさせていただいたのは、こちらのサイト様です[1][2]。

状態指定系

  1. SendMessage(hEdit, EM_SETREADONLY, FALSE, 0); // 読み取り専用の解除(入力を許可する)
  2. SendMessage(hEdit, EM_SETREADONLY, TRUE, 0); // 読み取り専用の指定(入力を禁止する)
  3. ShowWindow(hEdit, SW_SHOW); // エディットコントロールの表示
  4. ShowWindow(hEdit, SW_HIDE); // エディットコントロールの非表示

範囲選択系

  1. SendMessage(hEdit, EM_SETSEL, 0, -1); // 全体を選択
  2. SetFocus(hEdit); // フォーカスを合わせる
  3.  
  4. // 末尾にカーソルを移動した状態でフォーカスを合わせる
  5. int index = GetWindowTextLength(hEdit);
  6. SetFocus(hEdit);
  7. SendMessage(hEdit, EM_SETSEL, (WPARAM)index, (LPARAM)index);

テキスト取得系

  1. SendMessage(hEdit, WM_COPY, 0, 0); // 選択範囲をコピーする
  2. SendMessage(hEdit, WM_CUT, 0, 0); // 選択範囲をカットする
  3. SendMessage(hEdit, WM_GETTEXT, (WPARAM)dst_size, (LPARAM)dst); // 選択範囲の文字列をクリップボードを介さずに取得する

テキスト編集系

  1. SendMessage(hEdit, WM_PASTE, 0, 0); // 選択範囲に貼り付けする
  2. SendMessage(hEdit, WM_CLEAR, 0, 0); // 選択範囲をクリアする

取得系、編集系のコマンドはユーザまたはプログラムにより選択された範囲に対してのみ実行される。
選択がなされていない場合には、何事も起こらない。
特にWM_CLEARなどはややこしいと思う。
端末でclearコマンドを入力すればバッファがクリアされるので、同じようにクリアされるのかと、暗黙の内に誤った認識を持っていた。

  1. void EditControl::Set(const wchar_t* format, ...) {
  2. wchar_t buffer[EDIT_BUFFER_MAX] = {0};
  3. va_list args;
  4. va_start(args, format);
  5. vswprintf_s(buffer, ARRAYSIZE(buffer), format, args);
  6. SetFocus(hEdit);
  7. SendMessage(hEdit, WM_SETTEXT, (WPARAM)0, (LPARAM)buffer);
  8. return;
  9. }
エディットコントロールの中身を丸ごと書き換える。
可変長引数を用いて実装。
可変長引数については、先日説明した[3]。
printfと同じように使うことができる。

  1. void EditControl::Add(const wchar_t* format, ...) {
  2. wchar_t buffer[EDIT_BUFFER_MAX] = {0};
  3. va_list args;
  4. va_start(args, format);
  5. vswprintf_s(buffer, ARRAYSIZE(buffer), format, args);
  6. int index = GetWindowTextLength(hEdit);
  7. SetFocus(hEdit);
  8. SendMessage(hEdit, EM_SETSEL, (WPARAM)index, (LPARAM)index);
  9. SendMessage(hEdit, EM_REPLACESEL, 0, (LPARAM)buffer);
  10. return;
  11. }
エディットコントロールにすでに含まれるテキストはそのままに、末尾にテキストを新たに追加する。
MSDNにテキストの追加方法に関する説明がある[4]。

まとめ

とりあえずクラス化した。
選択範囲に対する操作が基本のようだが、全体に対する操作として一まとめにした方がプログラマには優しいかもしれない。

付録


今回のコードの最新版はここに上げておく。


参考文献

  1. エディットコントロール
  2. エディットメッセージ
  3. 可変長引数について
  4. How To Programatically Append Text to an Edit Control

0 件のコメント:

コメントを投稿

コメント表示は承認制に設定しています