[solved] Reihenfolge der INI Einträge in Verbindung mit ListView

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

Umek
Posts: 65
Joined: 06 Oct 2015, 12:40
Location: Germany

[solved] Reihenfolge der INI Einträge in Verbindung mit ListView

13 Oct 2015, 15:03

Aahhhhhhhhhhhhhrrg! Gehirnsuppe!

Ich habe mich bereits in dem anderen Forum zu diesem Thema gemeldet und es fällt mir schwer den richtigen Weg für mich zu erkennen.

Wenn ich zum Beispiel 250 Einträge aus einer INI-Datei in eine ListView lade und dann Eintrag 50 lösche, möchte ich, dass die INI-Datei in neuer Reihenfolge von 1 bis 249 geschrieben wird.

Ist das überhaupt sinnvoll? Und was passiert, wenn ich 1000 Einträge habe? Die ganzen Einträge müssen erstmal geschrieben und dann neu geladen werden.

Ich befürchte das macht alles keinen Sinn. Kann mir jemand sagen, welches der beste Weg ist?
Last edited by Umek on 29 Oct 2015, 04:59, edited 2 times in total.
just me
Posts: 7093
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Reihenfolge der INI Einträge in Verbindung mit ListView

13 Oct 2015, 15:18

Hallo,

für heute ist es ein wenig spät, aber ich melde mich morgen, wenn das bis dahin noch nicht erledigt ist.

Gute Nacht!
User avatar
nnnik
Posts: 4455
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Reihenfolge der INI Einträge in Verbindung mit ListView

13 Oct 2015, 15:21

Der standard Weg ist es erst dann zu Speichern wenn die fertige Datei benötigt wird.
Der standard Weg um zu bestimmen ob die Datei benötigt wird oder nicht ist indem man einen Speichern Knopf hinzufügt.
Recommends AHK Studio
Umek
Posts: 65
Joined: 06 Oct 2015, 12:40
Location: Germany

Re: Reihenfolge der INI Einträge in Verbindung mit ListView

13 Oct 2015, 15:52

Hallo,

muss ich die Datei nicht neu laden um die Änderung sichtbar zu machen? Habe zwischenzeitig überlegt wieder auf eine Textdatei umzusteigen und es wie folgt zu lösen:

Code: Select all

AppDB = 
(
Title 1<a>Text 1
Title 2<a>Text 2
Title 3<a>Text 3
Title 4<a>Text 4
Title 5<a>Text 5
)

MsgBox, %AppDB%
Loop, parse, AppDB, `n, `r
  {
	LR:=A_LoopField
		if LR=
			continue 
		NeuerStr := RegExReplace(LR, "Title 4<a>Text 4", "Test 1<a>Mein neuer Eintrag")
		NewAppDB := NewAppDB . "`n" . NeuerStr 
  }
  MsgBox, %NewAppDB%
Ich speichere den vorhandenen Eintrag in eine Variable und wenn diese Geändert wird, kann ich den alten Eintrag in der Datei suchen und mit dem neuen ersetzen. Beim Löschen kann ich ihn suchen und durch nichts ersetzen und neue Einträge werden einfach an das Ende gesetzt. Das ist vielleicht die Beste Lösung.

Ich bin dem Rat gefolgt und habe mir bezüglich der INI-Datei ein kleines Grundgerüst gebaut. Das ist nun fertig. Aber irgendwie habe ich gerade (oder grundsätzlich) eine Blockade und stell mir die Frage ob ich auf diese doofe Reihenfolge bestehen muss. Ich bin zwar ein ordentlicher Mensch aber in diesem Fall neige ich zu anderen Maßnahmen.

Ich sollte mal eine Nacht drüber schlafen.

Gruß
Umek
Posts: 65
Joined: 06 Oct 2015, 12:40
Location: Germany

Re: Reihenfolge der INI Einträge in Verbindung mit ListView

13 Oct 2015, 16:02

Wenn ich aber tatsächlich mal 1000 Einträge habe, könnte meine Idee mit der Textdatei zu lange dauern. Daten lesen, ersetzen, neu speichern und dann in ListView laden. Ich glaube das ist nicht der richtige Ansatz. Gott!


Gute Nacht.
Umek
Posts: 65
Joined: 06 Oct 2015, 12:40
Location: Germany

Re: Reihenfolge der INI Einträge in Verbindung mit ListView

14 Oct 2015, 00:53

Morgen!

Ich glaube ich habe es verstanden. War spät gestern. Ich werde versuchen, dass sich zunächst alles in der ListView abspielt. Beim speichern fahre ich einfach mit einem Loop durch ListView und überschreibe damit die INI-Datei.

Ich versuch das heute mal und berichte.
just me
Posts: 7093
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Reihenfolge der INI Einträge in Verbindung mit ListView

14 Oct 2015, 01:54

Guten Morgen,

wenn ich das hier lese, habe ich den Eindruck, dass Du Dich ziemlich unter Druck setzt. Geht es um einen bestimmten Termin, zu dem Du fertig sein musst?

Nun zum Thema INI-Dateien. Sie haben Vor- und Nachteile. Der Vorteil ist der klare strukturierte Aufbau, der sie auch für menschliche Augen lesbar und die Bedeutung der Einträge erkennbar macht. Die Nachteile bestehen darin, dass Einträge nicht mehrzeilig sein können (bzw. dass man dafür die Zeilenwechsel 'maskieren' muss) und dass die Windows Funktionen zum Zugriff auf INI-Dateien, die AHK verwendet, immer mal wieder die maximale Länge der zu lesenden/schreibenden Inhalte auf 64 KB begrenzen. Microsoft selbst hat das Konzept der INI-Dateien schon vor langer Zeit durch die Registrierungsdatenbank ersetzt.

Egal in welchem Format Du Deine Textbausteine speicherst, für die Verarbeitung innerhalb Deines Skripts bieten sich wegen der von Dir gewünschten 'chronologischen' Reihenfolge Arrays an, weil sie jederzeit die Lesereihenfolge abbilden und auch über spezielle Mechanismen verfügen, die die korrekte Reihenfolge auch nach Änderungen gewährleisten. Damit spart man sich schon mal das Wiedereinlesen nach Änderungen ein.
Außerdem macht ein Array die Verarbeitung unabhängig von der Art der Speicherung der Daten. Nur die Lese- und Schreibroutinen müssen wissen, wie die Dateien aufgebaut sind. Alle anderen Routinen verlassen sich einfach auf das Array.

Die Idee, alles im ListView abzuwickeln, halte ich nicht für zielführend, weil Du ja die ListView auch zur Selektion bestimmter Textbausteine nutzt. Du müsstest dann unerwünschte Einträge ausblenden, und das wird schnell unübersichtlich. Außerdem kann man die Reihenfolge durch Sortieren durcheinanderbringen, wenn Du das nicht verhinderst.

Wie oft Du die Daten nach Änderungen speicherst, bleibt Dir überlassen. Das Speichern ist in der Regel mit Festplattenzugriffen verbunden und kostet damit relativ zur Verarbeitung im Arbeitsspeicher viel Zeit. Ob das irgendwann zu viel wird, um kontinuierlich Speichern zu können, wird sich erweisen. Der Verzicht auf das sorfortige Wegschreiben von Änderungen birgt aber das Risiko, Änderungen zu verlieren.

So, nun zum konkreten Problem.

Ich habe mal ein paar Routinen aus Deinem im anderen Forum eingestellten Skript auf ein Array umgestellt, um das Prinzip zu zeigen:

Code: Select all

; GUI 1 Fill ListView
;--------------------------------------------------
G1FillLV:
   Gui, 1:Default
   GuiControl, -Redraw, LV
   LV_Delete()
   For Index, TBS In AppDB
      LV_Add("", Index, TBS.Title, TBS.Text)
   GuiControl, +Redraw, LV
   ShowPreview()
Return

ReadINI:
   AppDB := [] ; leeres Array erstellen
   IniRead, TBSAmount, %AppINI%, Textbausteine, Quantity
   Loop, %TBSAmount%
   {
   	IniRead, TBSTitle, %AppINI%, Textbausteine, Title%A_Index%
   	IniRead, TBSText, %AppINI%, Textbausteine, Text%A_Index%
      AppDB.Push({Title: TBSTitle, Text: TBSText}) ; eingelesenen Werte anhängen
   }
   Gosub, G1FillLV
Return

SaveINI:
   IniDelete, %AppINI%, Textbausteine ; vorhandene Section löschen
   NewContent := "Quantity=" . AppDB.Length() ; section neu aufbauen und ...
   For Index, TBS In AppDB
      NewContent .= "`nTitle" . Index . "=" . TBS.Title . "`nText" . Index . "=" . TBS.Text
   IniWrite, %NewContent%, %AppINI%, Textbausteine ; ... wegschreiben
Return
Wenn Du diesen Weg versuchen willst, würde ich Dir bei der weiteren Umsetzung gern helfen, wenn Du Hilfe benötigst.

Noch etwas. Ich würde die Ersetzung der Textbausteinvariablen ausschließlich für die Beispielausgabe in Edit2 machen, und mich für das Senden von Bausteinen auch dort bedienen.

Viel Glück!
just me
Umek
Posts: 65
Joined: 06 Oct 2015, 12:40
Location: Germany

Re: Reihenfolge der INI Einträge in Verbindung mit ListView

14 Oct 2015, 03:36

Also zunächst mal bin ich über die ausführliche und nette Antwort sowie die Hilfsbereitschaft überwältigt. Ich habe kein Zeitdruck aber diese Herausforderung verursacht bei mir so ein leichtes Girnzellengewitter. Ich bin zur Zeit auf der Arbeit und mache hier gefühlt 5 Sachen gleichzeitig. Das ist nicht förderlich. Ich muss mir das heute Abend nochmal ansehen, da ich hier nicht die Ruhe dafür habe. Ich habe zwar schon ein kleinen Versuch gestartet, dabei aber festgestellt, dass ich das ohne Ruhe nicht verstehen werde. Ich habe mir das Ganze erstmal losgelöst von meinem eigentlichen Skript erstellt und bin dabei soweit gekommen:

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

AppINI = config.ini
Gosub, ReadINI

;------------------------- GUI 1
	Gui, 1:Add, ListView, x5 y5 w450 h220 vLV gG1LVEvents, Nr.|Titel|Text
	LV_ModifyCol(1,45)
	LV_ModifyCol(2,200)
	LV_ModifyCol(3,200)
	Gosub, G1LVLoad
	Gui, 1:Add, Button, x155 y229 w100 h24 gG1Test, Test
	Gui, 1:Add, Button, x255 y229 w100 h24 gSaveINI, Speichern
	Gui, 1:Add, Button, x355 y229 w100 h24 gG2Show, Bearbeiten
	Gui, 1:Show, w460 h259, Untitled GUI
Return

G1Test:
	; LVTest := LV_GetCount()
	
	;MsgBox, %LVTest%
Return

G1LVLoad:
   Gui, 1:Default
   GuiControl, -Redraw, LV
   LV_Delete()
   For Index, TBS In AppDB
      LV_Add("", Index, TBS.Title, TBS.Text)
   GuiControl, +Redraw, LV
   ShowPreview()
Return

G1LVEvents:
Gui,1:Default
Gui,1:ListView, LV
    if(A_GuiEvent == "I")
         {

         }
    if(A_GuiEvent == "Normal")
         {

         }
    if(A_GuiEvent == "DoubleClick")
        {
		Gosub, G2Show
        Return
        }
Return

;------------------------- GUI 2
G2Show:
	GuiControlGet, FocusedTBS, FocusV
	FocusedTBS := % LV_GetNext(0, "Focused")
	if (FocusedTBS = "0") {
		MsgBox 8240, %App%, Bitte wähle einen Eintrag aus.`t
		Return
	}
	LV_GetText(TBS1, FocusedTBS, 1)
	LV_GetText(TBS2, FocusedTBS, 2)
	LV_GetText(TBS3, FocusedTBS, 3)
	Gui, 1:+Disabled
	Gui, 2:Default
	Gui, 2: +AlwaysonTop
	Gui, 2:-MaximizeBox -MinimizeBox -Resize -SysMenu +ToolWindow
	Gui, 2:Add, Edit, x5 y5 w50 h20 vG2Edit1, Edit
	Gui, 2:Add, Edit, x5 y30 w400 h20 vG2Edit2, Edit
	Gui, 2:Add, Edit, x60 y5 w345 h20 vG2Edit3, Edit
	Gui, 2:Add, Button, x5 y55 w100 h24 , Neu
	Gui, 2:Add, Button, x105 y55 w100 h24 , Speichern
	Gui, 2:Add, Button, x205 y55 w100 h24 gG2Delete, Löschen
	Gui, 2:Add, Button, x305 y55 w100 h24 gG2Close, Abbrechen
	GuiControl, 2:, G2Edit1, %TBS1%
	GuiControl, 2:, G2Edit2, %TBS2%
	GuiControl, 2:, G2Edit3, %TBS3%
	Gui, 2:Show, w410 h84, Bearbeiten
Return

;------------------------- GUI 2 schließen
G2Close:
    Gui, 1:-Disabled 
	Gui, 2:Destroy
    Gui, 1:Default 
Return

G2Delete:
GuiControlGet, G2Edit1, , G2Edit1
;MsgBox, %G2Edit1%
    Gui, 1:-Disabled 
	Gui, 2:Destroy
    Gui, 1:Default 
	LV_Delete(G2Edit1)

Return

ReadINI:
   AppDB := [] ; leeres Array erstellen
   IniRead, TBSAmount, %AppINI%, Textbausteine, Quantity
   Loop, %TBSAmount%
   {
   	IniRead, TBSTitle, %AppINI%, Textbausteine, Title%A_Index%
   	IniRead, TBSText, %AppINI%, Textbausteine, Text%A_Index%
      AppDB.Push({Title: TBSTitle, Text: TBSText}) ; eingelesenen Werte anhängen
   }
   Gosub, G1LVLoad
Return

SaveINI:
   IniDelete, %AppINI%, Textbausteine ; vorhandene Section löschen
   NewContent := "Quantity=" . AppDB.Length() ; section neu aufbauen und ...
   For Index, TBS In AppDB
      NewContent .= "`nTitle" . Index . "=" . TBS.Title . "`nText" . Index . "=" . TBS.Text
   IniWrite, %NewContent%, %AppINI%, Textbausteine ; ... wegschreiben
   MsgBox, %NewContent%
Return



;------------------------- Anwendung beenden 
GuiClose:
ExitApp

^!r::
	Reload
Return




; GUI 1 Endless scrolling in a listview
; http://www.autohotkey.com/board/topic/41349-example-endless-scrolling-in-a-listview/
;--------------------------------------------------
#If (WinActive(App) and ActiveControlIs("Edit1"))
Up::
PreviousPos:=LV_GetNext()
if (PreviousPos = 0) ; exeption, focus is not on listview this will allow you to jump to last item via UP key
	{
	 ControlSend, SysListview321, {End}, %AppWindow%
	 Return
	}
ControlSend, SysListview321, {Up}, %AppWindow%
ItemsInList:=LV_GetCount()
ChoicePos:=PreviousPos-1
if (ChoicePos <= 1)
	ChoicePos = 1
if (ChoicePos = PreviousPos)
	ControlSend, SysListview321, {End}, %AppWindow%
ShowPreview()
Return
 
Down::
PreviousPos:=LV_GetNext()
ControlSend, SysListview321, {Down}, %AppWindow%
ItemsInList:=LV_GetCount()
ChoicePos:=PreviousPos+1
if (ChoicePos > ItemsInList)
	ChoicePos := ItemsInList
if (ChoicePos = PreviousPos)
	ControlSend, SysListview321, {Home}, %AppWindow%
ShowPreview()
Return
#If
 
ActiveControlIs(Control)
	{
	 ControlGetFocus, FocusedControl, A
	 if (FocusedControl = Control)
		Return 1
	 else
		Return 0	
	}
 
ShowPreview()
	{
	 Gui, Submit, NoHide
	 SelItem := LV_GetNext()
	 if (SelItem = 0)
	    SelItem = 1
	 LV_GetText(Idx, SelItem, 2) ; Search in section 2
	 GuiControl, , G1Edit2, % Idx
	}

Code: Select all

[Textbausteine]
Quantity=5
Title1=Titel 1
Text1=Text 1
Title2=Titel 2
Text2=Text 2
Title3=Titel 3
Text4=Text 3
Title5=Titel 4
Text5=Text 4
Title6=Titel 5
Text6=Text 5

Ich mach das heute Abend in Ruhe. Ich komme gerne auf dein Angebot zurück, komme nur gerade nicht hinterher, es zu verstehen. Das darf nicht sein.

Viele Grüße
just me
Posts: 7093
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Reihenfolge der INI Einträge in Verbindung mit ListView

14 Oct 2015, 04:47

Hallo,

ja, zu hoher Druck erzeugt in der Regel auch eine hohe Fehlerquote und gelegentlich sogar Gehirnblockaden. Deshalb lass Dir Zeit.

Eine grundsätzliche Sache noch vorab. In Deinem letzten Beispiel wie auch in dem aus dem englischen Forum fehlt mir die Anweisung SetBatchLines, -1 (siehe) im Skriptkopf, die dafür sorgt, dass das Skript mit maximaler Geschwindigkeit läuft. Das wird in der irgendwann kommenden AHK-Version 2 das Standardverhalten sein, in der aktuellen Version 1.1 muss man das aber selbst erledigen. Ursache dafür sind die 'guten alten Zeiten', in denen die Skripte auf ressoucenarmen Einprozessormaschinen andere Anwendungen nicht unnötig ausbremsen sollten. Wie ich bemerkt habe, ist die Anweisung auch im aktuellen Musterkopf für AHK-Scripte (Neu -> AutoHotkey Script) nicht enthalten. Wenn eine Anwendung häufig mit Schleifen über größere Datenmengen arbeitet, kann sich das aber lohnen.

Wenn Du weitere Fragen hast, solltest Du die auf bestimmte Probleme in bestimmten Subroutinen beziehen. Dann kann das Stück für Stück weiter entwickelt werden, bis Du den Rest allein hinkriegst.

Bis dann!

just me

P.S.: Ich habe nicht ohne Hintergedanken das Tutorial über Arrays gerade jetzt gestartet. Ich arbeite weiter daran, sodass es sich lohnen könnte, da ab und zu mal reinzuschauen. ;)
Umek
Posts: 65
Joined: 06 Oct 2015, 12:40
Location: Germany

Re: Reihenfolge der INI Einträge in Verbindung mit ListView

14 Oct 2015, 15:38

Maximale Leistung hört sich gut an. Ich arbeite gerade das Tutorial durch und scheitere schon an Punkt 1. :headwall:

Code: Select all

AppINI=config.ini
Gosub, ReadINI
Gui, Add, Button, x5 y5 w200 h25 gButton1, AppDB
Gui, Add, Button, x5 y30 w200 h25 gButton2, Button
Gui, Add, Button, x5 y55 w200 h25 gButton3, Button
Gui, Add, Button, x5 y80 w200 h25 gButton4, Button
Gui, Add, Button, x5 y105 w200 h25 gButton5, Button
Gui, Add, Button, x5 y130 w200 h25 gButton6, Button
Gui, Add, Button, x5 y155 w200 h25 gButton7, Button
Gui, Show, w210 h190, Arrays
return


ReadINI:
   AppDB := [] ; leeres Array erstellen
   IniRead, TBSQuantity, %AppINI%, Textbausteine, Quantity
   Loop, %TBSQuantity%
   {
   	IniRead, TBSTitle, %AppINI%, Textbausteine, Title%A_Index%
   	IniRead, TBSText, %AppINI%, Textbausteine, Text%A_Index%
	AppDB.Push({Title: TBSTitle, Text: TBSText}) ; eingelesenen Werte anhängen
   }
Return

Button1:
	MsgBox, AppDB:`n%AppDB% ; WIESO IST ES LEER?
Return
Button2:

Return
Button3:

Return
Button4:

Return
Button5:

Return
Button6:

Return
Button7:

Return


GuiClose:
ExitApp

Code: Select all

[Textbausteine]
Quantity=5
Title1=Titel 1
Text1=Text 1
Title2=Titel 2
Text2=Text 2
Title3=Titel 3
Text3=Text 3
Title4=Titel 4
Text4=Text 4
Title5=Titel 5
Text5=Text 5
Was mache ich denn falsch? Ich kriege ja garnichts mehr hin.

Gruß
just me
Posts: 7093
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Reihenfolge der INI Einträge in Verbindung mit ListView

14 Oct 2015, 23:40

Moin!
Ich arbeite gerade das Tutorial durch und scheitere schon an Punkt 1.
Das mag durchaus am Tutorial liegen. Ich nutze Arrays schon eine ganze Weile, so wird es wohl immer wieder passieren, dass ich Dinge übergehe, die mir klar erscheinen, anderen aber nicht.

Zu Deinem Beispiel:
Die Variable AppDB enthält nicht das Array selbst als ausgeb-/anzeigbaren Text sondern nur eine Referenz / einen Verweis auf das Array. Die Hilfedatei sagt dazu weiter:
Dort, wo ein Objekt nicht erwartet wird, wird das Objekt als leerer String angesehen. Zum Beispiel würde MsgBox %objekt% eine leere MsgBox anzeigen und objekt + 1 einen leeren String zurückgeben. Verlasse dich nicht auf dieses Verhalten, weil es noch geändert werden könnte.
Deshalb zeigt Deine MsgBox nichts an.

Anzeigbare Zeichenfolgen findest Du erst in den einzelnen Elementen des Arrays. So würde AppDB[Index, "Title"] für Index = 1 den Titel des ersten Textbausteins ausgeben (andere Schreibweisen sind möglich). Um das komplette Array auszugeben, musst Du die Inhalte der Elemente z. B. (wie gezeigt) über eine For-Schleife zusammenfügen.

Reicht diese Erklärung?

just me
Umek
Posts: 65
Joined: 06 Oct 2015, 12:40
Location: Germany

Re: Reihenfolge der INI Einträge in Verbindung mit ListView

15 Oct 2015, 01:00

Guten Morgen,

super! Das reicht mir.

Offen gesagt weiß ich nicht was ich ohne dich täte. Vielen Dank dafür.

Man hört von mir. (hihi ...)

Gruß
Umek
Posts: 65
Joined: 06 Oct 2015, 12:40
Location: Germany

Re: Reihenfolge der INI Einträge in Verbindung mit ListView

15 Oct 2015, 11:28

Was stimmt mit mir nicht? Wie habe ich es überhaupt bis hier geschafft? Wieso geht das nicht? :headwall:

Code: Select all

AppINI=config.ini
Gosub, ReadINI
Gui, Add, Button, x5 y5 w200 h25 gButton1, MeinArray
Gui, Add, Button, x5 y30 w200 h25 gButton2, MeinArray.Pop()
Gui, Add, Button, x5 y55 w200 h25 gButton3, MeinArray.Length()
Gui, Add, Button, x5 y80 w200 h25 gButton4, MeinArray.InsertAt()
Gui, Add, Button, x5 y105 w200 h25 gButton5, MeinArray.RemoveAt()
; Gui, Add, Button, x5 y130 w200 h25 gButton6, Button
; Gui, Add, Button, x5 y155 w200 h25 gButton7, Button
Gui, Show, w210 h135, Arrays
return


ReadINI:
   AppDB := [] ; leeres Array erstellen
   IniRead, TBSQuantity, %AppINI%, Textbausteine, Quantity
   Loop, %TBSQuantity%
   {
   	IniRead, TBSTitle, %AppINI%, Textbausteine, Title%A_Index%
   	IniRead, TBSText, %AppINI%, Textbausteine, Text%A_Index%
	AppDB.Push({Title: TBSTitle, Text: TBSText}) ; eingelesenen Werte anhängen
   }
Return


; MeinArray
Button1: 
   For Index, TBS In AppDB
      AppDB .= "`nTitle" . Index . "=" . TBS.Title . "`nText" . Index . "=" . TBS.Text 
      MsgBox, %AppDB%
Return


; MeinArray.Pop()
Button2: 
LetzterWert := AppDB.Pop()
    MsgBox, %LetzterWert%
Return

; MeinArray.Length()
Button3:

Return

; MeinArray.InsertAt()
Button4:

Return

;MeinArray.RemoveAt()
Button5:

Return
Button6:

Return
Button7:

Return

GuiClose:
ExitApp

Code: Select all

[Textbausteine]
Quantity=5
Title1=Titel 1
Text1=Text 1
Title2=Titel 2
Text2=Text 2
Title3=Titel 3
Text3=Text 3
Title4=Titel 4
Text4=Text 4
Title5=Titel 5
Text5=Text 5
just me
Posts: 7093
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Reihenfolge der INI Einträge in Verbindung mit ListView

16 Oct 2015, 02:45

Moin Umek,

Code: Select all

; MeinArray
Button1: 
   For Index, TBS In AppDB
      AppDB .= "`nTitle" . Index . "=" . TBS.Title . "`nText" . Index . "=" . TBS.Text 
      MsgBox, %AppDB%
Return
Hier bist Du in die 'böseste Falle' getappt. Wie schon gesagt enthält die Variable AppDB einen Verweis auf das Array. In einer Anweisung AppDB .= ... wird sie allerdings als leere Zeichenfolge gesehen und mit der Zeichenfolge auf der rechten Seite überschrieben. Damit werden sowohl die Verbindung zum Array als auch das Array selbst zerstört. Merke: Benutze eine Variable, die auf ein Array zeigt, niemals als Ergebnis einer Zuweisung, wenn Du das Array anschließend noch brauchst.

Code: Select all

; MeinArray
Button1:
   Inhalt := ""
   For Index, TBS In AppDB
      Inhalt .= "`nTitle" . Index . "=" . TBS.Title . "`nText" . Index . "=" . TBS.Text 
   MsgBox, %Inhalt%
Return

Code: Select all

; MeinArray.Pop()
Button2: 
LetztesElement := AppDB.Pop()
    MsgBox, %LetzterWert%
Return
Das Array AppDB ist zweidimensional, d.h. jedes Element enthält wiederum ein Array, und zwar ein assoziatives mit den Schlüsseln Title und Text. (Ich bin mit dem Tutorium zu assoziativen Arrays noch nicht weitergekommen, weil mir kein sinnvolles und einfaches Beispiel für ein eindimensionales assoziatives Array einfallen wollte.) Die Anweisung AppDB.Pop() liefert also ein Arrayobjekt mit der bekannten Konsequenz: "Zum Beispiel würde MsgBox %objekt% eine leere MsgBox anzeigen". Die Werte erreichts Du nur über die Schlüssel:

Code: Select all

; MeinArray.Pop()
Button2: 
   LetztesElement := AppDB.Pop()
   MsgBox, % "Das letzte Element war`nTitle" . Index . "=" . LetztesElement.Title . "`nText" . Index . "=" . LetztesElement.Text 
Return
Und noch etwas: AppDB.Pop() entfernt das letzte Element aus dem Array. Willst Du das hier?

Umek wrote:Was stimmt mit mir nicht?
Du brauchst noch etwas Erfahrung/Praxis im Umgang mit AHK-Arrays. ;)

Grüße,
just me
Umek
Posts: 65
Joined: 06 Oct 2015, 12:40
Location: Germany

Re: Reihenfolge der INI Einträge in Verbindung mit ListView

16 Oct 2015, 06:32

Hallo Just Me,

ein herzliches Dankeschön für die ausführliche Erklärung.
Und noch etwas: AppDB.Pop() entfernt das letzte Element aus dem Array. Willst Du das hier?
Ich will das "nur" verstehen und wollte ein wenig rumprobieren. Ich glaube ich muss auf den zweiten Teil deines Tutorials warten.

Sorry, dass ich mich so blöd anstelle.

Viele Grüße

Umek
just me
Posts: 7093
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Reihenfolge der INI Einträge in Verbindung mit ListView

16 Oct 2015, 06:57

Umek wrote:Sorry, dass ich mich so blöd anstelle.
Was glaubst Du, wie man sich fühlt, wenn man schon einiges mit Arrays gemacht hat und dann in einem Skript nichts funktioniert, bis man nach langem Suchen und Probieren merkt, dass man versehentlich den Namen der Arrayvariablen an anderer Stelle noch einmal verwendet und sich deshalb mittendrin das Array zerschossen hat?

Man klopft sich auf die Schulter und sagt sich mit einem etwas schiefen Lächeln: "Aus Fehlern lernt man, und diesen habe ich immerhin gefunden!". ;)
Umek
Posts: 65
Joined: 06 Oct 2015, 12:40
Location: Germany

Re: Reihenfolge der INI Einträge in Verbindung mit ListView

16 Oct 2015, 10:06

Na du machst mir Mut.

Ich gebe für's erste auf, was den Einsatz dieser Arrays in meiner Anwendung betrifft. Ich werde die Nutzer der Anwendung bitten die Einträge manuell in der INI-Datei zu ändern oder hinzuzufügen. Ist ein bisschen Software zu Fuß, aber mir brummt der Schädel.

Ich danke dir vielmals für deine Unterstützung. Du hast mir sehr geholfen das eine oder andere zu verstehen. Das große Ganze will aber irgendwie nicht in mein Schädel.

Gruß

PS: Ich gucke gerne Filme in 3D, kann aber nicht mal zweidimensional denken! Wie eindimensional ist das denn! :crazy:
just me
Posts: 7093
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Reihenfolge der INI Einträge in Verbindung mit ListView

17 Oct 2015, 04:15

Moin Umek,

ich kann Dich natürlich nicht zwingen, aber ich fände es schade, wenn Du aufgeben würdest. Das Tutorial macht mir mehr Probleme als ich dachte. Es fällt mir schwer, sinnvolle Beispiele zu finden und das Ganze nicht 'zu technisch' werden zu lassen. Ich werde vielleicht auch die Reihenfolge ändern müssen, damit das (hoffentlich) verständlicher wird.

Ich Deinem Skript sind die Dinge aber noch recht übersichtlich, zumindest für mich. Und wir haben ja Wochenende, und Du hast damit vielleicht etwas mehr Ruhe, um das noch einmal durchzuarbeiten.

Was Du da brauchst ist ein zweidimensionales Array, d.h. jedes Element des Arrays beinhaltet wiederum ein Array.

Code: Select all

   +---+-------+
   I 1 I Title I
   I   I Text  I
   +---+-------+
   I 2 I Title I
   I   I Text  I
   +---+-------+
   I 3 I Title I
   I   I Text  I
   +---+-------+
Für die erste Dimension wird als Index die laufenden Nummern des Textbausteins in der INI verwendet. Die Indices entsprechen exakt den in der ListView angezeigten Nummern. Zwischen ListView und Array besteht damit eine eindeutige Beziehung. Beim Füllen der ListView wird dieser Arrayindex in die erste Spalte übertragen, für den Zugriff auf das Array kannst Du die erste Spalte der ListView auslesen und als Index nutzen.

Die zweite Dimension ist ein assoziatives Array mit zwei Schlüsseln: Title und Text. Unter dem Schlüssel Titel ist der in der INI im Key (Schlüssel) Titlen, unter dem Schlüssel Text der im INI-Key Textn abgelegt. Jeder Zugriff auf das Array AppDB über einen Index (Nummer) wie TBS := AppDB[Index] liefert deshalb in TBS ein Array, auf dessen Inhalte Du mit TBS.Title und TBS.Text zugreifen und mit diesen Werten dann die Spalten 2 und 3 der ListView bzw. die Felder der Gui 2 füllen kannst.

In der umgekehrten Richtung kannst Du ein neues Array TBS aufbauen und dieses dann einem Index in AppDB zuweisen:

Code: Select all

TBS := [] ; neues leeres Array erstellen
TBS["Title"] := TitelfeldInhalt ; Schlüssel Title erstellen und füllen, man kann auch TBS.Title := ... schreiben.
TBS["Text"] := TextfeldInhalt ; Schlüssel Text erstellen und füllen, man kann auch TBS.Text := ... schreiben
AppDB[Index] := TBS ; Array TBS im Array AppDB unter Index Index speichern.
Dasselbe in Kurzform erreicht man mit

Code: Select all

AppDB[Index] := {Title: TitelfeldInhalt, Text: TextfeldInhalt}
Dabei wird auf der rechten Seite der Zuweisung ein assoziatives Array per Objektsyntax {...} erstellt und dann im Array AppDB abgelegt. Die Schlüsselnamen müssen hier nicht in Anführungszeichen eingeschlossen werden, wenn sie nur aus Buchstaben, Ziffern und dem Unterstrich bestehen.

Innerhalb einer For-Schleife über das gesamte Array wie

Code: Select all

For Index, TBS In AppDB
werden die Inhalte beider Dimensionen in den Variablen Index und TBS abgelegt. Für die Verarbeitung innerhalb der Schleife liegen deshalb alle benötigten Werte in Index, TBS.Title (oder TBS["Title"]) und TBS.Text (oder TBS["Text"]).

Ich habe mal Dein Beispielskript mit Leben gefüllt. Es könnte noch etwas Feinschliff brauchen, aber vielleicht kannst Du damit das 'was und wie' besser verstehen, als nur mit meinen theoretischen Erläuterungen:

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
SetBatchLines, -1
;------------------------- Testhilfe -----------------------------------------------------------------------------------------------
TestINI := "
(Join`r`n
[Textbausteine]
Quantity=6
Title1=Titel 1
Text1=Text 1
Title2=Titel 2
Text2=Text 2
Title3=Titel 3
Text3=Text 3
Title4=Titel 4
Text4=Text 4
Title5=Titel 5
Text5=Text 5
Title6=Titel 6
Text6=Text 6
)"
;------------------------- Konstanten ----------------------------------------------------------------------------------------------
AppINI := "config.ini"
TBSSection := "Textbausteine"
;------------------------- INI -----------------------------------------------------------------------------------------------------
; If !FileExist(AppINI)
;    FileAppend, %TestINI%, %AppINI%, UTF-16
AppDB := [] ; leeres Array für die Werte ause der INI erstellen
IniRead, TBSAmount, %AppINI%, %TBSSection%, Quantity
Loop, %TBSAmount%
{
	IniRead, TBSTitle, %AppINI%, %TBSSection%, Title%A_Index%
	IniRead, TBSText, %AppINI%, %TBSSection%, Text%A_Index%
   AppDB.Push({Title: TBSTitle, Text: TBSText}) ; eingelesenen Werte anhängen
}
;------------------------- GUI 1 ---------------------------------------------------------------------------------------------------
Gui, 1:Add, ListView, x5 y5 w450 h220 vLV gG1LVEvents -Multi, Nr.|Titel|Text
LV_ModifyCol(1, "45 Integer Left")
LV_ModifyCol(2, 200)
LV_ModifyCol(3, 200)
If (AppDB.Length() = 0)
   SelectedTBS := 0
Else
   SelectedTBS := 1
Gosub, G1LVLoad
Gui, 1:Add, Button, x255 y229 w100 h24 gG1SaveINI, Speichern
Gui, 1:Add, Button, x355 y229 w100 h24 gG2Show, Bearbeiten
Gui, 1:Show, w460 h259, Test GUI
Return
;-------------------------
G1LVLoad:
   Gui, 1:Default
   Gui, ListView, LV
   GuiControl, -Redraw, LV
   LV_Delete()
   For Index, TBS In AppDB
      LV_Add("", Index, TBS.Title, TBS.Text)
   GuiControl, +Redraw, LV
   LV_Modify(SelectedTBS, "Select Focus Vis")
Return
;-------------------------
G1LVEvents:
   If (A_GuiEvent = "DoubleClick") {
      If (LV_GetNext() <> 0) {
         SelectedTBS := LV_GetNext()
         Gosub, G2Show
      }
   }
   If (LV_GetNext() = 0)
      LV_Modify(LV_GetNext(0, "Focus"), "Select")
Return
;-------------------------
G1SaveINI:
   IniDelete, %AppINI%, %TBSSection% ; vorhandene Section löschen
   NewContent := "Quantity=" . AppDB.Length() ; section neu aufbauen und ...
   For Index, TBS In AppDB
      NewContent .= "`nTitle" . Index . "=" . TBS.Title . "`nText" . Index . "=" . TBS.Text
   IniWrite, %NewContent%, %AppINI%, %TBSSection% ; ... wegschreiben
   GuiControl, Focus, LV
Return
;-------------------------
GuiClose:
ExitApp
;------------------------- GUI 2 ---------------------------------------------------------------------------------------------------
G2Show:
	If (SelectedTBS = 0) {
		TBS1 := ""
		TBS2 := ""
		TBS3 := ""
	}
	Else {
   	LV_GetText(TBS1, SelectedTBS, 1)
   	LV_GetText(TBS2, SelectedTBS, 2)
   	LV_GetText(TBS3, SelectedTBS, 3)
   }
	Gui, 1:+Disabled
	Gui, 2:Default
	Gui, 2:+AlwaysonTop
	Gui, 2:Margin, 5, 5
	Gui, 2:-MaximizeBox -MinimizeBox -Resize -SysMenu +Owner1 +ToolWindow
	Gui, 2:Add, Text, , Nr.
	Gui, 2:Add, Text, x60 yp, Titel:
	Gui, 2:Add, Edit, xm y+2 w50 h20 vG2Edit1 +Disabled, Edit
	Gui, 2:Add, Edit, x+m yp w345 h20 vG2Edit2, Edit
	Gui, 2:Add, Text, xm y+2, Text:
	Gui, 2:Add, Edit, xm y+2 w400 h20 vG2Edit3, Edit
	Gui, 2:Add, Button, xm w100 h24 gG2Add , Neu
	Gui, 2:Add, Button, x105 yp w100 h24 vG2BtnChange gG2Change, Ändern
	Gui, 2:Add, Button, x205 yp w100 h24 vG2BtnDelete gG2Delete, Löschen
	Gui, 2:Add, Button, x305 yp w100 h24 gG2Close, Abbrechen
	GuiControl, 2:, G2Edit1, %TBS1%
	GuiControl, 2:, G2Edit2, %TBS2%
	GuiControl, 2:, G2Edit3, %TBS3%
	If (SelectedTBS = 0) {
      GuiControl, 2:Disable, G2BtnChange
      GuiControl, 2:Disable, G2BtnDelete
   }
	Gui, 2:Show, , Textbaustein bearbeiten
Return
;-------------------------
G2Add:
   Gui, Submit, NoHide
   Gui, 1:Default
   Gui, 1:ListView, LV
   NewTBS := AppDB.Push({Title: G2Edit2, Text: G2Edit3})
   LV_Insert(NewTBS, "", NewTBS, G2Edit2, G2Edit3)
   LV_Modify(NewTBS, "Select Focus Vis")
   SelectedTBS := NewTBS
   GoSub, G2Close
Return
;-------------------------
G2Change:
   Gui, Submit, NoHide
   Gui, 1:Default
   Gui, 1:ListView, LV
   AppDB[SelectedTBS] := {Title: G2Edit2, Text: G2Edit3}
   LV_Modify(SelectedTBS, "Col2", G2Edit2)
   LV_Modify(SelectedTBS, "Col3", G2Edit3)
   GoSub, G2Close
Return
;-------------------------
G2Delete:
   Gui, 1:-Disabled
   Gui, 2:Destroy
   AppDB.RemoveAt(SelectedTBS)
   If (SelectedTBS > AppDB.Length())
      SelectedTBS := AppDB.Length()
   Gosub, G1LVLoad
   GoSub, G2Close
Return
;-------------------------
G2Close:
   Gui, 1:-Disabled
   Gui, 2:Destroy
   Gui, 1:Default
   GuiControl, 1:Focus, LV
Return
Fragen dazu werde ich gern beantworten, und wenn Du wirklich nicht mehr willst, ist das auch OK.

Übrigens: Ich würde wetten, dass Du es nicht schaffst, einen Fehler zu machen, den ich nicht auch schon mindestens einmal gemacht habe. ;)

Viel Erfolg!

just me
Umek
Posts: 65
Joined: 06 Oct 2015, 12:40
Location: Germany

Re: Reihenfolge der INI Einträge in Verbindung mit ListView

17 Oct 2015, 17:55

Ich verneige mich vor dir, deiner Geduld und der ermutigenden Worte. Dank dieser konnte ich das ganze zum Einsatz bringen. Das Beste dabei ist, dass ich anfange es zu verstehen. Die Suchfunktion funktioniert auch. Zudem konnte ich einige Fehler ausmerzen. Das muss alles noch verfeinert werden, aber das Grundgerüst steht. Selbst mit 500 Einträgen läuft es noch recht geschmeidig.

Code: Select all

SetBatchLines, -1
#SingleInstance, Force
;----------[ Konstanten 
Title=APP
Version=1.0
App := Title . " " . Version
AppINI := "config.ini"
; AppICO = %A_ScriptDir%\icons\app.ico
SBIconDefault = %A_ScriptDir%\icons\app.ico
TBSSection := "Textbausteine"

CrmCN=Herr Mustermann
CrmDate=31.12.2015
CrmCust=12345
CrmOrder=852825689421
 
 Gosub, ReadINI
;----------[ GUI 1 Tray Menü
Menu, Tray, NoStandard ; Removes all standard (non-custom) menu items
Menu, Tray, Icon, %AppICO%
Menu, Tray, Add, Öffnen, G1Show 
Menu, Tray, Add, Beenden, G1ExitApp 
Menu, Tray, Default, Öffnen  ; Make a double-click on tray icon show the GUI. 

;----------[ GUI 1 
Gui, 1:Font, s8 Q5, Arial
Gui, 1:Add, Button, Hidden Default gG1ButtonOK, OK
Gui, 1:Add, Edit, x2 y2 w320 h21 vEdit1 gG1FindIt, 
Gui, 1:Add, ListView, x2 y25 w750 h296 hwndLV1 vLV gG1ListViewEvents +AltSubmit -Multi, Nummer|Beschreibung|Textbaustein
	LV_ModifyCol(1,50)
	LV_ModifyCol(2,300)
	; LV_ModifyCol(2,728)
	LV_ModifyCol(3,300)
		If (AppDB.Length() = 0)
			SelectedTBS := 0
		Else
			SelectedTBS := 1
Gui, 1:Add, Text, x8 y328 w744 h58 vG1Edit2 c999999, 

;----------[ GUI 1 Statusbar
Gui, 1:Font, s8 Bold Q5, Arial
Gui, 1:Add, StatusBar, h30 vG1StatusBar +Theme, 
	SB_SetIcon(SBIconDefault)
	SB_SetParts(330, 330, 100)
	SB_SetText("Auftrags-Nr.: " CrmOrder, 1)
	SB_SetText("Endkunde: " CrmCN, 2)
	SB_SetText("Gesamt: " TBSAmount, 3)	
	
;----------[ GUI 1 Dateimenü
	Menu, FileMenu, Add, &Schließen, G1Hide
	Menu, FileMenu, Add, &Beenden, G1ExitApp
	; Menu, EditMenu, Add, &Neuer Eintrag, G2New
	Menu, EditMenu, Add, &Eintrag ändern, G2Show
	Menu, FileMenuBar, Add, &Datei, :FileMenu
	Menu, FileMenuBar, Add, &Bearbeiten, :EditMenu
Gui, 1:Menu, FileMenuBar
	GUIsVisible := False 
	Gosub, G1FillLV
Return
 
 ;----------[ Initialisierungsdatei lesen
ReadINI:
AppDB := [] ; leeres Array für die Werte ause der INI erstellen
IniRead, TBSAmount, %AppINI%, %TBSSection%, Quantity
Loop, %TBSAmount%
{
	IniRead, TBSTitle, %AppINI%, %TBSSection%, Title%A_Index%
	IniRead, TBSText, %AppINI%, %TBSSection%, Text%A_Index%
   AppDB.Push({Title: TBSTitle, Text: TBSText}) ; eingelesenen Werte anhängen
}
Gosub, G1FillLV
Return
 
 ;----------[ GUI 1 MenuHandler 
G1MenuHandler:

Return
 
 
 ;----------[ GUI 1 Button Ok
G1ButtonOK:
Gui,1: Submit, Nohide
    FocusedTBS =
    GuiControlGet, FocusedTBS, FocusV
    FocusedTBS := % LV_GetNext(0, "Focused")
    if (FocusedTBS = "0") 
    {
        MsgBox 8240, %GuiTitel%, Bitte wähle einen Eintrag aus.`t
        return
    }
    LV_GetText(TBSNo, FocusedTBS, 1)
    LV_GetText(TBSTitle, FocusedTBS, 2)
	LV_GetText(TBSText, FocusedTBS, 3)
	MsgBox, TBSNo:`t%TBSNo%`nTBSTitle:`t%TBSTitle%`nTBSText:`t%TBSText%
	Gosub, G1Insert
Return

;----------[ GUI 1 ListView befüllen
G1FillLV:
   Gui, 1:Default
   Gui, ListView, LV
   GuiControl, -Redraw, LV
   LV_Delete()
   For Index, TBS In AppDB
      LV_Add("", Index, TBS.Title, TBS.Text)
   GuiControl, +Redraw, LV
   LV_Modify(SelectedTBS, "Select Focus Vis")
ShowPreview()
Return

;----------[ GUI 1 Suche
G1FindIt:
Gui,1: Submit, Nohide
SRC := Edit1
if (SRC="")
   {
   Gosub,G1FillLV
   Return
   }
LV_Delete()
For Index, TBS In AppDB
  {
  LR := TBS.Title
  if SRC<>
     {
  	  re:="iUms)" Src ; Great job Mr. Unknown!
  	  if InStr(Src,A_Space) ; prepare regular expression to ensure search is done independent on the position of the words
		re:="iUms)(?=.*" RegExReplace(Src,"iUms)(.*)\s","$1)(?=.*") ")"
	  if RegExMatch(LR, re)
       {
		LV_Add("", Index, TBS.Title, TBS.Text)
       }
      ShowPreview() 
     }
  else
   Continue
   }
Return

;----------[ GUI 1 Show
!1::
G1Show:
{ 
   if GUIsVisible {
      Gui, 1:Hide 
	  Menu, Tray, Rename, Schließen, Öffnen
    }
   else {
        Gui, Show, w754 h415, %App%
		Menu, Tray, Rename, Öffnen, Schließen
		GuiControl, , Edit1
		GuiControl, Focus, Edit1
    }
   GUIsVisible := not GUIsVisible
}
ShowPreview()
Return
 

;----------[ GUI 1 schließen
G1Hide:
    Gui, 1:Hide 
	; Gui, 1:Cancel  ; Fenster verstecken 
    GUIsVisible := not GUIsVisible
	Menu, Tray, Rename, Schließen, Öffnen
	GuiControl, , Edit1, ; Edit1 leeren
	GuiControl, , G1Edit2, ; G1Edit2 leeren
Return

;----------[ GUI 1 Textbaustein einfügen
G1Insert:
    Gui, 1:Hide 
    GUIsVisible := not GUIsVisible
	Menu, Tray, Rename, Schließen, Öffnen
	TBSText := RegExReplace(TBSText, "<n>", "`n")
	SendInput, %TBSText%
Return
 
;----------[ GUI 1 ListView Aktionen
G1ListViewEvents:
Gui,1:Default
Gui,1:ListView, LV
    if(A_GuiEvent == "I") {
		 ShowPreview()
         }
    if(A_GuiEvent == "Normal") {
		ShowPreview()
         }
    if(A_GuiEvent == "DoubleClick") {
		LV_GetText(TBSText, A_EventInfo, 3)
		MsgBox, %TBSText%
		Gosub, G1Insert
        }
Return

;----------[ Initialisierungsdatei speichern
G1SaveINI:
IniDelete, %AppINI%, %TBSSection% ; vorhandene Section löschen
NewAppDB := "Quantity=" . AppDB.Length() ; section neu aufbauen und ...
	For Index, TBS In AppDB
		NewAppDB .= "`nTitle" . Index . "=" . TBS.Title . "`nText" . Index . "=" . TBS.Text
IniWrite, %NewAppDB%, %AppINI%, %TBSSection% ; ... wegschreiben
GuiControl, Focus, LV
Return

;----------[ Anwendung beenden
G1ExitApp:
	ExitApp
 return

;----------[ GUI 2 
G2Show:
	If (LV_GetNext() <> 0) {
         SelectedTBS := LV_GetNext()
	 }
	If (SelectedTBS = 0) {
		TBSNo := ""
		TBSTitle := ""
		TBSText := ""
	}
	Else {
   	LV_GetText(TBSNo, SelectedTBS, 1)
   	LV_GetText(TBSTitle, SelectedTBS, 2)
   	LV_GetText(TBSText, SelectedTBS, 3)
   }
Gui, 1:+Disabled
Gui, 2:Default
Gui, 2: +AlwaysonTop
Gui, 2:-MaximizeBox -MinimizeBox -Resize -SysMenu +ToolWindow
Gui, 2:Add, Edit, x2 y2 w576 h20 vG2Edit2, Edit
Gui, 2:Add, Edit, x2 y24 w576 h140 vG2Edit3, Edit
Gui, 2:Add, Edit, Hidden  vG2Edit1, 
Gui, 2:Add, Button, x178 y166 w100 h23 gG2Add, &Neu
Gui, 2:Add, Button, x278 y166 w100 h23 vG2BtnChange gG2Change, &Ändern
Gui, 2:Add, Button, x378 y166 w100 h23 vG2BtnDelete gG2Delete, &Löschen
Gui, 2:Add, Button, x478 y166 w100 h23 gG2Close, &Abbrechen

;----------[ GUI 2 Dateimenü
Menu, G2FileMenu, Add, Neu, G2Add
Menu, G2PluginsMenu, Add, Zwischenablage, G2PluginsMenuHandler
Menu, G2FileMenuBar, Add, &Datei, :G2FileMenu
Menu, G2FileMenuBar, Add, &Plugins, :G2PluginsMenu
Gui, 2:Menu, G2FileMenuBar
	If (SelectedTBS = 0) {
      GuiControl, 2:Disable, G2BtnChange
      GuiControl, 2:Disable, G2BtnDelete
   }
GuiControl, 2:, G2Edit1, %TBSNo%
GuiControl, 2:, G2Edit2, %TBSTitle%
GuiControl, 2:, G2Edit3, %TBSText%

;----------[ GUI 2 Statusbar
Gui, 2:Font, s8 Bold Q5, Arial
Gui, 2:Add, StatusBar, h30 vG2StatusBar +Theme, 
	SB_SetIcon(SBIconDefault)
	SB_SetParts(380, 100, 100)
	SB_SetText("Textbaustein: ", 1)
	SB_SetText("Nummer: " TBSNo, 2)
	SB_SetText("Gesamt: " TBSAmount, 3)
Gui, 2:Show, w580 h214, Eintrag Nr. %TBSNo%
Return

;----------[ GUI 2 Neuer Eintrag
G2Add:
   Gui, Submit, NoHide
   Gui, 1:Default
   Gui, 1:ListView, LV
   NewTBS := AppDB.Push({Title: G2Edit2, Text: G2Edit3})
   LV_Insert(NewTBS, "", NewTBS, G2Edit2, G2Edit3)
   LV_Modify(NewTBS, "Select Focus Vis")
   SelectedTBS := NewTBS
   GoSub, G2Close
Return

;----------[ GUI 2 Eintrag ändern
G2Change:
   Gui, Submit, NoHide
   Gui, 1:Default
   Gui, 1:ListView, LV
   AppDB[SelectedTBS] := {Title: G2Edit2, Text: G2Edit3}
   LV_Modify(SelectedTBS, "Col2", G2Edit2)
   LV_Modify(SelectedTBS, "Col3", G2Edit3)
   GoSub, G2Close
Return

;----------[ GUI 2 Eintrag löschen 
G2Delete:
   Gui, 1:-Disabled
   Gui, 2:Destroy
   AppDB.RemoveAt(SelectedTBS)
   If (SelectedTBS > AppDB.Length())
      SelectedTBS := AppDB.Length()
   Gosub, G1FillLV
   GoSub, G2Close
Return

;----------[ GUI 2 schließen
G2Close:
   Gui, 1:-Disabled
   Gui, 2:Destroy
   Gui, 1:Default
   GuiControl, 1:Focus, LV
   Gosub, G1SaveINI
Return

;----------[ GUI 2 Menü-Aktion
G2PluginsMenuHandler:
	MsgBox, Plugin Menu
Return

;----------[ GUI 1 Verschiedene Tastenkürzel
#If ActiveControlIs("SysListView321")
~Up::
ShowPreview()
Return
~Down::
ShowPreview()
Return
#If
 
;----------[ Endloser Bildlauf in der ListView
; http://www.autohotkey.com/board/topic/41349-example-endless-scrolling-in-a-listview/
#If (WinActive(App) and ActiveControlIs("Edit1"))
Up::
PreviousPos:=LV_GetNext()
if (PreviousPos = 0) ; exeption, focus is not on listview this will allow you to jump to last item via UP key
	{
	 ControlSend, SysListview321, {End}, %AppWindow%
	 Return
	}
ControlSend, SysListview321, {Up}, %AppWindow%
ItemsInList:=LV_GetCount()
ChoicePos:=PreviousPos-1
if (ChoicePos <= 1)
	ChoicePos = 1
if (ChoicePos = PreviousPos)
	ControlSend, SysListview321, {End}, %AppWindow%
ShowPreview()
Return
 
Down::
PreviousPos:=LV_GetNext()
ControlSend, SysListview321, {Down}, %AppWindow%
ItemsInList:=LV_GetCount()
ChoicePos:=PreviousPos+1
if (ChoicePos > ItemsInList)
	ChoicePos := ItemsInList
if (ChoicePos = PreviousPos)
	ControlSend, SysListview321, {Home}, %AppWindow%
ShowPreview()
Return
#If
 
ActiveControlIs(Control)
	{
	 ControlGetFocus, FocusedControl, A
	 if (FocusedControl = Control)
		Return 1
	 else
		Return 0	
	}
 
ShowPreview()
	{
	 Gui, Submit, NoHide
	 SelItem := LV_GetNext()
	 if (SelItem = 0)
	    SelItem = 1
	 LV_GetText(TBSText, SelItem, 3) ; Suche in der Sektion zwei (TBSText)
	 TBSText := RegExReplace(TBSText, "<n>", "`n")
	 GuiControl, , G1Edit2, %TBSText%
	}

;----------[ Anwendung neu laden
!r::
G1Reload:
	Reload
Return

;----------[ Anwendung beenden
GuiClose:
ExitApp

Code: Select all

[Textbausteine]
Quantity=99
Title1=Test Titel Nummer 1.
Text1=Ich bin der Textbaustein Nummer 1.<n>Zeile 2<n>Zeile 3<n>Zeile 4
Title2=Test Titel Nummer 2.
Text2=Ich bin der Textbaustein Nummer 2.<n>Zeile 2<n>Zeile 3<n>Zeile 4
Title3=Test Titel Nummer 3.
Text3=Ich bin der Textbaustein Nummer 3.<n>Zeile 2<n>Zeile 3<n>Zeile 4
Title4=Test Titel Nummer 4.
Text4=Ich bin der Textbaustein Nummer 4.<n>Zeile 2<n>Zeile 3<n>Zeile 4
Title5=Test Titel Nummer 5.
Text5=Ich bin der Textbaustein Nummer 5.<n>Zeile 2<n>Zeile 3<n>Zeile 4
Title6=Test Titel Nummer 6.1
Text6=Ich bin der Textbaustein Nummer 6.<n>Zeile 2<n>Zeile 3<n>Zeile 4<n>Zeile 5
Title7=Test Titel Nummer 7.
Text7=Ich bin der Textbaustein Nummer 7.<n>Zeile 2<n>Zeile 3<n>Zeile 4
Title8=Test Titel Nummer 8.
Text8=Ich bin der Textbaustein Nummer 8.<n>Zeile 2<n>Zeile 3<n>Zeile 4
Title9=Test Titel Nummer 9.
Text9=Ich bin der Textbaustein Nummer 9.<n>Zeile 2<n>Zeile 3<n>Zeile 4
Title10=Test Titel Nummer 10.
Text10=Ich bin der Textbaustein Nummer 10.<n>Zeile 2<n>Zeile 3<n>Zeile 4
Title11=Test Titel Nummer 11.
Text11=Ich bin der Textbaustein Nummer 11.<n>Zeile 2<n>Zeile 3<n>Zeile 4
Title12=Test Titel Nummer 12.
Text12=Ich bin der Textbaustein Nummer 12.<n>Zeile 2<n>Zeile 3<n>Zeile 4
Title13=Test Titel Nummer 13.
Text13=Ich bin der Textbaustein Nummer 13.<n>Zeile 2<n>Zeile 3<n>Zeile 4
Title14=Test Titel Nummer 14.
Text14=Ich bin der Textbaustein Nummer 14.<n>Zeile 2<n>Zeile 3<n>Zeile 4
Title15=Test Titel Nummer 15.
Text15=Ich bin der Textbaustein Nummer 15.<n>Zeile 2<n>Zeile 3<n>Zeile 4
Title16=Test Titel Nummer 16.
Text16=Ich bin der Textbaustein Nummer 16.<n>Zeile 2<n>Zeile 3<n>Zeile 4
Title17=Test Titel Nummer 17.
Text17=Ich bin der Textbaustein Nummer 17.<n>Zeile 2<n>Zeile 3<n>Zeile 4
Title18=Test Titel Nummer 18.
Text18=Ich bin der Textbaustein Nummer 18.<n>Zeile 2<n>Zeile 3<n>Zeile 4
Title19=Test Titel Nummer 19.
Text19=Ich bin der Textbaustein Nummer 19.<n>Zeile 2<n>Zeile 3<n>Zeile 4
Title20=Test Titel Nummer 20.
Text20=Ich bin der Textbaustein Nummer 20.<n>Zeile 2<n>Zeile 3<n>Zeile 4
Wenn das bei meinem Skript noch recht übersichtlich ist, bin ich erst recht gespannt auf das Tutorial. Wahrscheinlich wirft das mein Gefühl, es ein bisschen was verstanden zu haben, komplett über den Haufen. Mir haben in dem ersten Teil nur etwas die Beispiele gefehlt. Deshalb habe ich auch versucht mir das Ding mit den ganzen Schaltflächen zu bauen. Um zu verstehen, wie das in der Praxis aussieht. Aber ich habe eigentlich nichts mit Programmierung am Hut. Daher bin ich hin und wieder mal etwas begriffsstutzig. Ok, … in den letzten Tagen nur. ;) Ich vermute der Großteil hier hat bereits Erfahrung und liest das Tutorials wie ein Zeitungartikel.

Herzlichen Dank für's wiederbeleben und deine Engelsgeduld!

Viele viele Grüße

Umek
just me
Posts: 7093
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Reihenfolge der INI Einträge in Verbindung mit ListView

18 Oct 2015, 03:07

Moin Umek,

willkommen bei den Wiederbelebten! ;)
Umek wrote:Ich vermute der Großteil hier hat bereits Erfahrung und liest das Tutorials wie ein Zeitungartikel.
Nach dem Split der AHK-Foren haben sich hier überwiegend die versammelt, die schon mehr Skripterfahrung hatten, weil sie unter den willkürlichen Änderungen im alten Forum am meisten zu leiden hatten. Ich beschäftige mich z.B. schon seit mehr als 10 Jahren mit AHK. Nachdem ich gemerkt habe, was man mit AHK zustande bringen kann, ist es eine Art 'Lieblingshobby' für mich geworden.

Deshalb freue ich mich immer, wenn ein Neuer auftaucht und versucht, mit AHK eine 'richtige' Anwendung zu schreiben, nicht nur ein paar Hotkeys für Spiele. Dabei helfen zu können macht mir Spaß. Außerdem wird der Daseinszweck des deutschen Subforums bestätigt. Wenn Du also noch/wieder Fragen hast, immer wieder gern.

Für jemand, der 'eigentlich nichts mit Programmierung am Hut' hat, schlägst Du Dich übrigens meiner Meinung nach recht gut.

just me

Return to “Ich brauche Hilfe”

Who is online

Users browsing this forum: No registered users and 21 guests