「CEditを継承したクラスを作成する」の版間の差分

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動
編集の要約なし
(文字列「</source>」を「</syntaxhighlight>」に置換)
 
(2人の利用者による、間の2版が非表示)
2行目: 2行目:
CEditを継承したクラスを作成し、OnChar関数をオーバーライドする。
CEditを継承したクラスを作成し、OnChar関数をオーバーライドする。


  <source lang="c++">
  <syntaxhighlight lang="c++">
  CNumericEdit.h
  CNumericEdit.h
   
   
33行目: 33行目:
     DECLARE_MESSAGE_MAP()
     DECLARE_MESSAGE_MAP()
  };
  };
  </source>
  </syntaxhighlight>
<br>
<br>
  <source lang="c++">
  <syntaxhighlight lang="c++">
  #include "stdafx.h"
  #include "stdafx.h"
  #include "CNumericEdit.h"
  #include "CNumericEdit.h"
112行目: 112行目:
     }
     }
  }
  }
  </source>
  </syntaxhighlight>
<br><br>
<br><br>


== ダイアログから値を取得する ==
== ダイアログから値を取得する ==
下記のように、ダイアログを起動して入力された値を取得するときは注意が必要である。
下記のように、ダイアログを起動して入力された値を取得するときは注意が必要である。<br>
DoModal()関数がIDOKを返した時点で、ダイアログ内のコントロールが破棄されてしまうため、値を取得する事ができない。
DoModal()関数がIDOKを返した時点で、ダイアログ内のコントロールが破棄されてしまうため、値を取得する事ができない。<br>
この場合、メンバにCString型の変数を定義し、DDX_Textで値を更新する。
この場合、メンバにCString型の変数を定義し、DDX_Textで値を更新する。<br>
<br>
  <syntaxhighlight lang="c++">
  <source lang="c++">
  CMyDialog dlg;
  CMyDialog dlg;
   
   
129行目: 128行目:
     dlg.m_editValue.GetWindowText(strText); // アサーションエラー
     dlg.m_editValue.GetWindowText(strText); // アサーションエラー
  }
  }
  </source>
  </syntaxhighlight>
<br><br>
<br><br>


== 入力値の制限と値取得を同時に行う ==
== 入力値の制限と値取得を同時に行う ==
CEdit型とCString型の変数を定義し、DoDataExchange内に、DDXControlとDDXTEXTを追加する。
CEdit型とCString型の変数を定義し、DoDataExchange内に、DDXControlとDDXTEXTを追加する。
  <source lang="c++">
  <syntaxhighlight lang="c++">
  void CMyDialog::DoDataExchange(CDataExchange* pDX)
  void CMyDialog::DoDataExchange(CDataExchange* pDX)
  {
  {
145行目: 144行目:
     DDX_Text(pDX, IDC_EDIT_VALUE, m_strValue);
     DDX_Text(pDX, IDC_EDIT_VALUE, m_strValue);
  }
  }
  </source>
  </syntaxhighlight>
<br><br>
<br><br>


151行目: 150行目:
ダイアログデータバリデーション(DDV)を使用する。<br>
ダイアログデータバリデーション(DDV)を使用する。<br>
DoDataExchange()内に下記のように関数を追加する。<br>
DoDataExchange()内に下記のように関数を追加する。<br>
  <source lang="c++">
  <syntaxhighlight lang="c++">
  void CMyDialog::DoDataExchange(CDataExchange* pDX)
  void CMyDialog::DoDataExchange(CDataExchange* pDX)
  {
  {
166行目: 165行目:
     DDV_MinMaxDouble(pDX, atof(m_strValue), 0.0, 1.0);
     DDV_MinMaxDouble(pDX, atof(m_strValue), 0.0, 1.0);
  }
  }
  </source>
  </syntaxhighlight>
<br><br>
<br><br>


174行目: 173行目:
そこで、データが有効か確認するための独自関数を作成する。<br>
そこで、データが有効か確認するための独自関数を作成する。<br>
<br>
<br>
  <source lang="c++">
  <syntaxhighlight lang="c++">
  void DDV_CheckLowerUpper(CDataExchange* pDX, double lower, double upper)
  void DDV_CheckLowerUpper(CDataExchange* pDX, double lower, double upper)
  {
  {
183行目: 182行目:
     }
     }
  }
  }
  </source>
  </syntaxhighlight>
上記の関数を、DoDataExchange()内に追記する。<br>
上記の関数を、DoDataExchange()内に追記する。<br>
  <source lang="c++">
  <syntaxhighlight lang="c++">
  void CMyDialog::DoDataExchange(CDataExchange* pDX)
  void CMyDialog::DoDataExchange(CDataExchange* pDX)
  {
  {
209行目: 208行目:
     }
     }
  }
  }
  </source>
  </syntaxhighlight>
<br><br>
<br><br>


__FORCETOC__
__FORCETOC__
[[カテゴリ:MFC]]
[[カテゴリ:MFC]]

2021年11月16日 (火) 15:23時点における最新版

エディットコントロールで入力制限を行う

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);
 }



入力値の範囲をチェックする

ダイアログデータバリデーション(DDV)を使用する。
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);
 }



複数のエディットコントロール間で有効性を確認する

2つのエディットコントロール間の関係性から、データの有効性を決めたいことがある。
例えば、ユーザに上限値と下限値を入力してもらう場合、上限値は下限値より大きくなければいけない。
そこで、データが有効か確認するための独自関数を作成する。

 void DDV_CheckLowerUpper(CDataExchange* pDX, double lower, double upper)
 {
    if(lower > upper)
    {
       AfxMessageBox(_T("下限値には上限値より小さい数値を入力してください."), MB_ICONWARNING);
       pDX->Fail();
    }
 }

上記の関数を、DoDataExchange()内に追記する。

 void CMyDialog::DoDataExchange(CDataExchange* pDX)
 {
    CDialog::DoDataExchange(pDX);
 
    // 入力値の制限,OnChar をオーバーライドしたクラス
    DDX_Control(pDX, IDC_EDIT_LOWER_VALUE, m_editLower);
    DDX_Control(pDX, IDC_EDIT_UPPER_VALUE, m_editUpper);
 
    // ダイアログ消滅後の値取得用
    DDX_Text(pDX, IDC_EDIT_LOWER_VALUE, m_strLower);
    DDX_Text(pDX, IDC_EDIT_UPPER_VALUE, m_strUpper);
 
    // 入力値の範囲確認
    // 他の型用のDDVも標準で存在する
    DDV_MinMaxDouble(pDX, atof(m_strLower), 0.0, 1.0);
    DDV_MinMaxDouble(pDX, atof(m_strUpper), 0.0, 1.0);
 
    // 下限値と上限値が入力されている場合は 下限値 < 上限値 であるかチェックする
    if(!m_strLower.IsEmpty() && !m_strUpper.IsEmpty())
    {
       DDV_CheckLowerUpper(pDX, atof(m_strLower), atof(m_strUpper));
    }
 }