Что нового

Составление списка из каталога

Автор
E

eil

Новичок
Сообщения
53
Репутация
0
сравнение одного и того же каталога До и После сортировки =>
в Каталоге оказались 2 предмета с одинаковыми именами - почему они не оказались подряд на одной позиции? при этом Предеметы по сути одинаковы и именами и параметрами/значениями. отличие только в том, что тот который выпал из списка(стоит выше), имеет 2 дополнительных параметра.
это случайность, баг, или я упускаю что-то в логике алгоритма?

рассмотрел скрины, понял что ошибки нет. :whistle:
 

Вложения

  • 2016-12-18_204214.png
    2016-12-18_204214.png
    6.6 КБ · Просмотры: 6
  • 2016-12-18_204239.png
    2016-12-18_204239.png
    6.5 КБ · Просмотры: 7
Автор
E

eil

Новичок
Сообщения
53
Репутация
0
Alofa сказал(а):
eil сказал(а):
или я упускаю что-то ...
ТУМБА ЯЩИКИ KLZ 600
ТУМБА ЯЩИКИ KYZ 600
да уже опосля досмотрелся где разница, спасибо.


Добавлено:
Сообщение автоматически объединено:

немного потетсировал и заметил что все же такое оптимизированное решение несколько неудобно. понимаю что сортировка только при сохранении уместа для сокращения операций записи/чтения над временным файлом, но так проблема решается только на половину - да, вот котрыл базу, все удобно видно, но создал пару предметов и они вновь гдето далеко внизу, сохраняешься, переоткрыаешь чтоб увидеть всю картину, и вновь по кругу.
нет ли какого-то варианта чтоб визуально было видно сортировку сразу, а в базу сохранялось бы потом? или это все равно пересоздание временного файла при кадом факте сортировки?
 
Автор
E

eil

Новичок
Сообщения
53
Репутация
0
ra4o сказал(а):
При добавлении/изменении предмета в базе перезаписываю, сортирую ini файл и удаляю и создаю уже отсортированный список. Изменил там-же http://autoit-script.ru/index.php?topic=21218.msg133629#msg133629
тоесть при каждом изминении/добавлении предмета временный файл базы физически удаляется и создаётся снова чтобы быть отсортированным?
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
247
Да, именно так. В ini файле невозможно переставить секции местами по-этому я читаю в массив название секций, сортирую их , создаю новый , временный ini файл с уже отсортированными секциями, далее удаляю старый и переименовываю временный. С ListView поступаю аналогично - после действий с ini файлом - удаляю весь ListView и создаю новый с уже отсортированными значениями по алфавиту. Изнаяально зная все "хотелки" правильнее было-бы хранить базу не в ini файле, а создать базу данных, и теперь не пришлось-бы писать такие "костыли".
 
Автор
E

eil

Новичок
Сообщения
53
Репутация
0
сам не знал сколько всего по ходу прилетит, а тем более с базами данных мало имел дела.
спасибо за вариант, попробую параллельно с предидущим. все же факт постоянной перезаписи заставляет задуматься о износе/нагрузке на винт.
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
247
OffTopic:
задуматься о износе/нагрузке на винт.
Объём информации мизерный, ведь это обычный текстовый файл. Вы никогда не задумывались сколько сама винда, браузеры создают временных файлов ?
 
Автор
E

eil

Новичок
Сообщения
53
Репутация
0
OffTopic:
ra4o сказал(а):
OffTopic:
задуматься о износе/нагрузке на винт.
Объём информации мизерный, ведь это обычный текстовый файл. Вы никогда не задумывались сколько сама винда, браузеры создают временных файлов ?
не подумайте что я выпендриваюсь, про именно винт я скорей фигурально сказал. но скажем теже торренты я качаю на микросд в разьёме ноутбука, с пониманием что через год её придётся выбросить изза того как торренты гробят своим алгоритмом записи информации.


ради интереса: если бы применять тут структуру базы данных, главным изминением стало было более "прямое" взаимодействие с записями в каталоге, или ещё чтото?
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
247
Да, при выборке данных из базы можно в запросе указать , что нужна сортировка и при этом не важно в какой последовательности идут записи в базе.
 
Автор
E

eil

Новичок
Сообщения
53
Репутация
0
ещё вопрос: а перевести все эти преобразования(вобщем-то все "хотелки" которые появились после основной первой версии) на _IniVirtual это много мороки?
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
247
это много мороки?
Нет, не очень, можно попробовать.
Вот, тестируйте:
Код:
#include <GUIConstants.au3>
#include <ListboxConstants.au3>
#include <GuiListBox.au3>
#include <GuiListView.au3>
#include <File.au3>
#include <Array.au3>
#include <IniVirtualSPE.au3>



Global $ListView, $ContextMenu, $ListView_GUI, $EditObject_GUI, $EditParam = 0, $Name, $NameParam, $path, $Param, $line, $ListOll, $ListNew, $Create = 0
Global $ReportIni = '', $Item = 0
Global $PathIni = ''

$Main = GUICreate("", 850, 500, -1, -1, $WS_OVERLAPPEDWINDOW)

$Group1 = GUICtrlCreateGroup('Файл', 5, 2, 240, 90)
GUICtrlSetFont(-1, 12, 600, 0, "MS Sans Serif")
GUICtrlSetResizing(-1, $GUI_DOCKALL)
$OpenBut = GUICtrlCreateButton('Открыть', 15, 20, 70, 60, $BS_MULTILINE)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
$SaveBut = GUICtrlCreateButton('Сохранить', 90, 20, 70, 60, $BS_MULTILINE)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetStyle(-1, $BS_VCENTER)
$NewBaseBut = GUICtrlCreateButton('Новый файл', 165, 20, 70, 60, $BS_MULTILINE)
GUICtrlSetResizing(-1, $GUI_DOCKALL)

$Group2 = GUICtrlCreateGroup('Предмет', 265, 2, 315, 90)
GUICtrlSetFont(-1, 12, 600, 0, "MS Sans Serif")
GUICtrlSetResizing(-1, $GUI_DOCKALL)
$AddBut = GUICtrlCreateButton('Добавить', 275, 20, 70, 60, $BS_MULTILINE)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
$CopyBut = GUICtrlCreateButton('Копировать', 350, 20, 70, 60, $BS_MULTILINE)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
$EditBut = GUICtrlCreateButton('Редактиро-' & @CR & 'вать', 425, 20, 70, 60, $BS_MULTILINE)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
$DelBut = GUICtrlCreateButton('Удалить', 500, 20, 70, 60, $BS_MULTILINE)
GUICtrlSetResizing(-1, $GUI_DOCKALL)

$Group3 = GUICtrlCreateGroup('Список', 600, 2, 240, 90)
GUICtrlSetFont(-1, 12, 600, 0, "MS Sans Serif")
GUICtrlSetResizing(-1, $GUI_DOCKALL)
$AddListBut = GUICtrlCreateButton('Добавить в список', 610, 20, 70, 60, $BS_MULTILINE)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
$RemoveListBut = GUICtrlCreateButton('Удалить из' & @CR & 'списка', 685, 20, 70, 60, $BS_MULTILINE)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
$ReportBut = GUICtrlCreateButton('Отчёт', 760, 20, 70, 60, $BS_MULTILINE)
GUICtrlSetResizing(-1, $GUI_DOCKALL)

$ListOll = GUICtrlCreateList('', 10, 100, 410, 395, BitOR($WS_BORDER, $WS_VSCROLL, $LBS_NOINTEGRALHEIGHT))
GUICtrlSetFont(-1, 12, 600, 0, "MS Sans Serif")
GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKBOTTOM))
$ListNew = GUICtrlCreateList('', 430, 100, 410, 395, BitOR($WS_BORDER, $WS_VSCROLL, $LBS_NOINTEGRALHEIGHT))
GUICtrlSetFont(-1, 12, 600, 0, "MS Sans Serif")
GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKBOTTOM))

GUISetState(@SW_SHOW, $Main)


While 1
	$msg = GUIGetMsg()
	Select

		Case $msg = $GUI_EVENT_CLOSE

			Exit

		Case $msg = $CopyBut
			_Copy()

		Case $msg = $NewBaseBut
			NewBase()

		Case $msg = $AddBut
			_Add()

		Case $msg = $OpenBut
			_Open()

		Case $msg = $AddListBut
			_AddList()

		Case $msg = $RemoveListBut
			_Remove()

		Case $msg = $EditBut
			_Edit($Main)

		Case $msg = $DelBut
			_Del()

		Case $msg = $SaveBut
			SaveBase()

		Case $msg = $ReportBut
			Report()

	EndSelect

	_PaintBut()

	_HotKey()

WEnd


Func _Open()
	$path = FileOpenDialog('Выбор файла каталога', @ScriptDir, 'ini file (*.ini)')
	If Not @error Then
		WinSetTitle('', '', $path)
		$ReportIni = '';Обнуление виртуального отчёта ini
		$PathIni = FileRead($path)
		$CreateData = 0

		_GUICtrlListBox_ResetContent($ListOll)
		_GUICtrlListBox_ResetContent($ListNew)

		_SortTempIni()
		_CreateListFromIni('')
	EndIf
EndFunc   ;==>_Open


Func _AddList()

	$Subject = GUICtrlRead($ListOll)

	If _IniVirtualSPE_Read($ReportIni, 'Предмет', $Subject, '-1') < 0 Then
		_IniVirtualSPE_Write($ReportIni, 'Предмет', $Subject, 1)
	Else
		_IniVirtualSPE_Write($ReportIni, 'Предмет', $Subject, _IniVirtualSPE_Read($ReportIni, 'Предмет', $Subject, '') + 1)
	EndIf

	$Parametr = _IniVirtualSPE_ReadSection($PathIni, $Subject)
	For $i = 1 To $Parametr[0][0]
		$Znach = _IniVirtualSPE_Read($ReportIni, 'Параметр', $Parametr[$i][0], '0')
		If $Parametr[$i][1] > 0 Then _IniVirtualSPE_Write($ReportIni, 'Параметр', $Parametr[$i][0], $Znach + $Parametr[$i][1])
	Next

	_GUICtrlListBox_BeginUpdate($ListNew)
	$Item = _GUICtrlListBox_FindString($ListNew, $Subject & '  X' & _IniVirtualSPE_Read($ReportIni, 'Предмет', $Subject, '') - 1, True)

	If $Item >= 0 Then
		_GUICtrlListBox_DeleteString($ListNew, $Item)
		_GUICtrlListBox_InsertString($ListNew, $Subject & '  X' & _IniVirtualSPE_Read($ReportIni, 'Предмет', $Subject, ''), $Item)
		_GUICtrlListBox_EndUpdate($ListNew)
	Else
		_GUICtrlListBox_AddString($ListNew, $Subject & '  X' & _IniVirtualSPE_Read($ReportIni, 'Предмет', $Subject, ''))
	EndIf

	_GUICtrlListBox_EndUpdate($ListNew)
EndFunc   ;==>_AddList


Func _Remove()

	$index = _GUICtrlListBox_GetCurSel($ListNew)
	$SubjectX = StringInStr(GUICtrlRead($ListNew), 'X', 1, -1)
	$Subject = StringLeft(GUICtrlRead($ListNew), $SubjectX - 3)

	If $index >= 0 Then
		$ZnachPredm = _IniVirtualSPE_Read($ReportIni, 'Предмет', $Subject, '') - 1
		If $ZnachPredm == 0 Then
			_IniVirtualSPE_Delete($ReportIni, 'Предмет', $Subject)
		Else
			_IniVirtualSPE_Write($ReportIni, 'Предмет', $Subject, $ZnachPredm)
		EndIf

		$Parametr = _IniVirtualSPE_ReadSection($PathIni, $Subject)
		For $i = 1 To $Parametr[0][0]
			$Znach = _IniVirtualSPE_Read($ReportIni, 'Параметр', $Parametr[$i][0], '0') - $Parametr[$i][1]
			If $Znach == 0 Then
				_IniVirtualSPE_Delete($ReportIni, 'Параметр', $Parametr[$i][0])
			Else
				_IniVirtualSPE_Write($ReportIni, 'Параметр', $Parametr[$i][0], $Znach)
			EndIf

		Next

		_GUICtrlListBox_BeginUpdate($ListNew)

		_GUICtrlListBox_DeleteString($ListNew, $index)
		If _IniVirtualSPE_Read($ReportIni, 'Предмет', $Subject, '0') > 0 Then
			$string = $Subject & '  X' & _IniVirtualSPE_Read($ReportIni, 'Предмет', $Subject, '')
			_GUICtrlListBox_InsertString($ListNew, $string, $index)
			_GUICtrlListBox_ClickItem($ListNew, $index)
		EndIf

		_GUICtrlListBox_EndUpdate($ListNew)

	EndIf
EndFunc   ;==>_Remove


Func _Del()
	_GUICtrlListBox_BeginUpdate($ListOll)
	$index = GUICtrlSendMsg($ListOll, $LB_GETCURSEL, 0, 0)
	$DelName = GUICtrlRead($ListOll)
	If MsgBox(32 + 1, 'Внимание !', 'Вы действительно хотите удалить ' & $DelName & '?') = 1 Then
		_GUICtrlListBox_DeleteString($ListOll, $index)
		_IniVirtualSPE_Delete($PathIni, $DelName)
	EndIf
	_GUICtrlListBox_EndUpdate($ListOll)
	$Create = 1

EndFunc   ;==>_Del


Func _PaintBut()

	If $Create Then
		$Create = Not $Create
		GUICtrlSetBkColor($SaveBut, 0xFF4500)
	EndIf
EndFunc   ;==>_PaintBut


Func _HotKey()
	If WinActive($Main) Then
		$Fokus = ControlGetFocus($path)

		Switch $Fokus
			Case 'Button1'
				HotKeySet("{Enter}")
			Case 'Button2'
				HotKeySet("{Enter}")
			Case 'Button3'
				HotKeySet("{Enter}")
			Case 'Button6'
				HotKeySet("{Enter}")
			Case 'Button7'
				HotKeySet("{Enter}")
			Case 'Button8'
				HotKeySet("{Enter}")
			Case 'Button10'
				HotKeySet("{Enter}")
			Case 'Button11'
				HotKeySet("{Enter}")
			Case 'Button12'
				HotKeySet("{Enter}")
			Case 'ListBox1'
				$line = _GUICtrlListBox_GetCurSel($ListOll)
				If $line >= 0 Then HotKeySet("{Enter}", "_Edit_")
			Case 'ListBox2'
				HotKeySet("{Enter}")

		EndSwitch
	Else
		HotKeySet("{Enter}")
	EndIf

EndFunc   ;==>_HotKey


Func _Add()

	_GUICtrlListBox_SetCurSel($ListOll, _AddObject($Main))
	ControlFocus($Main, '', $ListOll)

EndFunc   ;==>_Add


Func _Copy()
	_GUICtrlListBox_SetCurSel($ListOll, _AddObject($Main, 1))
	ControlFocus($Main, '', $ListOll)
EndFunc   ;==>_Copy


Func _Edit_()
	HotKeySet("{Enter}")
	_Edit($Main)
	GUICtrlSetState($ListOll, $GUI_FOCUS)
EndFunc   ;==>_Edit_


Func SaveBase()

	$NewBaseFile = FileSaveDialog('Выберите название нового файла базы ', @ScriptDir, 'ini файл(*.ini)', 0, 'Новая база')
	If Not @error Then
		If $PathIni <> '' Then
			_SortTempIni();Функция сортировки секций ини файла по алфавиту
			If FileExists($NewBaseFile) Then
				$answer = MsgBox(48 + 3, 'Внимание !', 'Файл базы ' & @CR & $NewBaseFile & @CR & 'уже существует , заменить ?' & @CR & 'Нет - сохранить отчёт под другим именем')
				Select
					Case $answer = 6
						FileDelete($NewBaseFile)
						FileWrite($NewBaseFile, $PathIni)
						If Not @error Then GUICtrlSetBkColor($SaveBut, 0x00CD00)
						$CreateData = @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC
						$NewFileIniData = $CreateData
					Case $answer = 7
						SaveBase()
				EndSelect
			Else
				FileWrite($NewBaseFile, $PathIni)
				ConsoleWrite(@error & @CR)
				If Not @error Then GUICtrlSetBkColor($SaveBut, 0x00CD00)
				$CreateData = @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC
				$NewFileIniData = $CreateData
			EndIf
		Else
			MsgBox(48, 'Ошибка !', 'Невозможно сохранить файл,' & @CR & 'так как никаких изменнений небыло.')
		EndIf
	EndIf

EndFunc   ;==>SaveBase


Func _SortTempIni()
	$NewIni = ''
	$aSections = _IniVirtualSPE_ReadSectionNames($PathIni)
	_ArraySort($aSections)
	For $i = 1 To $aSections[0]
		$aKey = _IniVirtualSPE_ReadSection($PathIni, $aSections[$i])
		For $j = 1 To $aKey[0][0]
			_IniVirtualSPE_Write($NewIni, $aSections[$i], $aKey[$j][0], $aKey[$j][1])
		Next
	Next

	$PathIni = $NewIni

EndFunc   ;==>_SortTempIni


Func NewBase()

	$NewFile = FileSaveDialog('Укажите новый файл базы', @ScriptDir, 'ini файл(*.ini)', 0, 'Новая база')
	If Not @error Then
		If Not FileExists($NewFile) Then
			_FileCreate($NewFile)
			$PathIni = ''
			WinSetTitle('', '', $NewFile)
			_GUICtrlListBox_ResetContent($ListOll)
			_GUICtrlListBox_ResetContent($ListNew)
			GUICtrlSetBkColor($SaveBut, 0xE8E8E8)
		Else
			MsgBox(48, 'Ошибка !', 'Такой файл уже существует !' & @CR & 'Укажите другое имя файла !')
			NewBase()
		EndIf
	EndIf

EndFunc   ;==>NewBase


Func Report()

	If $ReportIni <> '' Then
		$ReportFile = FileSaveDialog('Выберите файл отчёта', @ScriptDir, 'Текстовый файл(*.txt)', 0, 'Отчёт')

		If FileExists($ReportFile) Then
			$answer = MsgBox(48 + 3, 'Внимание !', 'Файл отчёта ' & @CR & $ReportFile & @CR & 'уже существует , заменить ?' & @CR & 'Нет - сохранить отчёт под другим именем')
			Select
				Case $answer = 6 ;Да
					CreateRepport($ReportFile)
				Case $answer = 7 ;Нет
					Report()

			EndSelect
		Else

			CreateRepport($ReportFile)

		EndIf

	Else
		MsgBox(48, 'Ошибка !', 'Не найден временный файл отчёта !')
	EndIf

EndFunc   ;==>Report


Func CreateRepport($ReportFile)

	$RepSub = _IniVirtualSPE_ReadSection($ReportIni, 'Предмет')

	If Not @error Then
		Dim $text[$RepSub[0][0]][2]
		For $i = 1 To $RepSub[0][0]
			$text[$i - 1][0] = $RepSub[$i][0] & ' = ' & $RepSub[$i][1]
		Next

	EndIf

	$RepParam = _IniVirtualSPE_ReadSection($ReportIni, 'Параметр')
	If Not @error Then
		ReDim $text[UBound($RepParam) + $i][1]
		For $j = 1 To UBound($RepParam) - 1
			$text[$j + $i - 1][0] = 'Сумма ' & $RepParam[$j][0] & ' = ' & $RepParam[$j][1]
		Next

		_FileWriteFromArray($ReportFile, $text)
		If Not @error Then MsgBox(48, 'Сохранение отчёта', 'Отчёт сохранён в файле ' & @CR & $ReportFile, 3)

	EndIf

EndFunc   ;==>CreateRepport


Func _AddObject($hParent = 0, $CopyName = 0)

	$Opt = Opt("GUIOnEventMode", 0)
	$Result = 0
	$ListView_GUI = GUICreate('Добавить новый предмет', 300, 400, -1, -1, -1, -1, $hParent)

	$EditName = GUICtrlCreateInput('Название предмета', 10, 10, 280, 30)
	GUICtrlSetFont(-1, 16, 400, 0, "MS Sans Serif")

	$ListView = GUICtrlCreateListView('Название параметра|Значение параметра', 10, 50, 280, 300, -1, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))

	If $CopyName Then

		$Items = _IniVirtualSPE_ReadSection($PathIni, GUICtrlRead($ListOll))
		For $i = 1 To UBound($Items) - 1
			_GUICtrlListView_AddItem($ListView, $Items[$i][0])
			_GUICtrlListView_AddSubItem($ListView, $i - 1, $Items[$i][1], 1, 2)
		Next

	EndIf

	$DummyMenu = GUICtrlCreateDummy()
	$ContextMenu = GUICtrlCreateContextMenu($DummyMenu)
	$ItemCreate = GUICtrlCreateMenuItem("Создать параметр", $ContextMenu)
	$ItemDelete = GUICtrlCreateMenuItem("Удалить параметр", $ContextMenu)

	$OkBut = GUICtrlCreateButton('Добавить', 100, 355, 100, 40)

	GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')
	GUISetState(@SW_DISABLE, $hParent)
	GUISetState(@SW_SHOW, $ListView_GUI)

	$EditParam = 0

	While 1
		$nMsg = GUIGetMsg()

		Switch $nMsg
			Case $GUI_EVENT_CLOSE
				ExitLoop
			Case $OkBut

				$Name = GUICtrlRead($EditName)

				$Items = _GUICtrlListView_GetItemCount($ListView)
				If $Items > 0 Then
					For $i = 0 To $Items - 1
						_IniVirtualSPE_Write($PathIni, $Name, _GUICtrlListView_GetItemText($ListView, $i, 0), _GUICtrlListView_GetItemText($ListView, $i, 1))
					Next
					$Create = 1
				Else
					MsgBox(48, 'Ошибка !', 'Невозможно добавить предмет без параметров !', 3)
					ExitLoop
				EndIf
				_SortTempIni()

				$Result = _CreateListFromIni($Name)

				ExitLoop

			Case $ItemCreate
				AddLine($ListView, GUICtrlRead($EditName), $ListView_GUI)

			Case $ItemDelete
				DelLine($ListView, GUICtrlRead($EditName), $hParent)

		EndSwitch
		If $EditParam Then NewObject($ListView, $ListView_GUI)
		$Fokus = ControlGetFocus('Добавить новый предмет')
		;   ConsoleWrite($Fokus&@CR)
		If $Fokus == 'SysListView321' Then
			HotKeySet("{Enter}", "_Add_")
		Else
			HotKeySet("{Enter}")
		EndIf

	WEnd

	HotKeySet("{Enter}")

	Opt("GUIOnEventMode", $Opt)
	GUISetState(@SW_ENABLE, $hParent)
	GUIDelete($ListView_GUI)
	Return $Result
EndFunc   ;==>_AddObject


Func _CreateListFromIni($Name)

	_GUICtrlListBox_ResetContent($ListOll)
	$aSection = _IniVirtualSPE_ReadSectionNames($PathIni)
	For $i = 1 To $aSection[0]
		_GUICtrlListBox_AddString($ListOll, $aSection[$i])
		If $Name = '' Then
			$Item = 0
		Else
			If $Name = $aSection[$i] Then $Item = $i - 1
		EndIf

	Next
	_GUICtrlListBox_SetCurSel($ListOll, $Item)
	Return $Item
EndFunc   ;==>_CreateListFromIni


Func _Add_()
	HotKeySet("{Enter}")
	NewObject($ListView, $ListView_GUI)
EndFunc   ;==>_Add_


Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
	Local $hWndFrom, $iCode, $tNMHDR, $hWndListView, $tInfo

	$hWndListView = $ListView
	If Not IsHWnd($ListView) Then $hWndListView = GUICtrlGetHandle($ListView)

	$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
	$hWndFrom = HWnd(DllStructGetData($tNMHDR, 'hWndFrom'))
	$iCode = DllStructGetData($tNMHDR, 'Code')

	Switch $hWndFrom
		Case $hWndListView
			Switch $iCode
				Case $NM_DBLCLK ;двойной клик левой кнопки мыши
					$tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
					$iIndex = DllStructGetData($tInfo, 'Index')

					If $iIndex <> -1 Then

						$iLast_LV_Index = $iIndex

						$NameParam = ControlListView("", "", $ListView, "GetText", $iLast_LV_Index, 0)
						$Param = ControlListView("", "", $ListView, "GetText", $iLast_LV_Index, 1)

						$line = $iLast_LV_Index + 1

						$EditParam = 1

					EndIf

				Case $NM_RCLICK ;один клик правой кнопки мыши
					$tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
					$iIndex = DllStructGetData($tInfo, 'Index')

					If $iIndex <> -1 Then

						$iLast_LV_Index = $iIndex
						$NameParam = ControlListView("", "", $ListView, "GetText", $iLast_LV_Index, 0)
						$line = $iLast_LV_Index + 1

					EndIf
					ShowMenu($hWnd, $ContextMenu, $ListView, 1)

			EndSwitch
	EndSwitch

	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY


Func ShowMenu($hWnd, $nContextID, $nContextControlID, $iMouse = 0)
	Local $hMenu = GUICtrlGetHandle($nContextID)
	Local $iCtrlPos = ControlGetPos($hWnd, "", $nContextControlID)

	Local $X = $iCtrlPos[0]
	Local $Y = $iCtrlPos[1] + $iCtrlPos[3]

	ClientToScreen($hWnd, $X, $Y)

	If $iMouse Then
		$X = MouseGetPos(0)
		$Y = MouseGetPos(1)
	EndIf

	DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $X, "int", $Y, "hwnd", $hWnd, "ptr", 0)
EndFunc   ;==>ShowMenu


Func ClientToScreen($hWnd, ByRef $X, ByRef $Y)
	Local $stPoint = DllStructCreate("int;int")

	DllStructSetData($stPoint, 1, $X)
	DllStructSetData($stPoint, 2, $Y)

	DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $hWnd, "ptr", DllStructGetPtr($stPoint))

	$X = DllStructGetData($stPoint, 1)
	$Y = DllStructGetData($stPoint, 2)
	$stPoint = 0
EndFunc   ;==>ClientToScreen


Func NewObject($ListView, $hParent1 = 0)
	$EditParam = 0
	$Item = _GUICtrlListView_GetSelectedIndices($ListView, True)
	If $Item[0] > 0 Then
		$Name = _GUICtrlListView_GetItemText($ListView, $Item[1])
		$Param = _GUICtrlListView_GetItemText($ListView, $Item[1], 1)
		Local $NewParam_GUI, $iGOEM_Opt

		$iGOEM_Opt = Opt("GUIOnEventMode", 0)

		$NewParam_GUI = GUICreate($Name, 150, 150, -1, -1, $WS_BORDER, -1, $hParent1)

		$NewParam = GUICtrlCreateInput($Param, 20, 20, 100, 30)
		GUICtrlSetFont(-1, 12, 600, 0, "MS Sans Serif")
		$OK = GUICtrlCreateButton('OK', 10, 70, 60, 30)
		$Cancel = GUICtrlCreateButton('Exit', 75, 70, 60, 30)

		GUISetState(@SW_DISABLE, $hParent1)
		GUISetState(@SW_SHOW, $NewParam_GUI)

		While 1
			$nMsg = GUIGetMsg()

			Switch $nMsg
				Case $GUI_EVENT_CLOSE
					ExitLoop
				Case $Cancel
					ExitLoop

				Case $OK
					$sText = StringReplace(GUICtrlRead($NewParam), ',', '.')
					$iDec = StringInStr($sText, '.', Default, 2);Количество точек в строке, кроме первой
					If $iDec > 0 Then $sText = StringReplace($sText, '.', '', 1 - $iDec);Убрать все точки, кроме первой

					$sText = StringRegExp($sText, '(\d+(\.(\d+)?)?)', 2)
					If @error Then
						_GUICtrlListView_SetItem($ListView, '', $Item[1], 1)
					Else
						_GUICtrlListView_SetItem($ListView, $sText[0], $Item[1], 1)
					EndIf

					ExitLoop

			EndSwitch

		WEnd

		Opt("GUIOnEventMode", $iGOEM_Opt)
		GUISetState(@SW_ENABLE, $hParent1)
		GUIDelete($NewParam_GUI)
	Else
		MsgBox(48, 'Ошибка !', 'Не выделена строка с параметром !')
	EndIf

EndFunc   ;==>NewObject


Func _Edit($hParent = 0)

	$EditParam = 0

	$Subject = GUICtrlRead($ListOll)

	$iGOEM_Opt = Opt("GUIOnEventMode", 0)

	$EditObject_GUI = GUICreate('Редактирование предмета', 300, 410, -1, -1, -1, -1, $hParent)

	$EditName = GUICtrlCreateInput($Subject, 10, 10, 280, 30)
	GUICtrlSetFont(-1, 12, 600, 0, "MS Sans Serif")
	$ListView = GUICtrlCreateListView('Название параметра|Значение параметра', 10, 45, 280, 300, -1, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_REPORT))

	$Items = _IniVirtualSPE_ReadSection($PathIni, $Subject)
	If Not @error Then
		For $i = 1 To UBound($Items) - 1
			_GUICtrlListView_AddItem($ListView, $Items[$i][0])
			_GUICtrlListView_AddSubItem($ListView, $i - 1, $Items[$i][1], 1, 2)
		Next
		ControlFocus($EditObject_GUI, 'Редактирование предмета', $ListView)
		_GUICtrlListView_SetItemSelected($ListView, 0)
	EndIf

	$DummyMenu = GUICtrlCreateDummy()
	$ContextMenu = GUICtrlCreateContextMenu($DummyMenu)
	$ItemCreate = GUICtrlCreateMenuItem("Создать параметр", $ContextMenu)
	$ItemDelete = GUICtrlCreateMenuItem("Удалить параметр", $ContextMenu)
	$ItemRename = GUICtrlCreateMenuItem("Переименовать параметр", $ContextMenu)

	$OK = GUICtrlCreateButton('OK', 110, 355, 80, 40)

	GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')
	GUISetState(@SW_DISABLE, $hParent)
	GUISetState(@SW_SHOW, $EditObject_GUI)

	While 1
		$nMsg = GUIGetMsg()

		Switch $nMsg
			Case $GUI_EVENT_CLOSE
				ExitLoop

			Case $ItemRename
				_RenameParam($ListView, $Subject, $EditObject_GUI)

			Case $OK
				$Create = 1
				$NewSubject = GUICtrlRead($EditName)
				_IniVirtualSPE_Delete($PathIni, $NewSubject)
				For $i = 0 To _GUICtrlListView_GetItemCount($ListView) - 1
					_IniVirtualSPE_Write($PathIni, $NewSubject, _GUICtrlListView_GetItemText($ListView, $i), _GUICtrlListView_GetItemText($ListView, $i, 1))
				Next

				If $NewSubject <> $Subject Then
					_IniVirtualSPE_Delete($PathIni, $Subject)
					_SortTempIni()
					_CreateListFromIni($PathIni)
				EndIf
				ExitLoop

			Case $ItemCreate
				AddLine($ListView, $Subject, $EditObject_GUI)

			Case $ItemDelete
				DelLine($ListView, $Subject, $EditObject_GUI)

		EndSwitch
		If $EditParam Then NewObject($ListView, $EditObject_GUI)

		$Fokus = ControlGetFocus($EditObject_GUI)
		If $Fokus == 'Button1' Then
			HotKeySet("{Enter}")
		Else
			HotKeySet("{Enter}", "_EditParam_")
		EndIf

	WEnd
	HotKeySet("{Enter}")
	Opt("GUIOnEventMode", $iGOEM_Opt)
	GUISetState(@SW_ENABLE, $hParent)
	GUIDelete($EditObject_GUI)
	ControlFocus($Main, '', $ListOll)
EndFunc   ;==>_Edit


Func _RenameParam($ListView, $ObjName, $hParent)

	Local $NewLine_GUI, $iGOEM_Opt

	$iGOEM_Opt = Opt("GUIOnEventMode", 0)
	$EditParamName = _GUICtrlListView_GetItemText($ListView, $line - 1)

	$EditLine_GUI = GUICreate('Переименовать параметр ' & $EditParamName, 260, 160, -1, -1, $WS_BORDER, -1, $hParent)

	$NewParamName = GUICtrlCreateInput($EditParamName, 10, 10, 240, 30)
	GUICtrlSetFont(-1, 12, 600, 0, "MS Sans Serif")

	$EditForAll = GUICtrlCreateCheckbox('Для всех', 15, 55, 100, 30)
	GUICtrlSetFont(-1, 12, 600, 0, "MS Sans Serif")

	$OK = GUICtrlCreateButton('OK', 10, 90, 60, 30)
	$Cancel = GUICtrlCreateButton('Exit', 75, 90, 60, 30)

	GUISetState(@SW_DISABLE, $hParent)
	GUISetState(@SW_SHOW, $EditLine_GUI)

	While 1
		$nMsg = GUIGetMsg()

		Switch $nMsg
			Case $Cancel
				ExitLoop

			Case $OK
				$NewName = GUICtrlRead($NewParamName)
				If $EditParamName <> $NewName Then
					If GUICtrlRead($EditForAll) = $GUI_CHECKED Then
						$text = 'Вы действительно хотите переименовать параметр "' & $EditParamName & '"' & @CRLF & 'для ВСЕХ предметов на новое "' & $NewName & '" ?'
					Else
						$text = 'Вы действительно хотите переименовать параметр "' & $EditParamName & '"' & @CRLF & 'в "' & $ObjName & '" на новое "' & $NewName & '" ?'
					EndIf

					If MsgBox(48 + 1, 'Внимание !', $text) == 1 Then

						_ReWriteOneIni($EditParamName, $ObjName, $NewName, $ListView)

						If GUICtrlRead($EditForAll) = $GUI_CHECKED Then

							_ReWriteOllIni($EditParamName, $NewName, $ObjName)

						EndIf

					EndIf
				Else
					MsgBox(48, 'Ошибка !', 'Имя параметра "' & $NewName & '" не изменилось !', 3)
				EndIf

				ExitLoop

		EndSwitch

	WEnd

	Opt("GUIOnEventMode", $iGOEM_Opt)
	GUISetState(@SW_ENABLE, $hParent)
	GUIDelete($EditLine_GUI)
	ControlFocus($EditObject_GUI, '', $ListView)

EndFunc   ;==>_RenameParam


Func _ReWriteOllIni($EditParamName, $NewName, $ObjName)

	$AllIni = _IniVirtualSPE_ReadSectionNames($PathIni)

	For $i = 1 To $AllIni[0]
		If $AllIni[$i] <> $ObjName Then
			;Проверка наличия параметра в предмете
			If _IniVirtualSPE_Read($PathIni, $AllIni[$i], $EditParamName, -1) >= 0 Then

				;Чтение параметров в массив и очистка
				$AllParam = _IniVirtualSPE_ReadSection($PathIni, $AllIni[$i])
				Local $aParam[$AllParam[0][0]][2]
				For $j = 1 To $AllParam[0][0]
					$aParam[$j - 1][0] = $AllParam[$j][0]
					$aParam[$j - 1][1] = $AllParam[$j][1]
					If $AllParam[$j][0] = $EditParamName Then $aParam[$j - 1][0] = $NewName
					_IniVirtualSPE_Delete($PathIni, $AllIni[$i], $AllParam[$j][0])
				Next
				;Запись новых значений в ini файлл
				For $Y = 0 To $AllParam[0][0] - 1
					_IniVirtualSPE_Write($PathIni, $AllIni[$i], $aParam[$Y][0], $aParam[$Y][1])
				Next
			EndIf

		EndIf

	Next

EndFunc   ;==>_ReWriteOllIni


Func _ReWriteOneIni($EditParamName, $ObjName, $NewName, $ListView)

	$sum = _GUICtrlListView_GetItemText($ListView, $line - 1, 1)
	_GUICtrlListView_InsertItem($ListView, $NewName, $line)
	_GUICtrlListView_AddSubItem($ListView, $line, $sum, 1)
	_GUICtrlListView_DeleteItem($ListView, $line - 1)

	$OllParam = _IniVirtualSPE_ReadSection($PathIni, $ObjName)
	If Not @error Then
		;Удалить все названия параметров предмета

		_IniVirtualSPE_Delete($PathIni, $ObjName)


		;Создать параметры заново из $ListView
		$SectionText = ''
		For $i = 0 To _GUICtrlListView_GetItemCount($ListView) - 1
			$SectionText &= _GUICtrlListView_GetItemText($ListView, $i) & '=' & _GUICtrlListView_GetItemText($ListView, $i, 1) & @CR
		Next
		_IniVirtualSPE_WriteSection($PathIni, $ObjName, $SectionText)
	EndIf

EndFunc   ;==>_ReWriteOneIni


Func _EditParam_()
	HotKeySet("{Enter}")
	NewObject($ListView, $EditObject_GUI)
EndFunc   ;==>_EditParam_


Func DelLine($ListView, $ObjName, $hParent)

	Local $NewLine_GUI, $iGOEM_Opt

	$iGOEM_Opt = Opt("GUIOnEventMode", 0)
	$DelParamName = _GUICtrlListView_GetItemText($ListView, $line - 1)

	$DelLine_GUI = GUICreate('Удалить параметр', 260, 160, -1, -1, $WS_BORDER, -1, $hParent)

	GUICtrlCreateLabel('Удалить "' & $DelParamName & '"', 10, 10, 240, 50)
	GUICtrlSetFont(-1, 12, 600, 0, "MS Sans Serif")

	$DellForAll = GUICtrlCreateCheckbox('Для всех', 15, 55, 100, 30)
	GUICtrlSetFont(-1, 12, 600, 0, "MS Sans Serif")

	$OK = GUICtrlCreateButton('OK', 10, 90, 60, 30)
	$Cancel = GUICtrlCreateButton('Exit', 75, 90, 60, 30)

	GUISetState(@SW_DISABLE, $hParent)
	GUISetState(@SW_SHOW, $DelLine_GUI)

	While 1
		$nMsg = GUIGetMsg()

		Switch $nMsg
			Case $Cancel
				ExitLoop

			Case $OK

				If GUICtrlRead($DellForAll) = $GUI_CHECKED Then

					If MsgBox(48 + 1, 'Внимание !', 'Вы действительно хотите удалить параметр ' & $DelParamName & @CRLF & 'для ВСЕХ предметов ?') == 1 Then

						_GUICtrlListView_DeleteItem($ListView, $line - 1)
						$OllName = _IniVirtualSPE_ReadSectionNames($PathIni)
						If Not @error Then
							For $i = 1 To UBound($OllName) - 1
								_IniVirtualSPE_Delete($PathIni, $OllName[$i], $DelParamName)
							Next
						EndIf
					EndIf

				Else

					If MsgBox(48 + 1, 'Внимание !', 'Вы действительно хотите удалить параметр ' & $DelParamName & @CRLF & 'в ' & $ObjName & ' ?') == 1 Then

						If _IniVirtualSPE_Delete($PathIni, $ObjName, $DelParamName) Then _GUICtrlListView_DeleteItem($ListView, $line - 1)

					EndIf

				EndIf

				ExitLoop
		EndSwitch

	WEnd

	Opt("GUIOnEventMode", $iGOEM_Opt)
	GUISetState(@SW_ENABLE, $hParent)
	GUIDelete($DelLine_GUI)
	ControlFocus($EditObject_GUI, '', $ListView)

EndFunc   ;==>DelLine


Func AddLine($ListView, $ObjName, $hParent)

	Local $NewLine_GUI, $iGOEM_Opt

	$iGOEM_Opt = Opt("GUIOnEventMode", 0)

	$NewLine_GUI = GUICreate('Добавить новый параметр', 260, 150, -1, -1, $WS_BORDER, -1, $hParent)

	$NewParam = GUICtrlCreateInput('Название параметра', 10, 10, 240, 30)
	GUICtrlSetFont(-1, 12, 600, 0, "MS Sans Serif")

	$AddForAll = GUICtrlCreateCheckbox('Для всех', 15, 45, 100, 30)
	GUICtrlSetFont(-1, 12, 600, 0, "MS Sans Serif")

	$OK = GUICtrlCreateButton('OK', 10, 80, 60, 30)
	$Cancel = GUICtrlCreateButton('Exit', 75, 80, 60, 30)

	GUISetState(@SW_DISABLE, $hParent)
	GUISetState(@SW_SHOW, $NewLine_GUI)

	While 1
		$nMsg = GUIGetMsg()

		Switch $nMsg
			Case $Cancel
				ExitLoop

			Case $OK
				$NewParamName = GUICtrlRead($NewParam)

				$id = _GUICtrlListView_FindText($ListView, $NewParamName, -1, False, True)

				If $id < 0 Then
					$ind = _GUICtrlListView_AddItem($ListView, $NewParamName)
					_GUICtrlListView_AddSubItem($ListView, $ind, 0, 1)
				Else
					MsgBox(48, 'Внимание !', 'Имя параметра "' & $NewParamName & @CRLF & '"' & 'уже есть в "' & $ObjName & '"' & ' !', 3)
				EndIf

				If GUICtrlRead($AddForAll) = $GUI_CHECKED Then

					;Запись во все секции, кроме текущей
					$Sections = _IniVirtualSPE_ReadSectionNames($PathIni)
					If Not @error Then
						For $i = 1 To UBound($Sections) - 1
							If $ObjName <> $Sections[$i] Then
								If _IniVirtualSPE_Read($PathIni, $Sections[$i], $NewParamName, -1) < 0 Then
									_IniVirtualSPE_Write($PathIni, $Sections[$i], $NewParamName, 0)
								Else
									MsgBox(48, 'Внимание !', 'Имя параметра "' & $NewParamName & @CRLF & '"' & ' уже есть в "' & $Sections[$i] & '" !', 3)
								EndIf
							EndIf
						Next
					EndIf

				EndIf
				ExitLoop
		EndSwitch

	WEnd

	Opt("GUIOnEventMode", $iGOEM_Opt)
	GUISetState(@SW_ENABLE, $hParent)
	GUIDelete($NewLine_GUI)
	ControlFocus($EditObject_GUI, '', $ListView)
EndFunc   ;==>AddLine
Прикрепил на всякий случай библиотеку "IniVirtualSPE.au3".
Сам чуть тестировал - заметил не стабильное срабатывание функции "_IniVirtualSPE_Delete" в цикле, когда удаляется для всех. В остальном, вроде-бы всё работает, как нужно.
 

Вложения

  • IniVirtualSPE.au3
    9.4 КБ · Просмотры: 4
Автор
E

eil

Новичок
Сообщения
53
Репутация
0
ого, спасибо! не ожидал да и не стал наглеть с такой переделкой - с одной стороны я понимаю что это чтото вроде замены команд физической работы с временным .ini на работу с виртуальным, с другой все равно много чего переписать :stars:

ra4o сказал(а):
Сам чуть тестировал - заметил не стабильное срабатывание функции "_IniVirtualSPE_Delete" в цикле, когда удаляется для всех. В остальном, вроде-бы всё работает, как нужно.
не стабильное срабатывание тоесть крашится програмка, или не выполняется комманда?
посомтрю как будет в использовании.


Добавлено:
Сообщение автоматически объединено:

заметил разницу в сохранении базы/каталога(самих строк внутри): раньше писались все строки подряд без промежутков, теперь пишется
[Предмет]
Параметр1=

Параметр2=

Параметр3=
не то что бы это сильно мешало, или что ранше было лучше, просто интересно это связано както с алгоритмом/так должно быть, или случайно?
но если вдруг это можно контролировать то подскажите где, подгоню под немного другую расстановку строк.
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
247
крашится програмка, или не выполняется комманда?
Просто не выполняется , если в цикле и то не всегда.
под немного другую расстановку строк.
Проверял у себя - между предметами в базе есть пробел, между параметрами внутри предмета - нет, как по мне - гораздо легче читается . В любом случае на работу не должно никак влиять.
 
Автор
E

eil

Новичок
Сообщения
53
Репутация
0
ra4o сказал(а):
крашится програмка, или не выполняется комманда?
Просто не выполняется , если в цикле и то не всегда
тобишь команда не выполняется, и параметр остаётся как был? уточняю потому что пока не столкнулся с этим(не часто же удаяешь у всех), но хочется знать чем оно грозит. если параметр остаётся то можно просто запустить удаление ещё раз, это не такая проблема, гланое чтобы ничего не терялось/не происходило "кусками".

ra4o сказал(а):
под немного другую расстановку строк.
Проверял у себя - между предметами в базе есть пробел, между параметрами внутри предмета - нет, как по мне - гораздо легче читается . В любом случае на работу не должно никак влиять.
странно у меня не так, хотя именно так я и хотел бы.
только что для проверки создал новую базу, вот так в точности со всеми пробелами она выглядит(именно с двумя пустыми строками вверху):
[aa]
a1=0

a2=0

[qq]
q1=0

q2=0

[qqq]
q1=0

q2=0

q3=0
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
247
тобишь команда не выполняется, и параметр остаётся как был?
Да , при установленой галке "для всех" - параметр удаляется только из текущего предмета, у остальных остаётся, но я так и не понял из-за чего это происходит (иногда), цикл отрабатывает , функция в цикле тоже отрабатывает без ошибки , но ничего не удаляет.
только что для проверки создал новую базу
А Вы чем открываете базу ? Только что создал тоже новую базу, сохранил, открыл блокнотом - получилось так, как я описал ранее, выделил всё, скопировал , что-бы вставить в сообщение - приняло вид , как у Вас :stars:
 
Автор
E

eil

Новичок
Сообщения
53
Репутация
0
ra4o сказал(а):
А Вы чем открываете базу ? Только что создал тоже новую базу, сохранил, открыл блокнотом - получилось так, как я описал ранее, выделил всё, скопировал , что-бы вставить в сообщение - приняло вид , как у Вас :stars:
AkelPad


Добавлено:
Сообщение автоматически объединено:

кстати попробовал открыть в стандартном Блокноте и действительно пробелы между параметрами предмета будто бы пропали(хотя 2 пустых строки сверху все равно на месте). НО это скорее с блокнотом чтото, потому что уверен вы знакомы с Notepad++ и он тоже показывает с пробелами как в моём примере.
 
Верх