ListIconGadget schnell mit 3700 Einträge füllen

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

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

Beitrag 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
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

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

Beitrag 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
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
Kiffi
Beiträge: 10621
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

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

Beitrag 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
Hygge
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

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

Beitrag 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!
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
mhs
Beiträge: 224
Registriert: 11.01.2009 16:30
Wohnort: Graben
Kontaktdaten:

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

Beitrag 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...
Michael Hack

Michael Hack Software :: Softwareentwicklung | Webentwicklung | IT-Dienstleistungen
www.michaelhacksoftware.de :: www.mh-s.de :: www.michael-hack.de
Benutzeravatar
Kiffi
Beiträge: 10621
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

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

Beitrag von Kiffi »

@ts-soft & mhs: Danke für die Richtigstellung!

Grüße ... Peter
Hygge
Joshua314
Beiträge: 115
Registriert: 06.04.2005 22:44

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

Beitrag 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
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

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

Beitrag 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?
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

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

Beitrag 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()
Benutzeravatar
Kukulkan
Beiträge: 1066
Registriert: 09.09.2004 07:07
Wohnort: Süddeutschland
Kontaktdaten:

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

Beitrag 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
Antworten