Вот. В моём варианте, я заметил, есть такая фича или баг , что цифры после точки переписываются поверх если поставить курсор(после точки) и начать вводить новые, здесь можно или всё сделать в таком стиле или пофиксить. ЗЫ: над оптимизацией кода особенно не задумывался, тебе ж всё-равно на C нужно. _1678523673__MaskedEdit.rar
Там ещё пары макросов не хватает: Код (Text): WM_CASE MACRO reg:REQ, msgs:REQ IRP msg, <msgs> cmp reg, WM_&msg je @&msg ENDM ENDM $invoke MACRO vars:VARARG invoke vars EXITM <eax> ENDM
Предлагаю модификацию варианта AsmGuru62: 1 начальное состояние буфера = ""; 2 по EN_CHANGE читаем GetWindowText и прогоняем через фильтр; 3 если фильтр проходит копируем в буфер и п.2 4 восстанавливаем из буфера edit посредством SetWindowText и п.2
Несколько измышлений на близкую тему: MaskEdit-ы с фиксированными позициями ввода ИМХО хороши для телефонных номеров, дат и т.п., а вот для нефиксированного числа символов эта фигня юзера напрягает. А посему я еще в стародавние времена на Delphi 3 смастерил себе контрол TFloatEdit (по смыслу decimal), и пользуюсь им по сей день. Хотелось сделать "на все случаи жизни", а по сему не обошлось без излишеств: допустимый диапазон чисел (min и max), начальное значение (оно же по умолчанию), разрешение\запрет пустого значения, возможность ввода в качестве разделителя точки и запятой (мы то к точке привыкли, а "девочки из бухгалтерии" к запятой). Первичный и основной контроль ес-но делается по вводу символа OnKeyPress (WM_CHAR или WM_KEYDOWN). Если числа положительные (Min >= 0) и нет ограничения на число цифр дробной части, то ваще все просто: цифры пропускаем без проверки, запятую меняем на точку, если в итоге точка - проверяем если уже есть, то запрет (если еще нет, но вводится в первую позицию в строке - можно тоже запретить). Если допустимы отрицательные числа, то все несколько усложняется - проверяем наличие минуса, если есть, то 1) минус должен быть на первой позиции и второй минус ес-но не допустим и 2) позиция вводимой цифры или точки д.б. > 1. С ограниченным числом цифр после запятой возможны 2 подхода: 1) не ограничивать при вводе, а просто округлять результат до нужного значения; можно делать форматирование по Enter, Tab или потере фокуса - юзверь сам сообразит, что больше двух вводить нет смысла (ну еще начальное значение или хинты помогают); еще надо заметить, что ограничение длины часто юзверя бесит - по идее какая фиг разница, что он там делает - лишь бы результат был "правильный" (сначала удалить 2 неверных символа и ввести другие или сначала вставить два других, а затем удалить ненужные). 2) можно ограничивать при вводе, тогда поступаем аналогично - если вводится цифра, то находим позицию точки в строке и если есть, сравниваем с позицией ввода, если разность больше допустимой, то beep. Насчет проверки по EN_CHANGE я уже говорил: если есть первичный контроль ввода и окончательный контроль валидности, то OnChange лучше не использовать, т.к. это "нарушение прав человека" - пусть творит че хочет в рамках разумного. Окончательный контроль я вешаю на нажатие клавиш Enter, Тab и на потерю фокуса (OnExit). Чтобы не выглядеть глупо, проверяю контрол, получивший фокус - если это кнопка Cancel (имеется ввиду модальный диалог), то выход без проверки. Иначе проверяем на пустое значение и его допустимость, если не пустое, то преобразуем в число и сравниваем с границами диапазона. В случае ошибки выдаем MessageBox и возвращаем фокус на ввод. Ну еще можно "отобрать" Escape у кнопки Cancel и восстанавливать по нему значение по умолчанию. PS: никакого смысла что-то оптимизировать или д'zенствовать в данном случае я не вижу, т.к. скорости реакции человека и компьютера просто несопоставимы - достаточно просто не глупить. А дзену думается всегда найдется более достойное применение. Хотя кому что нравится, или как говорил один знакомый "кто на что учился"...
leo EN_CHANGE ... лучше не использовать Символы могут поступать из буфера обмена. Я отдаю предпочтение обработке EN_CHANGE.
q_q leo > "EN_CHANGE ... лучше не использовать" Я имел ввиду только случай, когда есть обработка нажатия клавиш и потери фокуса. Тогда использование CHANGE уже выглядит излишним. Хотя, чтобы выдавать предупреждение сразу после неверной вставки, то можно и EN_CHANGE задействовать.
сделал по обработке EN_CHANGE но по идеологии leo. Спасибо за идеи, моя реализация не совсем то что хотелось бы, но пока меня устраивает.
leo выдавать предупреждение сразу после неверной вставки Это не мой метод. Я предпочитаю молчаливое (даже без beep'ов) игнорирование недопустимых символов, разумеется форма строится так, чтобы пользователю было понятно, что можно вводить, а что можно даже не пробовать.
q_q Я с тобой согласен, при вводе символов с клавы я так и делаю. Но что делать при вставке "мусора" из буфера ? Неужели молча проигнорировать и не будет ли это выглядеть странно ? PS: Еще раз отмечу, что я лично на "общении" с юзером стараюсь не экономить, но и не выглядеть тупым и надоедливым (поэтому все эти юзер-интерфейсы так достают, несмотря на "помощь" Delphi...) А потому, что приходится "творить" для родной фирмы и если "девочкам-мальчикам" будет что непонятно - будут каждые пять минут бегать с вопросами, а это гораздо хуже...
Вобще-то с этими EN_CHANGE/EN_UPDATE нужно быть ооочень внимательным, потому как можно в бесконечный цикл влететь при неправильной обработке этих сообщений
leo при вставке "мусора" из буфера ... молча проигнорировать и не будет ли это выглядеть странно? Думаю, не будет. Можно вставлять только первые символы, удовлетворяющие маске и текущей позиции курсора. Если таковых нет, то молчаливое игнорирование. Afaik так ведет себя calc.exe.