Как зафиксировать ширину столбцов в ListView
Как зафиксировать ширину столбцов в ListView
ListView - очень удобный элемент диалоговых окон для вывода структурированных табличных данных. Но при всех своих плюсах, на мой взгляд, у него есть одно очень неприятное свойство. Чтобы зафиксировать ширину столбцов, ListView надо выводить без заголовков. Если в таблице отображается заголовок, то ширину столбцов пользователь может менять перетаскиванием или двойным кликом на границах заголовков. Чтобы одновременно таблица и с заголовком, и с фиксированной шириной столбцов - так сделать не получится ни через описания ресурсов, ни через установку расширенного стиля ListView. В большинстве случаев это действительно ни к чему, данные в ячейках могут быть шире столбцов, и пользователю может понадобиться двигать границы, чтобы посмотреть содержимое. Но иногда для лучшей функциональности приложению требуется, чтобы и таблица имела заголовок, и пользователь не мог намеренно или случайно изменить ширину ее столбцов.
Если воспользоваться какой-нибудь программой для получения информации о диалоговых окнах и их элементах, то выяснится, что заголовок является дочерним окном ListView. Для подавления всех действий пользователя, надо субклассировать обработчик заголовка, а в нашей собственной процедуре обработки отслеживать сообщения WM_SETCURSOR и WM_LBUTTONDOWN. Это предотвратит изменение формы курсора при наведении на границу заголовка столбца и заблокирует любые действия по нажатию левой кнопки мыши. Все остальные строки списка при этом будут работать без изменений.
Code (Assembler) : Убрать нумерацию
- ; Сегмент данных
- section '.data' data readable writeable
- szHList db 'SysHeader32',0 ; Класс окна заголовка ListView
- OldProc dd ? ; Предыдущий обработчик для субклассирования
- hList dd ? ; Хэндл ListView
- hHead dd ? ; Хэндл заголовка списка
- ...
- ...
- ; Сегмент кода
- section '.code' code readable executable
- ...
- ...
- ; Получить хэндл ListView
- invoke GetDlgItem,[hwnddlg],ID_LIST
- mov [hList],eax
- ...
- ...
- ; Найти окно заголовка ListView
- invoke FindWindowEx,[hList],NULL,szHList,NULL
- mov [hHead],eax
- ; Установить наш собственный обработчик
- invoke SetWindowLong,[hHead],GWL_WNDPROC,ListWindowProc
- ; Сохранить хэндл предыдущего обработчика
- mov [OldProc],eax
Code (Assembler) : Убрать нумерацию
- ; Субклассированный обработчик заголовка ListView
- proc ListWindowProc hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
- ; Установить курсор внутрь заголовка?
- cmp [uMsg],WM_SETCURSOR
- je .disable
- ; Нажатие кнопки мыши?
- cmp [uMsg],WM_LBUTTONDOWN
- je .disable
- .exit:
- ; Передать управление предыдущему обработчику
- invoke CallWindowProc,[OldProc],[hWnd],[uMsg],[wParam],[lParam]
- ret
- .disable:
- ; Подавить сообщение
- xor eax,eax
- ret
- endp
Code (Assembler) : Убрать нумерацию
- ; Обработка сообщений окна
- cmp [msg],WM_NOTIFY
- je .wmnotify
- ...
- ...
- ; Обработка уведомлений окна
- .wmnotify:
- ; Указатель на NMHDR
- mov eax,[lparam]
- ; Уведомление об изменении ширины столбца
- cmp dword [eax+NMHDR.code],HDN_ITEMCHANGING
- jne @f
- ; Установить ответ окна
- invoke SetWindowLong,[hwnddlg],DWL_MSGRESULT,TRUE
- @@:
- jmp .processed
В приложении пример программы с исходным текстом, демонстрирующей фиксацию заголовков ListView. С помощью чекбокса фиксацию заголовка можно включать или отключать.
Просмотров: 4740 | Комментариев: 4
Метки: Assembler
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(01.06.2015 в 08:45):
С отключенной галочкой автоподгонка работает, при включении фиксации заголовка - не работает. ЧТД.
Compiller
(01.06.2015 в 08:44):
Сорри, Ctrl + Gray"+". Что-то я задумался когда писал...
Проверил, при установленной галке не срабатывает.
Проверил, при установленной галке не срабатывает.
ManHunter
(31.05.2015 в 22:33):
У меня это сочетание и так не работает. Готовый exe-шник для тестов в архиве.
Compiller
(31.05.2015 в 17:16):
А сочетание Ctrl+Gray- будет работать по прежнему для автоподгонки ширины столбцов?
Добавить комментарий
Заполните форму для добавления комментария