etwas modernisiert und wichtig war mir klein, relativ simpel und kein Callback und Felder sperren.
ohne Callback gibt es natürlich einige Einschränkungen was Edit der Felder angeht, aber dann wäre es nicht mehr klein. Mehr geht immer.
zuerst ein kleines Demoprog
dann das Modul, habe es ListIconEdit.pbi genannt
Code: Alles auswählen
XIncludeFile "ListIconEdit.pbi" ;12.08.2022
EnableExplicit
Enumeration 10
#window
#liste1
#liste2
EndEnumeration
Define fontStd = LoadFont(#PB_Any, "Calibri", 11)
OpenWindow(#window, 0, 0, 820, 600, "LV Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ListIconGadget(#liste1, 5, 5, 500, 590, "Column 0", 125, #PB_ListIcon_FullRowSelect|#PB_ListIcon_GridLines)
ListIconGadget(#liste2, 510, 5, 300, 590, "Col 0", 60, #PB_ListIcon_FullRowSelect|#PB_ListIcon_GridLines)
SetGadgetFont(#liste1, FontID(fontStd)) ;zu empfehlen, für mich old man sonst zu klein
SetWindowTheme_(GadgetID(#liste1), "explorer", 0) ;sieht besser aus finde ich
Define j, jahr, zahl
For j = 1 To 15
AddGadgetColumn(#liste1, j, "Col " + Chr(j+64), 75)
AddGadgetColumn(#liste2, j, "Col " + Str(j), 55)
Next
For j = 0 To 30
jahr = Random(2022, 2010)
zahl = Random(6000, 1000)
AddGadgetItem(#liste1, -1, "Col 0/" + Str(j) + #LF$ + Str(jahr) + #LF$ + Str(zahl) + #LF$ + Str(zahl*2))
AddGadgetItem(#liste2, -1, "Col 0/" + Str(j) + #LF$ + Str(jahr) + #LF$ + Str(zahl) + #LF$ + Str(zahl*2))
Next
SetListAlign(#liste1, 1, #LVCFMT_RIGHT)
SetListAlign(#liste1, 2, #LVCFMT_RIGHT)
setEditOk(#liste1, "x-bcdefghi") ;die 2. Spalte gesperrt für Edit(Strich oder Space), dann bis i erlaubt, Rest gesperrt
setEditOk(#liste2, " xxx") ;die 1. Spalte gesperrt, 2.+3.+4. erlaubt, Rest gesperrt da nicht definiert
;-Repeat Event
Define event
Repeat
event = WaitWindowEvent()
event = ListIconEdit(event)
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case #liste1
If EventType() = #PB_EventType_LeftDoubleClick
Debug "EventType: " + "#PB_EventType_LeftDoubleClick"
ElseIf EventType() = #PB_EventType_Input
Debug "#PB_EventType_Input"
Debug "row = " + GetGadgetState(#liste1)
Debug "col = " + EventData()
Debug GetGadgetItemText(#liste1, GetGadgetState(#liste1), EventData())
EndIf
EndSelect
EndSelect
Until Event = #PB_Event_CloseWindow
Code: Alles auswählen
;{ Info
;-Info ListIconEdit.pbi
; Include für ListIconGadget um Felder zu editieren, ist klein, einfach und simpel, für kleinere Listen gedacht.
;
; V 2.01 2009/2022 by HJBremer - getestet PB 5.70x86 5.72x64 6.00x64 Unicode Windows 64 Bit !!!!!!
;
; das Original wurde von mir 2009 veröffentlich und nun von mir überarbeitet
; Original siehe http://forums.purebasic.com/german/viewtopic.php?t=20818
; Aufruf: im Hauptprogramm nur eine Zeile einfügen, direkt nach
; event = WaitWindowEvent()
; kommt event = ListIconEdit(event)
; in ALLEN ListIcongadgets können dann Felder via Doppelclick bearbeitet werden !!!
;
; zusätzlicher Parameter selflag 0, 1 oder 2, gilt für alle Listen
; event = ListIconEdit(event, 2)
; 0 = Cursor am Anfang, 1 = ans Ende, ist Vorgabe !!!
; 2 = Cursor ans Ende + Feldinhalt wird markiert
;
; mit Doppelclick auf ein Feld wird Edit aktiviert
; mit ESC oder ein Klick auf ein Feld/Gadget/Window oder Zeile wird Edit beendet, siehe exitflag
;
; !!! NUR mit Return werden Eingaben übernommen !!!
; und ein EventType() = #PB_EventType_Input wird gesendet incl. die Column als EventData()
;
;SetEditOk(pbnr, ok.s)
; dient dazu bestimmte Spalten oder alle einer Liste zu sperren
; pbnr = GadgetNummer der Liste
; ok.s = ein Strich/Leerzeichen oder keine Angabe sperrt die Spalte
;
; SetEditOk(#liste2, "x x") ;die 1. + 3. Spalte erlaubt, Rest gesperrt !!!
; SetEditOk(#liste1, "x-xxx") ;die 2. Spalte gesperrt mit Info
; SetEditOk(#liste5, "") ;alle Spalten gesperrt für Edit
;
; Strich (Minus) für gesperrt = es erscheint eine Info "ist gesperrt", Leerzeichen keine Info.
; gibt es mehr Spalten als man im ok.s angegeben hat werden diese gesperrt
; wenn eine Spalte gesperrt ist, gibt es beim Doubleclick immer das entsprechende Eventtype()
;Hinweis:
; wenn die 2 EnableScrollBar_() Befehle aktiviert sind, kann man nicht Horz. scrollen wenn Edit aktiv,
; denn das scrollen verursacht Drawfehler, sieht etwas doof aus.
; Da PB die Scrollevents nicht sofort rausrückt, weiß ich nicht wie man das abstellt, außer man hat einen Callback.
;}
;-Modul
DeclareModule ListIconEdit
Declare.i ListIconEdit(event, selflag = 1)
Declare.i SetEditOk(pbnr, ok.s)
Declare.i SetListAlign(pbnr, column, align)
EndDeclareModule
Module ListIconEdit
EnableExplicit
Procedure.i GetGadgetColumn(pbnr) ;intern
Protected lvid = GadgetID(pbnr), lvhit.LVHITTESTINFO
GetCursorPos_(lvhit\pt) ;wo ist Maus on Screen
ScreenToClient_(lvid, lvhit\pt) ;Mausposi in Liste
SendMessage_(lvid, #LVM_SUBITEMHITTEST, 0, lvhit)
ProcedureReturn lvhit\iSubItem ;Column ab null zurückgeben
EndProcedure
;EditOk Proceduren
Structure EditOk
pbnr.l ;PB-Nummer der Liste für Abfrage in GetEditOk()
ok.s ;Ok-String (die Abfrage via Mid() ergibt Null wenn ok.s zu klein ist)
EndStructure
Global NewList editok.EditOk()
Procedure.i GetEditOk(pbnr, col, editfeld = 0) ;intern, überprüft ob column gesperrt
Protected iitem$, okchar, ok = #True
ForEach editok()
If editok()\pbnr = pbnr
okchar = Asc(Mid(editok()\ok, col+1, 1)) ;col+1 weil Mid() bei 1 beginnt, Listen bei null
If editfeld = 0 ;wenn null dann Abfrage ob Column gesperrt.
Select okchar
Case 45: ok = #PB_Ignore: MessageRequester("Info", "bearbeiten gesperrt"): Break ;45=Strich (Minus)
Case 0,32: ok = #PB_Ignore: Break ;0=nicht definiert, 32=Leerzeichen
EndSelect
EndIf
EndIf
Next
ProcedureReturn ok
EndProcedure
Procedure.i SetEditOk(pbnr, ok.s)
Protected found = #False
ForEach editok()
If editok()\pbnr = pbnr ;falls schon vorhanden dann ändern
editok()\ok = ok: found = #True
EndIf
Next
If found = #False ;wenn noch nicht vorhanden dann neu
AddElement(editok())
editok()\pbnr = pbnr: editok()\ok = ok
EndIf
EndProcedure
Procedure.i SetListAlign(pbnr, column, align)
Protected lv.LV_Column\mask = #LVCF_FMT
lv\fmt = align ;#LVCFMT_LEFT=0, #LVCFMT_RIGHT=1, #LVCFMT_CENTER=2
SendMessage_(GadgetID(pbnr), #LVM_SETCOLUMN, column, lv) ;LVCFMT_FIXED_WIDTH = $100
EndProcedure
;-Edit Procedure
Procedure ListIconEdit(event, selflag = 1)
Protected exitflag, iitem$, r.RECT
Static lvnr, lvrow, lvcol, editfeld
If editfeld ;wenn es ein Editfeld gibt
Select event
Case #PB_Event_Gadget ;Edit beeenden wenn LostFocus
If EventGadget() = editfeld
If EventType() = #PB_EventType_LostFocus
exitflag = 1
EndIf
EndIf
Case #WM_KEYDOWN ;Edit beeenden wenn ESC oder Return
If EventwParam() = #VK_ESCAPE: exitflag = 1: EndIf
If EventwParam() = #VK_RETURN: exitflag = 2: EndIf
Case #WM_NCLBUTTONDOWN ;Maustaste gedrückt im NichtClientBereich z.B. Scrollbalken etc
exitflag = 1
SendMessage_(GadgetID(lvnr), #WM_SETREDRAW, #True, 0) ;neu zeichnen falls Liste verschoben
InvalidateRect_(GadgetID(lvnr), 0, #True)
Case #WM_MOUSEWHEEL, #PB_Event_Menu, #PB_Event_SysTray ;bei Bedarf mehr Events für Abbruch
exitflag = 1
EndSelect
If exitflag ;Edit beenden
If exitflag = 2 ;Return gedrückt = Daten übernehmen + #PB_EventType_Input senden
GetEditOk(lvnr, lvcol, editfeld)
iitem$ = GetGadgetText(editfeld)
SetGadgetItemText(lvnr, lvrow, iitem$, lvcol) ;dann EventType() senden
PostEvent(#PB_Event_Gadget, EventWindow(), lvnr, #PB_EventType_Input, lvcol)
EndIf
FreeGadget(editfeld): editfeld = 0
SetGadgetState(lvnr, lvrow)
EnableScrollBar_(GadgetID(lvnr), #SB_HORZ, #ESB_ENABLE_BOTH)
EndIf
ElseIf event = #PB_Event_Gadget ;wenn es noch kein Editfeld gibt dann erstellen
lvnr = EventGadget() ;Gadget Nummer holen
If IsGadget(lvnr) = 0: ProcedureReturn -1: EndIf ;falls es kein gültiges Gadget ist
If GadgetType(lvnr) = #PB_GadgetType_ListIcon ;wenn ein ListIconGadget
If EventType() = #PB_EventType_LeftDoubleClick
lvrow = GetGadgetState(lvnr) ;in welcher Zeile
lvcol = GetGadgetColumn(lvnr) ;in welcher Spalte Doubleclick
If lvrow = -1: ProcedureReturn event: EndIf ;wenn -1, z.B. Header angeclickt
If GetEditOk(lvnr, lvcol) = #PB_Ignore: ProcedureReturn event: EndIf ;gesperrt
r\top = lvcol: r\left = #LVIR_LABEL ;Vorgaben für #LVM_GETSUBITEMRECT
SendMessage_(GadgetID(lvnr), #LVM_GETSUBITEMRECT, lvrow, r) ;Größe holen
iitem$ = GetGadgetItemText(lvnr, lvrow, lvcol) ;Text als Vorgabe + Gadget erstellen
editfeld = StringGadget(#PB_Any, r\left, r\top, r\right-r\left-1, r\bottom-r\top-1, iitem$)
SetParent_(GadgetID(editfeld), GadgetID(lvnr)) ;sehr wichtig, editfeld wird Teil der Liste
SetGadgetFont(editfeld, GetGadgetFont(lvnr)) ;Font der Liste dem editfeld zuweisen
SetActiveGadget(editfeld)
If selflag = 1
SendMessage_(GadgetID(editfeld), #EM_SETSEL, Len(iitem$), -1) ;Cursor ans Ende
ElseIf selflag = 2
SendMessage_(GadgetID(editfeld), #EM_SETSEL, 0, -1) ;ans Ende + alles markieren
EndIf
SetGadgetState(lvnr, -1) ;während der Eingabe Selectbalken weg, wird von exitflag wieder hergestellt
EnableScrollBar_(GadgetID(lvnr), #SB_HORZ, #ESB_DISABLE_BOTH) ;scrollen Horizontal aus
EndIf
EndIf
EndIf
ProcedureReturn event
EndProcedure
EndModule
UseModule ListIconEdit