Listicon Gadget

Anfängerfragen zum Programmieren mit PureBasic.
a14xerus
Beiträge: 1440
Registriert: 14.12.2005 15:51
Wohnort: Aachen

Listicon Gadget

Beitrag von a14xerus »

Ich Suche eine Möglichkeit ein ListiconGadget so wie in jedem normalen Windowsprogram üblichen Stil zu sortieren.
Sprich ein klick auf die Titel-Leiste sorgt für eine Sortierung des Inhalts.

Dabei geht es mir nichtmals vorrangig um die Sortierung, sondern um das Layout..

Also das so ein kleines Dreieck angezeigt wird in der jeweiligen Titelspalte, und das ich dieses Event halt bekomme.
Sortieren kann ich auch selber, falls es noch keine Funktion dafür gibt :)
Bild

Und wenn ihr ganz nett seit (und wisst wie es geht), könntest ihr mir noch verraten, wie man ein DropdownMenü ausgehend von einer Titel-Spalte anzeigt ;)
Das wäre aber nur 2.rangig
Bild
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Re: Listicon Gadget

Beitrag von hjbremer »

folgender Apibefehl ist dafür zuständig

Code: Alles auswählen

;Pfeil im Header Windows XP
#HDF_SORTDOWN = $200 
#HDF_SORTUP = $400 

HD_ITEM.HD_ITEM
HD_ITEM\mask=#HDI_FORMAT
SendMessage_(hdid, #HDM_GETITEM, col, HD_ITEM) 

If HD_ITEM\fmt & #HDF_SORTDOWN
   HD_ITEM\fmt ! #HDF_SORTDOWN
   HD_ITEM\fmt | #HDF_SORTUP  
   richtung = #PB_Sort_Ascending
ElseIf HD_ITEM\fmt & #HDF_SORTUP
   HD_ITEM\fmt ! #HDF_SORTUP
   HD_ITEM\fmt | #HDF_SORTDOWN  
   richtung = #PB_Sort_Descending
Else
   HD_ITEM\fmt | #HDF_SORTDOWN  
   richtung = #PB_Sort_Descending
EndIf   

SendMessage_(hdid, #HDM_SETITEM, col, HD_ITEM)
Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Listicon Gadget

Beitrag von Kiffi »

@a14xerus: Falls Du nichts gegen UserLibs hast, könnte
ich PureLVSORT von gnozal empfehlen:

http://gnozal.ucoz.com/#UserLibs

Grüße ... Kiffi
a²+b²=mc²
a14xerus
Beiträge: 1440
Registriert: 14.12.2005 15:51
Wohnort: Aachen

Re: Listicon Gadget

Beitrag von a14xerus »

@ kiffi: die lib kenne ich, war mir aber zuuuu .. "exotisch"
ne quatsch.. hab halt nach genau soetwas gesucht das hjbremer mit geliefert hat.
Also dieses "native" was schon in Windows eingebaut ist. Sortieren kann ich ja, da ich ja sowieso die Daten intern immer in LL verwalte.

@hjbremer
Danke ist schonmla die hälfte :)


Weiß jetzt noch jemand wie ich das Event abfange, auf welche Column geklickt wurde? (Also auf welchen Titel-eintrag)
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Re: Listicon Gadget

Beitrag von hjbremer »

Das mit dem Headerclick ist im Prinzip simpel, aber auch knifflig,
denn man muß einen Click zum Sortieren von einem Click zum Verschieben der Spalten
oder Drag Drop von Spalten unterscheiden.

Zuerst der Headerclick ohne Callback

Code: Alles auswählen

Procedure.i MainListeHeaderClick()
With pv.myProgrammvariablen

Protected spalte = -1   
Protected p.POINT  
Protected HitInfo.HD_HITTESTINFO 
Protected flags, iitem

  If GetCapture_() = \headerid
     GetCursorPos_(p) 
     MapWindowPoints_(0,\headerid,p,1) ;hwndfrom muß null sein !        
     Hitinfo\pt\x = p\x 
     HitInfo\pt\y = p\y 
     SendMessage_(\headerid,#HDM_HITTEST,0,HitInfo)        
     flags = hitinfo\flags      ;:Debug "flags " + Str(flags)
     iitem = hitinfo\iitem      ;:Debug "iitem " + Str(iitem)
     If flags = #HHT_ONHEADER
        spalte = iitem  
     ElseIf flags = #HHT_ONDIVOPEN And iitem = 0
        \headernull = 1  ;es wird versucht 
     EndIf               ;die Breite von Spalte 0 zu ändern
  EndIf

EndWith
  
ProcedureReturn spalte 
EndProcedure
Und nun die Events abfangen

Code: Alles auswählen

Procedure.i WM_events(event)
Protected point.Point, j
Static spalte 

Select event
        
   ;für Mainliste per Headerclick sortieren         
   Case #WM_LBUTTONDOWN ;linke Maustaste gedrückt
      ;Rückgabe ist -1 oder Spaltennr. ab 1. Spalte null wird nicht benutzt.
      spalte = MainListeHeaderClick() 
                 
   Case #WM_MOUSEMOVE ;wenn zwischen #WM_LBUTTONDOWN + #WM_LBUTTONUP ein move, 
      spalte = -1     ;dann Aktion = Drag/Drop oder Breite ändern
       
   Case #WM_LBUTTONUP   ;nur wenn zwischen down + up kein move, dann sortieren
      If spalte > -1
         MainListeHeaderSort(spalte)
      ElseIf pv\headernull   ;wird in MainListeHeaderClick() ev. gesetzt
         pv\headernull = 0
         SetGadgetItemAttribute(#main_liste, 0, #PB_ListIcon_ColumnWidth, 0, 0)
      EndIf   
       
EndSelect

EndProcedure
in der Main Repeat Schleife sieht es etwa so aus um WM_events(event) einzubinden

Code: Alles auswählen

Repeat: event = WaitWindowEvent() ;: Debug event
   
   WM_events(event)
           
   Select event          
                  
      Case #PB_Event_Gadget, #PB_Event_Menu  
         
         wB = EventGadget()
               
         Datei_Events(wB)
         Daten_Events(wB)
         
         If wB = #menu_progende: event = #PB_Event_CloseWindow: EndIf
           
   EndSelect
   
Until event = #PB_Event_CloseWindow 
PS: mit Callback ist es einen Tick einfacher, aber der Weg ist der Gleiche

Das Problem ist ein #WM_MOUSEMOVE zwischen #WM_LBUTTONDOWN + #WM_LBUTTONUP
bei Drag und Drop, falls Drag Drop denn erlaubt wurde
Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
a14xerus
Beiträge: 1440
Registriert: 14.12.2005 15:51
Wohnort: Aachen

Re: Listicon Gadget

Beitrag von a14xerus »

danke danke danke :)

ich bau's gleich mal ein und schmöker etwas durch den code um ihn in mich aufzusaugen wie in schwamm :D

Drag and Drop brauche ich erstmal nicht (zum glück^^;) )
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Re: Listicon Gadget

Beitrag von hjbremer »

Hab vergessen zu posten wie man die Headerid bekommt, falls du es nicht wissen solltest

Code: Alles auswählen

headerid = SendMessage_(Gadgetid(lvpbnr), #LVM_GETHEADER, 0, 0) 
Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
a14xerus
Beiträge: 1440
Registriert: 14.12.2005 15:51
Wohnort: Aachen

Re: Listicon Gadget

Beitrag von a14xerus »

Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Re: Listicon Gadget

Beitrag von hjbremer »

a14xerus hat geschrieben: Und wenn ihr ganz nett seit (und wisst wie es geht), könntest ihr mir noch verraten, wie man ein DropdownMenü ausgehend von einer Titel-Spalte anzeigt
Dies geht eigentlich sinnvoll nur über Subclassing des Headers. Wenn man mehrere Listicongadgets hat muß man noch hwnd des Callbacks mit den Headerids vergleichen.

ein simples Beispiel, welches bei Rightclick auf den Header ein PopUp anzeigt
je nach Spalte ein anderes.

Code: Alles auswählen

;Rightclick on LvHeader mit PopUpMenu

#window   = 0 
#listview = 0 
  
Procedure myLvHeaderCallback(hwnd, msg, wParam, lParam) 
Protected old = GetWindowLongPtr_(hwnd,#GWL_USERDATA) 
Protected hd.HD_HITTESTINFO 
    
If msg = #WM_RBUTTONDOWN 
      
   hd\pt\x = lParam & $FFFF 
   hd\pt\y = (lParam >> 16) & $FFFF 
   SendMessage_(hwnd, #HDM_HITTEST, 0, hd) 
   
   DisplayPopupMenu(hd\iItem, hwnd)

EndIf 
    
ProcedureReturn CallWindowProc_(old, hwnd, msg, wParam, lParam) 
EndProcedure 
  
Procedure SubClassHeader(pbnr) 
If IsGadget(pbnr) 
   Protected id  = SendMessage_(GadgetID(pbnr), #LVM_GETHEADER, 0, 0) 
   Protected old = SetWindowLongPtr_(id, #GWL_WNDPROC, @myLvHeaderCallback()) 
   Protected prv = SetWindowLongPtr_(id, #GWL_USERDATA, old) 
EndIf 
EndProcedure 
  
  
OpenWindow(#window, 0, 0, 300, 400, "LvTest", 1) 
 
   ListIconGadget(#listview, 0, 0, 400, 400, "col 0", 150)
   SubClassHeader(#listview) 
   AddGadgetColumn(#listview, 1, "col 1", 150) 
  
   CreatePopupMenu(0)
   MenuItem(1001, "Hallo")
   MenuItem(1002, "Du da")

   CreatePopupMenu(1)
   MenuItem(1101, "Guten Tag")
   MenuItem(1102, "Guten Abend")

Repeat: Until WaitWindowEvent() = #PB_Event_CloseWindow 
Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Antworten