Seite 2 von 4

Re: ListIconGadget schnell mit 3700 Einträge füllen

Verfasst: 04.05.2016 10:19
von CSHW89
Cross-Plattform wäre ein HideGadget vor dem Befüllen. Ist bei mir ein Tick schneller (290 zu 340ms), als die Variante von RSBasic mit #WM_SETREDRAW. Aber edel's Variante ist wirklich beeindruckend :shock:

lg Kevin

Re: ListIconGadget schnell mit 3700 Einträge füllen

Verfasst: 04.05.2016 10:28
von RSBasic
Ich würde eigentlich HideGadget auch bevorzugen, aber diese Variante kann man nur beim Start verwenden.
Sonst sieht es komisch aus, wenn während der Laufzeit das Gadget einfach für eine Sekunde verschwindet und anschließend wieder auftaucht. Da braucht man dann zusätzlich einen Platzhalter oder einen Screenshot des Gadgets.

@Andre
Frag am besten im englischen Forum nach. Da gibt es mehr MacOS-User, die sich damit auskennen. Vielleicht gibt es sowas ähnliches auch bei MacOS. Viel Glück

Re: ListIconGadget schnell mit 3700 Einträge füllen

Verfasst: 04.05.2016 13:33
von Kiffi
RSBasic hat geschrieben:Sonst sieht es komisch aus, wenn während der Laufzeit das Gadget einfach für eine Sekunde verschwindet und anschließend wieder auftaucht.
korrigier mich, wenn ich falsch liege, aber da zwischen HideGadget(..., #True) und HideGadget(..., #False) keine Eventverarbeitung stattfindet, dürfte das Gadget nicht sichtbar verschwinden.

Grüße ... Peter

Re: ListIconGadget schnell mit 3700 Einträge füllen

Verfasst: 04.05.2016 13:55
von ts-soft
Kiffi hat geschrieben:korrigier mich, wenn ich falsch liege, aber da zwischen HideGadget(..., #True) und HideGadget(..., #False) keine Eventverarbeitung stattfindet, dürfte das Gadget nicht sichtbar verschwinden.
Aber wenn keine Eventverarbeitung stattfinden sollte, so gäbe es auch keinerlei Auswirkungen
auf die Geschwindigkeit und das ListIcon würde auch nicht gefüllt. :mrgreen:

Alles nicht so logisch :D

Den coolen Code von edel, hat er bereits vor Jahren mal gepostet, da hat es aber kaum einer wahrgenommen.
Besser spät als nie!

Re: ListIconGadget schnell mit 3700 Einträge füllen

Verfasst: 04.05.2016 14:10
von mhs
@Kiffi: Nicht vergessen, im Hintegrund ist eine Warteschleife :)

Das HideGadget() legt genau wie ein SendMessage() einen Eintrag in der EventQueue ab, die mit WaitWindowEvent() abgearbeitet wird. Irgendwann wird also das Ereignis zum Ausblenden des Gadgets verarbeitet, danach folgen die ganzen Zeileneinträge und zum Schluss dann das Einblenden.

In der Zeit wo die ganzen Zeileneinträge verarbeitet werden, wird das Gadget ausgeblendet.

Vermunderlich finde ich nur, dass ein HideGadget() tatsächlich schneller ist als den Redraw auszuschalten...

Re: ListIconGadget schnell mit 3700 Einträge füllen

Verfasst: 04.05.2016 14:21
von Kiffi
@ts-soft & mhs: Danke für die Richtigstellung!

Grüße ... Peter

Re: ListIconGadget schnell mit 3700 Einträge füllen

Verfasst: 09.05.2016 16:43
von Joshua314
edel hat geschrieben:0 ms :lurk:

Code: Alles auswählen

EnableExplicit

Structure struct
  a.s
  b.s
  c.s
  d.s
EndStructure

#ARRAY_SIZE = 37000

Global Dim List.struct(#ARRAY_SIZE)

Procedure Callback(hwnd, msg, wparam, lparam)
  Protected *hdr.NMHDR
  Protected *di.NMLVDISPINFO
  Protected str.i
  
  If msg = #WM_NOTIFY
    *hdr = lparam
    
    If *hdr\code = #LVN_GETDISPINFO
      *di = lparam      
      
      Select *di\item\iSubItem
        Case 0
          str.i = @List(*di\item\iItem)\a
        Case 1
          str.i = @List(*di\item\iItem)\b
        Case 2
          str.i = @List(*di\item\iItem)\c
        Case 3
          str.i = @List(*di\item\iItem)\d
      EndSelect
      
      *di\item\pszText = str
      
      ProcedureReturn #True
    EndIf
    
  EndIf
  
  ProcedureReturn #PB_ProcessPureBasicEvents  
EndProcedure  

Procedure InitArray()
  Protected a
  For a = 0 To #ARRAY_SIZE   
    List(a)\a = "Hallo " + Str(a)
    List(a)\b = "Pure " + Str(a)
    List(a)\c = "Basic " + Str(a)
    List(a)\d = "Welt " + Str(a)
  Next
EndProcedure

Procedure Main()
  Protected EventID
  
  InitArray()
  
  If OpenWindow(0, 0, 0, 500, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    
    SetWindowCallback(@Callback(), 0)
    
    ListIconGadget(1, 10, 10, 480, 380, "Spalte 1", 100, #LVS_OWNERDATA | #PB_ListIcon_FullRowSelect)
    AddGadgetColumn(1, 1, "Spalte 2", 100)
    AddGadgetColumn(1, 2, "Spalte 3", 100)
    AddGadgetColumn(1, 3, "Spalte 4", 100)
    
    SendMessage_(GadgetID(1), #LVM_SETITEMCOUNT, #ARRAY_SIZE, 0)
    
    Repeat      
    Until WaitWindowEvent() = #PB_Event_CloseWindow
    
  EndIf
  
EndProcedure:End Main()
Danke dir Edel,

stimmt, diese Version ist sehr schnell, sozusagen Blitz schnell.
Ich konnte deine Version auch erfolgreich einbauen.
Leider habe ich es nicht geschafft, eine Checkbox dazu zu machen.
Auch hab ich keine Ahnung, wie ich die Checkbox, wenn Diese dann da ist, wieder abfragen kann.
Kannst du mir hier noch einmal aushelfen?

Gruß Thomas

Re: ListIconGadget schnell mit 3700 Einträge füllen

Verfasst: 09.05.2016 16:50
von RSBasic
@Joshua314
Hast du trotzdem mal versucht, meinen Code zu testen?
Wie lange dauert dein Code normalerweise? Und wie lange dauert der von mir geschriebene Code? Mit oder ohne Debugger?

Re: ListIconGadget schnell mit 3700 Einträge füllen

Verfasst: 09.05.2016 19:08
von edel
Joshua314 hat geschrieben: Danke dir Edel,

stimmt, diese Version ist sehr schnell, sozusagen Blitz schnell.
Ich konnte deine Version auch erfolgreich einbauen.
Leider habe ich es nicht geschafft, eine Checkbox dazu zu machen.
Auch hab ich keine Ahnung, wie ich die Checkbox, wenn Diese dann da ist, wieder abfragen kann.
Kannst du mir hier noch einmal aushelfen?

Gruß Thomas
Das scheint wohl auch nicht mehr zu funktionieren. Man kann aber eine Checkbox selber einbauen.
Abrufen kannst du das dann einfach ueber das Array.

Code: Alles auswählen

Structure checkbox
  s.s
  state.l
EndStructure

Structure struct
  a0.checkbox
  a.s
  b.s
  c.s
  d.s
EndStructure

Global Theme

#BP_CHECKBOX          = 3
#CBS_CHECKEDNORMAL    = 5
#CBS_UNCHECKEDNORMAL  = 1

#ARRAY_SIZE           = 37300

Global Dim List.struct(#ARRAY_SIZE)

Procedure Callback(hwnd, msg, wparam, lparam)
  Protected *hdr.NMHDR
  Protected *di.NMLVDISPINFO
  Protected str.i
  Protected *t.NMITEMACTIVATE
  Protected t0.LVHITTESTINFO
  
  If msg = #WM_NOTIFY
    *hdr = lparam
    
    If *hdr\code = #NM_DBLCLK
      *t = lparam
      
      If List(*t\iItem)\a0\state
        List(*t\iItem)\a0\state = 0
      Else
        List(*t\iItem)\a0\state = 1
      EndIf
      
      InvalidateRect_(*hdr\hwndFrom, 0, 0)
      
    EndIf       
    
    If *hdr\code = #NM_CLICK
      *t = lparam
      t0\pt       = *t\ptAction
      
      SendMessage_(*hdr\hwndFrom, #LVM_SUBITEMHITTEST, 0, t0) 
      
      If t0\flags & #LVHT_ONITEMICON = #LVHT_ONITEMICON
        If List(t0\iItem)\a0\state
          List(t0\iItem)\a0\state = 0
        Else
          List(t0\iItem)\a0\state = 1
        EndIf
        
      EndIf
      
      InvalidateRect_(*hdr\hwndFrom, 0, 0)
      
    EndIf    
    
    If *hdr\code = #LVN_GETDISPINFO
      *di = lparam      
      
      Select *di\item\iSubItem
        Case 0
          *di\item\iImage = List(*di\item\iItem)\a0\state
          str.i = @List(*di\item\iItem)\a0\s
        Case 1
          str.i = @List(*di\item\iItem)\a
        Case 2
          str.i = @List(*di\item\iItem)\b
        Case 3
          str.i = @List(*di\item\iItem)\c
        Case 4
          str.i = @List(*di\item\iItem)\d
      EndSelect
      
      *di\item\pszText = str
      
    EndIf
    
  EndIf
  
  ProcedureReturn #PB_ProcessPureBasicEvents  
EndProcedure  

Procedure InitArray()
  Protected a
  For a = 0 To #ARRAY_SIZE   
    List(a)\a0\state = 0
    List(a)\a0\s = "check " + Str(a)
    List(a)\a = "Hallo " + Str(a)
    List(a)\b = "Pure " + Str(a)
    List(a)\c = "Basic " + Str(a)
    List(a)\d = "Welt " + Str(a)
  Next
  ProcedureReturn a
EndProcedure

Procedure InitCheckBoxImageListForListIconGadgetHahaIstDasEinLangerNameObderNochLaengerWerdenDarfFragezeichen(Gadget)
  Protected rc.rect
  Protected image.i 
  Protected imagelist.i 
  Protected hdc.i 
    
  Theme = OpenThemeData_(GadgetID(gadget), "Button")  
  
  
  rc\left   = 0
  rc\top    = 0
  rc\right  = 16
  rc\bottom = 16      
  
  imagelist = ImageList_Create_( rc\right, rc\bottom, #ILC_COLOR, 2, 0 )
  
  image = CreateImage(#PB_Any, rc\right, rc\bottom)
  
  hdc = StartDrawing(ImageOutput(image))
  DrawThemeParentBackground_(GadgetID(gadget), hdc, rc)
  DrawThemeBackground_(Theme, hdc, #BP_CHECKBOX, #CBS_UNCHECKEDNORMAL, rc, #Null)
  StopDrawing()  
  
  ImageList_Add_(imagelist, ImageID(image), #Null)
  
  hdc = StartDrawing(ImageOutput(image))
  DrawThemeParentBackground_(GadgetID(gadget), hdc, rc)
  DrawThemeBackground_(Theme, hdc, #BP_CHECKBOX, #CBS_CHECKEDNORMAL, rc, #Null);
  StopDrawing()
  
  ImageList_Add_(imagelist, ImageID(image), #Null)  
  
  SendMessage_(GadgetID(gadget), #LVM_SETIMAGELIST, #LVSIL_SMALL, imagelist)
  
EndProcedure

Procedure Main()
  Protected EventID
  
  If OpenWindow(0, 0, 0, 600, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    
    SetWindowCallback(@Callback(), 0)
    
    ListIconGadget(1, 10, 10, 580, 380, "Spalte 1", 150, #LVS_OWNERDATA | #PB_ListIcon_CheckBoxes |#PB_ListIcon_FullRowSelect|#PB_ListIcon_GridLines)
    AddGadgetColumn(1, 1, "Spalte 2", 100)
    AddGadgetColumn(1, 2, "Spalte 3", 100)
    AddGadgetColumn(1, 3, "Spalte 4", 100)
    AddGadgetColumn(1, 4, "Spalte 5", 100)    
    
    
    InitCheckBoxImageListForListIconGadgetHahaIstDasEinLangerNameObderNochLaengerWerdenDarfFragezeichen(1)
    SendMessage_(GadgetID(1), #LVM_SETITEMCOUNT, InitArray(), 0)
    
    Repeat      
    Until WaitWindowEvent() = #PB_Event_CloseWindow
    
    CloseThemeData_(Theme)
  EndIf
  
EndProcedure:End Main()

Re: ListIconGadget schnell mit 3700 Einträge füllen

Verfasst: 10.05.2016 12:26
von Kukulkan
Versuch doch mal das ListIcon Gadget durch das hier zu ersetzen:

http://www.purebasic.fr/english/viewtop ... 81#p471581

Da sind die 3'700 Einträge in 18ms drinnen. Und das Cross-Platform...

[EDIT]Ok, Checkboxen kann das (noch?) nicht...[/EDIT]

Grüße,

Kukulkan