ListIconGadget - Einzelne Zelle markieren & editieren

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

ListIconGadget - Einzelne Zelle markieren & editieren

Beitrag von RSBasic »

Hallo Leute,

ich habe zurzeit folgendes Problem.
Ich weis nicht wie ich eine einzelne Zelle markieren soll.
Dazu möchte ich auch gerne den Eintrag editieren.

Entweder kann man nur die erste Zelle einer Zeile oder die ganze Zeile mit #PB_ListIcon_FullRowSelect markieren.

Habt ihr eine Lösung für mich, wie ich das am besten lösen kann?
(Wenn das mit WinAPI zu tun hat, dann verschiebe ich mein Thread)
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:

Beitrag von edel »

Dann verschieb mal ...

Es gibt ein beispiel von freak (codearchiv) womit du pruefen
kannst, welche Feld angeklickt wurde. Fuer den Rest gibt es
hier und im Englischen auch eniges. Einfach mal suchen...
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Beitrag von RSBasic »

@edel
>Dann verschieb mal ...
Ok habe ich und Danke

\\Edit:
Diese Aktion kann man folgendes realisieren:
http://www.purearea.net/pb/CodeArchiv/G ... ditable.pb

Aber nicht für mich.
Code ist zu umständlich groß für ein kleines Ergebnis.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Beitrag von hjbremer »

Hier ein Beispiel ohne Callback ! Besonders geeignet wenn man keine Lust hat einen vorhandenen Callback so umzubauen das das Beispiel aus dem Codearchiv mit den eigenem Callback funktioniert.

Es sieht auf den ersten Blick gewaltig aus, aber das meiste an Code braucht man sowieso.

Code: Alles auswählen

; HJ Bremer 
; Dez.2007
; OS: Windows

Declare   Api_WM_SetReDraw(IDnr)
Declare   Api_LVM_MousePosition(IDnr)
Declare   Api_LVM_SpaltenHoehe(IDnr)
Declare   Api_LVM_SpaltenBreite(IDnr, col)
Declare   Api_LVM_SetListZeilenHoehe(IDnr,hh)
Declare   LV_Edit(pbnr,ein,x=0,y=0)

#aus=1
#ein=0
#return=13

Enumeration
#list1_nr = 0 
#list2_nr 
#Edit_strg_nr

EndEnumeration

OpenWindow(0,0,0,300,500, "",#PB_Window_SystemMenu|#PB_Window_ScreenCentered) 
    
  CreateGadgetList(WindowID(0)) 
  
    ;Eingabefeld für Edit ListIcon
    StringGadget(#Edit_strg_nr,0,0,0,0,"")
    HideGadget(#Edit_strg_nr,#aus)
    
    ;1.Listicon
    listiconflag=#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection
    IDlist1_nr = ListIconGadget(#list1_nr,0,0,300,100, "1", 80, listiconflag) 
    AddGadgetColumn(#list1_nr, 1, "x", 80) 
    AddGadgetColumn(#list1_nr, 2, "y", 80) 
    AddGadgetColumn(#list1_nr, 3, "z", 80) 
    AddGadgetColumn(#list1_nr, 4, "u", 80) 
  
    AddGadgetItem(#list1_nr,0,"Links" + Chr(10) + "Rechts") 
    AddGadgetItem(#list1_nr,1,"Links" + Chr(10) + "Mitte") 
    
    Api_LVM_SetListZeilenHoehe(IDlist1_nr,20)
  
    ;2.Listicon
    listiconflag=#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection
    IDlist2_nr = ListIconGadget(#list2_nr,0,200,300,100, "2", 80, listiconflag) 
    AddGadgetColumn(#list2_nr, 1, "t", 80) 
    AddGadgetColumn(#list2_nr, 2, "z", 80) 
  
    For j=1 To 20
       AddGadgetItem(#list2_nr,-1,"1" + Chr(10) + "BlaBla" + Chr(10) + "xxxxx") 
    Next

  AddKeyboardShortcut(0, #PB_Shortcut_Return, #return)
  
Repeat  
    EventID=WaitWindowEvent()
    
    ;auf verlassen (event 160) oder verschieben (event 161) 
    ;eines Editfeldes im ListIconGadget reagieren = Ende Editmode
    ;besonders das Verschieben der Liste führt sonst zu Bildfehlern
    If eventID=161    ;160 
       If editflag
          editflag=0
          LV_Edit(editpbnr,editflag)
          Api_WM_SetReDraw(GadgetID(editpbnr))  ;wenn 161, dann muß Redraw sein
       EndIf
    
    ElseIf EventID = #PB_Event_Gadget Or EventID = #PB_Event_Menu ;Menu/Shortcut kann gleiche Nummer wie ein Gadget haben
      
      welcherButton=EventGadget()            
      
      Select welcherButton      
        
        Case #list1_nr
                                          
              listevent=EventType()   ;:Debug "list-event-"+Str(listevent)
                                                
              Select listevent
                  
                  ;linke Maustaste                  
                  Case 768 ;#PB_EventType_LeftClick erzeugt immer 0 + 768
                      
                  ;rechte Maustaste
                  Case #PB_EventType_RightClick          
                      
                  ;linke Maustaste Doppelklick
                  Case #PB_EventType_LeftDoubleClick          
                        
                          col = Api_LVM_MousePosition(IDlist1_nr)
                                                                          
                          Select col
                          
                              Case 0: MessageRequester("","verboten")
                              
                              Default
                              
                                  editflag=1            ;editflag muß hier gesetzt werden
                                  editpbnr=#list1_nr
                                  LV_Edit(editpbnr,editflag,0,0)     
                                  
                          EndSelect
                
              EndSelect ;von listevent              

        Case #list2_nr
                                          
              listevent=EventType()   ;:Debug "list-event-"+Str(listevent)
                                                
              Select listevent
                  
                  ;linke Maustaste                  
                  Case 768 ;#PB_EventType_LeftClick erzeugt immer 0 + 768
                      
                  ;rechte Maustaste
                  Case #PB_EventType_RightClick          
                      
                  ;linke Maustaste Doppelklick
                  Case #PB_EventType_LeftDoubleClick          
                        
                          col = Api_LVM_MousePosition(IDlist2_nr)
                                                                          
                          Select col
                          
                              Case 0: MessageRequester("","verboten")
                              
                              Default
                              
                                  editflag=1            ;editflag muß hier gesetzt werden
                                  editpbnr=#list2_nr
                                  LV_Edit(editpbnr,editflag,0,0)     
                                  
                          EndSelect
                
              EndSelect ;von listevent              
        
        Case #Edit_strg_nr
              
              ;wenn im Editmodus die Liste oder das Editfeld angeklickt wurde = Ende Editmode
              If editflag
                  If EventType() = #PB_EventType_LostFocus        
                    editflag=0
                    LV_Edit(editpbnr,editflag)
                  EndIf
              EndIf
      
              If editflag=0
                                                      
                  If editpbnr=#list1_nr
                      
                      ;welche Spalte wurde bearbeitet ?
                      col = GetGadgetData(#Edit_strg_nr)
                      zeile=GetGadgetState(#list1_nr)

                      ;es folgt die Auswertung der Eingabe
                      Select col
                                                
                        Case 1,2
                            ;hier kann eine Überprüfung hin
                            ;und bei Falscheingabe kann man edit_alt$ wieder einsetzen
                        
                      EndSelect
                      
                      SetActiveGadget(#list1_nr)
                  
                  ElseIf editpbnr=#list2_nr
                  
                      ;welche Spalte wurde bearbeitet ?
                      col = GetGadgetData(#Edit_strg_nr)
                      zeile=GetGadgetState(#list2_nr)

                      ;es folgt die Auswertung der Eingabe
                      Select col
                                                
                        Case 1,2
                        
                      EndSelect
                      
                      SetActiveGadget(#list2_nr)
                  
                  EndIf
              EndIf
              
        Case #return
              
              ;#return Abfrage muß sein, sonst wird bei Return Stringgadget nicht geschlossen
              
              If GetActiveGadget() = #Edit_strg_nr
                  editflag=0
                  LV_Edit(editpbnr,editflag)                  
              EndIf                

      EndSelect

    EndIf
    
Until EventID = #PB_Event_CloseWindow

End

;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Procedure   LV_Edit(pbnr,ein,x=0,y=0)

;simples Edit eines ListIcon Feldes

;Parameter: pbnr = List PB Gadgetnr
;           ein  = flag für Editmodus  ein/aus
;           x + y werden zur Posi addiert zwecks Positionierung falls nötig         

Shared edit_alt$      ;wegen/falls Eingabekontrolle

Static row, col       ;muß static sein wegen Ende Edit um neuen Text anzuzeigen

IDLst=GadgetID(pbnr)  ;:Debug IDLst
  
If ein 

  SetParent_(GadgetID(#edit_strg_nr), IDlst)

  row = GetGadgetState(pbnr)  ;:Debug row
  
  If row > -1
      col = Api_LVM_MousePosition(IDLst)
      br  = Api_LVM_SpaltenBreite(IDLst,col)
      hh  = Api_LVM_SpaltenHoehe(IDLst)
      
      ;Position des Feldes holen, geht auch mit PB aber so ist einfacher
      rc.RECT 
      rc\top = col 
      SendMessage_(IDLst, #LVM_GETSUBITEMRECT, row, rc) 
      
      ;Eingabefeld positionieren und anzeigen
      ResizeGadget(#Edit_strg_nr,rc\left+x+1,rc\top+y,br+2,hh+2)
      edit_alt$=GetGadgetItemText(pbnr,row,col)
      SetGadgetText(#Edit_strg_nr,edit_alt$)
      HideGadget(#Edit_strg_nr,#ein)
      
      ;Cursor hinter den Text stellen
      SetActiveGadget(#Edit_strg_nr) 
      lg = Len(GetGadgetText(#Edit_strg_nr)) 
      SendMessage_(GadgetID(#Edit_strg_nr),#EM_SETSEL,lg,lg)
      
      SetGadgetData(#Edit_strg_nr,col)
      
  EndIf
  
Else

  DisableGadget(pbnr,#ein)
  HideGadget(#Edit_strg_nr,#aus)
  
  txt$=GetGadgetText(#Edit_strg_nr)
  SetGadgetItemText(pbnr, row, txt$, col)
  SetGadgetState(pbnr,row)
  SetActiveGadget(pbnr)

EndIf

EndProcedure

Procedure   Api_WM_SetReDraw(IDnr)
    
  SendMessage_(IDnr, #WM_SETREDRAW, #True, 0) 
 
  InvalidateRect_(IDnr, 0, #True) 

EndProcedure
Procedure   Api_LVM_MousePosition(IDnr)
  
  GetCursorPos_(@cp.POINT) 
  MapWindowPoints_(0,IDnr,@cp,1) 

  HitInfo.LVHITTESTINFO 
  
  Hitinfo\pt\x = cp\x 
  HitInfo\pt\y = cp\y 
  SendMessage_(IDnr,#LVM_SUBITEMHITTEST ,0,@HitInfo) 
  
  row = hitinfo\iitem 
  col = hitinfo\isubitem 
  
  ProcedureReturn col
      
EndProcedure      
Procedure   Api_LVM_SpaltenBreite(IDnr, col)

;gibt die Breite einer bestimmten Spalte des Listicon zurück

;Parameter: pbnr = PB Gadgetnr
;           col  = Spalte
  
  breite = SendMessage_(IDnr,#LVM_GETCOLUMNWIDTH,col,0)

ProcedureReturn breite

EndProcedure
Procedure   Api_LVM_SpaltenHoehe(IDnr)

;gibt die Höhe einer Spalte des Listicon zurück

;Parameter: pbnr = PB Gadgetnr
  
  SendMessage_(IDnr,#LVM_GETITEMRECT,0,r.rect)
   
  hoehe = r\bottom - r\top 

ProcedureReturn hoehe

EndProcedure
Procedure   Api_LVM_SetListZeilenHoehe(IDnr,hh)

  ImageHandle = ImageList_Create_(0, hh, #ILC_COLORDDB, 0, 0) 
  SendMessage_(IDnr, #LVM_SETIMAGELIST, #LVSIL_SMALL, ImageHandle) 

EndProcedure
Ist zwar nicht ganz perfekt, aber für den Hausgebrauch eignet es sich ganz gut. Außerdem man kann es noch stark verbessern. Wer Lust dazu hat ! z.B. die Prozedur mit der Mouseposition gibt nur die Spalte zurück. Oder einen TAB einbauen. Oder den schnellen Zeilenwechsel per Doppelclick.

Eine einzelne Zelle markieren, das geht zwar auch relativ einfach mit den Farbbefehlen von PB, allerdings ist mir der Aufwand zu hoch. Das ist mit einen CallBack einfacher. Siehe Beispiel aus dem Codearchiv. Wie gesagt wer Lust dazu hat.
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
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Beitrag von RSBasic »

@hjbremer
Erstmal vielen Dank für dein Code. :allright:
Ich werde erstmal schauen, was ich da machen kann.
Benutzeravatar
Shardik
Beiträge: 746
Registriert: 25.01.2005 12:19

Beitrag von Shardik »

Im englischen Forum finden sich auch noch andere interessante Beiträge, wie der komplette Thread zum Editieren von Zellen in ListIcon-Gadgets von srod:
http://www.purebasic.fr/english/viewtopic.php?t=27012

oder dieser Thread, in dem mehrere (auch kürzere) Lösungsmöglichkeiten gezeigt werden:
http://www.purebasic.fr/english/viewtopic.php?t=23673
Antworten