Yo usualmente lo que hago es derivar una clase de CEdit , capturar el mensaje WM_CHAR y en OnChar validar el texto ingresado. He aquí un pequeño ejemplo:
class CNumEdit : public CEdit
{
protected:
virtual void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
DECLARE_MESSAGE_MAP();
public:
CNumEdit() {}
};
BEGIN_MESSAGE_MAP(CNumEdit, CEdit)
ON_WM_CHAR()
END_MESSAGE_MAP()
void CNumEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CString str;
TCHAR ch;
ch = nChar
GetWindowText(str);
if (!_istdigit(nChar)) {
MessageBox(_T("Sólo se permiten caracteres numéricos."), NULL, MB_ICONEXCLAMATION);
str = str.Mid(0, str.GetLength() - 1);
SetWindowText(str);
}
}
y ya en tu ventana, solo mandas a llamar al control vía DDX. Asumamos que en tu cuadro de diálogo (IDD_EJEMPLODLG), tienes una
caja de texto cuyo ID es IDC_TEXTONUMERICO. Entonces sólo tendrías que enlazarlo con CNumEdit vía DDX:
class CEjemploDlg : public CDialog
{
private:
CNumEdit m_objTxtNumerico;
enum { IDD = IDD_EJEMPLODLG; }
protected:
virtual void DoDataExchange(CDataExchange* pDX);
public:
CEjemploDlg(CWnd* pParent);
};
CEjemploDlg::CEjemploDlg(CWnd* pParent)
: CDialog(IDD, pParent)
{
}
void CEjemploDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_TEXTONUMERICO, m_objTxtNumerico);
}
Así, mandarías crear el diálogo en forma normalita; asumiendo que la creas desde algún metodo de una clase derivada de CWnd,
CEjemploDlg wndEj = this; // el constructor no es "explicit" :P
wndEj.DoModal();
En resumen, todo está en el manejo de OnChar. Saludos.