Поле EDIT для ввода шестнадцатеричных цифр

Поле для ввода только цифр организовать несложно, для этого достаточно просто прописать в ресурсах у нужного поля флаг ES_NUMBER. После этого с клавиатуры в это поле можно будет ввести только символ из интервала "0" - "9". Впрочем этот ничуть не мешает через Ctrl+C / Ctrl+V затолкать в него все что угодно, вплоть до непечатных бинарных данных. А как сделать поле, в которое можно вводить с клавиатуры только шестнадцатеричные цифры? Ведь там могут быть не только символы с десятичными цифрами, но и символы "A" - "F", которые также являются шестнадцатеричными цифрами. Это делается через субклассирование. Мы уже рассмотрели один пример субклассирования, превратив поле EDIT в гиперссылку, и там же определили алгоритм обработчика субклассированного элемента. Как и в прошлый раз, субклассирование должно выполняться на этапе инициализации диалогового окна.
; Сегмент данных
section '.data' data readable writeable  
OldProc dd ?    ; Адрес предыдущего обработчика
 
; Сегмент кода
section '.code' code readable executable
        ...
        ; Субклассирование на этапе инициализации окна
        invoke  GetDlgItem,[hwnddlg],ID_HEX
        ; Установить наш собственный обработчик
        invoke  SetWindowLong,eax,GWL_WNDPROC,EditWindowProc
        ; Сохранить хэндл предыдущего обработчика
        mov     [OldProc],eax
        ...

Здесь все почти то же самое, разница будет лишь в обрабатываемых сообщениях. Соответственно, если будет несколько полей ввода, то надо субклассировать каждое из них отдельно.

Назначенная процедура EditWindowProc будет обрабатывать только одно сообщение: WM_CHAR, оно происходит при нажатии на любую клавишу, когда курсор находится в нашем поле EDIT. При фильтрации нажатых клавиш, кроме шестнадцатеричных цифр не забывайте про служебные комбинации Ctrl+C / Ctrl+V и клавишу Backspace. Все остальные клавиши фильтруются и блокируются. Похожий пример на MASM был показан в одном из уроков Iczelion'а, но в нем не учитывались клавиши копирования-вставки.
proc EditWindowProc hEdit:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
        ; Нажатие клавиши?
        cmp     [uMsg],WM_CHAR
        je      .chk_char
.char_ok:
        ; Передать управление предыдущему обработчику или пропустить
        ; разрешенный символ
        invoke  CallWindowProc,[OldProc],[hEdit],[uMsg],[wParam],[lParam]
        ret
.chk_char:
        ; Проверить код нажатой клавиши
        mov     eax,[wParam]
        cmp     al,VK_BACK      ; Backspace
        je      .char_ok
        cmp     al,22           ; Ctrl+V
        je      .char_ok
        cmp     al,3            ; Ctrl+C
        je      .char_ok
        cmp     al,'0'          ; Hex-цифра?
        jb      .exit_proc
        cmp     al,'9'
        jbe     .char_ok
        or      al,20h          ; Символ в нижний регистр
        cmp     al,'a'
        jb      .exit_proc
        cmp     al,'f'
        jbe     .char_ok
.exit_proc:
        ; Подавить сообщение нажатия клавиши и вернуть из обработчика FALSE
        xor     eax,eax
        ret
endp

Обработчик можно легко модифицировать для других правил фильтрации ввода, например, если требуется ввести только латинские символы или число в восьмеричной системе счисления. Напоминаю, что такие методы обеспечивают защиту только от ручного ввода, и никакое субклассирование не спасает от копирования и вставки данных в поле EDIT. Поэтому обязательно выполняйте дополнительные проверки при чтении и дальнейшем использовании введенных данных!

В приложении пример диалогового окна с двумя полями ввода. Одно имеет флаг ES_NUMBER для ввода десятичных цифр, второе реализовано через субкласирование и позволяет вводить шестнадцатеричные цифры.
Теги:
Поле EDIT
Добавлено: 10 Апреля 2018 20:25:48 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...