エディットコントロールで入力制限を行う
CEditを継承したクラスを作成し、OnChar関数をオーバーライドする。
CNumericEdit.h
#pragma once
class CNumericEdit : public CEdit
{
DECLARE_DYNAMIC(CNumericEdit)
public:
CNumericEdit();
virtual ~CNumericEdit();
void SetRoundPlaceValue(const int RoundPlaceValue)
{
m_iRoundPlaceValue = RoundPlaceValue;
}
int GetRoundPlaceValue() const
{
return m_iRoundPlaceValue;
}
protected:
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
CString m_strDelim;
int m_iRoundPlaceValue;
DECLARE_MESSAGE_MAP()
};
#include "stdafx.h"
#include "CNumericEdit.h"
IMPLEMENT_DYNAMIC(CNumericEdit, CEdit)
CNumericEdit::CNumericEdit()
{
// determine the decimal delimiter buffer size
const int nBuffLen = ::GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, NULL, 0 );
_ASSERT( nBuffLen > 0 );
// get the decimal number delimiter
const int nResult = ::GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, m_strDelim.GetBuffer(nBuffLen), nBuffLen);
_ASSERT(nResult != 0);
m_strDelim.ReleaseBuffer();
}
CNumericEdit::~CNumericEdit()
{
}
BEGIN_MESSAGE_MAP(CNumericEdit, CEdit)
ON_WM_CHAR()
END_MESSAGE_MAP()
void CNumericEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CString strText;
GetWindowText(strText);
int iStart, iEnd;
GetSel(iStart, iEnd);
// 小数点が入力された場合
if(nChar == m_strDelim)
{
// 空欄の場合は小数点の入力を許可しない
if(strText.IsEmpty())
{
return;
}
else
{ // 小数点が既に入力されている場合は入力を許可しない
if (strText.Find(m_strDelim) >= 0)
return;
}
}
if(nChar == '-')
{ // マイナスを入力できるのは空欄の時のみ
if (!strText.IsEmpty())
{
return;
}
}
// 小数点以下の入力文字数を制限
if(nChar >= '0' && nChar <= '9' && strText.Find(m_strDelim) != -1)
{
int iLength = strText.GetLength();
int iRoundPlaceValue = strText.Find(m_strDelim);
if(iStart == iEnd)
{
if(iStart > iRoundPlaceValue && (iLength - iRoundPlaceValue) > m_iRoundPlaceValue)
{
return;
}
}
}
if((nChar >= '0' && nChar <= '9') || (nChar == m_strDelim) || (nChar == '-') || (nChar == '\b'))
{
CEdit::OnChar(nChar, nRepCnt, nFlags);
}
}
ダイアログから値を取得する
下記のように、ダイアログを起動して入力された値を取得するときは注意が必要である。
DoModal()関数がIDOKを返した時点で、ダイアログ内のコントロールが破棄されてしまうため、値を取得する事ができない。
この場合、メンバにCString型の変数を定義し、DDX_Textで値を更新する。
CMyDialog dlg;
if(dlg.DoModal() == IDOK)
{
// この時点で CMyDialog 内のコントロールは消滅する
CString strText;
dlg.m_editValue.GetWindowText(strText); // アサーションエラー
}
入力値の制限と値取得を同時に行う
CEdit型とCString型の変数を定義し、DoDataExchange内に、DDXControlとDDXTEXTを追加する。
void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
// 入力値の制限,OnChar をオーバーライドしたクラス
DDX_Control(pDX, IDC_EDIT_VALUE, m_editValue);
// ダイアログ消滅後の値取得用
DDX_Text(pDX, IDC_EDIT_VALUE, m_strValue);
}
入力値の範囲をチェックする
ダイアログデータバリデーションを使用します.DoDataExchange 内に下記のように関数を追加します.
void CMyDialog::DoDataExchange(CDataExchange* pDX) {
CDialog::DoDataExchange(pDX);
// 入力値の制限,OnChar をオーバーライドしたクラス DDX_Control(pDX, IDC_EDIT_VALUE, m_editValue);
// ダイアログ消滅後の値取得用 DDX_Text(pDX, IDC_EDIT_VALUE, m_strValue);
// 入力値の範囲確認 // 他の型用の DDV も標準であります DDV_MinMaxDouble(pDX, atof(m_strValue), 0.0, 1.0);
}