123iamking 123iamking - 1 month ago 38
C++ Question

MFC - Remove leading zeros for CEdit number control

I find that CEdit control has option 'Number' in its property, so that I can prevent user from enter non-digit character into this textbox - it is CEdit number control now.
If there is an option 'Number', I think maybe there is a way to remove leading zeros for CEdit which is just simple like option 'Number'.

I have tried Dialog Data Exchange with hope that it would remove leading zeros for me automatically, but it won't.

Then I think the way to do this is add EN_KILLFOCUS message for each of the CEdit number controls, but I find that exhausted.

So I think the better way to do that is add EN_KILLFOCUS, but all the CEdit number controls lose focus event point to one function, in this function I'll remove leading zero for the 'current' control, but in C# I can get the 'current' control, in C++ I don't know if it's supported.

Or inherit CEdit to make CEditNum - which implement lose focus remove leading zeros feature, but with this solution, I can't design it on the Visual Studio design window (I think). I hope there is a solution similar to this solution (which is a solution for Draw&Drop problem)

Anyway, before apply the final solution (EN_KILLFOCUS), I want to make sure if is there better way - least implement, reuse the existing implement of MFC.

A little explain about remove leading zeros: you enter: 00001 into the CEdit control, then lose focus, the CEdit control show you: 1. The idea is like MS Excel when you enter a number into its cell.

Answer Source

"but all the CEdit number controls lose focus event point to one function"

That is true, but you get the control ID of the control that's just lost focus as a parameter.

Add this to your Message table, replace IDC_FIRST, IDC_LAST with the first and last IDs of your edit controls, or use 0, 0xFFFFFFFF for all.

ON_CONTROL_RANGE(EN_KILLFOCUS, IDC_FIRST, IDC_LAST, OnKillFocus). 

Here is the signature of OnKillFocus, and how to get a CWnd to apply changes.

void CMyDialogClass::OnKillFocus(UINT nID) 
{
    // you can further check if the ID is one of interest here...
    // if your edit control control IDs are not contiguous, for example.

    // you can get a CEdit* here, but only if you used DDX to map the 
    // control to a CEdit.  
    CWnd* pCtrl = GetDlgItem(nID);
    if (pCtrl)
    {
        CString str;
        pCtrl->GetWindowText(str);
        // remove zeroes, or format as you like....
        str.Format(_T("%d"), _tcstoi(str));
        pCtrl->SetWindowText(str);
    }
}

// if you mapped the control to a CEdit, here's how you can safely          
// get a pointer to a CEDit

CEdit* pEdit = (CEdit*)GetDlgItem(nID);
ASSERT_KINDOF(CEdit, pEdit);  // debug check
if (pEdit && pEdit->IsKindOf(RUNTIME_CLASS(CEdit)))  // standard check
{
// ....
}