*

MFCプログラミング(4):Enter(ESC)キーでダイアログが閉じないようにする

公開日: : C++, MFC, Windows, 開発

どもです。
今回は、キーボード入力の処理、特にEnterキー/ESCキーでダイアログが閉じられることの回避です。

1.背景(簡単に)

データ入力画面をダイアログで作成した際に、画面上でEnterキー/ESCキーを押すと、画面(ダイアログ)が閉じられます。
この動作を回避する際に、少しハマりました。

2.内容

MFCのダイアログは、画面上でEnterキー/ESCキーを押すと閉じる、というのがデフォルトの動作です。
しかし、ダイアログベースの画面で複数の入力用コントロールを持つ場合、この動作ではアプリケーションが使いにくくなります。
事実、Enterキーを押下したら画面が閉じる、というのを仕様としてユーザー側に注意してもらう、ということも考えましたが、現実的ではありませんでした。
なので、何とかしてEnterキー/ESCキー(特にEnterキー)を押してもダイアログが閉じないようにする必要がありました。

3.原因

CDialogクラスでは、Enterキー押下のイベントハンドラにOnOk()が、ESCキー押下のイベントハンドラにOnCancel()が、それぞれ設定されています。
そのため、デフォルトの状態で、各キーを押すと画面が閉じるようになっています。

Enterキー/ESCキー押下に対するイベントハンドラの設定は、CDialogクラスの設定です。
CDialogクラス自体の変更はできないので、それを継承したクラスで対応する必要があります。

4.対応

CDialogクラスでEnterキー/ESCキー押下のイベントが処理される前に、その処理を「横取り」することで対応します。
この「横取り」を実施するために、「PreTranslateMessage()」をオーバーライドします。
なお、PreTranslateMessage()は、MSDNで下記のように定義されています。

MSDN
具体的な実装を示すと、下記のようになります。

この実装で、まずはEnterキー/ESCキーを押してもダイアログが閉じなくなります。

5.注意点

「4.対応」で示した実装では、実は問題があります。
それは、
Enterキー/ESCキーが押された際のPreTranslateMessage()の戻り値
です。
「4.対応」のコードでは、Enterキー/ESCキーが押された場合には「TRUE」を返していますが、たとえば複数行入力可能に設定したCEditがフォーカスされていた場合、エンターキーを押しても、改行が行われなくなります。
ENTERキーを押してもダイアログが閉じず、しかし改行が行われるようにするためには、PreTranslateMessage()の戻り値を「FALSE」にします。
具体的な実装は、下記の通りです。

即ち、MSDNでも解説されている通り、他のコントロールに対してENTERキー/ESCキー押下のイベントを通知する必要がある場合にはFALSEを、通知する必要がない場合にはTRUEをそれぞれ返すように実装します。
このように、PreTranslateMessage()によるEnterキー/ESCキーイベントを「横取り」では、他のコントロールでの当該キー入力に対する動作を考えて戻り値を決定する必要があります。

6.まとめ

今回は、MFCのダイアログにおいて、Enterキー/ESCキーが押されても画面が閉じられないようにする方法について書きました。
この方法の実装そのものは、とても簡単です。
しかし、ダイアログのEnterキー/ESCキーに対する動作のみではなく、ダイアログ上の他のコントロールの動作も考える必要があるので、少し注意が必要です。

ではっ!

関連記事

python

VisualStudioCommunityでのPython開発環境構築

どもです。 最近、VisualStudioでのPython開発を始めました。 その際の環境構築に

記事を読む

no image

C言語でEV3開発(4)

どもです。 今回のエントリーは、前回のエントリー内容/EclipseでEV3の実行ファイルをビルド

記事を読む

Splash

EV3開発サポートツール(3)-Ev3Controller

どもです。 今回は、以前ちらりと紹介した、Ev3のモーターの出力を調整するアプリケーションについて

記事を読む

raspberry-pi

QtでRaspberryPi/GUI開発(7):pigpioを使用したチャタリング対策の問題

どもです。 前回のエントリーで、pigpioを使用したチャタリング対策について記載しました。 今

記事を読む

ADT7310_DHT11_eye_catch

温度センサの出力値の比較

どもです。 今回は、センサーの性能、測定結果を比較してみたので、それについて書きます。 1.

記事を読む

MindStormControl_SprachScreen

EV3開発サポートツール(2)-C#のユーザーコントロール開発(2つ目)

どもです。 前回に引き続き、今回もC#/WPFでの独自UI(ユーザーコントロール)の作成についての

記事を読む

Arduino_Logo

ホールセンサーの種類と使い方

どもです。 今回のエントリは、表題にある「ホールセンサー」についてです。 1.「ホールセンサ

記事を読む

toppers

C言語でEV3開発(19)-コマンド通信処理でEchoBackしてみた

どもです。 前回は、Bluetoothの接続状態の変化に伴う、状態遷移について書きました。 今回

記事を読む

no image

QtでRaspberryPi/GUI開発(3):ためしに時計を作ってみた(其の参)-StyleSheetの適用

どもです。 前回のエントリーでは、グループ化されたボタンに対するイベントハンドラについて書きました

記事を読む

no image

C言語でEV3開発(15)-TOPPERS/HRP2 EV3 で PID制御

どもです。 今回のエントリーは、コレまでのエントリーから内容を変えて、モーターの動作の制御をします

記事を読む

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

c_sharp_eye_catch
セルに「取り消し線」が設定されているかを判定してみた

どもです。 前回、前々回と、エクセルのセル内の文字列から、「取り

c_sharp_eye_catch
セル内の「取り消し線で消された文字列」の削除を簡単にしてみた

どもです。 前回、C#/OpenXmlを用いて、エクセルのセル内

c_sharp_eye_catch
セル内の「取り消し線で消された文字列」を削除してみた

どもです。 今回は、C#/OpenXmlの組み合わせで、エクセル

c_sharp_eye_catch
C#でバッファの内容を表示する処理を実装してみた-
データ型に従って動的に書式を設定する

どもです。 最近、C#でバッファ/配列の値をコンソールに表示した

arduino_relay_switch_003_self_preservation_circuit_eye_catch
Arduinoでリレースイッチ(3)-自己保存回路

どもです。 前回の記事で、リレースイッチ「AE-G5V-DRV」

→もっと見る

PAGE TOP ↑