purebasic.info

PureBasic forum
Текущее время: Пт сен 21, 2018 3:32 am

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 11 ] 
Автор Сообщение
 Заголовок сообщения: Ускорить заполнение ListIconGadget
СообщениеДобавлено: Вт авг 06, 2013 9:02 pm 
Не в сети
PureBasic Coder
Аватар пользователя

Зарегистрирован: Чт ноя 10, 2011 10:50 am
Сообщений: 4049
Откуда: Ростов-на-Дону
Благодарил (а): 70 раз.
Поблагодарили: 81 раз.
Пункты репутации: 24
Небольшой совет, пригодится тем, кому нужно записать большое количество строк в ListIconGadget. Для примера, обычный код, добавляет в список 10 тысяч элементов.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
OpenWindow(0,5,5,400,400,"")
ListIconGadget(0,5,5,390,390,"",300)
 
start = ElapsedMilliseconds()
 
For i = 1 To 10000
  AddGadgetItem(0, -1, Str(i))
Next
 
Debug ElapsedMilliseconds()-start
 
Repeat:Until WaitWindowEvent() = #PB_Event_CloseWindow


Данный код отрабатывает у меня за 2891 мс (~3 с).

Для убыстрения этого процесса есть один способ, но два метода его реализации.

Метод первый (только Windows). Функциями Windows API запретить прорисовку гаджета.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
OpenWindow(0,5,5,400,400,"")
ListIconGadget(0,5,5,390,390,"",300)
 
SendMessage_(GadgetID(0),#WM_SETREDRAW,#False,0)
 
start = ElapsedMilliseconds()
 
For i = 1 To 10000
  AddGadgetItem(0, -1, Str(i))
Next
 
Debug ElapsedMilliseconds()-start
 
SendMessage_(GadgetID(0),#WM_SETREDRAW,#True,0)
RedrawWindow_(GadgetID(0), #Null, #Null, #RDW_ERASE | #RDW_FRAME | #RDW_INVALIDATE | #RDW_ALLCHILDREN)
 
Repeat:Until WaitWindowEvent() = #PB_Event_CloseWindow


Данный код заполняет список за 157 мс. Скорость выросла в 18,4 раз!

Второй способ - просто скрыть гаджет, а потом показать его.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
OpenWindow(0,5,5,400,400,"")
ListIconGadget(0,5,5,390,390,"",300)
 
HideGadget(0,1)
 
start = ElapsedMilliseconds()
 
For i = 1 To 10000
  AddGadgetItem(0, -1, Str(i))
Next
 
Debug ElapsedMilliseconds()-start
 
HideGadget(0,0)
 
Repeat:Until WaitWindowEvent() = #PB_Event_CloseWindow


Данный код работает за 172 мс. Немного медленнее, чем API, но этот способ является кроссплатформенным.

И ещё тест - повторим эти манипуляции, добавляя 100 тысяч строк. Вот как работает у меня:
Стандартный способ - 28907 мс
С помощью WinAPI - 1563 мс
С помощью HideGadget - 1578 мс

_________________
Пурик - лучший язык программирования


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт авг 06, 2013 9:31 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11255
Благодарил (а): 4 раз.
Поблагодарили: 429 раз.
Еще один быстрый способ заполнения ListIcon'а.
Он настолько быстр что 10 тысяч элементов заполняются меньше чем за миллисекунду, поэтому число элементов увеличено до миллиона.
Код:
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
#ItemCount = 1000000;размер массива и кол-во строк. 
#list = 0
#LVSICF_NOINVALIDATEALL = 1
#LVN_ODCACHEHINT = #LVN_FIRST - 13
 
Global Dim myItems.s(#ItemCount, 2)
 
Procedure turumtumtum(hwnd, msg, wParam, lParam)
  result = #PB_ProcessPureBasicEvents
  If msg <> #WM_NOTIFY
    ProcedureReturn result
  EndIf
 
  *pnmh.NMHDR = lParam
 
  If *pnmh\code = #LVN_ODCACHEHINT
    ProcedureReturn 0
  EndIf
 
  If *pnmh\code = #LVN_GETDISPINFO
    *pnmlvdi.NMLVDISPINFO = lParam
    If *pnmlvdi\item\mask & #LVIF_TEXT
      *pnmlvdi\item\pszText = @myItems(*pnmlvdi\item\iItem, *pnmlvdi\item\iSubItem)
    EndIf
  EndIf
  ProcedureReturn result
EndProcedure
 
If OpenWindow(0, 0, 0, 640, 300, "ListIconGadgets", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  SetWindowCallback(@turumtumtum())
  ListIconGadget(#list,10,10,620,280,"ID",50,#LVS_OWNERDATA)
  AddGadgetColumn(#list,2,"Name",100)
 
  start = ElapsedMilliseconds()
 
  For i=0 To #ItemCount
    myItems(i, 0) = Str(i)+" - ParamPamPam"
  Next i
  SendMessage_(GadgetID(#list), #LVM_SETITEMCOUNT, #ItemCount, #LVSICF_NOINVALIDATEALL)
 
  Debug ElapsedMilliseconds()-start
 
 
  Repeat
    event = WaitWindowEvent()    
   
  Until event = #PB_Event_CloseWindow
EndIf


_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт авг 06, 2013 9:35 pm 
Не в сети
PureBasic Coder
Аватар пользователя

Зарегистрирован: Чт ноя 10, 2011 10:50 am
Сообщений: 4049
Откуда: Ростов-на-Дону
Благодарил (а): 70 раз.
Поблагодарили: 81 раз.
Пункты репутации: 24
Круто, чё сказать! :)

_________________
Пурик - лучший язык программирования


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Ускорить заполнение ListIconGadget
СообщениеДобавлено: Вс авг 31, 2014 8:03 pm 
Не в сети
PureBasic Coder
Аватар пользователя

Зарегистрирован: Чт ноя 10, 2011 10:50 am
Сообщений: 4049
Откуда: Ростов-на-Дону
Благодарил (а): 70 раз.
Поблагодарили: 81 раз.
Пункты репутации: 24
А как дальше работать с этим листиконом? Неправильно работает GetGadgetItemText (при попытке запросить текст 96854-го элемента он мне возвращает текст 900001-го). Не работает SetGadgetState, SetGadgetItemText, SetGadgetItemColor. Неужели всё придётся в callback вручную делать?
P.S. При использования флага #PB_ListIcon_CheckBoxes самих чекбоксов нет :cry:

_________________
Пурик - лучший язык программирования


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Ускорить заполнение ListIconGadget
СообщениеДобавлено: Вс авг 31, 2014 10:24 pm 
Не в сети
профессор

Зарегистрирован: Ср янв 14, 2009 4:12 pm
Сообщений: 2002
Благодарил (а): 12 раз.
Поблагодарили: 101 раз.
Пункты репутации: 43
Никита, почитай тут viewtopic.php?f=5&t=1137&start=15

_________________
Всё должно быть просто, настолько просто, насколько возможно, но не проще. (c) Альберт Эйнштейн
Изображение


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Ускорить заполнение ListIconGadget
СообщениеДобавлено: Пн сен 01, 2014 3:46 am 
Не в сети
профессор

Зарегистрирован: Вс июн 10, 2012 8:18 am
Сообщений: 1294
Благодарил (а): 60 раз.
Поблагодарили: 49 раз.
Пункты репутации: 14
Никита Однороб писал(а):
При использования флага #PB_ListIcon_CheckBoxes самих чекбоксов нет

Код:
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
 
#ItemCount = 10000
 
#LVSICF_NOINVALIDATEALL = 1
#LVSICF_NOSCROLL = 2
#LVN_ODCACHEHINT = #LVN_FIRST - 13
 
 
Global Dim myItems.s(#ItemCount,1)
Global Dim CheckFlag(#ItemCount)
 
Procedure WinCallback(hwnd, msg, wParam, lParam)
  result = #PB_ProcessPureBasicEvents
  Select msg
    Case #WM_NOTIFY                            
      *nmh.NMHDR = lParam
      Select *nmh\code
                           
        Case #LVN_ODCACHEHINT
          result = 0
         
        Case #LVN_ODFINDITEM
          result = -1  
           
        Case #LVN_GETDISPINFO
          *nmlvd.NMLVDISPINFO = lParam
           *nmlvd\item\mask & #LVIF_IMAGE|#LVIF_STATE|#LVIF_TEXT
            *nmlvd\item\stateMask = #LVIS_STATEIMAGEMASK
            *nmlvd\item\pszText = @myItems(*nmlvd\item\iItem,*nmlvd\item\iSubItem)
           
            Select CheckFlag(*nmlvd\item\iItem)
              Case 0
                  *nmlvd\item\state = 1<<12              
              Case 1
                  *nmlvd\item\state = 2<<12
            EndSelect
         
        Case #NM_CLICK
          *nmlv.NM_LISTVIEW = lParam
          If *nmlv\iSubItem = 0 And *nmlv\iItem >= 0
              CheckFlag(*nmlv\iItem) = CheckFlag(*nmlv\iItem) ! 1
              SendMessage_(GadgetID(0), #LVM_REDRAWITEMS ,*nmlv\iItem,*nmlv\iItem)
          EndIf
 
      EndSelect    
 
  EndSelect
  ProcedureReturn result
EndProcedure
 
  OpenWindow(0, 0, 0, 640, 300, "Virtual ListIconGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  SetWindowCallback(@WinCallback())
  ListIconGadget(0,10,10,620,280,"ID",100,#LVS_OWNERDATA|#PB_ListIcon_CheckBoxes| #PB_ListIcon_GridLines)
  SetGadgetColor(0,#PB_Gadget_BackColor, $E1FEFD)
  SendMessage_(GadgetID(0), #LVM_SETITEMCOUNT, #ItemCount, #LVSICF_NOINVALIDATEALL|#LVSICF_NOSCROLL)
  AddGadgetColumn(0,2,"Name",100)
  For i=0 To #ItemCount
    myItems(i,0) = Str(i)
    myItems(i,1) = "Name "+Str(i)
  Next i
 
 
  Repeat
  Until WaitWindowEvent() = #PB_Event_CloseWindow
 


Никита Однороб писал(а):
А как дальше работать с этим листиконом?

В виртуальном режиме надо обращаться к соответствующим массивам, а не к гаджету на прямую.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Ускорить заполнение ListIconGadget
СообщениеДобавлено: Вс ноя 16, 2014 12:01 am 
Не в сети
профессор

Зарегистрирован: Вс июн 10, 2012 8:18 am
Сообщений: 1294
Благодарил (а): 60 раз.
Поблагодарили: 49 раз.
Пункты репутации: 14
А как создать несколько виртуальных листиконов, и желательно динамически?


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Ускорить заполнение ListIconGadget
СообщениеДобавлено: Вс ноя 16, 2014 5:15 pm 
Не в сети
профессор

Зарегистрирован: Ср янв 14, 2009 4:12 pm
Сообщений: 2002
Благодарил (а): 12 раз.
Поблагодарили: 101 раз.
Пункты репутации: 43
MrF писал(а):
А как создать несколько виртуальных листиконов, и желательно динамически?

Как то так
Код:
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
#LVN_ODCACHEHINT = #LVN_FIRST - 13
#SHGFI_ADDOVERLAYS = $20
Enumeration
  #MenuPopUp = 100
  #Copy      = 101
EndEnumeration  
 
  Declare WinCallback(hwnd, msg, wParam, lParam)
Global Column.l
Global Row.l
If OpenWindow(0, 0, 0, 640, 610, "ExplorerListGadget Demo", #PB_Window_SizeGadget|#PB_Window_SystemMenu | #PB_Window_MaximizeGadget| #PB_Window_ScreenCentered)  
  ListIconGadget(111,10,10,620,250,"Column1",240,#LVS_OWNERDATA|#PB_ListIcon_FullRowSelect|#PB_ListIcon_GridLines)
  AddGadgetColumn(111,1,"Column2",100)
  AddGadgetColumn(111,2,"Column3",150)
  AddGadgetColumn(111,3,"Column4",100)
 
  ListIconGadget(112,10,300,620,250,"Column1",240,#LVS_OWNERDATA|#PB_ListIcon_FullRowSelect|#PB_ListIcon_GridLines)
  AddGadgetColumn(112,1,"Column2",100)
  AddGadgetColumn(112,2,"Column3",150)
  AddGadgetColumn(112,3,"Column4",100)
  ButtonGadget(3, 520,560, 40, 35,"Go")
 
 
    If CreatePopupMenu(#MenuPopUp)
      MenuItem(#Copy, "Копировать")
    EndIf
  SetWindowCallback(@WinCallback())
 
Repeat
  Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
              Quit = 1
      Case #PB_Event_Gadget
        Select EventGadget()
           Case 3    
                Count = 100000
                ClearGadgetItems(111)
                    Global Dim myItems.s(Count, 3)
                    SendMessage_(GadgetID(111), #LVM_SETITEMCOUNT, Count,1 )
                    For i = 0 To Count
                      myItems(i,0) = "11111111111111"
                      myItems(i,1) = "22222222222222"
                      myItems(i,2) = "33333333333333"
                      myItems(i,3) = "44444444444444"
                    Next i
                ClearGadgetItems(112)
                    Global Dim myItems1.s(Count, 3)
                    SendMessage_(GadgetID(112), #LVM_SETITEMCOUNT, Count,1 )
                    For i = 0 To Count
                      myItems1(i,0) = "55555555555555"
                      myItems1(i,1) = "77777777777777"
                      myItems1(i,2) = "88888888888888"
                      myItems1(i,3) = "99999999999999"
                    Next i
        EndSelect
      Case #PB_Event_Menu
        EventMenu = EventMenu()
                                     
  EndSelect
Until Quit = 1
EndIf
 
Procedure WinCallback(hwnd, msg, wParam, lParam)
  result = #PB_ProcessPureBasicEvents
  Select msg        
     Case #WM_NOTIFY
      *pnmh.NMHDR = lParam;        
        Select *pnmh\code        
          Case #LVN_ODCACHEHINT
            result = 0
          Case #LVN_GETDISPINFO
            *pnmlvdi.NMLVDISPINFO = lParam
            Select *pnmlvdi\hdr\idFrom
              Case 111
               If *pnmlvdi\item\mask & #LVIF_IMAGE|#LVIF_TEXT              
                  *pnmlvdi\item\pszText = @myItems(*pnmlvdi\item\iItem,*pnmlvdi\item\iSubItem)  ; text to set
                EndIf
              Case 112  
               If *pnmlvdi\item\mask & #LVIF_IMAGE|#LVIF_TEXT              
                  *pnmlvdi\item\pszText = @myItems1(*pnmlvdi\item\iItem,*pnmlvdi\item\iSubItem)  ; text to set    
                EndIf
            EndSelect    
               
          Case #NM_RCLICK
               If *pnmh\hwndFrom = GadgetID(111)
                    *lpnmitem.NMITEMACTIVATE = lParam
                    Row = *lpnmitem\iItem
                    Column = *lpnmitem\iSubItem
                    DisplayPopupMenu(#MenuPopUp, WindowID(0))
               EndIf
          Case #LVN_ODFINDITEM
            result = -1        
        EndSelect      
  EndSelect
  ProcedureReturn result
EndProcedure


_________________
Всё должно быть просто, настолько просто, насколько возможно, но не проще. (c) Альберт Эйнштейн
Изображение


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Ускорить заполнение ListIconGadget
СообщениеДобавлено: Вс ноя 16, 2014 6:03 pm 
Не в сети
профессор

Зарегистрирован: Вс июн 10, 2012 8:18 am
Сообщений: 1294
Благодарил (а): 60 раз.
Поблагодарили: 49 раз.
Пункты репутации: 14
pablov писал(а):
Select *pnmlvdi\hdr\idFrom
Case 111

Вот этого разделения гаджетов и не хватало. Спасибо.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Ускорить заполнение ListIconGadget
СообщениеДобавлено: Вс ноя 16, 2014 7:16 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11255
Благодарил (а): 4 раз.
Поблагодарили: 429 раз.
Лучше создать структуру с массивом и поместить ее в #GWL_USERDATA. Тогда получится универсальнее и без правки кода можно будет создать много гаджетов.

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Ускорить заполнение ListIconGadget
СообщениеДобавлено: Пн ноя 17, 2014 2:31 am 
Не в сети
профессор

Зарегистрирован: Вс июн 10, 2012 8:18 am
Сообщений: 1294
Благодарил (а): 60 раз.
Поблагодарили: 49 раз.
Пункты репутации: 14
Пётр, покажи пример? Про структуру с массивом понятно, но как ее поместить в #GWL_USERDATA, и как использовать потом?


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 11 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group (блог о phpBB)
Сборка создана CMSart Studio
Русская поддержка phpBB