simple Adressverwaltung für PB Demoversion 4.3 x86

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Beitrag von hjbremer »

kleines Update. Programm merkt sich die letzten 10 Dateien. Simpel aber auch wieder nicht.

Voraussetzung letztes Update vom 9.5.

Es folgen die Änderungen und 3 neue Proceduren. Hoffe ich habe alle Änderungen erwischt.

1.eine Konstante und erweiterte Struktur um 4 Werte am Ende

Code: Alles auswählen

#lastfilesmax = 9

Structure myProgrammvariablen
  dateiname.s
  desktopbreite.i     ;Breite des Monitors in Pixel
  desktophoehe.i      ;Höhe
  windowbreite.i      ;
  windowhoehe.i       ;
  subwindowx.i        ;
  subwindowy.i        ;
  buttonbr.i          ;Buttonbreite
  buttonhh.i          ;
  datensatz.s         ;letzter geladener, bearbeiteter Datensatz
  eingabeitem.i       ;
  suchmodus.i         ;enthalten im ganzen Datensatz oder im Feld
  suchwort.s
  suchsatz.s
  suchitem.i
  suchgk.i            ;bei Suche Groß/Kleinschrift beachten
  suchlv.i            ;
  suchart.s           ;für verschiedene Sucharten, in dieser Version nur eine
  feldanzahl.i        ;
  feldnamen.s[#maxfelder+1]     ;Platz für Felder reservieren = 0 - 20
  feldbreite.i[#maxfelder+1]    ;wir benutzen Feld null allerdings nicht
  eingabepbnr.i[#maxfelder+1]   ;für Identnummern der StringGadgets = Eingabefelder
  orderarray.i[#maxfelder+1]    ;für Drag and Drop = verschieben der Spalten
  titelflag.i                   ;für diverse Spalten Funktionen
  inidatei.s                    ;Name der Inidatei
  lastenumeration.i             ;
  lastfiles.s[#lastfilesmax+1]  ;für Menu Letzte Dateien
  lastmenunr.i[#lastfilesmax+1] ;
EndStructure
2.Menu erweitern um OpenSubMenu und einen Aufruf

Code: Alles auswählen

    CreateMenu(0, WindowID(#window_main))
      MenuTitle("&Datei")
        MenuItem( #menu_new,  "&Neu")
        MenuItem( #menu_load, "Ö&ffnen" + #TAB$ + "Strg+O")
        MenuItem( #menu_save, "&Speichern" + #TAB$ + "Strg+S")
        MenuItem( #menu_save1, "Speichern &als...")
        MenuBar()
        OpenSubMenu("letzte Dateien")
          For j = 0 To #lastfilesmax
            MenuItem( prgv\lastmenunr[j], "")
          Next
        CloseSubMenu()                    
        MenuBar()
        MenuItem( #menu_load1, "Öffnen ohne Titel")
        MenuBar()
        MenuItem( #menu_ende, "&Beenden" + #TAB$ + "Alt+F4")
      MenuTitle("&Bearbeiten")
        MenuItem( #menu_neu, "&Neu" + #TAB$ + "Strg+N")
        MenuItem( #menu_edit, "&ändern")
        MenuItem( #menu_kill,"&löschen")
      MenuTitle("&Suchen")
        MenuItem( #menu_such1, "&Suchen" + #TAB$ + "Strg+F / F4")
        MenuItem( #menu_such2, "Suchen im &Feld")
        MenuItem( #menu_suchN, "&Weitersuchen" + #TAB$ + "F3")
      MenuTitle("S&ortieren")
        MenuItem( #menu_sort, "sortieren")
      MenuTitle("&Optionen")
        MenuItem( #menu_titel, "Spaltennamen ändern")
        MenuItem( #menu_spDel, "Spalte entfernen")
        MenuItem( #menu_spIns, "Spalte anhängen")
      MenuTitle("&Info")
        MenuItem( #menu_info, "Info")
        MenuItem( #menu_inf1, "Reihenfolge")
    
    LastFilesSetMenu()
3.Procedure Datei laden - speichern

Code: Alles auswählen

Procedure DateiLaden(titel,flag=0)
  
  If titel = 0
     For j = 1 To #maxfelder: prgv\feldnamen[j] = Str(j): Next
  EndIf
  
  If flag = 0
    prgv\dateiname = DateiAuswahl(0,prgv\dateiname) 
  ElseIf flag = 1
    ;Programmstart mit folgender Datei
    prgv\dateiname = GetCurrentDirectory() + "miniadress.txt"
  ElseIf flag = 2
    ;prgv\dateiname wurde von LastFileOpen zugewiesen
  EndIf

  dnr = ReadFile(#PB_Any,prgv\dateiname)  
  If dnr
     j = 0
     While Eof(dnr) = 0          
        prgv\datensatz = ReadDatensatz(dnr)        
        If j = 0  ;wird nur einmal ausgeführt, um Liste zu erstellen
           j = 1
           prgv\feldanzahl = CountString(prgv\datensatz, #LF$) - 1
           If prgv\feldanzahl > 20
             MessageRequester("Error","mehr als 20 Felder",#MB_ICONASTERISK)
             End
           EndIf 
           CreateListIcon()
           CreateListIconColumn()
           HideGadget(#main_liste,1)      ;für schnelleres Laden der Liste        
        EndIf
        If titel
           titel = 0: DatenListeTitel(prgv\datensatz)
        Else
           AddGadgetItem(#main_liste,-1, prgv\datensatz)
        EndIf
     Wend
     CloseFile(dnr)
     LastFilesSave(prgv\dateiname)
  EndIf
  
  StatusBarText(0, 0, prgv\dateiname)
  StatusBarText(0, 1, Str(CountGadgetItems(#main_liste)))
  ListeAutosize(#main_liste) ;enthält HideGadget(#main_liste,0)
EndProcedure
Procedure DateiSpeichern(flag=0)
  If prgv\dateiname = "" Or flag = 1
    prgv\dateiname = DateiAuswahl(1,prgv\dateiname)
  EndIf
  dnr = CreateFile(#PB_Any, prgv\dateiname)
  If dnr
    orderflag = GetOrderArray()
    For item = -1 To CountGadgetItems(#main_liste) - 1  ;ab -1 = Spaltentitel
      If orderflag
         x$ = Datensatzholen_Save(item) ;:Debug x$
      Else
         x$ = Datensatzholen(item) ;:Debug x$
      EndIf
      ReplaceString(x$,#LF$,#TAB$,#PB_String_InPlace)
      WriteStringN(dnr, x$)
    Next   
    CloseFile(dnr)
    LastFilesSave(prgv\dateiname)
  EndIf
  StatusBarText(0, 0, prgv\dateiname)
  StatusBarText(0, 1, "gespeichert: " + Str(item)) 
EndProcedure
4.Procedure DatenIni()

Code: Alles auswählen

Procedure DatenIni()
With prgv
  ExamineDesktops()
  \desktopbreite = DesktopWidth(0)
  \desktophoehe = DesktopHeight(0) 
  \windowbreite = 650
  \windowhoehe = 500
  \subwindowx = 50
  \subwindowy = 30
  \buttonbr = 85
  \buttonhh = 22
  
  \lastenumeration = #PB_Compiler_EnumerationValue
  
  For j = 0 To #maxfelder
    \lastenumeration + j
    \eingabepbnr[j] = \lastenumeration 
  Next
   
  For j = 0 To #lastfilesmax  
    \lastenumeration + j
    \lastmenunr[j] = \lastenumeration
  Next  
  
  CompilerIf #PB_Compiler_Debugger
    prgdat$ = #PB_Compiler_File 
  CompilerElse
    prgdat$ = ProgramFilename() 
  CompilerEndIf  
    
  prgdat$ = GetFilePart(prgdat$)  
  p = FindString(prgdat$, ".",1)
  If p: prgdat$ = Left(prgdat$,p-1): EndIf
  \inidatei = prgdat$ + ".ini"
  
  ;lastfiles lesen
  dnr = ReadFile(#PB_Any, \inidatei)  
  If dnr: j = 0
     While Eof(dnr) = 0          
        \lastfiles[j] = ReadString(dnr)  ;:Debug \lastfiles[j]
        j + 1: If j > #lastfilesmax: Break: EndIf
     Wend
     CloseFile(dnr)
  EndIf
    
EndWith
EndProcedure
5.Eventabfrage erweitern

Code: Alles auswählen

          welchesgadget = EventGadget()
          FeldGadgets(welchesgadget)
          LastFileOpen(welchesgadget)    
          
          Select welchesgadget
6.drei neue Proceduren

Code: Alles auswählen

Procedure LastFileOpen(menupunkt)

  Select menupunkt
    Case prgv\lastmenunr[0] To prgv\lastmenunr[#lastfilesmax]
         
         For j = 0 To #lastfilesmax
             If menupunkt = prgv\lastmenunr[j]
                Break
             EndIf   
         Next 
         
         prgv\dateiname = prgv\lastfiles[j]
         DateiLaden(1,2)
         
  EndSelect
  
EndProcedure
Procedure LastFilesSetMenu()
With prgv
  For j = 0 To #lastfilesmax
    menutext$ = Str(j) + ")  " + \lastfiles[j]
    SetMenuItemText(0, \lastmenunr[j], menutext$)
    DisableMenuItem(0, \lastmenunr[j], 0)
    If Not Trim(\lastfiles[j])
       DisableMenuItem(0, \lastmenunr[j], 1)
    EndIf 
  Next
EndWith
EndProcedure
Procedure LastFilesSave(dat$)
With prgv
  
  ;schon vorhanden ?
  posi = #lastfilesmax
  For j = 0 To #lastfilesmax
    If dat$ = \lastfiles[j]: posi = j: Break: EndIf
  Next
  
  ;schieben
  For j = posi To 1 Step -1
    \lastfiles[j] = \lastfiles[j-1]
  Next
  \lastfiles[0] = dat$

  ;speichern
  dnr = CreateFile(#PB_Any, \inidatei)  
  If dnr
     For j = 0 To #lastfilesmax
        WriteStringN(dnr, \lastfiles[j]) 
     Next
     CloseFile(dnr)
     LastFilesSetMenu() 
  EndIf
  
EndWith
EndProcedure
7. Declare Anweisungen

Code: Alles auswählen

Declare LastFileOpen(menupunkt)
Declare LastFilesSave(dat$)
Declare LastFilesSetMenu()
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
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Beitrag von Fluid Byte »

Es ist sinnvoller den Code im Eingangspost zu aktualisieren anstatt das mann mühselig jedes neue Codesegment suchen und einfügen muss.

Mal nur so am Rande ...
Windows 10 Pro, 64-Bit / Outtakes | Derek
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Beitrag von hjbremer »

Der Code im erwähnten Eingangspost ist so wie er ist für die PB Demoversion gedacht und ca 500 Zeilen lang. Jedes Update = Erweiterung ist über dem Limit von 600 Zeilen. Und darum ist der Code im Eingangspost in seiner Struktur unveränderlich.

Hier nun aber auf Wunsch ein Update als kompletter Code. Dieser ist aber nur noch mit der Vollversion lauffähig !!!

Die Änderungen die ich als Stückwerk gestern gepostet habe sind enthalten, plus eine Sortierfunktion, wenn man auf den Spaltenheader drückt.

Update 27.5.2009
Da ich nun mit dem Speichern der letzten 10 Dateien eine IniDatei eingeführt habe, hier nun eine richtige Inidatei mit den Preference Befehlen. Außerdem eine komplette Überarbeitung des Eingabefensters. Dessen Code funktionierte zwar, aber war auch ein abschreckendes Beispiel, wie man es nicht machen sollte.
Plus einige andere Kleinigkeiten und Vereinfachungen etc.

12.7.2009
kleiner Fehler im Eingabefenster beseitigt, da stand 99999 ;z !
die 99999 waren nur für Testzwecke

Code: Alles auswählen

Declare CreateListIcon()
Declare CreateListIconColumn()
Declare DateiLaden(titel,flag=0)
Declare DateiNeu()
Declare DateiSpeichern(flag=0)
Declare ProgrammIni()
Declare MainListeEvent()
Declare ListeResize()
Declare MainListeMakeTitel(satz$)
Declare DatenBearbeiten(flag=0)
Declare DatenNeu()
Declare DatenSortierenAuswahl()
Declare DatenSortierenStart()
Declare DatenSuchListe()
Declare DatenSuchListeMem()
Declare DatenSuchen(abitem)
Declare DatenSuchenFirst(modus)
Declare DatenSuchenNext()
Declare EingabeFenster(info$,vorgabe$,item)
Declare EingabeLeer()
Declare EingabeOk()
Declare FeldAendern()
Declare FeldAendernCbox()
Declare FeldData()
Declare FeldFenster()
Declare FeldKill()
Declare FeldListbox()
Declare FeldNeu()
Declare FeldNeuCbox()
Declare FeldObenUnten(flag)
Declare FeldStart()
Declare FeldnameCheck(pbnr,name$)
Declare GetOrderArray()
Declare LastFileOpen(menupunkt)
Declare LastFilesSave(dat$)
Declare LastFilesSetMenu()
Declare ListeAutosize(pbnr)
Declare MainInfo()
Declare MainListeHeaderClick()
Declare MainListeHeaderSort(spalte)
Declare MainListeHeaderSpalte0()
Declare TasteReturn()
Declare TitelAendern()
Declare TitelAnhaengen()
Declare TitelFenster(flag=0)
Declare TitelListBox()
Declare TitelLoeschen()
Declare VergleicheSatz(q$,s$)
Declare.s DateiAuswahl(flag=0,dat$="")
Declare.s Datensatzholen(item,flag=0)
Declare.s ReadDatensatz(dnr)
Declare.s Zufallsdaten()
Declare Infomeldung(titelnr=0, info$="", flag=0)
Declare SetColorFont()
Declare SubWindowClose()
Declare SubWindowOpen(titel$, close$="Close", flag=0)
Declare GetTextBreite(txt$) 
Declare GetTextHoehe()

Declare EingabeFensterWriteFeld(von,bis,x1,x2,x$)
Declare EingabeFensterFeldbreite(von,bis) 
Declare EingabeFensterNamebreite(von,bis)

#version = "MiniAdress von HJ Bremer®" + #LF$ + "27. Mai 2009 - Version 3.021a"

;Menu + Button Nummern etc. als Konstanten
Enumeration  
#menu_new: #menu_load: #menu_load1: #menu_save: #menu_save1: #menu_ende
#menu_neu: #menu_edit: #menu_kill: #menu_such1: #menu_such2: #menu_suchN
#menu_sort: #menu_titel: #menu_spDel: #menu_spIns: #menu_option: #menu_info: #menu_inf1
#main_window: #main_liste: #main_info: #sub_window: #subwin_ende
#sort_box1: #sort_box2: #sort_box3: #sort_start: #sort_gk: #sort_up: #sort_dn
#eingabe_leer: #eingabe_save: #eingabe_scb1: #eingabe_scb2
#feld_box: #feld_oben: #feld_unten: #feld_kill: #feld_data: #feld_start
#feld_cb1: #feld_ein1: #feld_name: #feld_cb2: #feld_ein2: #feld_neu: #feld_test
#suchliste: #such_cbmem: #titel_box: #titel_ein: #titel_name: #titel_kill
#farbe_text: #farbe_back: #farbe_line: #farbe_line1
#font_lvtext: #font_butext: #auto_start: #auto_datei: #head_theme
#taste_return: #read: #write: #fontnrListe: #fontnrButton
EndEnumeration

;weitere Konstanten
#suchart1 = "alle Eingaben enthalten"
#maxfelder = 20       ;20-30 Felder erlaubt, wer mehr will, muß eventuell EingabeFenster() ändern
#maxbreite = 200      ;für ListeAutosize, max Spaltenbreite für Anzeige
#lastfilesmax = 9     ;letzte benutzte Dateien 0-9
#button_abstand = 30  ;zuständig für Gadgetabstand und Höhe in allen Subfenstern

Structure myProgrammvariablen
  dateiname.s
  errorflag.i
  desktopbreite.i     ;Breite des Monitors in Pixel
  desktophoehe.i      ;Höhe
  windowbreite.i      ;
  windowhoehe.i       ;
  subwinlastrow.i     ;letzte Buttonzeile im SubWindow
  buttonbr.i          ;Buttonbreite
  buttonhh.i          ;Buttonhöhe abhängig vom Font
  datensatz.s         ;letzter geladener, bearbeiteter Datensatz
  eingabeitem.i       ;
  sortgk.i            ;
  sortrt.i            ;
  suchmodus.i         ;enthalten im ganzen Datensatz oder im Feld
  suchwort.s
  suchsatz.s
  suchitem.i
  suchgk.i            ;bei Suche Groß/Kleinschrift beachten
  suchlv.i            ;Suchausgabe in Liste
  suchlvmem.i         ;wenn Suchliste Inhalt merken
  suchart.s           ;für verschiedene Sucharten, in dieser Version nur eine
  feldanzahl.i                  ;anzahl Felder der geladenen Datei
  feldnamen.s[#maxfelder+1]     ;Platz für Felder reservieren = 0 - 20
  feldbreite.i[#maxfelder+1]    ;wir benutzen Feld null allerdings nicht
  eingabepbnr.i[#maxfelder+1]   ;für Identnummern der StringGadgets = Eingabefelder
  orderarray.i[#maxfelder+1]    ;für Drag and Drop = verschieben der Spalten
  titelflag.i                   ;für diverse Spalten Funktionen
  inidatei.s                    ;Name der Inidatei
  lastenumeration.i             ;
  lastfiles.s[#lastfilesmax+1]  ;für Menu Letzte Dateien
  lastmenunr.i[#lastfilesmax+1] ;
  headerid.i                    ;headerid der mainliste für Headerabfrage
  headernull.i                  ;wird 1, wenn Breite von Spalte 0 verändert wird
  headertheme.i                 ;
  lvlinecolor.i
  lvbackcolor.i
  lvtextcolor.i
  lvlinecolor1.i
  lvfontname.s
  lvfonthoehe.i
  bufontname.s
  bufonthoehe.i
  startdateiflag.i
  startdateiname.s
EndStructure

Global prgv.myProgrammvariablen
Global Dim suchitems.s(0)        ;für Suchliste Inhalt merken

With prgv.myProgrammvariablen    ;gilt fürs ganze Programm

Procedure OpenIniFile(flag)
  testen = OpenPreferences(\inidatei)
  If testen = 0: CreatePreferences(\inidatei): EndIf

  If flag = #write
     
     PreferenceGroup("MainWindow")
         WritePreferenceInteger("Windowbreite", \windowbreite)
         WritePreferenceInteger("Windowhoehe", \windowhoehe)
     PreferenceGroup("LastFiles")
         For j = 0 To #lastfilesmax
           WritePreferenceString ("File"+Str(j), \lastfiles[j])
         Next
     PreferenceGroup("Font")
         WritePreferenceString ("FontnameListe", \lvfontname)
         WritePreferenceInteger("FonthoeheListe", \lvfonthoehe)
         WritePreferenceString ("FontnameButton", \bufontname)
         WritePreferenceInteger("FonthoeheButton", \bufonthoehe)
     PreferenceGroup("Colors")
         WritePreferenceInteger("LineColor", \lvlinecolor)
         WritePreferenceInteger("BackColor", \lvbackcolor)
         WritePreferenceInteger("FrontColor", \lvtextcolor)
         WritePreferenceInteger("LineColor1", \lvlinecolor1)
     PreferenceGroup("Suchen") 
         WritePreferenceInteger("GrossKlein", \suchgk)
         WritePreferenceInteger("AusinListe", \suchlv)
     PreferenceGroup("Sortieren") 
         WritePreferenceInteger("GrossKlein", \sortgk)
         WritePreferenceInteger("Richtung", \sortrt)
     PreferenceGroup("Diverses")
         WritePreferenceInteger("Startflag", \startdateiflag)
         WritePreferenceString ("StartDatei", \startdateiname) 
         WritePreferenceInteger("Headertheme", \headertheme)  
         
  ElseIf flag = #read
     
     PreferenceGroup("MainWindow")
         \windowbreite = ReadPreferenceInteger("Windowbreite", 650)
         \windowhoehe = ReadPreferenceInteger("Windowhoehe", 500)
     PreferenceGroup("LastFiles")
         For j = 0 To #lastfilesmax
            \lastfiles[j] = ReadPreferenceString ("File"+Str(j), "")
         Next
     PreferenceGroup("Font")
         \lvfontname = ReadPreferenceString ("FontnameListe", "Arial")
         \lvfonthoehe = ReadPreferenceInteger("FonthoeheListe", 9)
         \bufontname = ReadPreferenceString ("FontnameButton", "Arial")
         \bufonthoehe = ReadPreferenceInteger("FonthoeheButton", 9)
     PreferenceGroup("Colors")
         \lvlinecolor = ReadPreferenceInteger("LineColor", #Gray)
         \lvbackcolor = ReadPreferenceInteger("BackColor", #White)
         \lvtextcolor = ReadPreferenceInteger("FrontColor", #Blue)
         \lvlinecolor1 = ReadPreferenceInteger("LineColor1", #Magenta)
     PreferenceGroup("Suchen") 
         \suchgk = ReadPreferenceInteger("GrossKlein", 0)
         \suchlv = ReadPreferenceInteger("AusinListe", 0)
     PreferenceGroup("Sortieren") 
         \sortgk = ReadPreferenceInteger("GrossKlein", 1)
         \sortrt = ReadPreferenceInteger("Richtung", 0)
     PreferenceGroup("Diverses")
         \startdateiflag = ReadPreferenceInteger("Startflag", 0)
         \startdateiname = ReadPreferenceString ("StartDatei", "miniadress.txt") 
         \headertheme    = ReadPreferenceInteger("Headertheme", 0)    
  EndIf
  ClosePreferences()
EndProcedure

Procedure ProgrammIni()

  ExamineDesktops()
  \desktopbreite = DesktopWidth(0)
  \desktophoehe = DesktopHeight(0) 
  \buttonbr = 99
  \buttonhh = 22 
  \lastenumeration = #PB_Compiler_EnumerationValue
  
  For j = 0 To #maxfelder
    \lastenumeration + j
    \eingabepbnr[j] = \lastenumeration 
  Next
   
  For j = 0 To #lastfilesmax  
    \lastenumeration + j
    \lastmenunr[j] = \lastenumeration
  Next  
  
  CompilerIf #PB_Compiler_Debugger
    prgdat$ = #PB_Compiler_File 
  CompilerElse
    prgdat$ = ProgramFilename() 
  CompilerEndIf  
    
  prgdat$ = GetFilePart(prgdat$)  
  p = FindString(prgdat$, ".",1)
  If p: prgdat$ = Left(prgdat$,p-1): EndIf
  \inidatei = prgdat$ + ".ini"
  
  ;lastfiles etc. lesen
  OpenIniFile(#read)
  
EndProcedure

Procedure GetTextBreite(txt$) 
  ;nur für Buttonfont
  dc = GetDC_(0) 
  If IsFont(#fontnrButton): id = FontID(#fontnrButton): EndIf
  SelectObject_(dc, id)   
  GetTextExtentPoint32_(dc, txt$, Len(txt$), s.size)   
  ReleaseDC_(0, dc) 
ProcedureReturn s\cx
EndProcedure 
Procedure GetTextHoehe() 
  dc = GetDC_(0) 
  If IsFont(#fontnrButton): id = FontID(#fontnrButton): EndIf
  SelectObject_(dc, id)      
  GetTextExtentPoint32_(dc, "Äg", 2, s.size) 
  ReleaseDC_(0, dc) 
ProcedureReturn s\cy
EndProcedure 

Procedure LastFileOpen(menupunkt)
  Select menupunkt
    Case \lastmenunr[0] To \lastmenunr[#lastfilesmax]
         For j = 0 To #lastfilesmax
             If menupunkt = \lastmenunr[j]: Break: EndIf   
         Next          
         \dateiname = \lastfiles[j]
         DateiLaden(1,2)
  EndSelect
EndProcedure
Procedure LastFilesSetMenu()
  For j = 0 To #lastfilesmax
    menutext$ = Str(j) + ")  " + \lastfiles[j]
    SetMenuItemText(0, \lastmenunr[j], menutext$)
    DisableMenuItem(0, \lastmenunr[j], 0)
    If Not Trim(\lastfiles[j])
       DisableMenuItem(0, \lastmenunr[j], 1)
    EndIf 
  Next
EndProcedure
Procedure LastFilesSave(dat$)
  ;schon vorhanden ?
  posi = #lastfilesmax
  For j = 0 To #lastfilesmax
    If dat$ = \lastfiles[j]: posi = j: Break: EndIf
  Next
  
  ;schieben
  For j = posi To 1 Step -1
    \lastfiles[j] = \lastfiles[j-1]
  Next
  \lastfiles[0] = dat$

  ;speichern
  OpenIniFile(#write)
  LastFilesSetMenu() 
EndProcedure

Procedure CreateListIcon()
  UseGadgetList(WindowID(#main_window))  
  flags = #PB_ListIcon_HeaderDragDrop|#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect
  id = ListIconGadget(#main_liste, 0, 0, \windowbreite, \windowhoehe-44, "Leer", 0, flags)
  
  If IsGadget(#main_info): FreeGadget(#main_info): EndIf  
  \headerid = SendMessage_(id, #LVM_GETHEADER, #Null, #Null) 
  SetColorFont()  
EndProcedure
Procedure CreateListIconColumn()
  For j = 1 To \feldanzahl
    AddGadgetColumn (#main_liste, j, \feldnamen[j],1) 
  Next
EndProcedure

Procedure DateiNeu()
 ;If IsGadget(#main_liste): ClearGadgetItems(#main_liste): EndIf
 \dateiname = ""
 StatusBarText(0, 0, \dateiname)
 FeldFenster()
EndProcedure  
Procedure DateiLaden(titel,flag=0)
  
  If titel = 0
     For j = 1 To #maxfelder: \feldnamen[j] = Str(j): Next
  EndIf
  
  If flag = 0  
    \dateiname = DateiAuswahl(0,\dateiname) 
  ElseIf flag = 1
    ;Programmstart mit folgender Datei
    \dateiname = GetCurrentDirectory() + \startdateiname
  ElseIf flag = 2
    ;\dateiname wurde von LastFileOpen zugewiesen
  EndIf

  dnr = ReadFile(#PB_Any,\dateiname)  
  If dnr
     j = 0
     While Eof(dnr) = 0          
        \datensatz = ReadDatensatz(dnr)        
        If j = 0  ;wird nur einmal ausgeführt, um Liste zu erstellen
           j = 1
           \feldanzahl = CountString(\datensatz, #LF$) - 1
           If \feldanzahl > 20
             Infomeldung(4, "mehr als 20 Felder"): End
           EndIf 
           CreateListIcon()
           CreateListIconColumn()
           HideGadget(#main_liste,1)      ;für schnelleres Laden der Liste        
        EndIf
        If titel
           titel = 0: MainListeMakeTitel(\datensatz)
        Else
           AddGadgetItem(#main_liste, -1, \datensatz)
        EndIf
     Wend
     CloseFile(dnr)
     LastFilesSave(\dateiname)
  EndIf
  
  StatusBarText(0, 0, \dateiname)
  If IsGadget(#main_liste)
     StatusBarText(0, 1, Str(CountGadgetItems(#main_liste)))
     ListeAutosize(#main_liste) ;enthält HideGadget(#main_liste,0)
  Else
     StatusBarText(0, 1, "Fehler beim Laden")
  EndIf
EndProcedure
Procedure DateiSpeichern(flag=0)
If Not \feldanzahl: InfoMeldung(): ProcedureReturn: EndIf
  If \dateiname = "" Or flag = 1
     \dateiname = DateiAuswahl(1, \dateiname)
     If \errorflag: \errorflag = 0: ProcedureReturn: EndIf    ;Dateiauswahl wurde abgebrochen
  EndIf
  dnr = CreateFile(#PB_Any, \dateiname)
  If dnr
    orderflag = GetOrderArray()                         
    For item = -1 To CountGadgetItems(#main_liste) - 1  ;ab -1 = incl. Spaltentitel
      If orderflag                                      ;falls GetOrderArray einmal nicht funktioniert
         x$ = Datensatzholen(item,1)                    ;wird zur Sicherheit dies abgefragt
      Else                                              ;und entsprechend die Daten geholt
         x$ = Datensatzholen(item)        
      EndIf
      ReplaceString(x$, #LF$, #TAB$, #PB_String_InPlace)
      WriteStringN(dnr, x$)
    Next   
    CloseFile(dnr)
    LastFilesSave(\dateiname)
  EndIf
  StatusBarText(0, 0, \dateiname)
  StatusBarText(0, 1, "gespeichert: " + Str(item)) 
EndProcedure

Procedure DatenSuchenFirst(modus)
If Not \feldanzahl: InfoMeldung(): ProcedureReturn: EndIf
  \suchmodus = modus
  Select modus
      Case 1
          \suchwort = InputRequester("Suchen","Suchbegriff: ",\suchwort)
          If \suchwort = "": ProcedureReturn: EndIf
          \suchitem = DatenSuchen(0)
          If \suchitem = -1: Infomeldung(1, "nix gefunden!"): EndIf  
      Case 11
          EingabeFenster("Suchen",\suchsatz,-2)          
  EndSelect
EndProcedure
Procedure DatenSuchenNext()
If Not \feldanzahl: InfoMeldung(): ProcedureReturn: EndIf
weitersuchen:
  \suchitem = DatenSuchen(\suchitem+1)
  If \suchitem = -1
     info$ = "nix mehr gefunden!"+#LF$+#LF$+"von Beginn an weitersuchen ?"
     antwort = Infomeldung(1, info$, #PB_MessageRequester_YesNo)
     If antwort = #PB_MessageRequester_Yes: Goto weitersuchen: EndIf
  EndIf
EndProcedure
Procedure DatenSuchen(abitem)
  ok = -1
  SetGadgetState(#main_liste,-1)
  
  Select \suchmodus  ;wird in DatensuchenFirst() gesetzt
      Case 1: ;\suchwort wird in DatensuchenFirst() gesetzt
              For item = abitem To CountGadgetItems(#main_liste) - 1
                  x$ = Datensatzholen(item): x$ = LCase(x$)
                  s$ = LCase(\suchwort)                  
                  If FindString(x$, s$, 1)
                     StatusBarText(0, 1, s$ + " in " + "Satz: " + Str(item+1))
                     SendMessage_(GadgetID(#main_liste),#LVM_ENSUREVISIBLE,item,1)
                     SetGadgetState(#main_liste,item): SetActiveGadget(#main_liste)
                     ok = item: Break    
                  EndIf
              Next
      Case 11 ;\suchsatz, \suchgk + \suchlv wird in EingabeOk() gesetzt
              For item = abitem To CountGadgetItems(#main_liste) - 1
                  x$ = Datensatzholen(item): ori$ = x$
                  s$ = \suchsatz
                  If \suchgk = 0: x$ = LCase(x$): s$ = LCase(s$): EndIf
                  If VergleicheSatz(x$, s$) = 1  
                     If \suchlv  
                       AddGadgetItem(#suchliste, -1, Str(item+1) + ori$)
                       ok = item
                     Else
                       StatusBarText(0, 1, "Satz: " + Str(item+1))
                       SendMessage_(GadgetID(#main_liste),#LVM_ENSUREVISIBLE,item,1)
                       SetGadgetState(#main_liste,item): SetActiveGadget(#main_liste)
                       ok = item: Break    
                     EndIf
                  EndIf
              Next
              If \suchlv: ListeAutosize(#suchliste): DatenSuchListeMem(): EndIf 
  EndSelect
ProcedureReturn ok     
EndProcedure
Procedure DatenSuchListe()
  ;Hinweis: Feldbreite wurde in Eingabefenster ermittelt/festgelegt
  z = SubWindowOpen("Suchergebnis"): hh = \subwinlastrow - \buttonhh
  ListIconGadget(#suchliste, 0, 0, z, hh, "Nr.", 40, #PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect)
  For j = 1 To \feldanzahl
    AddGadgetColumn(#suchliste, j, \feldnamen[j], 1)  ;ListeAutoSize setzt später die Breite
  Next
  
  CheckBoxGadget(#such_cbmem, 10, \subwinlastrow, \buttonbr, \buttonhh, "Inhalt merken")
  SetGadgetState(#such_cbmem, \suchlvmem)
  SetGadgetColor(#suchliste, #PB_Gadget_LineColor, \lvlinecolor1)
  
  If \suchlvmem
     For item = 1 To Val(suchitems(0))
        AddGadgetItem(#suchliste,-1,suchitems(item))
     Next
  EndIf
EndProcedure
Procedure DatenSuchListeMem()
  If \suchlvmem
     anz = CountGadgetItems(#suchliste)
     ReDim suchitems(anz)
     suchitems(0) = Str(anz)  
     For item = 1 To anz
       x$ = ""
       For j = 0 To \feldanzahl: x$ + GetGadgetItemText(#suchliste, item-1, j) + #LF$: Next
       suchitems(item) = x$
     Next
  EndIf
EndProcedure
Procedure DatenSuchListeMemSet()
  \suchlvmem = GetGadgetState(#such_cbmem)  ;Checkbox Inhalt merken
  If \suchlvmem: DatenSuchListeMem(): EndIf
EndProcedure

Procedure DatenNeu()
  EingabeFenster("Neu",\datensatz, -1) ; -1 = flag für hinzufügen
EndProcedure

Procedure DatenBearbeiten(flag=0)
If Not \feldanzahl: InfoMeldung(): ProcedureReturn: EndIf
   item = GetGadgetState(#main_liste)   
   If item > -1
      \datensatz = Datensatzholen(item)
      If flag  ;löschen
         RemoveGadgetItem(#main_liste,item): SetGadgetState(#main_liste,item)
      Else
         EingabeFenster("Ändern",\datensatz,item)
      EndIf
   Else
    Infomeldung(1,"kein Eintrag markiert!") 
   EndIf 
EndProcedure

Procedure DatenSortierenAuswahl()
If Not \feldanzahl: InfoMeldung(): ProcedureReturn: EndIf
Shared sort1, sort2, sort3

  z = SubWindowOpen("Sortieren") 
  x = 10: br = (z - 20 ) / 3: ab = #button_abstand
  y = 10: TextGadget(#PB_Any, x, y, z-20, \buttonhh, "Wählen Sie die Sortierreihenfolge")
  y + ab: ListViewGadget(#sort_box1, x, y, br, 220): x + br
          ListViewGadget(#sort_box2, x, y, br, 220): x + br
          ListViewGadget(#sort_box3, x, y, br, 220): x = 10
  y =270: ButtonGadget  (#sort_start,x, y, \buttonbr, \buttonhh, "Start")
          x + \buttonbr + 20
          CheckBoxGadget(#sort_gk, x, y, z-sp, \buttonhh, "Groß/Kleinschrift beachten") 
  y + ab: OptionGadget  (#sort_up, x, y, z-sp, \buttonhh, "aufsteigend") 
  y + ab: OptionGadget  (#sort_dn, x, y, z-sp, \buttonhh, "absteigend") 
  For j = 1 To \feldanzahl
    AddGadgetItem (#sort_box1, -1, \feldnamen[j])   
    AddGadgetItem (#sort_box2, -1, \feldnamen[j])   
    AddGadgetItem (#sort_box3, -1, \feldnamen[j])   
  Next
  SetGadgetState(#sort_box1, sort1)
  SetGadgetState(#sort_box2, sort2)
  SetGadgetState(#sort_box3, sort3) 
  SetGadgetState(#sort_gk, \sortgk)
  If \sortrt: SetGadgetState(#sort_up, 1): Else: SetGadgetState(#sort_dn, 1): EndIf
  
EndProcedure
Procedure DatenSortierenStart()
Shared sort1, sort2, sort3
  sort1 = GetGadgetState(#sort_box1)
  sort2 = GetGadgetState(#sort_box2)
  sort3 = GetGadgetState(#sort_box3)
  sorttiefe = 25
  datenposi = 1 + (sorttiefe*3)
  datenanzahl = CountGadgetItems(#main_liste)-1
  Dim daten$(datenanzahl+1)
  For j = 0 To datenanzahl 
    x$ = Datensatzholen(j)
    a$ = LSet(StringField(x$, sort1+2, #LF$), sorttiefe);  :Debug a$
    a$ + LSet(StringField(x$, sort2+2, #LF$), sorttiefe);  :Debug a$
    a$ + LSet(StringField(x$, sort3+2, #LF$), sorttiefe);  :Debug a$
    daten$(j) = a$ + x$   
  Next
  
  \sortgk = GetGadgetState(#sort_gk)
  \sortrt = GetGadgetState(#sort_up)
  If \sortgk = 0: sortoption = #PB_Sort_NoCase: EndIf
  If \sortrt = 0: sortoption = #PB_Sort_Descending|sortoption: EndIf
  SortArray(daten$(), sortoption, 0, datenanzahl)
  
  HideGadget(#main_liste,1): ClearGadgetItems(#main_liste) 
  For j = 0 To datenanzahl 
    x$ = Mid(daten$(j), datenposi): AddGadgetItem(#main_liste,-1, x$)
  Next
  HideGadget(#main_liste,0)
  SubWindowClose()
EndProcedure

Procedure MainListeEvent()
  Select EventType()  ;die 768 gilt für Tasten Pfeil oben/unten
    Case #PB_EventType_LeftClick, 768: StatusBarText(0, 1, "Satz: " + Str(GetGadgetState(#main_liste)+1))
    Case #PB_EventType_LeftDoubleClick: DatenBearbeiten()
  EndSelect   
EndProcedure
Procedure MainListeMakeTitel(satz$)
;erstellt aus dem 1. gelesenem Datensatz die Titel der Spalten
  For j = 1 To \feldanzahl
    \feldnamen[j] = StringField(satz$,j+1,#LF$)
    SetGadgetItemText(#main_liste, -1, \feldnamen[j], j)
  Next  
EndProcedure
Procedure ListeResize()
  \windowbreite = WindowWidth(#main_window)
  \windowhoehe = WindowHeight(#main_window)
  If IsGadget(#main_liste)
     ResizeGadget(#main_liste, #PB_Ignore, #PB_Ignore, \windowbreite, \windowhoehe-44) 
     ;InvalidateRect_(GadgetID(#main_liste), 0, 0) 
     ListeAutosize(#main_liste)          
  EndIf            
EndProcedure

Procedure EingabeFenster(info$,vorgabe$,item)
If Not \feldanzahl: InfoMeldung(): ProcedureReturn: EndIf

  \eingabeitem = item ; \eingabeitem = wofür ist die Eingabe, siehe EingabeOk(), ändern, neu, suchen 
  
  z = SubWindowOpen(info$, "Abbruch");, #PB_Window_Invisible)
  AddKeyboardShortcut(#sub_window, #PB_Shortcut_Alt|#PB_Shortcut_L, #eingabe_leer)  
  AddKeyboardShortcut(#sub_window, #PB_Shortcut_Return, #taste_return) 
   
  #anzahlsenkrecht = 10 
  x = 0
  For j = 1 To \feldanzahl Step #anzahlsenkrecht
      von = j: bis = von - 1 + #anzahlsenkrecht
      If bis > \feldanzahl: bis = \feldanzahl: EndIf
      namebrmax = EingabeFensterNamebreite(von, bis)
      feldbrmax = EingabeFensterFeldbreite(von, bis)
      x + 10:     EingabeFensterWriteFeld(von, bis, x, namebrmax, vorgabe$) 
      x + namebrmax + feldbrmax + 10
  Next
  subwindowbreite = x + 10
  
  saveinfo$ = "Daten übernehmen"  ;wenn \eingabeitem null oder größer
  If \eingabeitem = -1
    saveinfo$ = "Daten Hinzufügen"
  ElseIf \eingabeitem = -2
    saveinfo$ = "Suche starten"
  EndIf
    
  y = (#anzahlsenkrecht * #button_abstand) + #button_abstand
  ButtonGadget(#eingabe_leer,  10, y, \buttonbr, \buttonhh, "&Leer")
  ButtonGadget(#eingabe_save, 120, y, \buttonbr*2, \buttonhh, saveinfo$)
  
  SetActiveGadget(\eingabepbnr[1])
  SendMessage_(GadgetID(\eingabepbnr[1]),#EM_SETSEL,0,-1)  ;markieren und Cursor ans Ende
  
  If \eingabeitem = -2  ;Sucheingabe
     y + #button_abstand: CheckBoxGadget(#eingabe_scb1, 10, y, \buttonbr*3, \buttonhh, "Groß/Kleinschrift beachten")
     y + #button_abstand: CheckBoxGadget(#eingabe_scb2, 10, y, \buttonbr*3, \buttonhh, "Ausgabe in Liste")
     SetGadgetState(#eingabe_scb1, \suchgk): SetGadgetState(#eingabe_scb2, \suchlv)        
     ;hier ev. Optiongadgets für Sucharten
  EndIf 
  
  ;Resize fall nötig, z wurde von SubWindowOpen zurückgegeben und ist die Standardbreite
  If subwindowbreite > z            
    x = 50 + WindowX(#main_window) 
    y = 30 + WindowY(#main_window) 
    ResizeWindow(#sub_window, x, y, subwindowbreite, #PB_Ignore)
    x = subwindowbreite - \buttonbr - 11
    ResizeGadget(#subwin_ende, x, #PB_Ignore, #PB_Ignore, #PB_Ignore)  
  EndIf
  
  ;HideWindow(#sub_window, 0) 
    
EndProcedure
Procedure EingabeFensterFeldbreite(von,bis)
  breite = 0  
  For j = von To bis      
      x = GetGadgetItemAttribute(#main_liste, 0, #PB_ListIcon_ColumnWidth, j)
      If x < 99: x = 99: EndIf
      If x > #maxbreite: x = #maxbreite: EndIf       
      \feldbreite[j] = x 
      If x > breite: breite = x: EndIf     
  Next
ProcedureReturn breite
EndProcedure
Procedure EingabeFensterNamebreite(von,bis)
  breite = 0
  For j = von To bis      
      x = Gettextbreite(\feldnamen[j])      ;x = Len(\feldnamen[j]) * 10
      If x > breite: breite = x: EndIf     
  Next
ProcedureReturn breite 
EndProcedure
Procedure EingabeFensterWriteFeld(von,bis,x1,textbr,vorgabe$)
  y  = 10: x2 = x1 + textbr + 10
  For k = von To bis      
      TextGadget(#PB_Any, x1, y, textbr, \buttonhh, \feldnamen[k], #PB_Text_Right|#SS_ENDELLIPSIS)
      x$ = StringField(vorgabe$, k+1, #LF$)
      StringGadget(\eingabepbnr[k], x2, y, \feldbreite[k], \buttonhh, x$)  
      y + #button_abstand
  Next
EndProcedure

Procedure EingabeLeer()
  For j = 1 To \feldanzahl: SetGadgetText(\eingabepbnr[j],""): Next
  SetActiveGadget(\eingabepbnr[1])
EndProcedure
Procedure EingabeOk()
  ;Eingaben auslesen
  eingabe$ = #LF$: For j = 1 To \feldanzahl: eingabe$ + GetGadgetText(\eingabepbnr[j]) + #LF$: Next
    
  If Len(eingabe$) > \feldanzahl+1  ;es gibt eine Eingabe in irgendeinem Feld
  
     Select \eingabeitem  ;wird in EingabeFenster gesetzt
         ;Suchen nach Feldern
         Case -2: \suchsatz = eingabe$
                  \suchgk = GetGadgetState(#eingabe_scb1)  ;wenn 1, Groß/Klein beachten 
                  \suchlv = GetGadgetState(#eingabe_scb2)  ;wenn 1, Ausgabe in Liste
                  ;hier ev. Abfrage für Optiongadgets Sucharten
                  \suchart = #suchart1    
                  SubWindowClose()                            
                  If \suchlv: DatenSuchListe(): EndIf      ;Suchliste erstellen
                  \suchitem = DatenSuchen(0)               ;ab Satz null suche starten
                  If \suchitem = -1
                     Infomeldung(1,"nix gefunden!")
                  EndIf  
         ;Neu
         Case -1: \datensatz = eingabe$
                  AddGadgetItem(#main_liste, 0, eingabe$)  ;am Anfang einfügen
                  ListeAutosize(#main_liste)                   
         ;Ändern
         Case 0 To CountGadgetItems(#main_liste)
                  RemoveGadgetItem(#main_liste,\eingabeitem)         ;entfernen
                  AddGadgetItem(#main_liste, \eingabeitem, eingabe$) ;einfügen
                  ListeAutosize(#main_liste) 
                  SubWindowClose()
     EndSelect
  Else  ;alle Felder sind leer
     SetActiveGadget(\eingabepbnr[1])
  EndIf
  
EndProcedure

Procedure GetOrderArray()
If Not \feldanzahl: InfoMeldung(): ProcedureReturn: EndIf
  ok = SendMessage_(GadgetID(#main_liste), #LVM_GETCOLUMNORDERARRAY, \feldanzahl+1, @\OrderArray[0]) 
  For j = 0 To \feldanzahl 
    i = \OrderArray[j]  ;:Debug GetGadgetItemText(#main_liste,-1,i)
    x$ + Str(i) + ","
  Next 
  StatusBarText(0, 1, x$)
ProcedureReturn ok  
EndProcedure

Procedure ListeAutosize(pbnr)
  HideGadget(pbnr,1) 
  For j = 1 To \feldanzahl
    SendMessage_(GadgetID(pbnr), #LVM_SETCOLUMNWIDTH, j, #LVSCW_AUTOSIZE_USEHEADER)
    breite = GetGadgetItemAttribute(pbnr, 0, #PB_ListIcon_ColumnWidth, j)
    If breite > #maxbreite
       SetGadgetItemAttribute(pbnr, 0, #PB_ListIcon_ColumnWidth, #maxbreite, j)
    EndIf
  Next
  HideGadget(pbnr,0)
EndProcedure

Procedure TasteReturn()
  welchesActiveGadget = GetActiveGadget() 
  Select welchesActiveGadget
      Case \eingabepbnr[1] To \eingabepbnr[\feldanzahl]
           For j = 1 To \feldanzahl 
              If \eingabepbnr[j] = welchesActiveGadget
                 SendMessage_(GadgetID(\eingabepbnr[j]),#EM_SETSEL,0,0) ;Markierung aufhebn
                 j + 1: If j > \feldanzahl: j = 1: EndIf  
                 SetActiveGadget(\eingabepbnr[j])
                 SendMessage_(GadgetID(\eingabepbnr[j]),#EM_SETSEL,0,-1) ;markieren + ans Ende
                 Break
              EndIf
           Next          
  EndSelect  
EndProcedure          
Procedure VergleicheSatz(q$,s$)
  ok = -1
  For j = 1 To \feldanzahl  
    qitem$ = StringField(q$, j+1, #LF$)  
    sitem$ = StringField(s$, j+1, #LF$)  
    If sitem$
        Select \suchart  ;wird in EingabeOk() gesetzt
          Case #suchart1     ;alle Eingaben enthalten
               If FindString(qitem$, sitem$,1)
                  ok = 1
               Else
                  ok = -1: Break   
               EndIf    
        EndSelect
    EndIf
  Next
ProcedureReturn ok    
EndProcedure

Procedure.s DateiAuswahl(flag=0, dat$="")
  \errorflag = 0
  file$ = GetCurrentDirectory() + GetFilePart(dat$) 
  patt$ = "Text (*.txt)|*.txt;|Alle Dateien (*.*)|*.*"
  If flag = 0
     file$ = OpenFileRequester("Laden: Datei auswählen oder neuen Namen eingeben", file$, patt$, 0)
     If file$ = "": file$ = GetCurrentDirectory() + "miniadress.txt": EndIf
  Else
     file$ = SaveFileRequester("Speichern: Datei auswählen oder neuen Namen eingeben", file$, patt$, 0)
     If file$ = "": file$ = dat$: \errorflag = 1: EndIf
  EndIf  
ProcedureReturn file$
EndProcedure
Procedure.s Datensatzholen(item,flag=0)
;wenn flag gesetzt, holt einen Datensatz mit dem OrderArray 
;um ihn in der optischen Reihenfolge zu speichern  
  x$ = ""
  For j = 0 To \feldanzahl
    k = j
    If flag: k = \orderarray[j]: EndIf
    x$ + GetGadgetItemText(#main_liste, item, k) + #LF$
  Next
ProcedureReturn x$
EndProcedure

Procedure.s ReadDatensatz(dnr)
  x$ = ReadString(dnr)  ;:Debug x$
  If Right(x$,1) <> #TAB$: x$ + #TAB$: EndIf
  ReplaceString(x$,#TAB$,#LF$,#PB_String_InPlace)
ProcedureReturn x$  
EndProcedure

Procedure FeldFenster()
  z = SubWindowOpen("Felder") 
  x1= 200: x2 = x1 + 10 + \buttonbr
  y = 10:              ListViewGadget(#feld_box,  10, y, 170, z-50)
                       ButtonGadget  (#feld_oben, x1, y, \buttonbr, \buttonhh, "nach oben") 
  y + #button_abstand: ButtonGadget  (#feld_unten,x1, y, \buttonbr, \buttonhh, "nach unten")
  y + #button_abstand: ButtonGadget  (#feld_kill, x1, y, \buttonbr, \buttonhh, "löschen")   
  y + #button_abstand: CheckBoxGadget(#feld_cb1,  x1, y, \buttonbr, \buttonhh, "Name ändern ")
  y + #button_abstand: StringGadget  (#feld_ein1, x1, y, \buttonbr, \buttonhh, "")        
                       ButtonGadget  (#feld_name, x2, y, \buttonbr, \buttonhh, "ändern")      
  y + #button_abstand: CheckBoxGadget(#feld_cb2,  x1, y, \buttonbr, \buttonhh, "Feld neu ")   
  y + #button_abstand: StringGadget  (#feld_ein2, x1, y, \buttonbr, \buttonhh, "")        
                       ButtonGadget  (#feld_neu,  x2, y, \buttonbr, \buttonhh, "hinzufügen")  
  y = \subwinlastrow:  ButtonGadget  (#feld_data, 10, y, \buttonbr, \buttonhh, "Vorgaben")   
                       ButtonGadget  (#feld_start,x1, y, \buttonbr, \buttonhh, "Start")
  y = \subwinlastrow - #button_abstand
                       CheckBoxGadget(#feld_test, x1, y, \buttonbr*2, \buttonhh, "mit Testdaten ?")  
  
  DisableGadget(#feld_oben,1): DisableGadget(#feld_unten,1): DisableGadget(#feld_kill,1)
  DisableGadget(#feld_cb1,1):  DisableGadget(#feld_ein1,1):  DisableGadget(#feld_name,1)
  DisableGadget(#feld_ein2,1): DisableGadget(#feld_neu,1): HideGadget(#feld_test,1) 
EndProcedure
Procedure FeldListbox()
  DisableGadget(#feld_oben,1)
  DisableGadget(#feld_unten,1)
  DisableGadget(#feld_kill,1)
  DisableGadget(#feld_cb1,1): DisableGadget(#feld_ein1,1): DisableGadget(#feld_name,1)

  fbanz = CountGadgetItems(#feld_box)
  fbitem = GetGadgetState(#feld_box)  ;wer ist markiert ab 0 ? 
  If fbitem = -1: flag = 0            ;keins ist markiert
  ElseIf fbitem = 0: flag = 1         ;das 1.ist markiert
  ElseIf fbitem = fbanz-1: flag = 2   ;das letzte ist markiert
  Else: flag = 3                      ;irgendeins dazwischen
  EndIf
  If flag & 2: DisableGadget(#feld_oben,0): EndIf
  If flag & 1: DisableGadget(#feld_unten,0): EndIf
  If flag & 3: DisableGadget(#feld_kill,0): EndIf
  If flag & 3: FeldAendernCbox(): EndIf
EndProcedure
Procedure FeldObenUnten(flag)
  fbitem = GetGadgetState(#feld_box)  ;wer ist markiert ab 0 ? 
  name$ = GetGadgetItemText(#feld_box, fbitem)  
  RemoveGadgetItem(#feld_box, fbitem)
  If flag = 0: fbitem-1: Else: fbitem+1: EndIf 
  AddGadgetItem(#feld_box, fbitem, name$)
  SetGadgetState(#feld_box, fbitem)
  FeldListbox()
EndProcedure
Procedure FeldKill()
fbitem = GetGadgetState(#feld_box)  ;wer ist markiert ab 0 ? 
If fbitem > -1
   RemoveGadgetItem(#feld_box, fbitem)
   SetGadgetState(#feld_box, fbitem)
   FeldListbox()
EndIf
EndProcedure
Procedure FeldData()
  ClearGadgetItems(#feld_box) 
  Restore Data_FeldNamen  ;Vorgaben lesen
  Read.i anz  
  For j = 1 To anz: Read.s name$: AddGadgetItem(#feld_box, -1, name$): Next 
  SetGadgetState(#feld_box, 0)
  HideGadget(#feld_test, 0)
  FeldListbox()
EndProcedure
Procedure FeldAendern()
  fbitem = GetGadgetState(#feld_box)  ;wer ist markiert ab 0 ? 
  name$ = Trim(GetGadgetText(#feld_ein1))
  If FeldnameCheck(#feld_box,name$)
     SetGadgetItemText(#feld_box, fbitem, name$)
     SetGadgetState(#feld_box, fbitem)
  EndIf
EndProcedure
Procedure FeldAendernCbox()
fbitem = GetGadgetState(#feld_box)  ;wer ist markiert ab 0 ? 
If fbitem > -1
 DisableGadget(#feld_cb1,0) 
 name$ = GetGadgetItemText(#feld_box,fbitem)
 SetGadgetText(#feld_ein1,name$)
 If GetGadgetState(#feld_cb1) 
    DisableGadget(#feld_ein1,0): DisableGadget(#feld_name,0)
 Else
    DisableGadget(#feld_ein1,1): DisableGadget(#feld_name,1)    
 EndIf
EndIf 
EndProcedure
Procedure FeldNeu()
 name$ = Trim(GetGadgetText(#feld_ein2))
 If FeldnameCheck(#feld_box,name$): AddGadgetItem(#feld_box, -1, name$): EndIf
EndProcedure
Procedure FeldNeuCbox()
 If GetGadgetState(#feld_cb2) 
    DisableGadget(#feld_ein2,0): DisableGadget(#feld_neu,0)
 Else
    DisableGadget(#feld_ein2,1): DisableGadget(#feld_neu,1)    
 EndIf
EndProcedure
Procedure FeldnameCheck(pbnr,name$)
  fbanz = CountGadgetItems(pbnr)
  For j = 0 To fbanz - 1
    feldboxname$ = Trim(GetGadgetItemText(pbnr,j))
    If name$ = feldboxname$
       Infomeldung(1,"Name bereits vorhanden")
       ProcedureReturn 0
    EndIf   
  Next
ProcedureReturn 1
EndProcedure
Procedure FeldStart()
  ;erst auslesen, denn gleich wird das Fenster zerstört und der Inhalt auch
  \feldanzahl = CountGadgetItems(#feld_box) 
  For j = 1 To \feldanzahl 
    \feldnamen[j] = Trim(GetGadgetItemText(#feld_box,j-1))
  Next 
  testdaten = GetGadgetState(#feld_test)  
  SubWindowClose()
  
  CreateListIcon()
  CreateListIconColumn()  
  \dateiname = "": \datensatz = ""
  
  If testdaten
     For j = 1 To 22: AddGadgetItem(#main_liste, 0, Zufallsdaten()): Next
     \dateiname = "test.txt"
  EndIf
  

  StatusBarText(0, 0, \dateiname)
  StatusBarText(0, 1, Str(CountGadgetItems(#main_liste)))
  ListeAutosize(#main_liste) 
EndProcedure

Procedure TitelFenster(flag=0)
If Not \feldanzahl: InfoMeldung(): ProcedureReturn: EndIf
  
  \titelflag = flag  ;wird in TitelListbox() gebraucht  
  Select flag
    Case 0: titel$ = "Spaltennamen ändern"
    Case 1: titel$ = "Spalte entfernen"
  EndSelect
  
  z = SubWindowOpen(titel$)
  
  x1 = 200: x2 = x1 + 10 + \buttonbr
  y = 10: ListViewGadget(#titel_box,  10, y, 170, z-50)
  y + 30: StringGadget  (#titel_ein,  x1, y, \buttonbr, \buttonhh, "")        
          ButtonGadget  (#titel_name, x2, y, \buttonbr, \buttonhh, "ändern")      
  
  y = \subwinlastrow
  ButtonGadget  (#titel_kill, x1, y, \buttonbr, \buttonhh, "Löschen")
  
  For j = 1 To \feldanzahl: AddGadgetItem(#titel_box,-1,\feldnamen[j]): Next
  
  Select flag
    Case 0: HideGadget(#titel_kill,1)
            DisableGadget(#titel_ein,1): DisableGadget(#titel_name,1)
    
    Case 1: DisableGadget(#titel_kill,1)
            HideGadget(#titel_ein,1): HideGadget(#titel_name,1) 
  EndSelect
  
EndProcedure
Procedure TitelListBox()
fbitem = GetGadgetState(#titel_box)  ;wer ist markiert ab 0 ? 
If fbitem > -1
   Select \titelflag
     Case 0: ;Spaltenname ändern
             DisableGadget(#titel_ein,0): DisableGadget(#titel_name,0)
             name$ = GetGadgetItemText(#titel_box,fbitem)
             SetGadgetText(#titel_ein,name$)
     
     Case 1: DisableGadget(#titel_kill,0)
   EndSelect
EndIf
EndProcedure
Procedure TitelAendern()
  ;Hinweis: in der Titelbox wird ab null gezählt
  ;der oberste Spaltename ist also item 0
  ;hingegen die Feldnamen bzw. die Spaltennamen der main_liste
  ;beginnen bei 1, denn Spalte null wird nicht benutzt !
  
  fbitem = GetGadgetState(#titel_box)  ;wer ist markiert ab 0 ? 
  name$ = Trim(GetGadgetText(#titel_ein))
  If FeldnameCheck(#titel_box,name$)
     SetGadgetItemText(#titel_box, fbitem, name$)
     SetGadgetState(#titel_box, fbitem)
     SetGadgetItemText(#main_liste, -1, name$, fbitem+1)
     \feldnamen[fbitem+1] = name$
     ListeAutosize(#main_liste)
  EndIf
EndProcedure
Procedure TitelLoeschen()
fbitem = GetGadgetState(#titel_box)  ;wer ist markiert ab 0 ? 
If fbitem > -1
   name$ = GetGadgetItemText(#titel_box,fbitem)
   text$ = "Wollen Sie die Spalte > " + name$ + " < wirklich löschen ?"
   antwort = Infomeldung(3, text$, #PB_MessageRequester_YesNo)
   If antwort = #PB_MessageRequester_Yes
     fbitem + 1  ; Erklärung siehe TitelAendern()
     HideGadget(#main_liste,1)
     RemoveGadgetColumn(#main_liste, fbitem)
     ListeAutosize(#main_liste)  ;incl. HideGadget(#main_liste,0)
     \feldanzahl - 1
     For j = 1 To \feldanzahl
       \feldnamen[j] = GetGadgetItemText(#main_liste,-1,j)
     Next
     SubWindowClose()
     text$ = "die Spalte [ " + name$ + " ] wurde entfernt" + #LF$ + #LF$
     text$ + "Entgültig gelöscht wird die Spalte" + #LF$
     text$ + "aber erst dann, wenn die Daten gespeichert werden !"
     Infomeldung(2, text$)
   EndIf
EndIf
EndProcedure
Procedure TitelAnhaengen()
If Not \feldanzahl: InfoMeldung(): ProcedureReturn: EndIf
  text$ = "Wie soll die Spalte heißen ?" + Space(22) + "(Esc = Abbruch)" 
  name$ = InputRequester("neue Spalte", text$, "neu")
  name$ = Trim(name$)
  If name$ 
     \feldanzahl + 1
     If \feldanzahl > 20
       Infomeldung(4,"mehr als 20 Felder")
     Else  
       HideGadget(#main_liste,1)
       AddGadgetColumn(#main_liste, \feldanzahl, name$,1)
       \feldnamen[\feldanzahl] = name$
       ListeAutosize(#main_liste)  
       text$ = "die Spalte [ " + name$ + " ] wurde angehängt" + #LF$ + #LF$
       text$ + "Sie können die Spalte nun mit der Maus verschieben !"+ #LF$ + #LF$
       text$ + "Entgültig Teil der Datei wird die Spalte" + #LF$
       text$ + "aber erst dann, wenn die Daten gespeichert werden !" 
       Infomeldung(2, text$)
     EndIf 
  EndIf
EndProcedure

Procedure MainListeHeaderClick()
  spalte = -1   
  
  If GetCapture_() = \headerid
     GetCursorPos_(p.POINT) 
     MapWindowPoints_(0,\headerid,p,1) ;hwndfrom muß null sein !        
     HitInfo.HD_HITTESTINFO 
     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
  
ProcedureReturn spalte 
EndProcedure
Procedure MainListeHeaderSort(spalte)
  hd.hd_item
  hd\mask = #HDI_LPARAM
  SendMessage_(\headerid, #HDM_GETITEM, spalte, @hd)
  
  If hd\lparam = spalte
     hd\lparam = -1
     sortoption = #PB_Sort_Ascending 
  Else
     hd\lparam = spalte
     sortoption = #PB_Sort_Descending
  EndIf   
  SendMessage_(\headerid, #HDM_SETITEM, spalte, @hd)

  sort1 = spalte
  sorttiefe = 25
  datenposi = 1 + sorttiefe
  datenanzahl = CountGadgetItems(#main_liste) -1
  Dim daten$(datenanzahl+1)
  For j = 0 To datenanzahl 
    x$ = Datensatzholen(j)
    a$ = LSet(StringField(x$, sort1+1, #LF$), sorttiefe)  ;:Debug a$
    daten$(j) = a$ + x$   
  Next
  
  SortArray(daten$(),sortoption,0,datenanzahl)
  
  HideGadget(#main_liste,1)
  ClearGadgetItems(#main_liste) 
  For j = 0 To datenanzahl 
    x$ = Mid(daten$(j), datenposi)
    AddGadgetItem(#main_liste,-1, x$)
  Next
  HideGadget(#main_liste,0)
    
EndProcedure
Procedure MainListeHeaderSpalte0()
  \headernull = 0
  SetGadgetItemAttribute(#main_liste, 0, #PB_ListIcon_ColumnWidth, 0, 0)
EndProcedure
Procedure SetColorFont()
  SetGadgetColor(#main_liste, #PB_Gadget_LineColor, \lvlinecolor)
  SetGadgetColor(#main_liste, #PB_Gadget_BackColor, \lvbackcolor)
  SetGadgetColor(#main_liste, #PB_Gadget_FrontColor, \lvtextcolor)
  If \bufonthoehe
     LoadFont(#fontnrButton, \bufontname, \bufonthoehe)
     SetGadgetFont(#PB_Default, FontID(#fontnrButton))
     \buttonhh = GetTextHoehe() + 5
     If \buttonhh > #button_abstand: \buttonhh = #button_abstand-2: EndIf
  EndIf
  If \lvfonthoehe
     LoadFont(#fontnrListe, \lvfontname, \lvfonthoehe)
     SetGadgetFont(#main_liste, FontID(#fontnrListe))
  EndIf
  If \headertheme: SetWindowTheme_(\headerid, @null, @null): EndIf
EndProcedure

Procedure Infomeldung(titelnr=0, info$="", flag=0)
  Select titelnr
    Case 0:  info$ = #version + #LF$ + #LF$ 
             info$ + "Bitte im Menu Datei" + #LF$ + #LF$
             info$ + "Neu, Öffnen oder falls vorhanden, Letzte Dateien wählen"
            titel$ = "Start":   icon = #MB_ICONASTERISK     ;64 
    Case 1: titel$ = "Info":    icon = #MB_ICONASTERISK     ;64
    Case 2: titel$ = "Hinweis": icon = #MB_ICONEXCLAMATION  ;48
    Case 3: titel$ = "Warnung": icon = #MB_ICONQUESTION     ;32
    Case 4: titel$ = "Error":   icon = #MB_ICONSTOP         ;16
  EndSelect  
  antwort = MessageRequester(titel$, info$, flag | icon)
ProcedureReturn antwort
EndProcedure

Procedure SubWindowClose()
  CloseWindow(#sub_window): DisableWindow(#main_window,0)
EndProcedure
Procedure SubWindowOpen(titel$, close$="Close", flag=0)
  DisableWindow(#main_window,1)
  x = 50 + WindowX(#main_window) 
  y = 30 + WindowY(#main_window) 
  z = 450
  OpenWindow(#sub_window, x, y, z, z, titel$, flag, WindowID(#main_window)) 
  AddKeyboardShortcut(#sub_window, #PB_Shortcut_Escape, #subwin_ende)
  x = z - \buttonbr - 11: y = z - \buttonhh - 11: \subwinlastrow = y
  ButtonGadget  (#subwin_ende, x, y, \buttonbr, \buttonhh, close$)
  ;GadgetToolTip(#subwin_ende, "Fenster schließen")
ProcedureReturn z  
EndProcedure

Procedure OptionenFenster()
If Not \feldanzahl: InfoMeldung(): ProcedureReturn: EndIf
  
  z = SubWindowOpen("Einstellungen")  ;z ist windowbreite/höhe
  x1= 20: x2 = z / 2: br = z / 2 - 20: ba = #button_abstand
  y = 10: Frame3DGadget(#PB_Any,      11, y, z-22, ba * 4,    "Farben der Listen")
  y + ba: OptionGadget (#farbe_line,  x1, y, br,   \buttonhh, "MainListe Gitterlinien")           
          OptionGadget (#farbe_line1, x2, y, br,   \buttonhh, "SuchListe Gitterlinien")
  y + ba: OptionGadget (#farbe_back,  x1, y, br,   \buttonhh, "MainListe Background")           
  y + ba: OptionGadget (#farbe_text,  x1, y, br,   \buttonhh, "MainListe Text")           
  y + ba: Frame3DGadget(#PB_Any,      11, y, z-22, ba * 2,    "Fonts")       
  y + ba: OptionGadget (#font_lvtext, x1, y, br,   \buttonhh, "Mainliste: " + \lvfontname)  
          OptionGadget (#font_butext, x2, y, br,   \buttonhh, "Buttons: " + \bufontname)  
  y + ba: Frame3DGadget(#PB_Any,      11, y, z-22, ba * 3,    "Diverses")       
  y + ba: CheckBoxGadget(#auto_start, x1, y, br,   \buttonhh, "automatisch starten mit ...")  
              TextGadget(#auto_datei, x2, y, br,   \buttonhh, \startdateiname,#PB_Text_Border|#PB_Text_Center|512|#SS_NOTIFY)  
          SetGadgetState(#auto_start, \startdateiflag)
  y + ba: CheckBoxGadget(#head_theme, x1, y, br+br,\buttonhh, "Spaltenkopf hat klassische Ansicht (ab nächster Liste)")  
          SetGadgetState(#head_theme, \headertheme)  
EndProcedure
Procedure Optionen(wofuer)
farbe = -1
Select wofuer
   Case #font_lvtext: If FontRequester(\lvfontname,\lvfonthoehe,0)
                         \lvfontname = SelectedFontName(): \lvfonthoehe = SelectedFontSize()
                         SetColorFont(): ListeAutosize(#main_liste)                      
                      EndIf  
   Case #font_butext: If FontRequester(\bufontname,\bufonthoehe,0)
                         \bufontname = SelectedFontName(): \bufonthoehe = SelectedFontSize()
                         SetColorFont(): SubWindowClose()
                      EndIf   
   Case #auto_start: \startdateiflag = GetGadgetState(#auto_start) 
   Case #auto_datei: \startdateiname = GetFilePart(DateiAuswahl())
                      SetGadgetText(#auto_datei, \startdateiname)
   Case #head_theme:  \headertheme = GetGadgetState(#head_theme) 
   Case #farbe_line:  farbe = ColorRequester(\lvlinecolor) 
   Case #farbe_back:  farbe = ColorRequester(\lvbackcolor) 
   Case #farbe_text:  farbe = ColorRequester(\lvtextcolor) 
   Case #farbe_line1: farbe = ColorRequester(\lvlinecolor1) 
EndSelect

If farbe > -1
   Select wofuer
       Case #farbe_line:  \lvlinecolor = farbe
       Case #farbe_back:  \lvbackcolor = farbe
       Case #farbe_text:  \lvtextcolor = farbe
       Case #farbe_line1: \lvlinecolor1 = farbe
   EndSelect
   SetColorFont()
EndIf
EndProcedure

Procedure.s Zufallsdaten()
Dim x$(40)
Restore ZufaDaten
For k = 1 To 40: Read.s x$(k): Next
text$ = #LF$
text$ + x$(Random(4)+1) + #LF$
text$ + x$(Random(4)+6) + #LF$
text$ + x$(Random(4)+11) + x$(Random(4)+16) + #LF$
text$ + x$(Random(4)+21) + Str(Random(990)+1) + #LF$
text$ + "0" + Str(Random(800)+99) + "-" + Str(Random(9990)+1000) + #LF$ + #LF$
text$ + Str(Random(2)+1) + x$(Random(4)+26) + #LF$
text$ + x$(Random(4)+31) + " + " + x$(Random(4)+36) + #LF$
ProcedureReturn text$
DataSection
ZufaDaten:
Data.s "Otto ", "Mike ", "Hans-Jürgen ", "Ulrike ", "Familie "
Data.s "Meier", "Bremer", "Müller", "Holzfäller", "Rappel"
Data.s "12345 ", "35793 ", "48265 ", "72561 ", "55127 "
Data.s "Wieda", "Bremen", "Kuhdorf", "Neustadt", "Bonn"
Data.s "Dorfstr. ", "Am Anger ", "Krugkoppel ", "Baumweg ", "Am Teich " 
Data.s " Hunde", " Katzen", " Vögel", " Pferde", " Schafe" 
Data.s "VW", "Opel", "BMW", "Ford", "Fahrrad", "Mercedes", "Mofa", "Porsche", "Audi", "Toyota" 
EndDataSection       
EndProcedure

; Programmoberfläche definieren----------------------
ProgrammIni()
flag = #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget
hwnd = OpenWindow(#main_window, 0, 0, \windowbreite, \windowhoehe, "MiniAdress (PB 4.3 x86)", flag) 
       
    CreateStatusBar(0, WindowID(#main_window))
      AddStatusBarField(#PB_Ignore)
      AddStatusBarField(#PB_Ignore)
          
    CreateMenu(0, WindowID(#main_window)) 
      MenuTitle("&Datei")
        MenuItem( #menu_new,  "&Neu")
        MenuItem( #menu_load, "Ö&ffnen" + #TAB$ + "Strg+O")
        MenuItem( #menu_save, "&Speichern" + #TAB$ + "Strg+S")
        MenuItem( #menu_save1, "Speichern &als...")
        MenuBar()
        OpenSubMenu("&Letzte Dateien")
          For j = 0 To #lastfilesmax: MenuItem( \lastmenunr[j], ""): Next
        CloseSubMenu()                    
        MenuBar()
        MenuItem( #menu_option, "&Einstellungen")
        MenuBar()
        MenuItem( #menu_ende, "&Beenden" + #TAB$ + "Alt+F4")
      MenuTitle("&Bearbeiten")
        MenuItem( #menu_neu, "&Neu" + #TAB$ + "Strg+N")
        MenuItem( #menu_edit, "&Ändern")
        MenuItem( #menu_kill,"&Löschen")
      MenuTitle("&Suchen")
        MenuItem( #menu_such1, "&Suchen" + #TAB$ + "Strg+F / F4")
        MenuItem( #menu_such2, "Suchen im &Feld")
        MenuItem( #menu_suchN, "&Weitersuchen" + #TAB$ + "F3")
      MenuTitle("S&ortieren")
        MenuItem( #menu_sort, "S&ortieren")
      MenuTitle("Di&verses")
        MenuItem( #menu_titel, "Spaltennamen ändern")
        MenuItem( #menu_spDel, "Spalte entfernen")
        MenuItem( #menu_spIns, "Spalte anhängen")
        MenuBar()
        MenuItem( #menu_load1, "öffnen ohne Titel/Spaltennamen")
      MenuTitle("&Info")
        MenuItem( #menu_info, "VersionInfo")
        MenuItem( #menu_inf1, "Reihenfolge")
    
    LastFilesSetMenu()
      
    AddKeyboardShortcut(#main_window, #PB_Shortcut_Control|#PB_Shortcut_O , #menu_load)
    AddKeyboardShortcut(#main_window, #PB_Shortcut_Control|#PB_Shortcut_S , #menu_save)
    AddKeyboardShortcut(#main_window, #PB_Shortcut_Alt    |#PB_Shortcut_F4, #menu_ende)
    AddKeyboardShortcut(#main_window, #PB_Shortcut_Control|#PB_Shortcut_N , #menu_neu)
    AddKeyboardShortcut(#main_window, #PB_Shortcut_Control|#PB_Shortcut_F , #menu_such1)
    AddKeyboardShortcut(#main_window,                      #PB_Shortcut_F4, #menu_such1)
    AddKeyboardShortcut(#main_window,                      #PB_Shortcut_F3, #menu_suchN)
 
    ;automatisch laden bei Start; welche Datei steht in OpenIniFile() bzw. siehe Menu Einstellungen
    If \startdateiflag: DateiLaden(1,1): Else: InfoMeldung(): EndIf

; Eingabeschleife----------------------------------------------
Repeat: event = WaitWindowEvent(1) ;:If event:Debug event:EndIf

 Select event
     ;Case 77: ;F1 
     
     Case #WM_LBUTTONDOWN
          spalte = MainListeHeaderClick()
                    
     Case #WM_MOUSEMOVE  ;wenn zwischen down + up 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): EndIf 
          If \headernull: MainListeHeaderSpalte0(): EndIf  
          
     Case #PB_Event_SizeWindow, #PB_Event_MoveWindow
          ListeResize()
            
     Case #PB_Event_Gadget, #PB_Event_Menu  ;Gadget oder Menupunkt
     
          welchesgadget = EventGadget()
          Optionen(welchesgadget)   
          LastFileOpen(welchesgadget) 

          Select welchesgadget
              Case #menu_new:   DateiNeu()
              Case #menu_load:  DateiLaden(1)
              Case #menu_load1: DateiLaden(0)    ;ohne Spaltentitel
              Case #menu_save:  DateiSpeichern()
              Case #menu_save1: DateiSpeichern(1)
              Case #menu_neu:   DatenNeu()
              Case #menu_edit:  DatenBearbeiten()
              Case #menu_kill:  DatenBearbeiten(1)
              Case #menu_such1: DatensuchenFirst(1)  ;
              Case #menu_such2: DatensuchenFirst(11) ;nach Feldern
              Case #menu_suchN: DatensuchenNext()
              Case #menu_sort:  Datensortierenauswahl()
              Case #menu_info:  Infomeldung(2, #version)
              Case #menu_inf1:  GetOrderArray()
              Case #menu_titel: TitelFenster()
              Case #menu_spDel: TitelFenster(1)
              Case #menu_spIns: TitelAnhaengen()
              Case #menu_ende:  event = #PB_Event_CloseWindow
              Case #menu_option: OptionenFenster() 
              
              Case #feld_box:   FeldListbox()
              Case #feld_oben:  FeldObenUnten(0)
              Case #feld_unten: FeldObenUnten(1)
              Case #feld_kill:  FeldKill()
              Case #feld_cb1:   FeldAendernCbox()
              Case #feld_cb2:   FeldNeuCbox()
              Case #feld_neu:   FeldNeu()
              Case #feld_name:  FeldAendern()
              Case #feld_data:  FeldData()
              Case #feld_start: FeldStart()
              Case #titel_box:  TitelListBox()
              Case #titel_name: TitelAendern()
              Case #titel_kill: TitelLoeschen()  

              Case #main_liste:   MainListeEvent() 
              Case #sort_start:   DatensortierenStart()
              Case #eingabe_save: EingabeOk()   
              Case #eingabe_leer: EingabeLeer() 
              Case #taste_return: TasteReturn() 
              Case #such_cbmem:   DatenSuchListeMemSet()              
              Case #subwin_ende:  SubWindowClose()                                                     
          EndSelect 
 EndSelect
Until event = #PB_Event_CloseWindow 

If Len(\dateiname) = 0 
   If IsGadget(#main_liste)
      If CountGadgetItems(#main_liste): DateiSpeichern(1): EndIf
   EndIf      
EndIf 

OpenIniFile(#write)
End
EndWith

DataSection
Data_FeldNamen:
Data.i 8
Data.s "Vorname","Nachname","Plz/Ort","Strasse","Tel.","Handy","Diverses","?"
EndDataSection
Zuletzt geändert von hjbremer am 12.06.2009 21:12, insgesamt 4-mal geändert.
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
Little John

Beitrag von Little John »

hjbremer hat geschrieben:Der Code im erwähnten Eingangspost ist so wie er ist für die PB Demoversion gedacht und ca 500 Zeilen lang. Jedes Update = Erweiterung ist über dem Limit von 600 Zeilen. Und darum ist der Code im Eingangspost in seiner Struktur unveränderlich.
Die Aussage in dieser Allgemeinheit so nicht richtig.
Ursprungspost hat geschrieben:die Prozeduren ans Ende gesetzt, damit auch jeder merkt, wozu die Declare Anweisungen gut sind.
Gerade wenn der Code eine Art Lehrbeispiel sein soll, halte ich es für besser die Prozeduren an den Anfang zu schreiben, damit auch jeder merkt dass Declare-Anweisungen überhaupt nicht erforderlich sind (außer für Rekursion).
Dies spielt in diesem Fall eine um so größere Rolle, als ja eine Begrenzung von 600 Zeilen eingehalten werden soll. Allein durch das Weglassen der unnötigen Declare-Anweisungen würde man Platz gewinnen.

Gruß, Little John
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

Beitrag von ts-soft »

+ 1

Hab bei über 10000 Zeilen nicht so viele Declares :mrgreen:
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
rolaf
Beiträge: 3843
Registriert: 10.03.2005 14:01

Beitrag von rolaf »

Zwar viel Gemecker hier im Thread, aber das Wichtigste, es funzt und ist absolut brauchbar, kann man ja nötigenfalls anpassen.

Von mir daher: :allright: :allright: :allright:
:::: WIN 10 :: PB 5.73 :: (x64) ::::
Andesdaf
Moderator
Beiträge: 2673
Registriert: 15.06.2008 18:22
Wohnort: Dresden

Beitrag von Andesdaf »

>Zwar viel Gemecker hier im Thread, aber das Wichtigste, es funzt und ist absolut brauchbar, kann man ja nötigenfalls anpassen.
so sehe ich das auch.
Win11 x64 | PB 6.20
Benutzeravatar
Vera
Beiträge: 928
Registriert: 18.03.2009 14:47
Computerausstattung: Win XP SP2, Suse 11.1
Wohnort: Essen

Beitrag von Vera »

HI hjbremer,
nochmals danke für Deine Mühe und die Weitergabe der Codes . :)

Alle drei Versionen laufen auch bei mir und ich fand witzig, dass Du einige meiner ToDos zur ersten Version, dann in die folgenden schon eingebaut hattest. Besonders gefreut hab' ich mich darüber, dass man Adress-unabhängig ganz eigene Datensätze anlegen kann und erstaunt war ich darüber, dass sich das Eingabeformular autogeneriert. Prima gefällt mir auch das Beispiel der zwei Variationen mit dem Code umzugehen, alles zusammengefasst bzw. auf mehrere Includes aufgeteilt. Insgesamt ist ein umfangreiches Anschauungsmaterial zusammengekommen, an dem man sicher eine Menge lernen kann.

Einen kleinen Beispiel-Tip würde gerne weitergeben. Da ich dieses oft zu häufige Geklingel von Messages so gar nicht mag, stelle ich sie gern ab:

Code: Alles auswählen

MessageRequester("Info", #version) ; ohne Icon, mit Alarm
MessageRequester("Info", #version, #MB_ICONASTERISK| $80); auch ohne Icon, ohne Alarm
[entscheidend ist das '| $80', welches natürlich ohne Flag nicht funktioniert]

Gruß ~ Vera
~
Andesdaf
Moderator
Beiträge: 2673
Registriert: 15.06.2008 18:22
Wohnort: Dresden

Beitrag von Andesdaf »

> Da ich dieses oft zu häufige Geklingel von Messages so gar nicht mag, stelle ich sie gern ab:
Bei mir ist die Lautstärke so leise, da höre ich das gar nicht.

@ha-jott:
Nur ein Hinweis, ich würde in den Menüs alles groß schreiben (nur so, ist mir
aufgefallen)
Win11 x64 | PB 6.20
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Beitrag von hjbremer »

Hallo und schönen Gruß,

Das mit dem Beep kann ich nachvollziehen, aber mit $80 hab ich kein Icon. Aber im nächsten Update werde ich alle Meesages in eine eigene Procedur auslagern und dann kann jeder es so machen wie er will.

In den Menus alles groß schreiben, wer macht denn so was ? Dat find ich ja merkwürdig :shock:
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