MFCで16進数用のテキストボックスを作成する
次のように16進数用のテキストボックスを作成する手順とテクニックを紹介します。
1 ダイアログクラス/リソース/ファイルの追加
事前準備として、「CDialogEx」を継承するクラス「CAppHexEdit」をID:「IDD_HEX_EDIT_DLG」として、「AppHexEdit.h」「AppHexEdit.cpp」作成します。加えて、ID名とクラス名が対応するように「AppHexEdit.h」の下記の場所をコメントアウトします。
#pragma once
#include "afxdialogex.h"
// CAppHexEdit dialog
class CAppHexEdit : public CDialogEx
{
DECLARE_DYNAMIC(CAppHexEdit)
public:
CAppHexEdit(CWnd* pParent = nullptr); // standard constructor
virtual ~CAppHexEdit();
// Dialog Data
//#ifdef AFX_DESIGN_TIME ← 『これをコメントアウト』
enum { IDD = IDD_HEX_EDIT_DLG };
//#endif ← 『これをコメントアウト』
// ... 以降省略 ...
};
2 エディットコントロールの配置
ダイアログ編集画面を開き、「ツールボックス」から「Edit Control」を選択し、ダイアログ上にドラッグアンドドロップします。

3 エディットコントロールのIDを変更
エディットコントロールのIDを変更します。ここでは「IDC_HEX_EDIT」にします。

4 エディットコントロールの変数を追加
上メニューから「プロジェクト」 → 「クラスウィザード」を開き、エディットコントロールのクラスを選択します。その後、「メンバ変数」のタブを開き、「IDC_HEX_EDIT」を選択し、「変数の追加」を選択します。

MFCではエディットコントロールをCEdit型の変数で制御します。ここでは「m_EdHex」という変数を追加し、適用してクラスウィザードを閉じます。

- エディットコントロールを選択し、「
プロパティ」 → 「Number」をFalseにしておきます。
- エディットコントロールが編集されたときのイベントハンドラ関数を追加します。イベントタブ「⚡」を開き、「
EN_CHANGE」のイベントに対して「OnEnChangeHexEdit」関数を自動生成します。
5 プログラムの作成
自動生成された関数「OnChangedHexEdit」の中身を次のよう実装します。
// エディットコントロールのイベントハンドラ関数
void CAppHexEdit::OnEnChangeHexEdit()
{
// 再入防止処理 (後述)
static bool bInChange = false;
if (bInChange) return;
// 入力値された文字として許可するもの
CString strAllowed = _T("0123456789abcdefABCDEF");
// 入力された文字列、修正後の文字列
CString strInput, strResult;
// 入力された文字列の取得
m_EdHex.GetWindowTextW(strInput);
// 除外文字のカウント
int nExclude = 0;
// 入力された文字列を1文字ずつチェックするループ
for (int i = 0; i < strInput.GetLength(); i++)
{
// 入力された文字列から1文字を抽出
TCHAR ch = strInput[i];
if (strAllowed.Find(ch) != -1)
{
// 許可された文字を追加
TCHAR ch = strInput[i];
strResult += ch;
}
else
{
// 除外した文字数をカウント
nExclude++;
}
}
// 修正後文字列な内部で、小文字を大文字に
strResult.Replace(_T("a"), _T("A"));
strResult.Replace(_T("b"), _T("B"));
strResult.Replace(_T("c"), _T("C"));
strResult.Replace(_T("d"), _T("D"));
strResult.Replace(_T("e"), _T("E"));
strResult.Replace(_T("f"), _T("F"));
if (strResult != strInput)
{
// 入力された文字列と修正後の文字列が異なるとき
// 再入防止をON
bInChange = true;
// 現在のカーソル位置の取得
int nStart(0), nEnd(0);
m_EdHex.GetSel(nStart, nEnd);
// 文字の置き換え (この関数が再度呼ばれる)
m_EdHex.SetWindowTextW(strResult);
// 置き換え後の文字列で以前と同じカーソル位置
int nNewPos = nStart - nExclude;
if (nNewPos > 0)
{
// カーソル位置を更新
m_EdHex.SetSel(nNewPos, nNewPos);
}
// 再入防止をOFF
bInChange = false;
}
}
6 ダイアログ初期化関数の追加
次に入力できる文字数を制限します。2バイト (0x0000 ~ 0xFFFF) の範囲での入力を許可する場合、最大で4文字まで入力できるように設定します。ダイアログ初期化をするタイミングがおすすめです。クラスウィザードを再度開き、「OnInitDialog」関数を追加します。

7 エディットコントロールの初期化
次のように、ダイアログ初期化関数の内部で、エディットコントロールの視覚情報を初期化するプログラムを追加します。
BOOL CAppHexEdit::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 文字数の最大数を4バイトする
m_EdHex.SetLimitText(4);
// 文字を右揃えにする
m_EdHex.ModifyStyle(0, ES_RIGHT);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
8 実行結果
以上のプロセスの後、ビルド & 実行すると、次のように16進数4桁まで入力が可能なエディットコントロールを作成することができました。


