Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > изменение свойств Edit Box


Автор: OPQ 2.8.2006, 07:17
Здравствуйте люди. Я новичок в MFC, поэтому не убивайте меня сильно, если вопрос покажется глупым

Есть диалог, 4 Radio Button и 2 Edit Box, надо чтобы при выборе первого Radio Button у первый Edit Box Disabled = false, а у второго Disabled = true, при выборе второго Radio Button  - наоборот.
А при выборе 3 и 4 Radio Button оба  Edit Box были Disabled = true.

Я это сделал вот так, но не уверен, что это хорошо, как можно сделать по-другому? 
Код

void CCalculatorDlg::OnBnClickedRadio1()
{
    CEdit *ed1;
    ed1 = (CEdit*) GetDlgItem (IDC_EDIT1);
    ed1->EnableWindow(TRUE);
    CEdit *ed2;
    ed2 = (CEdit*) GetDlgItem (IDC_EDIT2);
    ed2->EnableWindow(FALSE);
}

void CCalculatorDlg::OnBnClickedRadio2()
{
    CEdit *ed2;
    ed2 = (CEdit*) GetDlgItem (IDC_EDIT2);
    ed2->EnableWindow(TRUE);
    CEdit *ed1;
    ed1 = (CEdit*) GetDlgItem (IDC_EDIT1);
    ed1->EnableWindow(FALSE);
}

void CCalculatorDlg::OnBnClickedRadio3()
{
    CEdit *ed1;
    ed1 = (CEdit*) GetDlgItem (IDC_EDIT1);
    ed1->EnableWindow(FALSE);
    CEdit *ed2;
    ed2 = (CEdit*) GetDlgItem (IDC_EDIT2);
    ed2->EnableWindow(FALSE);
}

void CCalculatorDlg::OnBnClickedRadio4()
{
    CEdit *ed1;
    ed1 = (CEdit*) GetDlgItem (IDC_EDIT1);
    ed1->EnableWindow(FALSE);
    CEdit *ed2;
    ed2 = (CEdit*) GetDlgItem (IDC_EDIT2);
    ed2->EnableWindow(FALSE);
}


Автор: Dart 2.8.2006, 08:23
Вообще-то сделано нормально, только я бы в отдельную функцию это засунул.
А вообще-то для изменения стилей окна существует метод ModifyStyle для основных и ModifyStyleEx для дополнительных свойств.
Почитай в MSDN о свойствах окна, и тебе станет все ясно.
Удачи!

Автор: Earnest 2.8.2006, 08:26
1) Лучше написать функцию, которая будет делать enable обоим полям в зависимости от текущего состояния радио-опции и вызывать ее из обоих обработчиков. Если все 4 радио-кнопки образуют группу (т.е. только одна из них может быть включена), то узнать, какая, можно одним вызовом GetCheckedRadioButon. 
Написанная функция тебе также пригодится и при инициализации диалога (для предустановки параметров). Вообще, состояние полей лучше привязывать к состоянию переменных или других полей, а не к действиям пользователя.

2) Продвинутый вариант: заставить работать обработчики ON_UPDATE_COMMAND_UI для каждого поля, чье состояние нужно менять, как это делается для немодальной диалоговой панели.

Автор: Dart 2.8.2006, 08:33
Цитата(Earnest @  2.8.2006,  08:26 Найти цитируемый пост)
2) Продвинутый вариант: заставить работать обработчики ON_UPDATE_COMMAND_UI для каждого поля, чье состояние нужно менять, как это делается для немодальной диалоговой панели.

Только без поллитра в этом новичку не разобраться.
Так что лучше 1 вариант, как и советует Earnest. Просто когда у тебя будет реальный проект, большое количество функций неизбежно приведет к каше в твоей голове.

Автор: OPQ 2.8.2006, 08:42
Earnest, а можно пример?

Автор: Dart 2.8.2006, 08:56
Что-то типа
Код

void CCalculatorDlg::EnablingEditControls(BOOL value1, BOOL value2, ...)
{
    CEdit* ed1 = (CEdit*)GetDlgItem(IDC_EDIT1);
    CEdit* ed2 = (CEdit*)GetDlgItem(IDC_EDIT2);
    ed1->EnableWindow(value1);
    ed2->EnableWindow(value2);
//// и так далее
}
А дальше спокойно описываешь логику своей работы, как тебе надо

Автор: Earnest 2.8.2006, 12:48
Насчет единой функции, я имела в виду немного другое:

Код

void CCalculatorDlg::UpdateEdits()
{
   // допустим, радиокнопки имеют ид-ры IDC_ONE, IDC_TWO, IDC_THREE, IDC_FOUR
   // кнопки следуют в порядке z-order!
   int btnChecked = GetCheckedRadioButton (IDC_ONE, IDC_FOUR);
   
   GetDlgItem (IDC_EDIT1)->EnableWindow (btnChecked == IDC_ONE);
   GetDlgItem (IDC_EDIT2)->EnableWindow (btnChecked == IDC_TWO);
}

И вызывать этот метод из всех OnBtnClicked. Больше там ничего делать не надо, так что можно поставить один обработчик на диапазон.

Насчет асинхронного обновления:
Цитата(Dart @  2.8.2006,  09:33 Найти цитируемый пост)
Только без поллитра в этом новичку не разобраться.

Ну, сам, может и не найдет, но если показать, то все просто. Чтобы работали обработчики ON_UPDATE, нужно добавить обработчик сообщения WM_KICKIDLE, а в нем вызывать UpdateDialogControls(). Сообщение определено в "afxpriv.h". Я уже писала об этом в форуме.

В этом случае достаточно будет написать свой OnUpdate для каждого поля, а обработчики OnBtnClicked вообще не нужны.


Автор: OPQ 3.8.2006, 11:50
Спасибо! У меня ещё один вопрос  smile  как сделать так, чтобы после ввода в Edit при нажатии Enter выполнялась определённая функция или происходило нажатие определённой кнопки, а то я нажимаю  Enter и происходит выход smile 

Автор: Earnest 3.8.2006, 15:43
1) Можно переопределить PreTranslateMessage для диалога, в котором ловить нажатие ENTER и проверять, не в едите ли фокус, и тогда делать что тебе надо (и возвращать TRUE).

2) При нажатии ENTER генерируется команда от кнопки по-умолчанию. Выход происходит, т.к. по умолчанию DefaultButton = OK. Переставь с помощью SetDefID. Или в дизайнере диалогов поставь свойство Default у нужной кнопки, а не у OK.

Автор: OPQ 8.8.2006, 16:02
Как отловить нажатие ENTER я разобрался, а как отловить нажатие других клавиш, например '*' , '/' , '+' , '-' smile 

И если можно еще пара вопросов. 

1. Как на Radio Button поставить картинку из ресурсов типа BITMAP, в свойствах Appearance Bitmap ставлю true, а чта дальше делать не знаю smile 

2. Как програмно изменить рисунок в  Picture Control ?

еще раз спасибо!

Автор: Earnest 8.8.2006, 18:26
1) RadioButton - это просто CButton, у последнего есть функция SetBitmap.
2) PictureControl - это, кажется, CStatic. Есть аналогичная ф-я.

Автор: Gremlin 7.9.2006, 12:07
А вот мне помогите с этим Едитом! Хочу чтобы текст был выровнен по вертикали по центру!
Тоесть я изменил размеры всего поля и оно стало в два раза больше текста и нужно выравнивание!
гы увеличения кегля не предлагать smile

Автор: zkv 7.9.2006, 12:31
Код

m_EditField.LineScroll(numLines, numChars );

так текст в едите можно крутить, а выравнивание вроде в свойствах можно указать

Автор: Earnest 8.9.2006, 06:38
По-моему, в эдите вертикальное выравнивание не предусмотрено... 

Автор: Gremlin 8.9.2006, 06:49
блин я бы не спрашивал еслибы если бы было предусмотрено штатно но сделать надо smile возможно есть какая нибуть возможность отступить определенное колво пикселей от границы?

Автор: Dart 8.9.2006, 10:52
Gremlin, только создавать всой контрол.
В принципе, есть еще одна достаточно простая возможность: на CEdit создать Child'а тоже CEdit, но без WS_BORDER. У родительского убрать WS_TABSTOP и WS_DISABLED и позиционировать его туда, куда тебе нужно в OnMove и OnSize.
Другой вариант - писать с нуля и плясать от CWnd.

Автор: Bishop 9.9.2006, 08:14
Gremlin, 
Код
CString string(_T("Мега - длинный текст. Его продолжение."));
int margin = 10;  // отсуп справа и слева, можно и разные задать
CRect wnd_rect;
CSize text_rect;
CWnd *edit = GetDlgItem(IDC_EDIT);
edit->GetClientRect(&wnd_rect);
bool multiline = !(edit->GetStyle() & ES_AUTOHSCROLL);
CDC *pdc = edit->GetDC();
// размер текста: высота и длина строки
GetTextExtentPoint32(pdc->m_hDC, string, string.GetLength(), &text_rect);
// ~ количество строк, если multiline
int text_lines = text_rect.cx/(wnd_rect.Width() - 2 * margin);
// tmp - отступ сверху и снизу
int tmp = wnd_rect.Height() - text_rect.cy * (multiline?text_lines:1);
tmp /= 2;

// устанавливаем RECT вывода. Если вместо последнего tmp подставить 0, 
// то при неверно вычисленном text_lines последняя строка не обрежется.
// т.к. текст лучше смотрится когда ближе к нижнему краю, а не к верхнему,
// то отступ от top при multiline немного увеличивается.
wnd_rect.DeflateRect(margin, 
    tmp + (multiline?text_rect.cy/4:0), margin, tmp);
edit->SendMessage(EM_SETRECT, 0, (LPARAM)&wnd_rect);
edit->SetWindowText(string);

Вот в таком вот примерно акцепте. Через EM_SETRECT выставляется прямоугольник, в который будет выведен текст. Применимо только для Multiline полей.

Автор: Gremlin 19.9.2006, 18:11
Вот ешо вопрос про Едит. Хочу чтобы в поле можно было вводить только цыфры  и символы "-" и ".". Я в принципе сделал в обработчике по изменению производить эту проверку но мне кажется это не правильно ибо символ сначала заносится в едит а потом если не удовлетворяет условию удаляется. Есть ли у кого пример как это сделать с помощью я так понимаю WM_KEYDOWN?

Автор: Earnest 20.9.2006, 08:26
Сделай свой обработчик WM_CHAR и проверяй в нем. Если символ устраивает, вызывай стандартный обработчик, нет - ничего не делай или пищи.

Автор: Gremlin 20.9.2006, 12:59
а как пикнуть?

Автор: vinter 20.9.2006, 15:20
Код

MessageBeep((WORD)-2);

Автор: Gremlin 20.9.2006, 17:22
гыгы это шутка была
а по теме: Создал OnChar ставлю внутри точку остановки жму символ и нефига не заходит а выполняется сразу обработчит на изменение Едита!

Автор: Earnest 21.9.2006, 18:48
Видимо, что-то делаешь неправильно.
Проверь, что 
1) OnChar переопределено у наследника CEdit (а не у диалога!)
2) обработчик подключен в карту сообщений 
3) контрол правильно субклассирован (т.е. есть DDX_Control с переменной нужного класса)

Автор: Gremlin 22.9.2006, 18:08
У меня 4 класса С...App, C...Dlg и два класса PropertySheet, вот на одной из вкладок и находится Edit Box так где мне нужно переопреелять onChar?

Автор: Bishop 23.9.2006, 18:55
Gremlin,
Можно и так (если Edit Box такой один и/или не хочешь заниматься наследованием/субклассированием):
Код

BOOL CtestDlg::PreTranslateMessage(MSG* pMsg)
{
    CString txt;
    bool positive = false;
    CEdit *pEdit = (CEdit *) GetDlgItem(IDC_EDIT1);
    int sel_start, sel_end;
    char DesimalSeparator[4];

    if (pMsg->message == WM_CHAR && pMsg->hwnd == pEdit->m_hWnd)
    {
        pEdit->GetWindowText(txt);
        GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, (LPTSTR) DesimalSeparator, 4);
        switch (pMsg->wParam)
        {
        case L'.':
        case L',':
            if (txt.Find(DesimalSeparator[0]) < 0) // можно вводить только 1 разделитель
            {
                if (txt.GetLength() == 0)// в пустое поле добавить ноль
                {
                    pEdit->SetWindowText(L"0");
                    pEdit->SetSel(1, 1);
                }
                pMsg->wParam = DesimalSeparator[0];
            }
            else
                return TRUE;
        case 0x8: // backspace
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            break;
        case '+':
            positive = true;
        case '-':
            pEdit->GetSel(sel_start, sel_end); // сохранить выделение/позицию
            if (positive)
            {
                if (txt[0] == '-')
                {
                    txt.TrimLeft('-');
                    sel_start--;
                    sel_end--;
                }
            }
            else if (txt[0] != '-')
            {
                txt.Insert(0, '-');
                sel_start++;
                sel_end++;
            }
            pEdit->SetWindowText(txt);
            pEdit->SetSel(sel_start, sel_end); // восстановить
            return TRUE;
        default:
            return TRUE;
        }
    }
    return CDialog::PreTranslateMessage(pMsg);
}

только для твоего PropertySheet. 

Автор: Gremlin 25.9.2006, 17:16
а почему нельзя для нескольких? у меня их 4 таких поля на одном щите, и где я должен эту функцию вызывать? в обработчике по изменению?

Автор: Earnest 26.9.2006, 16:48
Если нужно для нескольких, то небольшое изменение в вышеприведенном коде от Bishop:
pMsg->hwnd == pEdit->m_hWnd заменяешь на проверку всех 4 полей. Можно функцию написать, чтобы красивее было.
Вариант со своим классом и обработчиком OnChar - сделай все эдиты этим классом.
 

Автор: Gremlin 26.9.2006, 17:41
а если проверять в котором чичас эдите курсор и проверять тока по этому эдиту?

Автор: Earnest 26.9.2006, 19:37
Цитата(Gremlin @  26.9.2006,  18:41 Найти цитируемый пост)
а если проверять в котором чичас эдите курсор 

Это и есть pMsg->hWnd. Тебе надо проверить, что это hWnd совпадает с одним из твоих.

Автор: Gremlin 27.9.2006, 18:41
немножко переделал но мне кажется не очень красиво вышло слишком много кода
Код

BOOL CMultiAmp::PreTranslateMessage(MSG* pMsg)
{
    // TODO: Add your specialized code here and/or call the base class
    CString txt;
    bool positive = false;
    CEdit *pEdit1 = (CEdit *) GetDlgItem(IDC_SENSIVITY1);
    CEdit *pEdit2 = (CEdit *) GetDlgItem(IDC_SENSIVITY2);
    CEdit *pEdit3 = (CEdit *) GetDlgItem(IDC_SENSIVITY3);
    CEdit *pEdit4 = (CEdit *) GetDlgItem(IDC_SENSIVITY4);
    int sel_start, sel_end;
    char DesimalSeparator[4] = ".";

    //-----------------------------------------------------------
    if (pMsg->message == WM_CHAR && pMsg->hwnd == pEdit1->m_hWnd)
    {
        pEdit1->GetWindowText(txt);
        //GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, (LPTSTR) DesimalSeparator, 4);
        switch (pMsg->wParam)
        {
        case ',':
            if (txt.Find(DesimalSeparator[0]) < 0) // можно вводить только 1 разделитель
            {
                if (txt.GetLength() == 0)// в пустое поле добавить 0
                {
                    pEdit1->SetWindowText("0");
                    pEdit1->SetSel(1, 1);
                }
                pMsg->wParam = DesimalSeparator[0];
            }
            else
                return TRUE;
        case '.':
            if (txt.Find(DesimalSeparator[0]) < 0) // можно вводить только 1 разделитель
            {
                if (txt.GetLength() == 0)// в пустое поле добавить 0
                {
                    pEdit1->SetWindowText("0");
                    pEdit1->SetSel(1, 1);
                }
                pMsg->wParam = DesimalSeparator[0];
            }
            else
                return TRUE;
        case 0x8: // backspace
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            break;
        case '+':
            positive = true;
        case '-':
            pEdit1->GetSel(sel_start, sel_end); // сохранить выделение/позицию
            if (positive)
            {
                if (txt[0] == '-')
                {
                    txt.TrimLeft('-');
                    sel_start--;
                    sel_end--;
                }
            }
            else if (txt[0] != '-')
            {
                txt.Insert(0, '-');
                sel_start++;
                sel_end++;
            }
            pEdit1->SetWindowText(txt);
            pEdit1->SetSel(sel_start, sel_end); // восстановить
            return TRUE;
        default:
            ::MessageBeep(MB_OKCANCEL);
            return TRUE;
        }
    }
    //-----------------------------------------------------------
    if (pMsg->message == WM_CHAR && pMsg->hwnd == pEdit2->m_hWnd)
    {
        pEdit2->GetWindowText(txt);
        //GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, (LPTSTR) DesimalSeparator, 4);
        switch (pMsg->wParam)
        {
        case ',':
            if (txt.Find(DesimalSeparator[0]) < 0) // можно вводить только 1 разделитель
            {
                if (txt.GetLength() == 0)// в пустое поле добавить 0
                {
                    pEdit2->SetWindowText("0");
                    pEdit2->SetSel(1, 1);
                }
                pMsg->wParam = DesimalSeparator[0];
            }
            else
                return TRUE;
        case '.':
            if (txt.Find(DesimalSeparator[0]) < 0) // можно вводить только 1 разделитель
            {
                if (txt.GetLength() == 0)// в пустое поле добавить 0
                {
                    pEdit2->SetWindowText("0");
                    pEdit2->SetSel(1, 1);
                }
                pMsg->wParam = DesimalSeparator[0];
            }
            else
                return TRUE;
        case 0x8: // backspace
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            break;
        case '+':
            positive = true;
        case '-':
            pEdit2->GetSel(sel_start, sel_end); // сохранить выделение/позицию
            if (positive)
            {
                if (txt[0] == '-')
                {
                    txt.TrimLeft('-');
                    sel_start--;
                    sel_end--;
                }
            }
            else if (txt[0] != '-')
            {
                txt.Insert(0, '-');
                sel_start++;
                sel_end++;
            }
            pEdit2->SetWindowText(txt);
            pEdit2->SetSel(sel_start, sel_end); // восстановить
            return TRUE;
        default:
            ::MessageBeep(MB_OKCANCEL);
            return TRUE;
        }
    }
    //-----------------------------------------------------------
    if (pMsg->message == WM_CHAR && pMsg->hwnd == pEdit3->m_hWnd)
    {
        pEdit3->GetWindowText(txt);
        //GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, (LPTSTR) DesimalSeparator, 4);
        switch (pMsg->wParam)
        {
        case ',':
            if (txt.Find(DesimalSeparator[0]) < 0) // можно вводить только 1 разделитель
            {
                if (txt.GetLength() == 0)// в пустое поле добавить 0
                {
                    pEdit3->SetWindowText("0");
                    pEdit3->SetSel(1, 1);
                }
                pMsg->wParam = DesimalSeparator[0];
            }
            else
                return TRUE;
        case '.':
            if (txt.Find(DesimalSeparator[0]) < 0) // можно вводить только 1 разделитель
            {
                if (txt.GetLength() == 0)// в пустое поле добавить 0
                {
                    pEdit3->SetWindowText("0");
                    pEdit3->SetSel(1, 1);
                }
                pMsg->wParam = DesimalSeparator[0];
            }
            else
                return TRUE;
        case 0x8: // backspace
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            break;
        case '+':
            positive = true;
        case '-':
            pEdit3->GetSel(sel_start, sel_end); // сохранить выделение/позицию
            if (positive)
            {
                if (txt[0] == '-')
                {
                    txt.TrimLeft('-');
                    sel_start--;
                    sel_end--;
                }
            }
            else if (txt[0] != '-')
            {
                txt.Insert(0, '-');
                sel_start++;
                sel_end++;
            }
            pEdit3->SetWindowText(txt);
            pEdit3->SetSel(sel_start, sel_end); // восстановить
            return TRUE;
        default:
            ::MessageBeep(MB_OKCANCEL);
            return TRUE;
        }
    }
    //-----------------------------------------------------------
    if (pMsg->message == WM_CHAR && pMsg->hwnd == pEdit4->m_hWnd)
    {
        pEdit4->GetWindowText(txt);
        //GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, (LPTSTR) DesimalSeparator, 4);
        switch (pMsg->wParam)
        {
        case ',':
            if (txt.Find(DesimalSeparator[0]) < 0) // можно вводить только 1 разделитель
            {
                if (txt.GetLength() == 0)// в пустое поле добавить 0
                {
                    pEdit4->SetWindowText("0");
                    pEdit4->SetSel(1, 1);
                }
                pMsg->wParam = DesimalSeparator[0];
            }
            else
                return TRUE;
        case '.':
            if (txt.Find(DesimalSeparator[0]) < 0) // можно вводить только 1 разделитель
            {
                if (txt.GetLength() == 0)// в пустое поле добавить 0
                {
                    pEdit4->SetWindowText("0");
                    pEdit4->SetSel(1, 1);
                }
                pMsg->wParam = DesimalSeparator[0];
            }
            else
                return TRUE;
        case 0x8: // backspace
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            break;
        case '+':
            positive = true;
        case '-':
            pEdit4->GetSel(sel_start, sel_end); // сохранить выделение/позицию
            if (positive)
            {
                if (txt[0] == '-')
                {
                    txt.TrimLeft('-');
                    sel_start--;
                    sel_end--;
                }
            }
            else if (txt[0] != '-')
            {
                txt.Insert(0, '-');
                sel_start++;
                sel_end++;
            }
            pEdit4->SetWindowText(txt);
            pEdit4->SetSel(sel_start, sel_end); // восстановить
            return TRUE;
        default:
            ::MessageBeep(MB_OKCANCEL);
            return TRUE;
        }
    }
    
    return CPropertyPage::PreTranslateMessage(pMsg);
}

Автор: Bishop 28.9.2006, 07:09
Gremlin,
хотя бы так
Код

CString txt;
bool positive = false;
int sel_start, sel_end;
char DesimalSeparator = '.'; // раз без GetLocaleInfo, то и массив не нужен

if (pMsg->message == WM_CHAR)// && pMsg->hwnd == pEdit->m_hWnd)
{
    CEdit *pEdit = NULL;
    UINT edit_controls[] = {IDC_SENSIVITY1, IDC_SENSIVITY2, IDC_SENSIVITY3, IDC_SENSIVITY4};
    for (UINT i = 0; i < sizeof(edit_controls)/sizeof(UINT); i++)
        if (::GetDlgCtrlID(pMsg->hwnd) == edit_controls[i])
        {
            pEdit = (CEdit *) GetDlgItem(edit_controls[i]);
            break;
        }
    if (pEdit) // обработка в единственном экземпляре
    {
        pEdit->GetWindowText(txt);    
        switch (pMsg->wParam)
        {
        case '.': // здесь тоже дублировать незачем 
        case ',':
        ...
        }
    }
}

Автор: Gremlin 28.9.2006, 17:47
ага я примерно так и думал тока реализовать не получалось smile сибо

Автор: Dart 29.9.2006, 14:27
Есть еще один метод, достаточно простой в использовании, но несколько корявый
(Не бейте меня, профи  smile )
Ловить событие изменения edit box, а потом 
UpdateData(TRUE); UpdateData(FALSE);
Только возможно, придется ещё устанавливать позицию курсора.
Зато кода 2 строчки smile

Автор: Bishop 30.9.2006, 08:35
Dart, это не метод, а побочный эффект.
  • поле не может быть пустым;
  • при вводе нечислового символа вся часть строки после места вставки исчезает;
  • разделитель целой и дробной части можно ввести только если в поле уже есть две цифры, т.е. между ними;
  • большие числа выводятся в экспоненциальном виде, мелкие (дробные) округляются, что недопустимо при вводе;
  • если недопустимый символ первый в строке, выводится сообщение с предложением ввести число.
Я бы не стал так делать.

Автор: Dart 30.9.2006, 09:19
Цитата(Bishop @  30.9.2006,  08:35 Найти цитируемый пост)
а побочный эффект

Почему же, очень даже метод smile 

Я исходил из того предположения, что в результате необходимо получить необходимые данные определённого типа (ну, int, float, и т.п.). Если не заморачиваться вводом специфичных данных (а как правило это и не надо), то такой метод упрощает решение вопросов правильности ввода данных.

Все твои мысли в принципе правильные, но тем не менее, если необходимо быстро решить этот вопрос, то лучшего решения пожалуй и не стоит придумывать. Потом, ведь не обязательно вешать это на обработчик EN_CHANGE, можно и на другие.

Я и сам так не делаю, когда хочется сделать всё нарядно. Я и в предыдущем посте сказал, что это несколько коряво. Но тем не менее такой вариант имеет право на жизнь.

Автор: Earnest 30.9.2006, 10:50
Цитата(Dart @  30.9.2006,  10:19 Найти цитируемый пост)
Я и сам так не делаю

А ты попробуй - наверняка понравится  smile  ... текст в эдите непрерывно дергается, да еще и меняться может, если форматирование или валидация используется.  Если уж ловить изменения EN_CHANGE, то только затем, чтобы установить факт изменения (ну или еще какие-то действия), но никак не для контроля ввода.
Для контроля ввода есть, в основном, 2 пути: контроль каждого CHAR - для этого надо свой эдит писать, и способ этот хорош только для тех случаев, когда можно задать позиционный шаблон, типа номера телефона и пр.
Второй способ - ждать пока пользователь не закончит мучить эдит, потом считать и поправить (проверить, отформатировать).

Автор: Dart 30.9.2006, 13:41
Цитата(Earnest @  30.9.2006,  10:50 Найти цитируемый пост)
наверняка понравится

Не понравится, я такие вещи к потере фокуса обычно привязываю smile

Слушайте, ну что мы из элементарного вопроса флуд устроили?
Цитата(Dart @  29.9.2006,  14:27 Найти цитируемый пост)
но несколько корявый

Я ж уже говорил  smile 
Но, такая возможность есть? - ЕСТЬ, и я о ней сказал.

И основной смысл в моем посте был именно в том, чтобы весь контроль за правильностью введения и интерпретации информации можно возложить на MFC.
А уж воспользуется ли кто этим или нет - не мне решать. Может, кому-нибудь и такой метод понравится.

Потом,
Цитата(Dart @  29.9.2006,  14:27 Найти цитируемый пост)
Ловить событие изменения edit box

вовсе не означает использование EN_CHANGE.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)