Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.60/25: Рейтинг темы: голосов - 25, средняя оценка - 4.60
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786

Как добавить в список ListBox большое количество строк, чтобы это было быстро по времени?

27.09.2023, 11:31. Показов 6960. Ответов 125

Всем привет! У меня есть листбокс List1 в VB6 и я пытаюсь добавить в этот список много строк, скажем 10 тысяч строк, но я хочу добавить их таким образом, чтобы они добавились быстро по времени, а не ждать целую секунду... Я этого делать не умею, поэтому помогите пожалуйста! Единственный лайфхак который я нашёл это сначала скрывать список а потом показывать так можно добавить в список много строк в 3 раза быстрее, но для 10 тысяч строк это всё равно занимает целых пол секунды времени...

Visual Basic
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
Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageW" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Const LB_INITSTORAGE = &H1A8
Private Const LB_ADDSTRING = &H180
 
Private Sub Command1_Click()
    Dim i As Integer
    Dim tick As Long
    
    List1.Clear
    tick = GetTickCount
    
    For i = 0 To 10000
        List1.AddItem i
    Next
    Me.Caption = GetTickCount - tick ' 1311 ml
End Sub
 
Private Sub Command2_Click()
    Dim i As Integer
    Dim tick As Long
    
    List1.Clear
    tick = GetTickCount
    
    List1.Visible = False
    
    For i = 0 To 10000
        List1.AddItem i
    Next
    
    List1.Visible = True
    
    Me.Caption = GetTickCount - tick ' 468 ml
End Sub
 
 
Private Sub Command3_Click()
    Dim i As Integer
    Dim tick As Long
    Dim str As String
    Dim hwndList As Long
    
    str = "123"
    hwndList = List1.hwnd
    
    List1.Clear
    tick = GetTickCount
    
    'List1.Visible = False
    
    Debug.Print SendMessage(hwndList, LB_INITSTORAGE, 10001, CLng(LenB(str) * 10001))
    
    For i = 0 To 10000
        SendMessage hwndList, LB_ADDSTRING, 0, StrPtr(str)
    Next
    'List1.Visible = True
    
    Me.Caption = GetTickCount - tick ' 1310 ml
End Sub
Я начал читать в MSDN про сообщение LB_INITSTORAGE но у меня ничего не получилось почему-то всё равно строки в список добавляются очень медленно! Помогите плиз!

Добавлено через 24 минуты
Вопрос: почему не работает сообщение LB_INITSTORAGE?

Добавлено через 24 секунды
Скорость добавления в листбокс никак не изменилась!
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
27.09.2023, 11:31
Ответы с готовыми решениями:

Как быстро создать список на большое количество элементов?
День добрый! Ищу информацию по такому вопросу. Например, в С++ объявить массив с сотней элементов можно простой строкой. string...

Максимально быстро записать большое количество строк SQLite
Приветствую всех. Думаю из заголовка понятно в чём вопрос как максимально эффективно и быстро записать в таблицу базы данных SQLite большое...

Как сделать так чтобы из продуктов можно было добавить в блюда и это списывалось все на кухне
Как сделать так чтобы из продуктов можно было добавить в блюда и это списывалось все на со склада

125
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786
01.10.2023, 15:51  [ТС]
Цитата Сообщение от Dragokas Посмотреть сообщение
Даже я не понимаю
Как ты не понимаешь, там очень много лишнего и не нужного! Мне даже моё чувство прекрасного не позволяет добавлять в свой проект так много всякой ненужной ерунды, так как в душе я идеалист. Плюс проблема совместимости пойдёт одинаковые функции, как я приводил уже пример с AppPath (а там таких функций много). Уверн, и ты любишь свой AppPath использовать, а не чужой...

Добавлено через 47 минут
Я вот например потратил пол часа на то чтобы по-убирать всё лишнее в Common.bas сам смотри сколько лишнего мусора там было, было 1336 строк и 53 КБ файл, а теперь стало всего 340 строк и всего 13 КБ файл модуля стал! После перемпиляции размер EXE сократился ажно на 10 КБ!!!

Добавлено через 59 секунд
Новый Common.bas (всего 340 строк, на тысячу строк меньше, чем было):

Visual Basic
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
Option Explicit
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Type POINTAPI
X As Long
Y As Long
End Type
Private Const LF_FACESIZE As Long = 32
Private Type LOGFONT
LFHeight As Long
LFWidth As Long
LFEscapement As Long
LFOrientation As Long
LFWeight As Long
LFItalic As Byte
LFUnderline As Byte
LFStrikeOut As Byte
LFCharset As Byte
LFOutPrecision As Byte
LFClipPrecision As Byte
LFQuality As Byte
LFPitchAndFamily As Byte
LFFaceName(0 To ((LF_FACESIZE * 2) - 1)) As Byte
End Type
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Private Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer
Private Declare Function GetCursorPos Lib "user32" (ByRef lpPoint As POINTAPI) As Long
Private Declare Function WindowFromPoint Lib "user32" (ByVal X As Long, ByVal Y As Long) As Long
Private Declare Function GetCapture Lib "user32" () As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, ByVal lpdwProcessId As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageW" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
Private Declare Function GetObjectAPI Lib "gdi32" Alias "GetObjectW" (ByVal hObject As Long, ByVal nCount As Long, ByRef lpObject As Any) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hDC As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function GetDC Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hDC As Long, ByVal nIndex As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hWnd As Long, ByVal hDC As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hDC As Long) As Long
Private Declare Function DrawIconEx Lib "user32" (ByVal hDC As Long, ByVal XLeft As Long, ByVal YTop As Long, ByVal hIcon As Long, ByVal CXWidth As Long, ByVal CYWidth As Long, ByVal istepIfAniCur As Long, ByVal hbrFlickerFreeDraw As Long, ByVal diFlags As Long) As Long
Private Declare Function FillRect Lib "user32" (ByVal hDC As Long, ByRef lpRect As RECT, ByVal hBrush As Long) As Long
Private Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hDC As Long) As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hDC As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function CreateFontIndirect Lib "gdi32" Alias "CreateFontIndirectW" (ByRef lpLogFont As LOGFONT) As Long
Private Declare Function OleTranslateColor Lib "oleaut32" (ByVal Color As Long, ByVal hPal As Long, ByRef RGBResult As Long) As Long
Public Function ProperControlName(ByVal Control As VB.Control) As String
Dim Index As Long
On Error Resume Next
Index = Control.Index
If Err.Number <> 0 Or Index < 0 Then ProperControlName = Control.Name Else ProperControlName = Control.Name & "(" & Index & ")"
On Error GoTo 0
End Function
Public Function MousePointerID(ByVal MousePointer As Integer) As Long
Select Case MousePointer
    Case vbArrow
        Const IDC_ARROW As Long = 32512
        MousePointerID = IDC_ARROW
    Case vbCrosshair
        Const IDC_CROSS As Long = 32515
        MousePointerID = IDC_CROSS
    Case vbIbeam
        Const IDC_IBEAM As Long = 32513
        MousePointerID = IDC_IBEAM
    Case vbIconPointer ' Obselete, replaced Icon with Hand
        Const IDC_HAND As Long = 32649
        MousePointerID = IDC_HAND
    Case vbSizePointer, vbSizeAll
        Const IDC_SIZEALL As Long = 32646
        MousePointerID = IDC_SIZEALL
    Case vbSizeNESW
        Const IDC_SIZENESW As Long = 32643
        MousePointerID = IDC_SIZENESW
    Case vbSizeNS
        Const IDC_SIZENS As Long = 32645
        MousePointerID = IDC_SIZENS
    Case vbSizeNWSE
        Const IDC_SIZENWSE As Long = 32642
        MousePointerID = IDC_SIZENWSE
    Case vbSizeWE
        Const IDC_SIZEWE As Long = 32644
        MousePointerID = IDC_SIZEWE
    Case vbUpArrow
        Const IDC_UPARROW As Long = 32516
        MousePointerID = IDC_UPARROW
    Case vbHourglass
        Const IDC_WAIT As Long = 32514
        MousePointerID = IDC_WAIT
    Case vbNoDrop
        Const IDC_NO As Long = 32648
        MousePointerID = IDC_NO
    Case vbArrowHourglass
        Const IDC_APPSTARTING As Long = 32650
        MousePointerID = IDC_APPSTARTING
    Case vbArrowQuestion
        Const IDC_HELP As Long = 32651
        MousePointerID = IDC_HELP
    Case 16
        Const IDC_WAITCD As Long = 32663 ' Undocumented
        MousePointerID = IDC_WAITCD
End Select
End Function
Public Sub RefreshMousePointer(Optional ByVal hWndFallback As Long)
Const WM_SETCURSOR As Long = &H20, WM_NCHITTEST As Long = &H84, WM_MOUSEMOVE As Long = &H200
Dim P As POINTAPI, hWndCursor As Long
GetCursorPos P
hWndCursor = GetCapture()
If hWndCursor = 0 Then hWndCursor = WindowFromPoint(P.X, P.Y)
If hWndCursor <> 0 Then
    If GetWindowThreadProcessId(hWndCursor, 0) <> App.ThreadID Then hWndCursor = hWndFallback
Else
    hWndCursor = hWndFallback
End If
If hWndCursor <> 0 Then SendMessage hWndCursor, WM_SETCURSOR, hWndCursor, ByVal MakeDWord(SendMessage(hWndCursor, WM_NCHITTEST, 0, ByVal Make_XY_lParam(P.X, P.Y)), WM_MOUSEMOVE)
End Sub
Public Function OLEFontIsEqual(ByVal Font As StdFont, ByVal FontOther As StdFont) As Boolean
If Font Is Nothing Then
    If FontOther Is Nothing Then OLEFontIsEqual = True
ElseIf FontOther Is Nothing Then
    If Font Is Nothing Then OLEFontIsEqual = True
Else
    If Font.Name = FontOther.Name And Font.Size = FontOther.Size And Font.Charset = FontOther.Charset And Font.Weight = FontOther.Weight And _
    Font.Underline = FontOther.Underline And Font.Italic = FontOther.Italic And Font.Strikethrough = FontOther.Strikethrough Then
        OLEFontIsEqual = True
    End If
End If
End Function
Public Function CreateGDIFontFromOLEFont(ByVal Font As IFont) As Long
If Font Is Nothing Then Exit Function
Dim LF As LOGFONT
' hFont will be cleared when the IFont reference goes out of scope or is set to nothing.
GetObjectAPI Font.hFont, LenB(LF), LF
CreateGDIFontFromOLEFont = CreateFontIndirect(LF)
End Function
Public Function GetShiftStateFromParam(ByVal wParam As Long) As ShiftConstants
Const MK_SHIFT As Long = &H4, MK_CONTROL As Long = &H8
If (wParam And MK_SHIFT) = MK_SHIFT Then GetShiftStateFromParam = vbShiftMask
If (wParam And MK_CONTROL) = MK_CONTROL Then GetShiftStateFromParam = GetShiftStateFromParam Or vbCtrlMask
If GetKeyState(vbKeyMenu) < 0 Then GetShiftStateFromParam = GetShiftStateFromParam Or vbAltMask
End Function
 
Public Function GetMouseStateFromParam(ByVal wParam As Long) As MouseButtonConstants
Const MK_LBUTTON As Long = &H1, MK_RBUTTON As Long = &H2, MK_MBUTTON As Long = &H10
If (wParam And MK_LBUTTON) = MK_LBUTTON Then GetMouseStateFromParam = vbLeftButton
If (wParam And MK_RBUTTON) = MK_RBUTTON Then GetMouseStateFromParam = GetMouseStateFromParam Or vbRightButton
If (wParam And MK_MBUTTON) = MK_MBUTTON Then GetMouseStateFromParam = GetMouseStateFromParam Or vbMiddleButton
End Function
 
Public Function GetShiftStateFromMsg() As ShiftConstants
If GetKeyState(vbKeyShift) < 0 Then GetShiftStateFromMsg = vbShiftMask
If GetKeyState(vbKeyControl) < 0 Then GetShiftStateFromMsg = GetShiftStateFromMsg Or vbCtrlMask
If GetKeyState(vbKeyMenu) < 0 Then GetShiftStateFromMsg = GetShiftStateFromMsg Or vbAltMask
End Function
 
Public Function PtrToObj(ByVal ObjectPointer As Long) As Object
Dim TempObj As Object
CopyMemory TempObj, ObjectPointer, 4
Set PtrToObj = TempObj
CopyMemory TempObj, 0&, 4
End Function
 
Public Function ProcPtr(ByVal Address As Long) As Long
ProcPtr = Address
End Function
 
Public Function LoWord(ByVal DWord As Long) As Integer
If DWord And &H8000& Then
    LoWord = DWord Or &HFFFF0000
Else
    LoWord = DWord And &HFFFF&
End If
End Function
 
Public Function HiWord(ByVal DWord As Long) As Integer
HiWord = (DWord And &HFFFF0000) \ &H10000
End Function
 
Public Function MakeDWord(ByVal LoWord As Integer, ByVal HiWord As Integer) As Long
MakeDWord = (CLng(HiWord) * &H10000) Or (LoWord And &HFFFF&)
End Function
 
Public Function Get_X_lParam(ByVal lParam As Long) As Long
Get_X_lParam = lParam And &H7FFF&
If lParam And &H8000& Then Get_X_lParam = Get_X_lParam Or &HFFFF8000
End Function
 
Public Function Get_Y_lParam(ByVal lParam As Long) As Long
Get_Y_lParam = (lParam And &H7FFF0000) \ &H10000
If lParam And &H80000000 Then Get_Y_lParam = Get_Y_lParam Or &HFFFF8000
End Function
 
Public Function Make_XY_lParam(ByVal X As Long, ByVal Y As Long) As Long
Make_XY_lParam = LoWord(X) Or (&H10000 * LoWord(Y))
End Function
 
Public Function UTF32CodePoint_To_UTF16(ByVal CodePoint As Long) As String
If CodePoint >= &HFFFF8000 And CodePoint <= &H10FFFF Then
    Dim HW As Integer, LW As Integer
    If CodePoint < &H10000 Then
        HW = 0
        LW = CUIntToInt(CodePoint And &HFFFF&)
    Else
        CodePoint = CodePoint - &H10000
        HW = (CodePoint \ &H400) + &HD800
        LW = (CodePoint Mod &H400) + &HDC00
    End If
    If HW = 0 Then UTF32CodePoint_To_UTF16 = ChrW(LW) Else UTF32CodePoint_To_UTF16 = ChrW(HW) & ChrW(LW)
End If
End Function
Public Function StrToVar(ByVal Text As String) As Variant
If Text = vbNullString Then
    StrToVar = Empty
Else
    Dim B() As Byte
    B() = Text
    StrToVar = B()
End If
End Function
Public Function UnsignedAdd(ByVal Start As Long, ByVal Incr As Long) As Long
UnsignedAdd = ((Start Xor &H80000000) + Incr) Xor &H80000000
End Function
Public Function CUIntToInt(ByVal Value As Long) As Integer
Const OFFSET_2 As Long = 65536
Const MAXINT_2 As Integer = 32767
If Value < 0 Or Value >= OFFSET_2 Then Err.Raise 6
If Value <= MAXINT_2 Then
    CUIntToInt = Value
Else
    CUIntToInt = Value - OFFSET_2
End If
End Function
Public Function CIntToUInt(ByVal Value As Integer) As Long
Const OFFSET_2 As Long = 65536
If Value < 0 Then
    CIntToUInt = Value + OFFSET_2
Else
    CIntToUInt = Value
End If
End Function
Public Function DPI_X() As Long
Const LOGPIXELSX As Long = 88
Dim hDCScreen As Long
hDCScreen = GetDC(0)
If hDCScreen <> 0 Then
    DPI_X = GetDeviceCaps(hDCScreen, LOGPIXELSX)
    ReleaseDC 0, hDCScreen
End If
End Function
 
Public Function DPI_Y() As Long
Const LOGPIXELSY As Long = 90
Dim hDCScreen As Long
hDCScreen = GetDC(0)
If hDCScreen <> 0 Then
    DPI_Y = GetDeviceCaps(hDCScreen, LOGPIXELSY)
    ReleaseDC 0, hDCScreen
End If
End Function
 
Public Function DPICorrectionFactor() As Single
Static Done As Boolean, Value As Single
If Done = False Then
    Value = ((96 / DPI_X()) * 15) / Screen.TwipsPerPixelX
    Done = True
End If
' Returns exactly 1 when no corrections are required.
DPICorrectionFactor = Value
End Function
 
Public Function CHimetricToPixel_X(ByVal Width As Long) As Long
Const HIMETRIC_PER_INCH As Long = 2540
CHimetricToPixel_X = (Width * DPI_X()) / HIMETRIC_PER_INCH
End Function
 
Public Function CHimetricToPixel_Y(ByVal Height As Long) As Long
Const HIMETRIC_PER_INCH As Long = 2540
CHimetricToPixel_Y = (Height * DPI_Y()) / HIMETRIC_PER_INCH
End Function
 
Public Function PixelsPerDIP_X() As Single
Static Done As Boolean, Value As Single
If Done = False Then
    Value = (DPI_X() / 96)
    Done = True
End If
PixelsPerDIP_X = Value
End Function
'
Public Function PixelsPerDIP_Y() As Single
Static Done As Boolean, Value As Single
If Done = False Then
    Value = (DPI_Y() / 96)
    Done = True
End If
PixelsPerDIP_Y = Value
End Function
Public Function WinColor(ByVal Color As Long, Optional ByVal hPal As Long) As Long
If OleTranslateColor(Color, hPal, WinColor) <> 0 Then WinColor = -1
End Function
Public Function BitmapHandleFromPicture(ByVal Picture As IPictureDisp, Optional ByVal BackColor As OLE_COLOR) As Long
If Picture Is Nothing Then Exit Function
With Picture
If .Handle <> 0 Then
    Dim hDCScreen As Long, hDC As Long, hBmp As Long, hBmpOld As Long
    Dim CX As Long, CY As Long, Brush As Long
    CX = CHimetricToPixel_X(.Width)
    CY = CHimetricToPixel_Y(.Height)
    Brush = CreateSolidBrush(WinColor(BackColor))
    hDCScreen = GetDC(0)
    If hDCScreen <> 0 Then
        hDC = CreateCompatibleDC(hDCScreen)
        If hDC <> 0 Then
            hBmp = CreateCompatibleBitmap(hDCScreen, CX, CY)
            If hBmp <> 0 Then
                hBmpOld = SelectObject(hDC, hBmp)
                If .Type = vbPicTypeIcon Then
                    Const DI_NORMAL As Long = &H3
                    DrawIconEx hDC, 0, 0, .Handle, CX, CY, 0, Brush, DI_NORMAL
                Else
                    Dim RC As RECT
                    RC.Right = CX
                    RC.Bottom = CY
                    FillRect hDC, RC, Brush
                    .Render hDC Or 0&, 0&, 0&, CX Or 0&, CY Or 0&, 0&, .Height, .Width, -.Height, ByVal 0&
                End If
                SelectObject hDC, hBmpOld
                BitmapHandleFromPicture = hBmp
            End If
            DeleteDC hDC
        End If
        ReleaseDC 0, hDCScreen
    End If
    DeleteObject Brush
End If
End With
End Function
Добавлено через 21 минуту
Может функции конечно и хорошие, но для работа контрола они не нужны, в итоге я повыбрасывал функции: MsgBox, SendKeys, GetAttr, SetAttr, Dir, MkDir, RmDir, FileLen, FileDateTime, Command$, FileExists, AppPath, AppEXEName, AppMajor, AppMinor, AppRevision, GetAppVersionInfo, GetClipboardText, SetClipboardText, AcelCharCode, ProperControlName, GetTopUserControl, CloneOLEFont, GetNumberGroupDigit, GetDicimalChar, IsFormLoaded, GetWindowTitle, GetWindowClassName, CenterFormToScreen, FlashForm, GetFormTitleBarHeight, GetFormNonScaleHeight, SetWindowRedraw, GetWindowsDir, GetSystemDir, GetMouseStateFromMsg, GetShiftState, GetMouseState, KeyToggled, KeyPressed, InIDE, LoByte, HiByte, MakeWord, UTF16_To_UTF8, UTF8_To_UTF16, VarToStr, UnsignedSub, CULngToLng, CLngToULng, PictureFromByteStream, RenderPicture. Итого я выбросил 52 функции!!! Без всяких сомнений функции конечно очень хорошие, но я люблю пользоваться своими и чтобы ничего лишнего небыло...
1
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786
01.10.2023, 17:05  [ТС]
Кстати, я добился того, чтобы в элементе управления пользователя ListBoxW1 добавлялось 10 тысяч строк так же быстро, как и в моём первом примере, где я через API создавал листбокс и добавлял строки. Скачайте архив, нажмите на Command2 и вы увидите, что добавление происходит всего за 47 млск. Быстрее всего добавляются строки через API! Для теста можете так же нажать и на Command1 и убедиться что добавление строк через ListBoxW1.AddItem в два раза медленнее.

P. S. Кстати говоря в этом архиве, модуль Common.bas уже урезанный до 13 Кб.
Вложения
Тип файла: zip ListBoxW new.zip (115.7 Кб, 2 просмотров)
0
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786
01.10.2023, 17:21  [ТС]
Теперь по идее The Trick ещё хочу сказать, насчёт того, чтобы записывать сразу массив строк в ListBox. Лично я это вижу для себя так:

1. Нужно сначала выделить память для множества строк листбокса с помощью SendMessage LB_INITSTORAGE
2. Потом нужно найти каким-то чудом, адрес в памяти куда записывать массив строк и записать его с помощью CopyMemory

Лично я это так вижу
0
1401 / 860 / 92
Регистрация: 08.02.2017
Сообщений: 3,664
Записей в блоге: 2
01.10.2023, 17:35
Цитата Сообщение от HackerVlad Посмотреть сообщение
Потом нужно найти каким-то чудом, адрес в памяти куда записывать массив строк и записать его с помощью CopyMemory
Примерно также это вижу ) ListBox это же виндовый класс с++ - ный, также как, допустим, SafeArray, и у него где-то хранятся его внутренности..
0
Модератор
10060 / 3905 / 885
Регистрация: 22.02.2013
Сообщений: 5,854
Записей в блоге: 79
01.10.2023, 18:43
Цитата Сообщение от HackerVlad Посмотреть сообщение
А не проще ли переходить на SetWindowSubClass который не вешается?
Вешается. SetWindowSubClass должен по умолчанию быть использован в любом случае чтобы иметь правильную последовательность деинициализации сабклассинга.

Цитата Сообщение от Dragokas Посмотреть сообщение
Т.е. в отдельном потоке создать COM-объект?
Не, привязать время жизни сабклассинга к времени жизни COM объекта. Т.к. при сбросе проекта (кнопка Stop/End/норамльное завершение) VB6 проходит по всем переменным и очищает их. Вот тут у нас и появляется шанс сделать снятие сабклассинга. Я кстати так и делал в своем последнем варианте. Там правда есть баг, заключающийся в том что при рекурсивном вызове может вызваться код освобождения и соответственно при возврате управление придет в никуда. Фиксится просто инкрементом счетчика в вызываемой процедуре, либо просто не вызывать очищение кода, т.к. код всегда в 1м экземпляре - он не будет множится при повторном перезапуске, а использоваться все тот же.

Добавлено через 1 минуту
Цитата Сообщение от HackerVlad Посмотреть сообщение
Теперь по идее The Trick ещё хочу сказать, насчёт того, чтобы записывать сразу массив строк в ListBox. Лично я это вижу для себя так:
Идея вообще другая была. Вот у листбокса можно в дизайнере задать список строк и он их грузит сразу же. Я хотел этот метод заюзать для добавления, но там подводные камни. Пока не знаю буду ли я их решать или нет.
0
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786
01.10.2023, 19:15  [ТС]
Цитата Сообщение от The trick Посмотреть сообщение
можно в дизайнере задать список строк
Там он имеет ограничение на количество строк, вообще мало можно добавить.

Добавлено через 3 минуты
Цитата Сообщение от The trick Посмотреть сообщение
Вешается.
У меня не вешался

Добавлено через 6 минут
Я только что проверил по SetWindowSubclass вешается только при коде End. Если останавливать в дизайнере то никаких проблем.

Добавлено через 32 секунды
Но сам по себе глючный код End думаю ни один уважающий себя программист не использует

Добавлено через 22 секунды
Поэтому можно спокойно использовать SetWindowSubclass
0
Модератор
10060 / 3905 / 885
Регистрация: 22.02.2013
Сообщений: 5,854
Записей в блоге: 79
01.10.2023, 19:16
Цитата Сообщение от HackerVlad Посмотреть сообщение
Я только что проверил по SetWindowSubclass вешается только при коде End. Если останавливать в дизайнере то никаких проблем.
Разницы нет что Stop что End - одно и тоже. Будет вылетать и при ошибках в сабклассинге - это вообще не зависит от того SetWindowSubclass ты юзаешь. Это может приключится при любом нативном колбеке.
0
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786
01.10.2023, 19:16  [ТС]
Вот простой пример сабклассинга
0
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786
01.10.2023, 19:24  [ТС]
The trick, так сам попробуй, я архив скинул даже с самым простым кодом, можно спокойно останавливать в дизайнере

Добавлено через 1 минуту
Если тот же самый простой код был бы через SetWindowLong по старой технологии то VB6 сразу бы повесился при остановки проекта в дизайнере

Добавлено через 1 минуту
Прошу прощения, я ошибся

Добавлено через 13 секунд
Произошла какая-то фантастика: SetWindowLong тоже не вешается

Добавлено через 1 минуту
Может потому что у меня семёрка 64-битная, это очень странно, я помню что раньше вешалась остановка проекта

Добавлено через 45 секунд
Ладно, сейчас попробую в XP
0
Модератор
10060 / 3905 / 885
Регистрация: 22.02.2013
Сообщений: 5,854
Записей в блоге: 79
01.10.2023, 19:27
Цитата Сообщение от HackerVlad Посмотреть сообщение
The trick, так сам попробуй, я архив скинул даже с самым простым кодом, можно спокойно останавливать в дизайнере
Что и требовалось доказать.
Миниатюры
Как добавить в список ListBox большое количество строк, чтобы это было быстро по времени?  
0
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786
01.10.2023, 21:12  [ТС]
The trick, я пока не знаю почему, но у меня работает, это странно

Добавлено через 38 секунд
Именно из-за этого у меня и возникло ложное впечатление, что SetWindowSubclass не вешается.

Добавлено через 2 минуты
Стоп-точка тоже не вешается у меня

Добавлено через 39 секунд
Я могу спокойно прервать через Ctrl+Break отредактировать код и продолжить - ничего не вешается вообще кроме кода ENd

Добавлено через 1 минуту
Это очень странно что у меня всё работает, при чём в XP тоже

Добавлено через 7 минут
The trick, Я не знаю почему у меня всё работает, но у меня всё работает, поэтому у меня и нет нужды даже использовать твой класс сабклассинга

Добавлено через 1 час 28 минут
Цитата Сообщение от testuser2 Посмотреть сообщение
Примерно также это вижу ) ListBox это же виндовый класс с++ - ный, также как, допустим, SafeArray, и у него где-то хранятся его внутренности..
Ну я подумал обо всём этом и это не стоит свеч на самом деле. Мало просто взять и перезаписать память, даже если это удастся сделать, нужно ещё и изменить размеры Height листбокса и ещё изменить свойства вертикальной полосы прокрутки а потом обновить и перерисовать листбокс. Листбокс хранит список строк в памяти кучи, скорее всего, что-то типа HeapAlloc. К сожалению функция добавления строки в листбокс каждый раз передёргивает и изменяет размеры самого листбокса, а потом код занимается математическими расчётами для переопределения вертикальной полосы прокрутки, а потом всё это перерисовывает. Только из-за этого и идёт такая медленная скорость добавления строки в листбокс.

Тот результат которого я достиг, а это 47 млск, меня вполне устраивает, тут не надо заниматься больше этим.
0
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786
01.10.2023, 22:20  [ТС]
Лучший ответ Сообщение было отмечено testuser2 как решение

Решение

Ещё я провёл тесты, и выяснил, что в XP работает добавление в список ещё быстрее почему-то. У меня вообще за 16 млск 10 тысяч строк добавляет в XP. И 32 - 47 млск теперь в семёрке. Самый новый и самый лучший самый быстрый вариант. Даже функцию SendMessage в цикле которая используется юзаю теперь из TLB!!! Уже убыстрил как только можно.
Вложения
Тип файла: zip ListBoxW new (2).zip (117.1 Кб, 2 просмотров)
0
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786
03.10.2023, 14:11  [ТС]
Итак финальный релиз контрола ListBoxW от Krool. Полностью урезанная версия. Здесь выброшено всё лишнее, что не касается работы листбокса. Почти 100Кб лишнего мусора выброшено. Как вы все помните, для работы контрола требовались следующие зависимости:

1. ComCtlsBase.bas (45 Кб)
2. Common.bas (52 Кб)
3. VisualStyles.bas (22 Кб)
4. VTableHandle.bas (33 Кб)
5. ISubclass.cls (0 Кб)

Итого: 152 Кб зависимостей было и это ещё помимо того, что сам контрол весит около 100 КБ!!!

Я взял на себя смелость произвести большую работу по чистке мусора из всех этих модулей, в итоге было выброшено сотни ненужных функций, все модули я объединил в один новый модуль modKroolControlsSmall.bas, который весит всего 58 Кб, что на 94 КБ меньше, чем было!!!

Итого теперь из зависимостей осталось всего 2 файла:

1. modKroolControlsSmall.bas (58 Кб)
2. ISubclass.cls (0 Кб)

Этот новый модуль является объединением всех четырёх старых модулей с тотальной чисткой ненужного мусора. Теперь чтобы работать с контролом не нужно таскать за собой 4 разных модуля, что согласитесь было крайне неудобно. Теперь достаточно таскать за собой только один модуль и один класс, что стало гораздо удобнее. Krool к сожалению, не думал о людях которые будут использовать только один его элемент и не делал компактного кода для одного контрола. Я это исправил.

И кстати размер EXE теперь будет меньше почти на 20 КБ!!!

Ну и тут, в этом моём примере так же видно, как очень быстро можно добавить 10 тысяч строк в листбокс.
Вложения
Тип файла: zip ListBoxW new (3).zip (95.4 Кб, 11 просмотров)
1
1401 / 860 / 92
Регистрация: 08.02.2017
Сообщений: 3,664
Записей в блоге: 2
08.05.2024, 21:45
Добавление строк путем прямой записи в память листбокса. Из минусов не оптимальный механизм поиска нужных указателей - сканирование памяти программы. Если возможно как-то по иному их вычислять, было бы идеально, я пока не нашел как это сделать. Проверял только в IDE, без компиляции. Пример в файле с комментариями.
Вложения
Тип файла: zip ListBoxTestuserAddItemsTurbo20.zip (9.4 Кб, 8 просмотров)
0
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786
08.05.2024, 22:26  [ТС]
testuser2, спасибо конечно за старания, но твой проект не работает
Миниатюры
Как добавить в список ListBox большое количество строк, чтобы это было быстро по времени?  
0
1401 / 860 / 92
Регистрация: 08.02.2017
Сообщений: 3,664
Записей в блоге: 2
08.05.2024, 22:31
Завтра проверю, у меня работало как часы, но может всякое быть
0
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786
08.05.2024, 22:37  [ТС]
testuser2, проверять надо в VB6 на семёрке - у меня вылетает сразу после запуска

Добавлено через 1 минуту
testuser2, и ещё большая просьба навести порядок в проекте чтобы он смог откомпилироваться в EXE и запускаться через Ctrl+F5

Добавлено через 3 минуты
testuser2, ещё так же удивило твоё заявление, что ты создал этот проект завтра

Visual Basic
1
'Created by Testuser 09.05.24
Сегодня 8 мая, а не 9 мая!!!
0
1401 / 860 / 92
Регистрация: 08.02.2017
Сообщений: 3,664
Записей в блоге: 2
09.05.2024, 02:49
Проверил на 7 виндюке и на 8.1 и на 10 везде работает. Единственно можт не сработать при загрузке винды, когда система еще не прогрузила все библиотеки
Вложения
Тип файла: zip Проект1.zip (8.8 Кб, 3 просмотров)
1
1401 / 860 / 92
Регистрация: 08.02.2017
Сообщений: 3,664
Записей в блоге: 2
09.05.2024, 02:52
Цитата Сообщение от HackerVlad Посмотреть сообщение
'Created by Testuser 09.05.24
Это чистая правда, я ночью доделывал этот проэкт, находясь, в своем часовом поясе )
1
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786
09.05.2024, 05:41  [ТС]
Цитата Сообщение от testuser2 Посмотреть сообщение
Проверил на 7 виндюке и на 8.1 и на 10 везде работает.
EXE твой работает который, ты приложил, а вот тот проект не работает НИГДЕ, в XP тоже, вот скрин.
Миниатюры
Как добавить в список ListBox большое количество строк, чтобы это было быстро по времени?  
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
09.05.2024, 05:41

Вывести файл на экран, чтобы в каждой строке было не больше 40 символов, и количество строк было минимальным
Дано файл f. Вывести этот файл на экран так что бы в каждой строчке было не больше, чем 40 символов и количество строк было минимальным.

Как исправить, чтобы количество столбцов и строк StringGrid было таким, как ввел пользователь
Подскажите, в чем дело, программа создает двумерный массив элементы которого вводят с клавиатуры, ввод осуществляется в stringGrid. При...

Как добавить значения с Листа в Listbox, если количество строк может меняться
Есть Лист с уже заданными значениями, но они могут изменяться (добавляться, удаляться). Нужно добавить этот столбец в Listbox. Помогите...

Как сделать так,чтобы количество строк и столбцов массива можно было менять через меню?
как сделать так,чтобы количество строк (n) и столбцов(m) массива можно было менять через меню? весь код #include...

Поиск минимального времени выполнения теста, чтобы количество набранных баллов было максимальным
Здравствуйте! Подскажите пожалуйста, в чем ошиблась у меня массив Examen структур с данными о номере Nomer. Для каждого номера дано время...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
80
Ответ Создать тему
Новые блоги и статьи
Контроль уникальности строк в табличной части документа
Maks 18.06.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ПланированиеСпецтехники" с табличной частью "НаличиеОборудования", разработанного в КА2. Задача: контроль уникальности строк в. . .
Клиент
Uhbif79 18.06.2026
Здесь простой клиент для работы с сервером.
Сервер
Uhbif79 18.06.2026
Выкладываю простейший сервер.
Дефенестрация
kumehtar 18.06.2026
Узнал интересное слово. Дефенестрация. Это когда ты выбрасываешь кого-либо или что-либо из окна. Возьму на вооружение)))
Дихотомия добра и зла
kumehtar 18.06.2026
Как Дзен-буддисты говорят о добре и зле: не нужно воевать против зла, нужно воевать против невежества. Тогда добро станет ествественным, и поэтому вечным. Но дело в том, что невежество всё время. . .
Своя Интернет-Компания
iceja 18.06.2026
Я программист с экономическим образованием, пишу свой проект, это SaaS для бизнесов. Мне нужен co-founder с высшим экономическим образованием, и/ или инвестор. Сейчас проект в интенсивной разработке,. . .
24 Мат модель здравосохранения: функциональные требования к строительству пищеблока
anaschu 18.06.2026
СРесурсами1: финансовый SD-контур, калькулятор функциональных требований пищеблока Сегодня разделили затраты в агенте Экономика по образцу модели НАСОСЫ, добавили расчёт ROI и построили первый. . .
23. что сделано за последнее время.
anaschu 17.06.2026
• Эталон: Клиника НИИ питания РАМН, Москва — централизованный пищеблок, 225 коек, 180 пациентов • Git: репозиторий med2, ветка абсентеизм. Рабочий файл: СРесурсами1_v4. alp • Смежный проект:. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru