[Release] GUI Inhalt dynamisch speichern

02/14/2013 22:25 Achat#1
Hi epvp!

Damit könnt ihr GUI Inhalte (Checkbox/Radio/Input/etc.) dynamisch speichern und laden:

Code:
; #FUNCTION# ====================================================================================================================
; Name ..........: _GUICtrlSaveState
; Description ...: Saves the state/text of gui controls
; Return values .: none
; Author ........: Achat
; Remarks .......: _GUICtrlLoadState()
; ===============================================================================================================================
Func _GUICtrlSaveState()
	Local Const $sINI = @ScriptDir & '\GUICtrlState.ini'
	For $i = 0 To 4096
		Local $vRead = GUICtrlRead($i)
		Local $vHandle = GUICtrlGetHandle($i)
		If Not ($vRead == 0 And $vHandle == 0) Then
			If IsInt($vRead) Then
				IniWrite($sINI, 'GuiCtrlState_CheckboxRadio', $i, StringRegExpReplace($vRead, '4', '0'))
			Else
				IniWrite($sINI, 'GuiCtrlState_Text', $i, StringToBinary($vRead))
			EndIf
		EndIf
	Next
	Local $sRead = FileRead($sINI)
	If Not StringRegExp($sRead, '^;.+') Then
		FileDelete($sINI)
		FileWrite($sINI, ';Please do not modify this file.' & @CRLF & $sRead)
	EndIf
EndFunc   ;==>_GUICtrlSaveState

; #FUNCTION# ====================================================================================================================
; Name ..........: _GUICtrlLoadState
; Description ...: Load the state/text of gui controls
; Return values .: none
; Author ........: Achat
; Remarks .......: _GuiCtrlSaveState()
; ===============================================================================================================================
Func _GUICtrlLoadState()
	Local Const $sINI = @ScriptDir & '\GUICtrlState.ini'
	Local $aCheckboxRadio = IniReadSection($sINI, 'GuiCtrlState_CheckboxRadio')
	Local $aText = IniReadSection($sINI, 'GuiCtrlState_Text')
	For $i = 1 To UBound($aCheckboxRadio) - 1
		GUICtrlSetState($aCheckboxRadio[$i][0], StringRegExpReplace($aCheckboxRadio[$i][1], '0', '4'))
	Next
	For $i = 1 To UBound($aText) - 1
		If Not GUICtrlGetHandle($aText[$i][0]) = 0 Then GUICtrlSetData($aText[$i][0], BinaryToString($aText[$i][1]))
	Next
EndFunc   ;==>_GUICtrlLoadState
Beispiel:

Code:
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Array.au3>
#region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 615, 438, 192, 124)
$Checkbox1 = GUICtrlCreateCheckbox("Checkbox1", 64, 32, 137, 41)
$Input1 = GUICtrlCreateInput("Input1", 56, 80, 185, 21)
$Button1 = GUICtrlCreateButton("Button1", 56, 120, 121, 17)
$Checkbox2 = GUICtrlCreateCheckbox("Checkbox2", 224, 128, 81, 33)
$Button2 = GUICtrlCreateButton("2222", 80, 248, 457, 137)
GUISetState(@SW_SHOW)
#endregion ### END Koda GUI section ###
#region ### START Koda GUI section ### Form=
$Form11 = GUICreate("Form2", 615, 438, 0, 0)
$Checkbox11 = GUICtrlCreateCheckbox("Checkbox1", 64, 32, 137, 41)
$Input11 = GUICtrlCreateInput("Input1", 56, 80, 185, 21)
$Button11 = GUICtrlCreateButton("Button1", 56, 120, 121, 17)
$Checkbox12 = GUICtrlCreateCheckbox("Checkbox2", 224, 128, 81, 33)
$Button12 = GUICtrlCreateButton("2222", 80, 248, 457, 137)
GUISetState(@SW_SHOW)
#endregion ### END Koda GUI section ###
_GUICtrlLoadState()
While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			_GUICtrlSaveState()
			Exit

	EndSwitch
WEnd

; #FUNCTION# ====================================================================================================================
; Name ..........: _GUICtrlSaveState
; Description ...: Saves the state/text of gui controls
; Return values .: none
; Author ........: Achat
; Remarks .......: _GUICtrlLoadState()
; ===============================================================================================================================
Func _GUICtrlSaveState()
	Local Const $sINI = @ScriptDir & '\GUICtrlState.ini'
	For $i = 0 To 4096
		Local $vRead = GUICtrlRead($i)
		Local $vHandle = GUICtrlGetHandle($i)
		If Not ($vRead == 0 And $vHandle == 0) Then
			If IsInt($vRead) Then
				IniWrite($sINI, 'GuiCtrlState_CheckboxRadio', $i, StringRegExpReplace($vRead, '4', '0'))
			Else
				IniWrite($sINI, 'GuiCtrlState_Text', $i, StringToBinary($vRead))
			EndIf
		EndIf
	Next
	Local $sRead = FileRead($sINI)
	If Not StringRegExp($sRead, '^;.+') Then
		FileDelete($sINI)
		FileWrite($sINI, ';Please do not modify this file.' & @CRLF & $sRead)
	EndIf
EndFunc   ;==>_GUICtrlSaveState

; #FUNCTION# ====================================================================================================================
; Name ..........: _GUICtrlLoadState
; Description ...: Load the state/text of gui controls
; Return values .: none
; Author ........: Achat
; Remarks .......: _GuiCtrlSaveState()
; ===============================================================================================================================
Func _GUICtrlLoadState()
	Local Const $sINI = @ScriptDir & '\GUICtrlState.ini'
	Local $aCheckboxRadio = IniReadSection($sINI, 'GuiCtrlState_CheckboxRadio')
	Local $aText = IniReadSection($sINI, 'GuiCtrlState_Text')
	For $i = 1 To UBound($aCheckboxRadio) - 1
		GUICtrlSetState($aCheckboxRadio[$i][0], StringRegExpReplace($aCheckboxRadio[$i][1], '0', '4'))
	Next
	For $i = 1 To UBound($aText) - 1
		If Not GUICtrlGetHandle($aText[$i][0]) = 0 Then GUICtrlSetData($aText[$i][0], BinaryToString($aText[$i][1]))
	Next
EndFunc   ;==>_GUICtrlLoadState
Viel Spaß

MfG
02/14/2013 23:38 butter123#2
habs nur kurz überflogen, dynamisch heißt es wird das was als letztes ausgewählt wurde beim nächsten start wieder ausgewählt? klingt gut^^
02/15/2013 00:22 Achat#3
Statt jedes Control einzeln speichern/laden zu müssen wie z.B.
Code:
GUICtrlSetData($Input1, IniRead($sINI, 'GUI', 'Input1', '1'))
GUICtrlSetData($Input2, IniRead($sINI, 'GUI', 'Input2', '2'))
GUICtrlSetData($Input3, IniRead($sINI, 'GUI', 'Input3', '3'))
GUICtrlSetData($Input4, IniRead($sINI, 'GUI', 'Input4', ''))
;etc

IniWrite($sINI, 'GUI', 'Input1', GUICtrlRead($Input1))
IniWrite($sINI, 'GUI', 'Input2', GUICtrlRead($Input2))
IniWrite($sINI, 'GUI', 'Input3', GUICtrlRead($Input3))
;etc.
übernimmt das nur eine Funktion.

Code:
_GUICtrlLoadState()
_GUICtrlSaveState()
Somit muss man auch nicht mehr neue Iniwrite/Guictrlsetdata Befehle für neue GUI - Controls hinzufügen.

MfG
02/15/2013 00:43 lolkop#4
Quote:
Originally Posted by Achat View Post
Statt jedes Control einzeln speichern/laden zu müssen wie z.B.
Code:
GUICtrlSetData($Input1, IniRead($sINI, 'GUI', 'Input1', '1'))
GUICtrlSetData($Input2, IniRead($sINI, 'GUI', 'Input2', '2'))
GUICtrlSetData($Input3, IniRead($sINI, 'GUI', 'Input3', '3'))
GUICtrlSetData($Input4, IniRead($sINI, 'GUI', 'Input4', ''))
;etc

IniWrite($sINI, 'GUI', 'Input1', GUICtrlRead($Input1))
IniWrite($sINI, 'GUI', 'Input2', GUICtrlRead($Input2))
IniWrite($sINI, 'GUI', 'Input3', GUICtrlRead($Input3))
;etc.
übernimmt das nur eine Funktion.

Code:
_GUICtrlLoadState()
_GUICtrlSaveState()
Somit muss man auch nicht mehr neue Iniwrite/Guictrlsetdata Befehle für neue GUI - Controls hinzufügen.

MfG
grundsätzlich sollte man immer nur das speichern, was ABSOLUT notwendig ist, da festplatten aktionen immer die langsamsten sind. abgesehn davon hat der user so die möglichkeit das sämtliche textstellen des programms mit einem einfachen editor zu ändern, was ebenfalls nicht schön ist.

in jedem erdenklichen falle sollte der programmierer immer darauf achten, das das programm nur das nötigste tut... dieses beispiel hier ist in meinen augen definitiv ein schritt in die falsche richtung.
02/15/2013 14:47 Achat#5
Quote:
Originally Posted by lolkop View Post
grundsätzlich sollte man immer nur das speichern, was ABSOLUT notwendig ist, da festplatten aktionen immer die langsamsten sind. abgesehn davon hat der user so die möglichkeit das sämtliche textstellen des programms mit einem einfachen editor zu ändern, was ebenfalls nicht schön ist.
[Only registered and activated users can see links. Click Here To Register...]

Dazu müsste ich irgendwie herausfinden, ob das Control ein Button/Input/Checkbox etc. ist. Es soll ja nur das gespeichert werden, was der User auch verändern kann (Input Inhalt etc.).

Ein weiteres Problem ist, da ja die Nummern von den Controls gespeichert werden, dass sich die Reihenfolge dieser Nummern ändert, wenn Controls entfernt oder hinzugefügt werden.
Ich müsste also die Nummer des Controls in den Variablennamen auflösen
Code:
Global $Input1 = GUICtrlCreateInput("Input1", 0, 0, 20, 20)
Also nicht den Wert von $Input1 speichern, sondern den Variablennamen, damit der Text eindeutig zu $Input1 zugeordnet werden kann.

Inhalt der *.ini
Code:
[GuiCtrlState_Text]
4=Input1
Es sollte aber so aussehen
Code:
[GuiCtrlState_Text]
$Input1=Input1
MfG
02/15/2013 15:12 lolkop#6
Quote:
Originally Posted by Achat View Post
Dazu müsste ich irgendwie herausfinden, ob das Control ein Button/Input/Checkbox etc. ist. Es soll ja nur das gespeichert werden, was der User auch verändern kann (Input Inhalt etc.).
auch das wäre nicht wirklich sinnvoll, da dynamische programme ohnehin viele controls abhängig vom zustand anderer controls setzen sollten.

denkbar sinnvoll wäre eine funktion, welche beispielsweise zu speichernde controls aufnehmen kann

beispiel:
Code:
GuiCreate(...)
[...]
$x = GuiCtrlCreate...
SetControlToBeSaved($x) ;eventeuell auch -1 als parameter ermöglichen
$y = GuiCtrlCreate...
SetControlToBeSaved($y)
[...]

LoadControlSettings()

While True
    Switch GuiGetMsg()
        Case -3
            SaveControlSettings()
            Exit
        [...]
    EndSwitch
WEnd
SetControlToBeSafed könnte in diesem beispiel sämtliche gewünschten controls in ein array sichern (im besten falle hier nicht die ControlId, sondern den variablen namen).

LoadControlSettings würde von sämtlichen variablen im array die settings aus der settingsdatei laden

SaveControlSettings würde von sämtlichen variablen im array die settings in der settingsdatei speichern
02/15/2013 23:46 Achat#7
Man kann Variablennamen leider nicht ausgeben lassen.

[Only registered and activated users can see links. Click Here To Register...]

Bei deinem Beispiel wäre ich dann wieder dabei, für jedes Control einzeln festzulegen, dass es gespeichert wird. Bei etwa 100+ Gui Controls ist das etwa der selbe Aufwand wie vorher auch :(

MfG
02/16/2013 00:29 lolkop#8
Quote:
Originally Posted by Achat View Post
Man kann Variablennamen leider nicht ausgeben lassen.

[Only registered and activated users can see links. Click Here To Register...]

Bei deinem Beispiel wäre ich dann wieder dabei, für jedes Control einzeln festzulegen, dass es gespeichert wird. Bei etwa 100+ Gui Controls ist das etwa der selbe Aufwand wie vorher auch :(

MfG
der punkt ist je eben, das genau das der fall sein MUSS, weil man keine überflüssigen controls speichern will/sollte/darf...

abgesehen davon ist es natürlich immer möglich variablen als strings zu übergeben. ob das ganze nun einfacher vom code her ist, bleibt natürlich fraglich, jedoch sollte klar sein, das diese methode deutlich übersichtlicher und sauber programmiert wäre, als später für jedes control einzeln die selben aktionen durchzuführen.