powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / ListView, Report - 1 колонка. Исключить горизонтальную прокрутку.
3 сообщений из 3, страница 1 из 1
ListView, Report - 1 колонка. Исключить горизонтальную прокрутку.
    #38202590
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть ListView - Report - единственный Column
Я хочу, чтоб этот Column вписывался в ширину ListView (максимально красиво).
При этом чтоб не было нижней полосы прокрутки.
Как зафиксировать ширину столбца через хитрый сабклассинг я знаю - чтоб юзер кривыми ручонками не тянул за header.

Вопрос как правильно установить ширину столбца, чтоб на весь ListView и без прокрутки?
Операционки разные XP, Vista, 7, 8 -метод подводить не должен - чтоб случайно Hscroll не всплывал и т.п.
Использовать всякие LVS_NOSCROLL не хочу, чревато это всякими спецпроблемами, которые решать неохота.

Далее, если элементов стало больше, то появляется V_SCROLL, его не отменяем.
Как рассчитать ширину столбца в этом случае?


И далее, как понять есль ли V_SCROLL или нет?
Как отследить момент появления/исчезновения V_SCROLL
чтоб перещелкнуть ширину в соответствии с написанным?

Задал голый вопрос, потому как м.б. кто-то сталкивался, а эксперементировать долго неохота.
...
Рейтинг: 0 / 0
ListView, Report - 1 колонка. Исключить горизонтальную прокрутку.
    #38202680
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Далее, если элементов стало больше, то появляется V_SCROLL, его не отменяем.
Как рассчитать ширину столбца в этом случае?
Ширину скролла можно узнать с помощью функции GetSystemMetrics.

Дмитрий77И далее, как понять есль ли V_SCROLL или нет?Скорее всего у окна появляется какой-то стиль. Проверить не могу, нет spy++

Дмитрий77Как отследить момент появления/исчезновения V_SCROLLПросабклассить и в режиме брейка отловить сообщение, после которого появляется скролл.
...
Рейтинг: 0 / 0
ListView, Report - 1 колонка. Исключить горизонтальную прокрутку.
    #38203462
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подразобрался, вот результаты (готовый тест-проект с прозрачным ListView во вложении).

Тупо убрать HSCROLL (с гарантией, что его не будет даже если столбец уедет) не получается.
LVS_NOSCROLL убирает оба скролла (включая вертикальный). Причем убирает так, что по вертикали даже с клавиатуры стрелкой вниз не прокрутишь - не вариант.
Есть еще набор ф-ций типа ShowScrollBar и EnableScrollBar, но рабочая область ListView при этом не перерисовывается (пусто там вместо строчки), а во вторых при перерисовке и т.п. скролбар опять выплывает.

Посему мой вариант жесткой установки ширины столбца думаю верный.
AntonariyДмитрий77И далее, как понять есль ли V_SCROLL или нет?Скорее всего у окна появляется какой-то стиль.
Да, правы. Стиль WS_VSCROLL.
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
Public Function ListView_IsVScrollBarVisible(m_ListView As ComctlLib.ListView) As Boolean
  Dim lStyle As Long
  lStyle = GetWindowLong(m_ListView.hwnd, GWL_STYLE)
  If (lStyle And WS_VSCROLL) Then
    ListView_IsVScrollBarVisible = True
  Else
    ListView_IsVScrollBarVisible = False
  End If
End Function




AntonariyДмитрий77Далее, если элементов стало больше, то появляется V_SCROLL, его не отменяем.
Как рассчитать ширину столбца в этом случае?
Ширину скролла можно узнать с помощью функции GetSystemMetrics.
Ну да, так и есть:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
Public Sub SetMyColumnWidth()
  If ListView_IsVScrollBarVisible(ListView1) Then
    SetColumnWidthPX ListView1, 1, ListView1.Width - (GetSystemMetrics(SM_CXHTHUMB) + 4)
  Else
    SetColumnWidthPX ListView1, 1, ListView1.Width - 4
  End If
End Sub


Здесь четверка подбирается опытным путем. Зависит от границы.
В моем случае:
Код: vbnet
1.
  pvSetBorderStyle ListView1.hwnd, eBorderStyleConstants.bsThin


При другой границе подойдет напр. цифра 2(px). Надо быть аккуратным. Но я проверил - результат стабилен (одинаковый код с одинаковой дельтой) для Классики, XP и вистообразных.

Дальше встает вопрос, в какой момент устанавливать ширину.
Самое простое,тупо всякий раз как меняется к-во итемов.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
Private Sub Form_Activate()
  SetMyColumnWidth
End Sub

Private Sub CommandAdd_Click()
  ListView1.ListItems.Add (ListView1.ListItems.Count + 1), , "my item " & (ListView1.ListItems.Count)
  'кроме XP, там с фоновой картинкой будет черный фон
  If IsWinVista Or IsIDEApp Then _
   ListViewSetItemPicture ListView1, ListView1.ListItems.Count, 0 '0=SETUP
  ListView1.ListItems(ListView1.ListItems.Count).Selected = True
  SetMyColumnWidth
  DrawListView
End Sub

Private Sub CommandRemove_Click()
  If ListView1.ListItems.Count > 0 Then _
   ListView1.ListItems.Remove ListView1.ListItems.Count
  SetMyColumnWidth
  DrawListView
End Sub



Но тут осечка. Когда число итемов превышает критическую высоту, то WS_VSCROLL устанавливается с задержкой, т.е. ListView_IsVScrollBarVisible в CommandAdd_Click один раз сработает неправильно (именно там где событие появления VSCROLL и происходит)

Плюс захотелось красивого варианта:
AntonariyДмитрий77Как отследить момент появления/исчезновения V_SCROLLПросабклассить и в режиме брейка отловить сообщение, после которого появляется скролл.
Событие WM_STYLECHANGED
Код: vbnet
1.
2.
   Case WM_STYLECHANGED:
     Form1.SetMyColumnWidth


Но опять проблема - не всегда оно генерируется. При появлении VSCROLL -да, при удалении -нет.
Т.е. пришлось совместить "тупой" метод с "красивым" - тогда "отслеживание" работает полностью.

Ну и механизм стопора ширины от кривых ручонок, естественно.
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
Public Function NewListHeadWindowProc( _
 ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  'для событий listview1
  Static pt As POINTAPI
  Static HTI As HD_HITTESTINFO
  If (Msg = &H201) Then 'WM_LBUTTONDOWN
  ElseIf (Msg = &H203) Then 'WM_LBUTTONDBLCLK
  Else
    GoTo Dalshe
  End If
  Call GetCursorPos(pt)
  Call ScreenToClient(hwnd, pt)
  'get the header's hit-test info
  With HTI
    .pt = pt
  End With
  Call SendMessage(hwnd, HDM_HITTEST, 0&, HTI)
  If (HTI.Flags = HHT_ONDIVIDER) Or (HTI.Flags = HHT_ONDIVOPEN) Then Exit Function   'HHT_ONDIVOPEN HHT_ONDIVIDER 'Or HHT_ONDIVOPEN)
Dalshe:
  NewListHeadWindowProc = CallWindowProc( _
   OldListHeadWindowProc, hwnd, Msg, wParam, _
   lParam)
End Function
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / ListView, Report - 1 колонка. Исключить горизонтальную прокрутку.
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]