Listicongadget simples Edit von Einträgen

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Hyper
Beiträge: 194
Registriert: 19.04.2005 19:14

Beitrag von Hyper »

Hallo hjbremer,

jetzt klappt es so, wie es soll. Feine Sache! Das baue ich bestimmt mal ein, nur noch die Variablendeklaration wegen EnableExplicit, aber sonst wirklich Klasse. Dickes Lob!
PB 5.72
MightyMAC
Beiträge: 55
Registriert: 07.01.2007 18:11
Wohnort: Duisburg
Kontaktdaten:

Re: Listicongadget simples Edit von Einträgen

Beitrag von MightyMAC »

Hallo,

ich habe mir diesen Code mal zu gemüte geführt und in mein kleines Proggie eingebaut. Jetzt hätte ich da mal eine kleine Frage. Ich möchte die Funktionalität für bestimmte Spalten erweitern, indem ich einen Browse-Button ("...") am Ende des Feldes einbaue. Das Einbauen hat auch geklappt und der Button wird rechts neben dem String-Gadget angezeigt, jedoch ist er nicht anklickbar, d.h. ein PB_Gadget_Event wird nicht ausgelöst.
Ich habe den Button analog zum String-Gadget eingebaut, also ihn zum Child-Objekt des ListIcon-Feldes gemacht. So sitzt er von der Position her an der richtigen Stelle, ist jedoch nicht anklickbar. Wenn ich ihn nicht zum Child mache kann ich ihn anklicken, er sitzt dann aber irgendwo in der Pampa.
Kann man nur ein Gadget zum Child eines anderen machen? Weiß da irgendjemand was?

Hier mal meine geänderte "lvedit"-Procedure:

Code: Alles auswählen

Procedure LvEdit1(event, selflag = 0, pointer = 0, font = -1)
Protected flag, x, y, br, hh, nix, iitem$, gadg
Protected rect.RECT
Protected point.POINT

Static lvid, lvnr, lvhd, lvrow, lvcol, editfeld, editfont, f2flag, brows
UseGadgetList(WindowID(#Window_Main))

If editfeld
  
   gadg=EventGadget() 

   Select event
           
     Case 161 ;Scrollbalken Keyup
          ;Edit beeenden
          flag = 3  

     
     Case #WM_KEYDOWN
          Debug "Key="+Str(EventwParam())
          ;Edit beeenden wenn ESC oder Return
          If EventwParam() = #VK_RETURN: flag = 2: EndIf
          If EventwParam() = #VK_ESCAPE: flag = 1: EndIf

          
     Case #PB_Event_Gadget 
       ;Edit beeenden wenn LostFocus 
       Debug "Gadget="+Str(gadg)
;       Debug "Browse="+Str(browse)
          If gadg = editfeld
;               If EventType() = #PB_EventType_LostFocus
;                  flag = 2
;               EndIf
          ElseIf gadg = brows
;              flag=2
              file.s=OpenFileRequester("Browse for voice-over soundfile",GetGadgetText(editfeld),"WME-Soundfiles (*.wav, *.ogg)|*.wav;*.ogg",0)
              If file<>""
                SetGadgetText(editfeld,file)
;                Redraw_Dialog(Akt_Dialog)
              EndIf  
          Else  ;oder irgendein anderes Gadget angeclickt
             flag = 2
          EndIf
          
          
     Case #PB_Event_Menu, #PB_Event_SysTray  ;bei Bedarf mehr Events
          flag = 2                           ;Edit beeenden
          
   EndSelect
   
   ;Header angeclickt ? wenn ja Edit Ende
   If GetCapture_() = lvhd: flag = 2: EndIf 
   
   If flag  ;Edit beenden
     
     Debug "Flag="+Str(flag)
     Editmodus=0
     SetGadgetState(lvnr,lvrow)
     
     ;Return gedrückt 
     If flag = 2 
        iitem$ = GetGadgetText(editfeld)
        SetGadgetItemText(lvnr, lvrow, iitem$, lvcol)
        Dialog(Akt_Dialog)\Line[lvrow]\Text=iitem$
        Debug "Line: "+Str(lvrow)+" = "+iitem$  
      EndIf
     
     ;neu zeichnen falls Liste verschoben
     If flag = 3
        SendMessage_(lvid, #WM_SETREDRAW, #True, 0) 
        InvalidateRect_(lvid, 0, #True)           
     EndIf
     
     FreeGadget(editfeld): editfeld = 0
     If IsGadget(brows)
        FreeGadget(brows): brows = 0
     EndIf  
     If font = -1: FreeFont(editfont): EndIf
     
   EndIf

ElseIf event = #PB_Event_Gadget
       
       lvnr = EventGadget() 
       If IsGadget(lvnr) = 0: ProcedureReturn -1: EndIf

;Debug "Editmode!"          
       If GadgetType(lvnr) = #PB_GadgetType_ListIcon ;And GadgetID(lvnr)=#ListIcon_Dialog;lvnr=#ListIcon_Dialog;
         If EventType() = #PB_EventType_LeftDoubleClick
           
                     
            lvid = GadgetID(lvnr) 
            lvhd = SendMessage_(lvid, #LVM_GETHEADER, 0, 0)
            
            LvMausclick(lvid, point)            
            If f2flag = 0
               lvcol = point\x
               lvrow = point\y
            Else
               lvrow = GetGadgetState(lvnr)    
            EndIf            
            If lvrow = -1: Editmode=0:ProcedureReturn -1: EndIf
            
               ok = LvCheckFeld(pointer, lvnr, lvcol, lvrow)
               ; ok gibt 2 zurück, wenn ein "Browse"-Button erzeugt werden soll
               If Not ok: Editmode=0:ProcedureReturn -1: EndIf
            
            Editmodus=1
            
            rect\top = lvcol
            rect\left = #LVIR_LABEL
            SendMessage_(lvid, #LVM_GETSUBITEMRECT , lvrow, rect) 
            
            InflateRect_(rect,1,1)  ;rect um 1 vergrößern    
                        
            x  = rect\left + 1 
            y  = rect\top 
            br = rect\right - rect\left 
            hh = rect\bottom - rect\top 
            
            iitem$ = GetGadgetItemText(lvnr, lvrow, lvcol)
            If ok=2
               brows = ButtonGadget(#PB_Any, x+br-20, y, 20, hh, "...")
               editfeld = StringGadget(#PB_Any, x, y, br-20, hh, iitem$)
               ;               Editmodus=2
               Debug "Browse="+Str(brows)
            Else   
               editfeld = StringGadget(#PB_Any, x, y, br, hh, iitem$)
            EndIf   
            
            If font = -1
               editfont = LoadFont(#PB_Any, "Arial", LvFontHoehe(lvnr) - 1)
            Else
               editfont = font
            EndIf
            If IsFont(editfont): SetGadgetFont(editfeld,FontID(editfont)): SetGadgetFont(brows,FontID(editfont)): EndIf
            
            If selflag = 1      ;ans Ende 
               SendMessage_(GadgetID(editfeld), #EM_SETSEL, Len(iitem$), -1)                
            ElseIf selflag = 2  ;ans Ende + alles markieren
               SendMessage_(GadgetID(editfeld), #EM_SETSEL, 0, -1) 
            EndIf
            
            ;sieht besser aus finde ich
            SetWindowTheme_(GadgetID(editfeld), @nix, @nix)  
            
            SetParent_(GadgetID(editfeld), lvid)  ;sehr wichtig
            If ok=2
               SetWindowTheme_(GadgetID(brows), @nix, @nix)  
               SetParent_(GadgetID(brows), lvid)  ;sehr wichtig
;               SetActiveGadget(brows)
            EndIf  
            SetActiveGadget(editfeld)
          EndIf
       EndIf     

EndIf

ProcedureReturn event
EndProcedure
Gruß
Mac
Windows XP 32-bit SP3, Windows 7 64-bit, PB 4.60, PB 5.11, PB 5.20
Benutzeravatar
X360 Andy
Beiträge: 1206
Registriert: 11.05.2008 00:22
Wohnort: Bodensee
Kontaktdaten:

Re: Listicongadget simples Edit von Einträgen

Beitrag von X360 Andy »

Hallo Zusammen,

auch wenn das Thema schon ein paar Jahre auf dem Buckel hat, ich finde nicht raus ... wieso es mit PB5.22 nicht mehr funktionieren möchte.
Das Edit String Gadget erscheint nicht mehr.

Jemand eine Idee ?

Ich teste / suche den Fehler im Beispielcode auf Seite 1

Grüße

Andreas
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 simples Edit von Einträgen

Beitrag von ts-soft »

PB_Gadget_SendGadgetCommand() ersetzen durch PostEvent()

Code: Alles auswählen

; ListIconGadget Felder editieren
;
; Aufruf: im Hauptprogramm nur eine Zeile einfügen, direkt nach
;         event = WaitWindowEvent() kommt
;         event = LvEdit1(event)
;
; zusätzlicher Parameter selflag 0, 1 oder 2
;         event = WaitWindowEvent()
;         event = LvEdit1(event, 1)
;         0 = Cursor am Anfang, nur nötig wenn font angegeben
;         1 = Cursor ans Ende
;         2 = Cursor ans Ende + Feldinhalt wird markiert
;
; zusätzlicher Parameter font
;         event = WaitWindowEvent()
;         event = LvEdit1(event, 0, fontnr)
;         Die fontnr muß eine PbNr sein, keine ID
;         Wird ein Font angegeben sollte dieser auch geladen sein.
;         Ohne fontnr wird ein etwas kleinerer Font geladen
;         
; mit Doppelclick auf ein Feld wird Edit aktiviert
; mit ESC oder ein Klick auf ein Feld/Gadget/Window wird Edit beendet
;
; NUR mit Return werden Eingaben übernommen !
;
; zusätzlicher Spielkram
; wenn eine Zeile markiert und F2 gedrückt wird,
; wird Edit aktiviert und zwar das Feld in dem die Maus sich befindet.
; Nun mit Pfeiltasten oder Maus eine andere Zeile wählen, F2 drücken
; und nächstes Feld in der gleichen Spalte bearbeiten.
; Diesen "F2-Modus" mit Doppelclick auf ein Feld wieder ausschalten

EnableExplicit

Procedure LvFontHoehe(pbnr)
  Protected lg.LOGFONT
  Protected fontid = GetGadgetFont(pbnr)
  Protected pixely = GetDeviceCaps_(GetDC_(0), #LOGPIXELSY)
  Protected retvalue = GetObject_(fontid, SizeOf(LOGFONT), lg)
  Protected fonthoehe = -MulDiv_(lg\lfHeight, 72, pixely)   
  
  ProcedureReturn fonthoehe
EndProcedure

Procedure LvMausclick(lvid,*p.Point)
  Protected lvhit.LVHITTESTINFO
  
  GetCursorPos_(*p)  ;wo ist Maus
  MapWindowPoints_(0, lvid, *p, 1)
  
  lvhit\pt\x = *p\x
  lvhit\pt\y = *p\y
  SendMessage_(lvid, #LVM_SUBITEMHITTEST, 0, lvhit)               
  
  *p\y = lvhit\iItem      ;row ab 0
  *p\x = lvhit\iSubItem   ;col ab 0
  
EndProcedure

Procedure LvEdit1(event, selflag = 0, font = -1)
  Protected flag, x, y, br, hh, nix, iitem$
  Protected rect.RECT
  Protected point.POINT
  
  Static lvid, lvnr, lvhd, lvrow, lvcol, editfeld, editfont, f2flag
  
  If editfeld 
    
    Select event
        
      Case 161 ;Scrollbalken Keyup
        ;Edit beeenden
        flag = 3 
        
      Case #WM_KEYDOWN
        ;Edit beeenden wenn ESC oder Return
        If EventwParam() = #VK_RETURN: flag = 2: EndIf
        If EventwParam() = #VK_ESCAPE: flag = 1: EndIf
        
      Case #PB_Event_Gadget
        ;Edit beeenden wenn LostFocus
        If EventGadget() = editfeld
          If EventType() = #PB_EventType_LostFocus
            flag = 1
          EndIf
        Else  ;oder irgendein anderes Gadget angeclickt
          flag = 1
        EndIf
        
      Case #PB_Event_Menu, #PB_Event_SysTray  ;bei Bedarf mehr Events
        flag = 1                           ;Edit beeenden
        
    EndSelect
    
    ;Header angeclickt ? wenn ja Edit Ende
    If GetCapture_() = lvhd: flag = 1: EndIf
    
    If flag  ;Edit beenden
      
      SetGadgetState(lvnr,lvrow)
      
      ;Return gedrückt
      If flag = 2
        iitem$ = GetGadgetText(editfeld)
        SetGadgetItemText(lvnr, lvrow, iitem$, lvcol)
      EndIf
      
      ;neu zeichnen falls Liste verschoben
      If flag = 3
        SendMessage_(lvid, #WM_SETREDRAW, #True, 0)
        InvalidateRect_(lvid, 0, #True)           
      EndIf
      
      FreeGadget(editfeld): editfeld = 0
      If font = -1: FreeFont(editfont): EndIf
      
    EndIf
    
  ElseIf event = #PB_Event_Gadget
    
    lvnr = EventGadget()
    If IsGadget(lvnr) = 0: ProcedureReturn -1: EndIf
    
    If GadgetType(lvnr) = #PB_GadgetType_ListIcon
      
      If EventType() = #PB_EventType_LeftDoubleClick
        
        lvid = GadgetID(lvnr)
        lvhd = SendMessage_(lvid, #LVM_GETHEADER, 0, 0)
        
        LvMausclick(lvid, point)           
        If f2flag = 0
          lvcol = point\x
          lvrow = point\y
        Else
          lvrow = GetGadgetState(lvnr)   
        EndIf           
        If lvrow = -1: ProcedureReturn -1: EndIf
        
        rect\top = lvcol
        rect\left = #LVIR_LABEL
        SendMessage_(lvid, #LVM_GETSUBITEMRECT , lvrow, rect)
        
        InflateRect_(rect,1,1)  ;rect um 1 vergrößern   
        
        x  = rect\left + 1
        y  = rect\top
        br = rect\right - rect\left
        hh = rect\bottom - rect\top
        
        iitem$ = GetGadgetItemText(lvnr, lvrow, lvcol)
        editfeld = StringGadget(#PB_Any, x, y, br, hh, iitem$)
        
        If font = -1
          editfont = LoadFont(#PB_Any, "Arial", LvFontHoehe(lvnr) - 1)
        Else
          editfont = font
        EndIf
        If IsFont(editfont): SetGadgetFont(editfeld,FontID(editfont)): EndIf
        
        If selflag = 1      ;ans Ende
          SendMessage_(GadgetID(editfeld), #EM_SETSEL, Len(iitem$), -1)               
        ElseIf selflag = 2  ;ans Ende + alles markieren
          SendMessage_(GadgetID(editfeld), #EM_SETSEL, 0, -1)
        EndIf
        
        ;sieht besser aus finde ich
        SetWindowTheme_(GadgetID(editfeld), @nix, @nix) 
        
        SetParent_(GadgetID(editfeld), lvid)  ;sehr wichtig
        SetActiveGadget(editfeld)
        
      EndIf
    EndIf     
    
  ElseIf event = #WM_KEYDOWN  ;etwas Spielkram
    
    If EventwParam() = #VK_F2
      lvnr = GetActiveGadget()
      If IsGadget(lvnr)
        If GadgetType(lvnr) = #PB_GadgetType_ListIcon
          f2flag = 1
          PostEvent(#PB_EventType_LeftDoubleClick, -1, GadgetID(lvnr))
        EndIf
      EndIf       
    EndIf
    
  ElseIf event = #WM_LBUTTONDBLCLK  ;beim nächsten Doubleclick auf null
    f2flag = 0   
  EndIf
  
  ProcedureReturn event
EndProcedure

DisableExplicit
;XIncludeFile "\Bremer\PureBasic430_Pbi\LvEdit1.pbi"

Enumeration
  #but1
  #lvg1
  #lvg2
  #lvg3
  #win1
  #font
  #font1
EndEnumeration

LoadFont(#font, "Arial", 10)
LoadFont(#font1, "Arial", 8)

OpenWindow(#win1,0,0,800,480,"ListIcon Gadget",#PB_Window_SystemMenu|1)

ButtonGadget(#but1,10,440,80,25,"Tue nix")

lvflags = #PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect|#PB_ListIcon_CheckBoxes ;|#LVS_NOCOLUMNHEADER)
ListIconGadget(#lvg1,10,10,280,400,"Spalte 0",140,lvflags)
AddGadgetColumn(#lvg1,1,"Spalte 1",55)
AddGadgetColumn(#lvg1,2,"Spalte 2",55)
SetGadgetFont(#lvg1,FontID(#font))
SetGadgetColor(#lvg1, #PB_Gadget_BackColor, #Yellow)

lvflags = #PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect|#LVS_NOCOLUMNHEADER
ListIconGadget(#lvg2,300,10,220,400,"Spalte 0",140,lvflags)
AddGadgetColumn(#lvg2,1,"Spalte 1",55)
SetGadgetFont(#lvg2,FontID(#font))

lvflags = #PB_ListIcon_GridLines
ListIconGadget(#lvg3,530,10,220,400,"Spalte 0",140,lvflags)
AddGadgetColumn(#lvg3,1,"Spalte 1",55)
SetGadgetFont(#lvg3,FontID(#font))

For i = 0 To 16
  nr$ = LSet(Str(i),3," ")
  txt$ = "Text in Zeile "+nr$+" in Spalte 0" + #LF$ + Str(Random(111))
  AddGadgetItem(#lvg1, -1, txt$)           
  AddGadgetItem(#lvg2, -1, txt$)           
  AddGadgetItem(#lvg3, -1, txt$)           
Next

;=====================================================

Repeat
  
  event = WaitWindowEvent(1)
  event = LvEdit1(event, 2)
  
  If Event = #PB_Event_Gadget Or Event = #PB_Event_Menu
    
    welcherButton = EventGadget()
    
    Select welcherButton
        
      Case #but1: Debug "Button 1 gedrückt"
        Case #lvg1: If EventType() = #PB_EventType_LeftClick
          ;LvMausclick kann auch separat benutzt werden
          LvMausclick(GadgetID(#lvg1),p.Point)
          Debug "lv1 " + Str(p\x) + " " + Str(p\y)
        EndIf                             
    EndSelect
    
  EndIf
  
Until event = #PB_Event_CloseWindow

End
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
X360 Andy
Beiträge: 1206
Registriert: 11.05.2008 00:22
Wohnort: Bodensee
Kontaktdaten:

Re: Listicongadget simples Edit von Einträgen

Beitrag von X360 Andy »

Ich danke für die Hilfe, allerdings ist es nur eine Teillösung.
Dadurch wird nun zwar wenn F2 gedrückt wird das Doppelcklick Event ausgeführt.

Aber eben noch nicht das eigentliche Problem das sich bei mir ( Windows 8 - 64 Bit bzw. 32 Bit 5.22 PB ) das Edit String Gadget nicht öffnet.

Grüße

Andreas

Edit
---
sehe gerade das es nur funktioniert wenn kein Text vorhanden ist in der Zelle.

Edit 2
---
Wenn ich das StringGadget ohne Text erstelle funktionier es...direkt nach dem erstellen setzte ich dann den Text und dann gehts ... sehr interessant

Code: Alles auswählen

iitem$ = GetGadgetItemText(lvnr, lvrow, lvcol)
        editfeld = StringGadget(#PB_Any, x, y, br, hh,"")
        SetGadgetText(editfeld,iitem$)
        If font = -1
          editfont = LoadFont(#PB_Any, "Arial", LvFontHoehe(lvnr) - 1)
        Else
          editfont = font
        EndIf
        If IsFont(editfont): SetGadgetFont(editfeld,FontID(editfont)): EndIf
        
        If selflag = 1      ;ans Ende
          SendMessage_(GadgetID(editfeld), #EM_SETSEL, Len(iitem$), -1)               
        ElseIf selflag = 2  ;ans Ende + alles markieren
          SendMessage_(GadgetID(editfeld), #EM_SETSEL, 0, -1)
        EndIf
        
        ;sieht besser aus finde ich
        SetWindowTheme_(GadgetID(editfeld), @nix, @nix) 
        
        SetParent_(GadgetID(editfeld), lvid)  ;sehr wichtig
        SetActiveGadget(editfeld)
      
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: Listicongadget simples Edit von Einträgen

Beitrag von GPI »

Kleiner Bugfix. Aus mir nicht ganz ersichtlichen Gründen darf man bei PB5.4 beim StringGadget nur einen Leerstring übergeben, ansonsten schließt sich das EditGadget sofort, mit SetGadgetText gehts dann, also so:

Code: Alles auswählen

iitem$ =GetGadgetItemText(lvnr, lvrow, lvcol)
        editfeld = StringGadget(#PB_Any, x, y, br, hh,"")
        SetGadgetText(editfeld,iitem$)
taucht später in PureBasic-CodeArchiv-Rebirth als \Gadgets\ListIconGadget\Simple_Editable_ListIconGadget[WIN].pbi auf.

Edit: Seite zwei übersehen, nichts für ungut :) - nichts für ungut.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Antworten