Blog. Just Blog

Автовыделение текста в поле EDIT

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Продолжаем улучшать базовый функционал стандартного поля ввода. При двойном клике на слове, находящемся в поле EDIT, это слово выделяется. Это хорошо и правильно. При двойном клике на пустом поле, которое находится справа от последнего символа текста, выделяется последнее слово в строке. И вот это, как мне кажется, неправильное поведение. По логике должна выделяться вся строка, что-то похожее реализовано в адресной строке браузеров. Вроде бы мелочь, но именно из таких незначительных деталей складывается общее впечатление о вашей программе. Давайте добавим чуточку красоты в этот мир.

При инициализации родительского окна установим свой субклассированный обработчик для нужного поля ввода. Эта тема должна быть вам уже хорошо знакома, она не раз обсуждалась на сайте. А вот сам обработчик:
  1. ;------------------------------------------------
  2. ; Субклассированный обработчик
  3. ;------------------------------------------------
  4. proc EditWindowProc hEdit:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
  5.         ; Даблклик левой кнопкой мыши?
  6.         cmp     [uMsg],WM_LBUTTONDBLCLK
  7.         je      .dblclick
  8. .char_ok:
  9.         ; Передать управление предыдущему обработчику
  10.         invoke  CallWindowProc,[OldProc],[hEdit],[uMsg],[wParam],[lParam]
  11.         ret
  12. .dblclick:
  13.         ; Передать управление предыдущему обработчику
  14.         invoke  CallWindowProc,[OldProc],[hEdit],[uMsg],[wParam],[lParam]
  15.  
  16.         ; Получить информацию о ближайшем символе, рядом с которым
  17.         ; произошло событие двойного клика
  18.         ; В lParam находятся координаты произошедшего события
  19.         invoke  SendMessage,[hEdit],EM_CHARFROMPOS,0,[lParam]
  20.         ; Сохранить для сравнения
  21.         mov     ebx,eax
  22.  
  23.         ; Получить длину текста в поле ввода
  24.         invoke  GetWindowTextLength,[hEdit]
  25.         ; Событие произошло за границами содержимого?
  26.         cmp     eax,ebx
  27.         jne     @f
  28.         ; Выделить весь текест в поле ввода
  29.         invoke  SendMessage,[hEdit],EM_SETSEL,0,eax
  30. @@:
  31.         ret
  32. endp
При поступлении в обработчик события WM_LBUTTONDBLCLK, получаем координаты, где оно произошло. Затем с помощью EM_CHARFROMPOS узнаем позицию ближайшего символа строки, рядом с которым произошло событие. Если эта позиция равна длине строки, то выделяем весь текст в поле ввода при помощи EM_SETSEL. Все очень просто.

Как показала практика, хорошим дополнением к этому функционалу будет выделение всего текста в поле ввода при нажатии комбинации Ctrl+A. Обработчик в этом случае немного дополнится:
  1. ;------------------------------------------------
  2. ; Субклассированный обработчик
  3. ;------------------------------------------------
  4. proc EditWindowProc hEdit:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
  5.         ; Даблклик левой кнопкой мыши?
  6.         cmp     [uMsg],WM_LBUTTONDBLCLK
  7.         je      .dblclick
  8.         ; Нажатие клавиши?
  9.         cmp     [uMsg],WM_CHAR
  10.         je      .chk_char
  11. .char_ok:
  12.         ; Передать управление предыдущему обработчику
  13.         invoke  CallWindowProc,[OldProc],[hEdit],[uMsg],[wParam],[lParam]
  14.         ret
  15. .chk_char:
  16.         ; Проверить код нажатой клавиши
  17.         mov     eax,[wParam]
  18.         ; Нажата комбинация Ctrl+A?
  19.         cmp     al,1
  20.         jne     .char_ok
  21.  
  22.         ; Получить длину текста в поле ввода
  23.         invoke  GetWindowTextLength,[hEdit]
  24.         ; Выделить весь текест в поле ввода
  25.         invoke  SendMessage,[hEdit],EM_SETSEL,0,eax
  26.         jmp     .loc_ret
  27. .dblclick:
  28.         ; Передать управление предыдущему обработчику
  29.         invoke  CallWindowProc,[OldProc],[hEdit],[uMsg],[wParam],[lParam]
  30.  
  31.         ; Получить информацию о ближайшем символе, рядом с которым
  32.         ; произошло событие двойного клика
  33.         ; В lParam находятся координаты произошедшего события
  34.         invoke  SendMessage,[hEdit],EM_CHARFROMPOS,0,[lParam]
  35.         ; Сохранить для сравнения
  36.         mov     ebx,eax
  37.  
  38.         ; Получить длину текста в поле ввода
  39.         invoke  GetWindowTextLength,[hEdit]
  40.         ; Событие произошло за границами содержимого?
  41.         cmp     eax,ebx
  42.         jne     .loc_ret
  43.         ; Выделить весь текест в поле ввода
  44.         invoke  SendMessage,[hEdit],EM_SETSEL,0,eax
  45. .loc_ret:
  46.         ret
  47. endp
Для многострочного поля EDIT код будет еще проще. Тут даже не надо проверять позицию курсора, по любому двойному клику выделяется весь текст. Также текст в поле ввода выделяется при нажатии комбинации Ctrl+A:
  1. ;------------------------------------------------
  2. ; Субклассированный обработчик
  3. ;------------------------------------------------
  4. proc EditWindowProc hEdit:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
  5.         ; Даблклик левой кнопкой мыши?
  6.         cmp     [uMsg],WM_LBUTTONDBLCLK
  7.         je      .loc_select
  8.         ; Нажатие клавиши?
  9.         cmp     [uMsg],WM_CHAR
  10.         je      .chk_char
  11. .char_ok:
  12.         ; Передать управление предыдущему обработчику
  13.         invoke  CallWindowProc,[OldProc],[hEdit],[uMsg],[wParam],[lParam]
  14.         ret
  15. .chk_char:
  16.         ; Проверить код нажатой клавиши
  17.         mov     eax,[wParam]
  18.         ; Нажата комбинация Ctrl+A?
  19.         cmp     al,1
  20.         jne     .char_ok
  21. .loc_select:
  22.         ; Выделить весь текест в поле ввода
  23.         invoke  PostMessage,[hEdit],EM_SETSEL,0,-1
  24. .loc_ret:
  25.         ret
  26. endp
В приложении примеры программ с исходными текстами, которые демонстрируют возможность выделения текста в поле ввода при двойном клике и при нажатии комбинации Ctrl+A.

Примеры программ с исходными текстами (FASM)Примеры программ с исходными текстами (FASM)

Auto.Select.EDIT.Demo.zip (5,663 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 567 | Комментариев: 2

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
ManHunter (03.03.2023 в 11:30):
Добавил пример для многострочного поля ввода, архив обновлен.
ManHunter (01.03.2023 в 15:25):
Добавил выделение текста по Ctrl+A, архив обновлен.

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.007 сек.) / Память: 4.5 Mb
Наверх