Автовыделение текста в поле EDIT
Продолжаем улучшать базовый функционал стандартного поля ввода. При двойном клике на слове, находящемся в поле EDIT, это слово выделяется. Это хорошо и правильно. При двойном клике на пустом поле, которое находится справа от последнего символа текста, выделяется последнее слово в строке. И вот это, как мне кажется, неправильное поведение. По логике должна выделяться вся строка, что-то похожее реализовано в адресной строке браузеров. Вроде бы мелочь, но именно из таких незначительных деталей складывается общее впечатление о вашей программе. Давайте добавим чуточку красоты в этот мир.При инициализации родительского окна установим свой субклассированный обработчик для нужного поля ввода. Эта тема должна быть вам уже хорошо знакома, она не раз обсуждалась на сайте. А вот сам обработчик:
Code (Assembler) : Убрать нумерацию
- ;------------------------------------------------
- ; Субклассированный обработчик
- ;------------------------------------------------
- proc EditWindowProc hEdit:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
- ; Даблклик левой кнопкой мыши?
- cmp [uMsg],WM_LBUTTONDBLCLK
- je .dblclick
- .char_ok:
- ; Передать управление предыдущему обработчику
- invoke CallWindowProc,[OldProc],[hEdit],[uMsg],[wParam],[lParam]
- ret
- .dblclick:
- ; Передать управление предыдущему обработчику
- invoke CallWindowProc,[OldProc],[hEdit],[uMsg],[wParam],[lParam]
- ; Получить информацию о ближайшем символе, рядом с которым
- ; произошло событие двойного клика
- ; В lParam находятся координаты произошедшего события
- invoke SendMessage,[hEdit],EM_CHARFROMPOS,0,[lParam]
- ; Сохранить для сравнения
- mov ebx,eax
- ; Получить длину текста в поле ввода
- invoke GetWindowTextLength,[hEdit]
- ; Событие произошло за границами содержимого?
- cmp eax,ebx
- jne @f
- ; Выделить весь текест в поле ввода
- invoke SendMessage,[hEdit],EM_SETSEL,0,eax
- @@:
- ret
- endp
Как показала практика, хорошим дополнением к этому функционалу будет выделение всего текста в поле ввода при нажатии комбинации Ctrl+A. Обработчик в этом случае немного дополнится:
Code (Assembler) : Убрать нумерацию
- ;------------------------------------------------
- ; Субклассированный обработчик
- ;------------------------------------------------
- proc EditWindowProc hEdit:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
- ; Даблклик левой кнопкой мыши?
- cmp [uMsg],WM_LBUTTONDBLCLK
- je .dblclick
- ; Нажатие клавиши?
- cmp [uMsg],WM_CHAR
- je .chk_char
- .char_ok:
- ; Передать управление предыдущему обработчику
- invoke CallWindowProc,[OldProc],[hEdit],[uMsg],[wParam],[lParam]
- ret
- .chk_char:
- ; Проверить код нажатой клавиши
- mov eax,[wParam]
- ; Нажата комбинация Ctrl+A?
- cmp al,1
- jne .char_ok
- ; Получить длину текста в поле ввода
- invoke GetWindowTextLength,[hEdit]
- ; Выделить весь текест в поле ввода
- invoke SendMessage,[hEdit],EM_SETSEL,0,eax
- jmp .loc_ret
- .dblclick:
- ; Передать управление предыдущему обработчику
- invoke CallWindowProc,[OldProc],[hEdit],[uMsg],[wParam],[lParam]
- ; Получить информацию о ближайшем символе, рядом с которым
- ; произошло событие двойного клика
- ; В lParam находятся координаты произошедшего события
- invoke SendMessage,[hEdit],EM_CHARFROMPOS,0,[lParam]
- ; Сохранить для сравнения
- mov ebx,eax
- ; Получить длину текста в поле ввода
- invoke GetWindowTextLength,[hEdit]
- ; Событие произошло за границами содержимого?
- cmp eax,ebx
- jne .loc_ret
- ; Выделить весь текест в поле ввода
- invoke SendMessage,[hEdit],EM_SETSEL,0,eax
- .loc_ret:
- ret
- endp
Code (Assembler) : Убрать нумерацию
- ;------------------------------------------------
- ; Субклассированный обработчик
- ;------------------------------------------------
- proc EditWindowProc hEdit:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
- ; Даблклик левой кнопкой мыши?
- cmp [uMsg],WM_LBUTTONDBLCLK
- je .loc_select
- ; Нажатие клавиши?
- cmp [uMsg],WM_CHAR
- je .chk_char
- .char_ok:
- ; Передать управление предыдущему обработчику
- invoke CallWindowProc,[OldProc],[hEdit],[uMsg],[wParam],[lParam]
- ret
- .chk_char:
- ; Проверить код нажатой клавиши
- mov eax,[wParam]
- ; Нажата комбинация Ctrl+A?
- cmp al,1
- jne .char_ok
- .loc_select:
- ; Выделить весь текест в поле ввода
- invoke PostMessage,[hEdit],EM_SETSEL,0,-1
- .loc_ret:
- ret
- endp
Просмотров: 567 | Комментариев: 2
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(03.03.2023 в 11:30):
Добавил пример для многострочного поля ввода, архив обновлен.
ManHunter
(01.03.2023 в 15:25):
Добавил выделение текста по Ctrl+A, архив обновлен.
Добавить комментарий
Заполните форму для добавления комментария