powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Проблемы с ListView
9 сообщений из 34, страница 2 из 2
Проблемы с ListView
    #38446042
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariy,

Ну я вроде доделал API-шный до состояния в котором могу делать тесты.
Что могу сказать (про шило и мыло).

Глюка с "автопрокруткой" на выделенную запись нет. (ради чего сыр-бор начался)

Хотя не могу сказать, что "автопрокрутка" полностью отсутствует.
Если например параллельно
1) таймер добавляет новые строчки
2) идут активные процессы (по ранее добавленным строчкам естественно)
А я естественно хочу смотреть в (2) активные строчки, т.к. там отображается статистика текущих процессов.
То (2) таки уезжает потихоньку по мере добавления(1) по законам какой-то пропорциональности что-ли.

Ну и сортировка - полная задница. С теми ф-циями что я привел в коде - тормоза полные.


Если сортировать после добавления КАЖДОЙ строчки, то прога зависнет и сдохнет
Как вариант выносить Sort за пределы блока добавления - таймер в (1) грубо на 1 секунду, в тесте что я делаю добавляет примерно по 20 строчек за раз (сколько есть готовых).

Как вариант:
AntonariyУ меня не письма, у меня факсы. И вот например юзер решил добавить 2000 заданий факса на отправкуЗачем их сортировать?
Зачем сортировать и по каким полям это уж юзер пускай решает.
Но с другой стороны м.б. правильно забить на попытки автосортировки и отдать ее полностью на откуп юзеру (т.е. только при загрузке и по Column_click).
Потому что новые записи логично добавлять сверху (в начала списка), иначе юзер их просто с ходу не увидит если сортировка по какому-то второстеренному полю.

Но все равно тормоза сортировки бесят, даже при щелчке по столбцу (на 5000 записях столбец будет тупо залипать на 2 сек).
В VB-Listview такого не было, очевидно ф-ции сравнения более продуманные.
Antonariy и сравнение строк без StrComp...
Что имел ввиду? Потому что оно и без дат тормозит.
...
Рейтинг: 0 / 0
Проблемы с ListView
    #38446381
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Что имел ввиду? Потому что оно и без дат тормозит.Сравнение строк тоже не быстрая операция. Функция StrComp немного улучшает ситуацию. Но есть и более производительные методы.

тынц
...
Рейтинг: 0 / 0
Проблемы с ListView
    #38446645
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariy тынц
Но "рекомендуемый метод" с LenB+Instr для ">" "<" то не применишь.
StrComp почти ничего не дает.
Кстати сразу вопрос:
Два варианта:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
Private Function pvCompareText(ByVal lParam1 As Long, ByVal lParam2 As Long, ByVal hwnd As Long) As Long
....
  If StrComp(val1, val2, vbTextCompare) = 1 Then
    pvCompareText = m_PRECEDE
  ElseIf StrComp(val1, val2, vbTextCompare) = -1 Then
    pvCompareText = m_FOLLOW
  End If
End Function


Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
Private Function pvCompareText(ByVal lParam1 As Long, ByVal lParam2 As Long, ByVal hwnd As Long) As Long
....
  If StrComp(val1, val2, vbTextCompare) = 1 Then
    pvCompareText = m_PRECEDE
  Else Then
    pvCompareText = m_FOLLOW
  End If
End Function


Какой правильный?
Следуя твоему коду правильный первый, но там к-во операций в 2 раза больше.
Но ты почему то не присваиваешь значение при "==".

Дальше, API вида
lstrcmp
StrCmp
и т.д.
я так понимаю будут тормозить при вызове из VB.
Или все таки надо искать?
И пробовать ByRef String?
Или самому преобразовывать строки в указатели?

Ну короче я в растройстве.
VB-ListView делает быструю сортировку (очевидно потому что на C++ написан),
а здесь функция сортировки отдается на откуп мне как Custom.
А я из VB это могу сделать только на VB. C VB-шной скоростью черепахи.

Я поэтому и спрашивал про
LVM_SORTITEMS, LVS_SORTASCENDING, LVS_SORTDESCENDING
М.б. есть какой-то "автоспособ"?
Но из msdn следует что LVS_SORTASCENDING, LVS_SORTDESCENDING
применяется только к item, но не к subitem.
А LVM_SORTITEMS по сути кастом-эквивалент тому который SEX c каким-то мелким ньюансом.
Т.е. ничего умного не следует.
...
Рейтинг: 0 / 0
Проблемы с ListView
    #38446730
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Блин, дебаг вроде показал что основные тормоза 300мс из 350мс на 6000 записей (если убрать сравнение)
вот здесь
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Private Function pvGetItemText(ByVal hwnd As Long, ByVal lParam As Long) As String
  Dim nRet As Long
  With m_uLVI
    .mask = LVIF_TEXT
    .iSubItem = m_lColumn
    .pszText = Space(MAX_LVMSTRING)
    .cchTextMax = Len(.pszText)
  End With
  nRet = SendMessage(hwnd, LVM_GETITEMTEXT, lParam, m_uLVI)
  pvGetItemText = Left$(m_uLVI.pszText, nRet)
End Function


Но она отличается от твоей.

А ни фига не в сравнении.
А >< либо strcomp
else либо elseif
- играет туда сюда на 5-10 мс
...
Рейтинг: 0 / 0
Проблемы с ListView
    #38446757
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vbTextCompare гораздо медленне, чем vbBinaryCompare. Используй text только при сравнении текстов, но не дат или номеров факсов.

Кстати, кому нужно видеть живой список из 5000 факсов? Что ему делать с этой простыней, медитировать над ней? В качестве реверанса свистелкам можно отображать последнюю пару десятков — в начало добавлять, из конца удалять. А желающим оглашения полного списка можно сделать кнопку с отдельной формой.

Какой правильный?
Следуя твоему коду правильный первый, но там к-во операций в 2 раза больше.Я не заморачивался оптимизацией, иначе бы использовал второй.

Дальше, API вида
lstrcmp
StrCmp
и т.д.
я так понимаю будут тормозить при вызове из VB.Не будут.
...
Рейтинг: 0 / 0
Проблемы с ListView
    #38447085
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Блин, дебаг вроде показал что основные тормоза 300мс из 350мс на 6000 записей (если убрать сравнение)
вот здесь
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Private Function pvGetItemText(ByVal hwnd As Long, ByVal lParam As Long) As String
  Dim nRet As Long
  With m_uLVI
    .mask = LVIF_TEXT
    .iSubItem = m_lColumn
    .pszText = Space(MAX_LVMSTRING)
    .cchTextMax = Len(.pszText)
  End With
  nRet = SendMessage(hwnd, LVM_GETITEMTEXT, lParam, m_uLVI)
  pvGetItemText = Left$(m_uLVI.pszText, nRet)
End Function


Но она отличается от твоей.
Твой вариант еще тормознутее:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Private Function pvGetItemText(ByVal hwnd As Long, ByVal lParam As Long) As String
Dim lIdx   As Long
Dim a(261) As Byte
Dim lLen   As Long
Dim m_uLVI_LNG As LV_ITEM_LNG
    With m_uLVI_LNG
        .mask = LVIF_TEXT
        .pszText = VarPtr(a(0))
        .cchTextMax = UBound(a)
        .iSubItem = m_lColumn
    End With
    lLen = SendMessage(hwnd, LVM_GETITEMTEXT, lParam, m_uLVI_LNG)
    pvGetItemText = Left$(StrConv(a(), vbUnicode), lLen)
End Function



Не в сравнении короче тормоза, а в скорости чтения сабитемов.
Можно буфер уменьшить до 32 напр, но это копейки.

Автоматический (внутренний) какой-то способ должен быть.
...
Рейтинг: 0 / 0
Проблемы с ListView
    #38447669
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77а здесь функция сортировки отдается на откуп мне как Custom.
А я из VB это могу сделать только на VB. C VB-шной скоростью черепахи.
А на хрена заниматься фигней с мульти-конвертацией в VB-шную String.
Все можно сделать на уровне указателей, используя 2 статических места в памяти на всю процедуру:

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
Private Type LV_ITEM_LNG
  mask As Long
  iItem As Long
  iSubItem As Long
  state As Long
  stateMask As Long
  pszText As Long
  cchTextMax As Long
  iImage As Long
  lParam As Long
  iIndent As Long
End Type

Private m_hMem1 As Long
Private m_hMem2 As Long
Private m_uLVI_LNG1 As LV_ITEM_LNG
Private m_uLVI_LNG2 As LV_ITEM_LNG
Public Declare Function lstrcmp Lib "kernel32" Alias "lstrcmpA" _
 (ByVal lpString1 As Long, ByVal lpString2 As Long) As Long

Public Function Sort(ByVal hListView As Long, ByVal Column As Integer, ByVal SortOrder As eSortOrderConstants, ByVal SortType As eSortTypeConstants) As Boolean
...
    Case soAscending, soDescending
      m_PRECEDE = SortOrder
      m_FOLLOW = -SortOrder
      'выделяем ДВЕ области памяти, куда будем копировать ВСЕ сравниваемые строки
      m_hMem1 = GlobalLock(GlobalAlloc(&H40, MAX_LVMSTRING))
      m_hMem2 = GlobalLock(GlobalAlloc(&H40, MAX_LVMSTRING))
      With m_uLVI_LNG1
        .mask = LVIF_TEXT
        .iSubItem = m_lColumn
        .pszText = m_hMem1
        .cchTextMax = MAX_LVMSTRING
      End With
      With m_uLVI_LNG2
        .mask = LVIF_TEXT
        .iSubItem = m_lColumn
        .pszText = m_hMem2
        .cchTextMax = MAX_LVMSTRING
      End With
      Select Case SortType
        Case [stString]
          lRet = SendMessageLong(hListView, LVM_SORTITEMSEX, hListView, AddressOf pvCompareText)
...
      End Select
    'освобождаем память
    GlobalFree (m_hMem1)
    GlobalFree (m_hMem2)
  End Select
  Sort = CBool(lRet)
End Function

Private Function pvCompareText(ByVal lParam1 As Long, ByVal lParam2 As Long, ByVal hwnd As Long) As Long
  'копируем в зарезервированную память
  pvGetItemText hwnd, lParam1, 1
  pvGetItemText hwnd, lParam2, 2
  If lstrcmp(m_hMem1, m_hMem2) > 0 Then
    pvCompareText = m_PRECEDE
  Else
    pvCompareText = m_FOLLOW
  End If
End Function

Private Sub pvGetItemText(ByVal hwnd As Long, ByVal lParam As Long, ByVal num As Long)
  If num = 1 Then
    SendMessage hwnd, LVM_GETITEMTEXT, lParam, m_uLVI_LNG1
  Else
    SendMessage hwnd, LVM_GETITEMTEXT, lParam, m_uLVI_LNG2
  End If
End Sub


Вот это работает на моем компьютере ~125мс на 6500 строчек и против 360мс это можно обозвать словом "мгновенно".
По крайней мере визуального залипания заголовка header нету.
Думаю дальше оптимизировать уже некуда, по сути использовал C-шный подход.
Все тормоза из за String в структуре LV_ITEM + я работаю с фиксированной памятью.
Оставшиеся миллисекунды упираются в основном в скорость работы LVM_GETITEMTEXT (без извращений со String), здесь не переплюнешь.
Хотя есть одно но. LVM_GETITEMTEXT для каждого итема по ходу вызывается дважды, если не больше.

Но вот как быть с датами?
6500 дат сортируется 1,5-2 сек, это ЖОПА плохо.
Вообще вот этот метод в VB-Listview работает быстро:
Дмитрий77У меня в VB-реализации код такой:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
                ListView1(Index).ListItems(i).Tag = ListView1(Index).ListItems(i).SubItems(ColStructMas(Index).StartTimeN)
                ListView1(Index).ListItems(i).SubItems(ColStructMas(Index).SubmissionTimeN) = _
                  Format(ListView1(Index).ListItems(i).SubItems(ColStructMas(Index).SubmissionTimeN), "yyyymmddhhmmss")
...
ListView1(Index).SortOrder =
'либо
ListView1(Index).SortKey =
'ListView1(Index).Sorted = True 'ЭТО ДАЖЕ НЕ НУЖНО, т.к. сортируется при изменении .SortOrder / .SortKey

                ListView1(Index).ListItems(i).SubItems(ColStructMas(Index).SubmissionTimeN) = ListView1(Index).ListItems(i).Tag
                ListView1(Index).ListItems(i).Tag = ""


Ну т.е. идею понял. Подменяю дату/время на "yyyymmddhhmmss" и сравниваю строки а не даты.

Вопрос только как его применить к API-реализации.
Любая попытка вытаскивать String из указателя приведет к тормозам.
Причем тупо по байтам я "yyyymmddhhmmss" не просчитаю,
у меня дата-время в тек. формате OS
Т.е. для России:
12.06.2013 15:12:10
А для США будет
06/12/2013 3:12:10 PM
Т.е. без VB Format я не обойдусь.
Нужна какая-то "быстрая махинация", но как это сделать? Создать Column, скинуть туда Format(data), отсортировать по новой Column, удалить Column?
Вообще линейный цикл по всем итемам с копированием/преобразованием в другой Column это быстрее чем сортировка?

М.б. есть "сишные"-API-шные аналоги Format(str, "yyyymmddhhmmss")?
...
Рейтинг: 0 / 0
Проблемы с ListView
    #38448929
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я пока что пытаюсь добраться до DATE непосредственно через указатель pszText as long
Т.е. хочу получить As Date минуя VB-шную As String.
1) VarDateFromStr - не могу скормить LPTSTR
2) VarDateFromStr -не могу скормить
Код: vbnet
1.
2.
Private Declare Function SysAllocString Lib "oleaut32.dll" (ByVal lpString As Long) As Long
  val1 = DateFromString(SysAllocString(m_hMem1))


3) Могу только скормить вот это:
Код: vbnet
1.
2.
Private Declare Function SysAllocString Lib "oleaut32.dll" (ByVal lpString As Long) As String
  val1 = DateFromString(StrPtr(SysAllocString(m_hMem1)))


Но это 2 обратных преобразования в VB as String ==ТОРМОЗА

А надо скормить указатель LPTSTR напрямую (без преобразования в BSTR).
А она блин не впихивается туда.
Выдает DISP_E_TYPEMISMATCH
Есть идеи?


На C++ форуме молчат.

Дмитрий77Ну, я пока нашел куда копать:
VarDateFromStr Function
Код: plaintext
1.
2.
3.
4.
5.
6.
 HRESULT VarDateFromStr(
   [in]  OLECHAR        *strIn,
   [in]  LCID           lcid,
   [in]  unsigned long  dwFlags,
   [out] DATE           *pdateOut
);


Но у меня в моем m_hMem указателе сидит LPTSTR а не OLECHAR .
LVITEM structure
Код: plaintext
1.
2.
3.
4.
typedef struct {
...
  LPTSTR pszText;
  int    cchTextMax;


pszTextType: LPTSTR
If the structure receives item attributes, pszText is a pointer to a buffer that receives the item text. Note that although the list-view control allows any length string to be stored as item text, only the first 260 TCHARs are displayed.
Т.е. если я делаю вот так:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
Private Function DateFromString(ByVal sDateIn As Long) As Date
    Dim hResult As Long
    Dim dtOut As Date
    hResult = VarDateFromStr(sDateIn, GetUserDefaultLCID(), LOCALE_NOUSEROVERRIDE, dtOut)
    Select Case hResult
        Case S_OK:
            DateFromString = dtOut



То вот так не работает (при попытке скормить LPTSTR вместо OLECHAR которую она хочет):
Код: vbnet
1.
  val1 = DateFromString(m_hMem1) 'ошибка DISP_E_TYPEMISMATCH


А вот так работает:
Код: plaintext
1.
  val1 = DateFromString(StrPtr(PtrToString(m_hMem1)))

1) m_hMem1 (LPTSTR) -> VB6 as String
2) VB6 as String -> получаем новый указатель через StrPtr
А задача как раз не связываться с VB-шными String, потому что они то и тормозят.
Т.е. вопрос как подкинуть указатель на LPTSTR в ф-цию кот. хочет указатель на OLECHAR
...
Рейтинг: 0 / 0
Проблемы с ListView
    #38450507
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyТ. е. как считаешь? Если забабахать что-то типа ... Оно как бы ускорится?Тут и Left, и Format... Вряд ли.
Еще как ускорится.
Мне удалось наконец обогнать объектный ListView в сортировке дат, использую по сути тот же способ "yyyymmddhhmmss"
Результаты для 6500 строк:
Объектный
Дата/время - 220-250мс; Строки - 30мс
API-шный
Дата/время - 170-190мс; Строки - 70-90мс (было изначально без оптимизации: Дата/время - 1000-2000мс; Строки - 350-400мс )
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
Private m_lColumn     As Long
Private m_PRECEDE     As Long
Private m_FOLLOW      As Long
Private m_hMem1 As Long
Private m_hMem2 As Long
Private m_uLVI_1 As LVITEM
Private m_uLVI_2 As LVITEM

Private Type LVITEM
  mask As Long
  iItem As Long
  iSubItem As Long
  state As Long
  stateMask As Long
  pszText As Long
  cchTextMax As Long
  iImage As Long
  lParam As Long
  iIndent As Long
End Type
Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
Private m_hMem1 As Long
Private m_hMem2 As Long
Private m_uLVI_1 As LVITEM
Private m_uLVI_2 As LVITEM

Public Declare Function lstrcmp Lib "kernel32" Alias "lstrcmpW" _
 (ByVal lpString1 As Long, ByVal lpString2 As Long) As Long
 
'!psDateIn - указатель на ЮНИКОД -строку, содержащую дата-время
Private Declare Function VarDateFromStr Lib "oleaut32.dll" ( _
 ByVal psDateIn As Long, _
 ByVal lcid As Long, _
 ByVal uwFlags As Long, _
 ByRef dtOut As Date) As Long
Private Declare Function GetUserDefaultLCID Lib "kernel32" () As Long

Public Function Sort(ByVal hListView As Long, ByVal Column As Integer, ByVal SortOrder As eSortOrderConstants, ByVal SortType As eSortTypeConstants) As Boolean
  Dim lRet As Long
  If SortType = [stDate] Then
    '1) создаем временный столбец и копируем туда "yyyymmddhhmmss"
    '2) везде стараемся использовать указатели
    '3) стараемся не разбрасываться памятью -единый адрес hMem
    '4) стараемся использовать W вместо A -юникод чуть быстрее
    '5) Используем DateFromString вместо CDate(String)
    '6) производим сортировку как текст по новому столбцу
    Dim iItemCount As Long
    Dim i As Long
    iItemCount = SendMessage(hListView, LVM_GETITEMCOUNT, 0, 0)
    If iItemCount = 0 Then Exit Function
    Dim lvc As LV_COLUMN
    lvc.mask = LVCF_WIDTH
    lvc.cx = 0
    m_lColumn = SendMessage(hListView, LVM_INSERTCOLUMN, _
     SendMessageLong(SendMessageLong(hListView, LVM_GETHEADER, 0, 0), HDM_GETITEMCOUNT, 0, 0), lvc)
    Dim hMem As Long
    hMem = GlobalLock(GlobalAlloc(&H40, MAX_LVMSTRING))
    Dim lvi_receive As LVITEM
    lvi_receive.mask = LVIF_TEXT
    lvi_receive.cchTextMax = MAX_LVMSTRING
    lvi_receive.pszText = hMem
    lvi_receive.iSubItem = Column
    Dim lvi_send As LVITEM
    lvi_send.mask = LVIF_TEXT
    lvi_send.iSubItem = m_lColumn
    For i = 0 To iItemCount - 1
      Call SendMessage(hListView, LVM_GETITEMTEXTW, i, lvi_receive)
      lvi_send.iItem = i
      lvi_send.pszText = StrPtr(Format$(DateFromString(hMem), "yyyymmddhhmmss"))
      Call SendMessage(hListView, LVM_SETITEMW, 0, lvi_send)
    Next
    GlobalFree hMem
  Else
    m_lColumn = CLng(Column)
  End If
  Select Case SortOrder
    Case soDefault
      m_PRECEDE = 1
      m_FOLLOW = -1
      lRet = SendMessageLong(hListView, LVM_SORTITEMSEX, hListView, AddressOf pvCompareIndex)
    Case soAscending, soDescending
      m_PRECEDE = SortOrder
      m_FOLLOW = -SortOrder
      'выделяем ДВЕ области памяти, куда будем копировать ВСЕ сравниваемые строки
      m_hMem1 = GlobalLock(GlobalAlloc(&H40, MAX_LVMSTRING))
      m_hMem2 = GlobalLock(GlobalAlloc(&H40, MAX_LVMSTRING))
      With m_uLVI_1
        .mask = LVIF_TEXT
        .iSubItem = m_lColumn
        .pszText = m_hMem1
        .cchTextMax = MAX_LVMSTRING
      End With
      With m_uLVI_2
        .mask = LVIF_TEXT
        .iSubItem = m_lColumn
        .pszText = m_hMem2
        .cchTextMax = MAX_LVMSTRING
      End With
      Select Case SortType
        Case [stString]
          lRet = SendMessageLong(hListView, LVM_SORTITEMSEX, hListView, AddressOf pvCompareText)
...
        Case [stDate]
          lRet = SendMessageLong(hListView, LVM_SORTITEMSEX, hListView, AddressOf pvCompareText)
          'удаляем подложный столбец
          Call SendMessageLong(hListView, LVM_DELETECOLUMN, m_lColumn, 0)
      End Select
    'освобождаем память
    GlobalFree (m_hMem1)
    GlobalFree (m_hMem2)
  End Select
  Sort = CBool(lRet)
End Function

Private Function pvCompareText(ByVal lParam1 As Long, ByVal lParam2 As Long, ByVal hwnd As Long) As Long
  'копируем в зарезервированную память
  pvGetItemText hwnd, lParam1, 1
  pvGetItemText hwnd, lParam2, 2
  If lstrcmp(m_hMem1, m_hMem2) > 0 Then
    pvCompareText = m_PRECEDE
  Else
    pvCompareText = m_FOLLOW
  End If
End Function

Private Sub pvGetItemText(ByVal hwnd As Long, ByVal lParam As Long, ByVal num As Long)
  If num = 1 Then
    Call SendMessage(hwnd, LVM_GETITEMTEXTW, lParam, m_uLVI_1)
  Else
    Call SendMessage(hwnd, LVM_GETITEMTEXTW, lParam, m_uLVI_2)
  End If
End Sub

Private Function DateFromString(ByVal sDateIn As Long) As Date
  Dim hResult As Long
  Dim dtOut As Date
  Const LOCALE_NOUSEROVERRIDE = &H80000000

  ' Do the conversion
  hResult = VarDateFromStr(sDateIn, GetUserDefaultLCID(), LOCALE_NOUSEROVERRIDE, dtOut)

  Select Case hResult
    Case S_OK:
      DateFromString = dtOut
...
  End Select
End Function



В принципе на этом можно сказать СТОП.

Честно, пытался еще перекидывать данные в нулевой столбец и выполнять "родную" сортировку
Код: vbnet
1.
2.
3.
4.
5.
6.
    Select Case m_SortOrder
      Case soAscending
        SetWindowLong m_hwndLV, GWL_STYLE, GetWindowLong(m_hwndLV, GWL_STYLE) Or Not LVS_SORTASCENDING And Not LVS_SORTDESCENDING
      Case soDescending
        SetWindowLong m_hwndLV, GWL_STYLE, GetWindowLong(m_hwndLV, GWL_STYLE) Or LVS_SORTDESCENDING And Not LVS_SORTASCENDING
    End Select


Но она сволочь в run тайме не работает.
...
Рейтинг: 0 / 0
9 сообщений из 34, страница 2 из 2
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Проблемы с ListView
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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