Что нового

Не читаются хендлы из массива в x64 исполнении (TreeView)

musicstashall

Знающий
Сообщения
322
Репутация
7
Столкнулся с таким конфузом — в 64 битном исполнении (на Win 10), хендлы не читаются из массивов. В данном случае это элементы TreeView. Ниже пример это демонстрирует:

Код:
#include <GUIConstantsEx.au3>
#include <GuiTreeView.au3>
#include <GuiImageList.au3>
#include <WindowsConstants.au3>
#include <Array.au3>

$Debug_TV = False ; Проверяет ClassName передаваемый в функции. Установите True и используйте дескриптор от другого элемента, чтобы увидеть как это работает

Global $hImage, $hStateImage

_Main()

Func _Main()

    Local $hItem[4], $hChildItem[120], $iYItem = 0, $iRand, $hTreeView
    Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS)

    GUICreate("Уровень вложенности", 400, 300)

    $hTreeView = GUICtrlCreateTreeView(2, 2, 396, 268, $iStyle, $WS_EX_CLIENTEDGE)
    GUISetState()

    _CreateNormalImageList()
    _GUICtrlTreeView_SetNormalImageList($hTreeView, $hImage)

    _CreateStateImageList()
    _GUICtrlTreeView_SetStateImageList($hTreeView, $hStateImage)

    _GUICtrlTreeView_BeginUpdate($hTreeView)
    For $x = 0 To 3
        $hItem[$x] = _GUICtrlTreeView_Add($hTreeView, 0, StringFormat("[%02d] Пункт", $x), 4, 5)
        _GUICtrlTreeView_SetStateImageIndex($hTreeView, $hItem[$x], 1)
        For $y = 0 To 4
            $hChildItem[$iYItem] = _GUICtrlTreeView_AddChild($hTreeView, $hItem[$x], StringFormat("[%02d] Дочерний", $iYItem), 0, 3)
            _GUICtrlTreeView_SetStateImageIndex($hTreeView, $hChildItem[$iYItem], 1)
            For $z = 1 To 5
                $hChildItem[$iYItem + $z] = _GUICtrlTreeView_AddChild($hTreeView, $hChildItem[$iYItem], StringFormat("[%02d] Дочерний", $iYItem + $z), 0, 3)
            Next
            $iYItem += 6
        Next
    Next
    _GUICtrlTreeView_EndUpdate($hTreeView)

	Local $DATA[0][2]

    For $i = 1 To UBound($hChildItem) - 1
		_ArrayAdd($DATA, $hChildItem[$i] & '|' & 'Text: ' & _GUICtrlTreeView_GetText($hTreeView, $hChildItem[$i]))
	Next
	_ArrayDisplay($DATA)

    ; Цикл выполняется, пока окно не будет закрыто
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    GUIDelete()
EndFunc   ;==>_Main

Func _CreateNormalImageList()
    $hImage = _GUIImageList_Create(16, 16, 5, 3)
    _GUIImageList_AddIcon($hImage, "shell32.dll", 110)
    _GUIImageList_AddIcon($hImage, "shell32.dll", 131)
    _GUIImageList_AddIcon($hImage, "shell32.dll", 165)
    _GUIImageList_AddIcon($hImage, "shell32.dll", 168)
    _GUIImageList_AddIcon($hImage, "shell32.dll", 137)
    _GUIImageList_AddIcon($hImage, "shell32.dll", 146)
EndFunc   ;==>_CreateNormalImageList

Func _CreateStateImageList()
    $hStateImage = _GUIImageList_Create(16, 16, 5, 3)
    _GUIImageList_AddIcon($hStateImage, "shell32.dll", 3)
    _GUIImageList_AddIcon($hStateImage, "shell32.dll", 4)
EndFunc   ;==>_CreateStateImageList


Здесь в массив помещаем хендлы элементов дерева и, обращаясь к этому массиву, получаем строки из этих элементов. В 32 битном исполнении строки стабильно всегда есть, а в 64 битном — раз через раз, а если запустить еще от имени админа, то и вовсе строки получить невозможно. То есть обращаться к элементам дерева, посредством массива данных, уже не представляется возможным, из массива всегда извлекается ноль. Результат такой же, если хендл представлять в виде строки — ноль. Может с кодировками что-то или... Винда исправна, специально переустановил и на свеженькой попробовал — результат тот же.



Или я что-то не понял?? Пожалуйста, спасите мои труды)) переделывать будет уже невозможно.
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
Re: SOS, глюки TreeView

Проверил у себя на Win10x64 , работает .
 

Вложения

  • Снимок.PNG
    Снимок.PNG
    58 КБ · Просмотры: 10

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Re: SOS, глюки TreeView

после создания дерева напиши
Код:
$hTreeView = GUICtrlGetHandle($hTreeView)

все функции по работе с деревом получают хэндл элемента из его ID
в х64 исполнении видимо какой то косяк. поэтому этим функциям лучше сразу скармливать хэндл а не ID элемента


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

ra4o
работает через раз. то есть подряд несколько раз может выдать, а потом пустое. я тоже проверил на десятке


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

вообще, если функция просит ИД элемента или его хэндл, то лучше давать последнее


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

да, еще момент, ты заполняешь массив с единицы а нужно с нуля
Код:
For $i = 0 To UBound($hChildItem) - 1
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
Re: SOS, глюки TreeView

работает через раз. то есть подряд несколько раз может выдать, а потом пустое. я тоже проверил на десятке
Запускал раз пятнадцать и скомпилированный и нет , ни одного сбоя :smile:
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Re: SOS, глюки TreeView

ты запусти с правами админа
Код:
#RequireAdmin

в этом случае вообще через раз выдает результат
важно то, что если функция не работает у всех одинаково, значит нужно что-то менять. Для того и просят протестировать. Я так понял, что ТС делает прогу для работы с файловой системой в х64 (папки, файлы). Проблема с деревом это еще цветочки ;D
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
Re: SOS, глюки TreeView

musicstashall

Предупреждение За нарушение правил форума (пункт Б.5):
Имя темы должно нести смысловую нагрузку (отражать суть вопроса/проблемы)
Правильно сформулированное название темы привлекает больше внимания, и шансы получить конкретный ответ увеличиваются.


Данные правила могут пополняться локальными правилами раздела.
Как правильно называть темы

"SOS, глюки TreeView" - это неприемлемое название темы, переименуйте тему иначе она будет закрыта, а вам возможно будет выдан бан на несколько дней.

С уважением, ваш Глобальный модератор.
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
Re: SOS, глюки TreeView

joiner сказал(а):
функциям лучше сразу скармливать хэндл а не ID элемента

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

Код:
$cTree = GUICtrlCreateTreeView(13, 75, 318, 455,$TVS_HASBUTTONS+$TVS_HASLINES+$TVS_LINESATROOT+$TVS_EDITLABELS)
GUICtrlSetState(-1, $GUI_DROPACCEPTED)
$hTreeView = GUICtrlGetHandle($cTree)


Как поступить?? Может есть способ обойти эти траблы и так и обращаться к элементу по индексу?? Но ведь существуют еще и дочерние элементы, которые тоже от нуля читаются?? Может _GUICtrlTreeView_SetItemParam попробовать?
Код:
_GUICtrlTreeView_SetItemParam



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

ra4o сказал(а):
работает через раз. то есть подряд несколько раз может выдать, а потом пустое. я тоже проверил на десятке
Запускал раз пятнадцать и скомпилированный и нет , ни одного сбоя :smile:

Видимо от железа зависит, может от процессора... Я проверял на двух разных компах, результат одинаковый — нули.


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

OffTopic:
joiner сказал(а):
Я так понял, что ТС делает прогу для работы с файловой системой в х64 (папки, файлы). Проблема с деревом это еще цветочки ;D

С файловой системой у меня как раз всё гладенько, а я заморочился над созданием редактора контекстных меню, которое как раз и представлено в виде дерева, где, ввиду данного глюка, нарушается не только сортировка пунктов, но и вообще пункты теряются...
 
A

Alofa

Гость
ra4o сказал(а):
Проверил у себя на Win10x64 , работает .
Запустите x64 версию скрипта.

joiner сказал(а):
после создания дерева напиши
Код:
$hTreeView = GUICtrlGetHandle($hTreeView)
Самое странное, что именно это и делается при входе почти в каждую функцию "GuiTreeView.au3", но...

musicstashall пробуйте так:
Код:
#include <GUIConstantsEx.au3>
#include <GuiTreeView.au3>
#include <GuiImageList.au3>
#include <WindowsConstants.au3>
#include <Array.au3>

Global $hImage, $hStateImage


Local $hItem[4], $hChildItem[120], $iYItem = 0, $iRand, $hTreeView
Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS)

GUICreate("Уровень вложенности", 400, 300)

$hTreeView = GUICtrlCreateTreeView(2, 2, 396, 268, $iStyle, $WS_EX_CLIENTEDGE)
GUISetState()

_CreateNormalImageList()
_GUICtrlTreeView_SetNormalImageList($hTreeView, $hImage)

_CreateStateImageList()
_GUICtrlTreeView_SetStateImageList($hTreeView, $hStateImage)

_GUICtrlTreeView_BeginUpdate($hTreeView)
For $x = 0 To 3
	$hItem[$x] = _GUICtrlTreeView_Add($hTreeView, 0, StringFormat("[%02d] Пункт", $x), 4, 5)
	_GUICtrlTreeView_SetStateImageIndex($hTreeView, $hItem[$x], 1)
	For $y = 0 To 4
		$hChildItem[$iYItem] = _GUICtrlTreeView_AddChild($hTreeView, $hItem[$x], StringFormat("[%02d] Дочерний", $iYItem), 0, 3)
		_GUICtrlTreeView_SetStateImageIndex($hTreeView, $hChildItem[$iYItem], 1)
		For $z = 1 To 5
			$hChildItem[$iYItem + $z] = _GUICtrlTreeView_AddChild($hTreeView, $hChildItem[$iYItem], StringFormat("[%02d] Дочерний", $iYItem + $z), 0, 3)
		Next
		$iYItem += 6
	Next
Next
_GUICtrlTreeView_EndUpdate($hTreeView)

Local $DATA[0][2]

For $i = 1 To UBound($hChildItem) - 1
	_ArrayAdd($DATA, $hChildItem[$i] & '|' & 'Text: ' & __GUICtrlTreeView_GetText($hTreeView, $hChildItem[$i]))
Next
_ArrayDisplay($DATA)

; Цикл выполняется, пока окно не будет закрыто
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
GUIDelete()


Func __GUICtrlTreeView_GetText($hWnd, $hItem = 0)
	If Not IsPtr($hItem) Then $hItem = __GUICtrlTreeView_GetItemHandle($hWnd, $hItem)
	If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)

	If $hItem = 0x00000000 Then Return SetError(1, 1, '')

	Local $tText, $tTVITEM = DllStructCreate($tagTVITEMEX)
	Local $iInd = 0, $aUnicode[2][2] = [['char', $TVM_GETITEMA], ['wchar', $TVM_GETITEMW]]
	If _GUICtrlTreeView_GetUnicodeFormat($hWnd) Then $iInd = 1

	$tText = DllStructCreate($aUnicode[$iInd][0] & ' Buffer[4096]'); create a text 'area' for receiving the text
	DllStructSetData($tTVITEM, 'Mask', $TVIF_TEXT)
	DllStructSetData($tTVITEM, 'hItem', $hItem)
	DllStructSetData($tTVITEM, 'TextMax', 4096)

	If _WinAPI_InProcess($hWnd, $__g_hTVLastWnd) Then
		DllStructSetData($tTVITEM, 'Text', DllStructGetPtr($tText))
		_SendMessage($hWnd, $TVM_GETITEMW, 0, $tTVITEM, 0, 'wparam', 'struct*')
	Else
		Local $iItem = DllStructGetSize($tTVITEM)
		Local $tMemMap
		Local $pMemory = _MemInit($hWnd, $iItem + 4096, $tMemMap)
		Local $pText = $pMemory + $iItem
		DllStructSetData($tTVITEM, 'Text', $pText)
		_MemWrite($tMemMap, $tTVITEM, $pMemory, $iItem)
		_SendMessage($hWnd, $aUnicode[$iInd][1], 0, $pMemory, 0, 'wparam', 'ptr')
		_MemRead($tMemMap, $pText, $tText, 4096)
		_MemFree($tMemMap)
	EndIf

	Return DllStructGetData($tText, 'Buffer')
EndFunc   ;==>__GUICtrlTreeView_GetText

Func __GUICtrlTreeView_GetItemHandle($hWnd, $hItem = 0)
	If Not $hItem Then $hItem = 0x00000000
	If IsPtr($hItem) Then Return $hItem
	If IsHWnd($hWnd) And $hItem = 0x00000000 Then
		$hItem = _SendMessage($hWnd, $TVM_GETNEXTITEM, $TVGN_ROOT, 0, 0, 'wparam', 'lparam', 'handle')
	Else
		$hItem = Ptr(GUICtrlSendMsg($hWnd, $TVM_GETNEXTITEM, $TVGN_ROOT, 0))
	EndIf
	Return $hItem
EndFunc   ;==>__GUICtrlTreeView_GetItemHandle

Func _CreateNormalImageList()
	$hImage = _GUIImageList_Create(16, 16, 5, 3)
	_GUIImageList_AddIcon($hImage, "shell32.dll", 110)
	_GUIImageList_AddIcon($hImage, "shell32.dll", 131)
	_GUIImageList_AddIcon($hImage, "shell32.dll", 165)
	_GUIImageList_AddIcon($hImage, "shell32.dll", 168)
	_GUIImageList_AddIcon($hImage, "shell32.dll", 137)
	_GUIImageList_AddIcon($hImage, "shell32.dll", 146)
EndFunc   ;==>_CreateNormalImageList

Func _CreateStateImageList()
	$hStateImage = _GUIImageList_Create(16, 16, 5, 3)
	_GUIImageList_AddIcon($hStateImage, "shell32.dll", 3)
	_GUIImageList_AddIcon($hStateImage, "shell32.dll", 4)
EndFunc   ;==>_CreateStateImageList


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

К стати, в Win7 x64 такого бага не наблюдается, как не старался воспроизвести.
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
Alofa, в моем случае мне требуется получать уровень вложенности, не могли бы вы представить подобную функцию для получения числа уровня вложенности 0, 1, 2, 3... И как быть с прочими функциями, когда нужно вставить элемент, добавить элемент, добавить дочерний, добавить первый дочерний и тд??
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
musicstashall [?]
_GUICtrlTreeView_SetItemParam
эта функция для присваивания числа элементу дерева. Строка не подходит
по поводу добавления, вложенности и прочего.. у меня есть прога jmpack, она для создания установщика. там реализовано добавление пунктов к дереву в любом желаемом месте, плюс перемещение веток. но эти функции сугубо индивидуальны для одной программы. в твоем случае нужно хотя бы приблизительно знать как работает твоя программа с деревом, чтобы помочь.



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

Alofa [?]
Самое странное, что именно это и делается при входе почти в каждую функцию
Согласен, что странно. Но факт на лицо - при передачи ИД элемента функция работает не стабильно
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
Я попробую сделать проще — вместо хендла буду использовать индекс элемента. В рамках моих требований это должно прокатить.


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

Кстати!! Полученный хендл от функции создания элементов вполне себе читается из переменной и его можно использовать, траблы начинаются именно только тогда, когда хендл читается из массива.
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
Реализовал у себя в скрипте таким образом... Я заметил, что хендлы «живы», пока они не попали в массив, и читаются благополучно. Поэтому я решил попробовать записывать хендлы элементов, сразу, после их создания, минуя массивов, в создаваемые переменные:

Код:
$hIndex = _GUICtrlTreeView_AddChild($hTreeView, $hParent, $Name)
Assign('hIndex_' & $i, $hIndex, 2)


А в массив заношу уже только имя переменной:

Код:
_ArrayAdd($CTRL_DATA, 'hIndex_' & $i)


Потом, обращаясь к массиву, получаю значение переменной:

Код:
$hIndex = Eval($CTRL_DATA[$i])


И у меня всё заработало стабильно. Решил таким же образом построить наш пример, где мы получали текст, и я не смог получить такого же результата. Теперь я вообще в растерянностях...

Код:
#include <GUIConstantsEx.au3>
#include <GuiTreeView.au3>
#include <GuiImageList.au3>
#include <WindowsConstants.au3>
#include <Array.au3>
Global $hImage, $hStateImage


Local $hItem[4], $hChildItem[120], $iYItem = 0, $iRand, $hTreeView
Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS)

GUICreate("Уровень вложенности", 400, 300)

$hTreeView = GUICtrlCreateTreeView(2, 2, 396, 268, $iStyle, $WS_EX_CLIENTEDGE)
GUISetState()

_CreateNormalImageList()
_GUICtrlTreeView_SetNormalImageList($hTreeView, $hImage)

_CreateStateImageList()
_GUICtrlTreeView_SetStateImageList($hTreeView, $hStateImage)

_GUICtrlTreeView_BeginUpdate($hTreeView)
Local $n = 0
For $x = 0 To 3
    $hItem[$x] = _GUICtrlTreeView_Add($hTreeView, 0, StringFormat("[%02d] Пункт", $x), 4, 5)
    _GUICtrlTreeView_SetStateImageIndex($hTreeView, $hItem[$x], 1)
    For $y = 0 To 4
		Local $h = _GUICtrlTreeView_AddChild($hTreeView, $hItem[$x], StringFormat("[%02d] Дочерний", $iYItem), 0, 3)
		$n += 1
		Assign('hItem_' & $n, $h, 2)
		$hChildItem[$iYItem] = 'hItem_' & $n
		_GUICtrlTreeView_SetStateImageIndex($hTreeView, Eval($hChildItem[$iYItem]), 1)
        For $z = 1 To 5
			Local $h = _GUICtrlTreeView_AddChild($hTreeView, Eval($hChildItem[$iYItem]), StringFormat("[%02d] Дочерний", $iYItem + $z), 0, 3)
			$n += 1
			Assign('hItem_' & $n, $h, 2)
			$hChildItem[$iYItem + $z] = 'hItem_' & $n
        Next
        $iYItem += 6
    Next
Next
_GUICtrlTreeView_EndUpdate($hTreeView)

Local $DATA[0][2]

For $i = 0 To UBound($hChildItem) - 1
    _ArrayAdd($DATA, Eval($hChildItem[$i]) & '|' & 'Text: ' & _GUICtrlTreeView_GetText($hTreeView, Eval($hChildItem[$i])))
Next
_ArrayDisplay($DATA)

; Цикл выполняется, пока окно не будет закрыто
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
GUIDelete()

Func _CreateNormalImageList()
    $hImage = _GUIImageList_Create(16, 16, 5, 3)
    _GUIImageList_AddIcon($hImage, "shell32.dll", 110)
    _GUIImageList_AddIcon($hImage, "shell32.dll", 131)
    _GUIImageList_AddIcon($hImage, "shell32.dll", 165)
    _GUIImageList_AddIcon($hImage, "shell32.dll", 168)
    _GUIImageList_AddIcon($hImage, "shell32.dll", 137)
    _GUIImageList_AddIcon($hImage, "shell32.dll", 146)
EndFunc   ;==>_CreateNormalImageList

Func _CreateStateImageList()
    $hStateImage = _GUIImageList_Create(16, 16, 5, 3)
    _GUIImageList_AddIcon($hStateImage, "shell32.dll", 3)
    _GUIImageList_AddIcon($hStateImage, "shell32.dll", 4)
EndFunc   ;==>_CreateStateImageList
 
A

Alofa

Гость
musicstashall
А может быть так (вариант с проверкой):
Код:
#include <GUIConstantsEx.au3>
#include <GuiTreeView.au3>
#include <GuiImageList.au3>
#include <WindowsConstants.au3>
#include <Array.au3>

Global $hImage, $hStateImage, $avChildItem[120][2]

; <<<<<<<<<<<<<<<<<<<<<<<<< П Р О В Е Р К А >>>>>>>>>>>>>>>>>>>>>>>>
$sText = 'УРА!!! Все нормально'
For $i = 1 To 100 ; Функция пересоздания окна с элементами будет повторена 100 раз
	$Ret = _Main()
	If Not $Ret Then
		$sText = 'Не получилось :(' & @CRLF & 'на шаге: ' & $i
		ExitLoop
	EndIf
Next
; Результат:
MsgBox(4096, Default, $sText)
_ArrayDisplay($avChildItem)
; <<<<<<<<<<<<<<<<<<<<<<<<< П Р О В Е Р К А >>>>>>>>>>>>>>>>>>>>>>>>

Func _Main()
	Local $hItem[4], $iYItem = 0, $iRand, $hTreeView
	Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS)

	GUICreate("Уровень вложенности", 400, 300)
	$hTreeView = GUICtrlCreateTreeView(2, 2, 396, 268, $iStyle, $WS_EX_CLIENTEDGE)
	;GUISetState()

	_CreateNormalImageList()
	_GUICtrlTreeView_SetNormalImageList($hTreeView, $hImage)

	_CreateStateImageList()
	_GUICtrlTreeView_SetStateImageList($hTreeView, $hStateImage)

	_GUICtrlTreeView_BeginUpdate($hTreeView)
	For $x = 0 To 3
		$hItem[$x] = _GUICtrlTreeView_Add($hTreeView, 0, StringFormat("[%02d] Пункт", $x), 4, 5)
		_GUICtrlTreeView_SetStateImageIndex($hTreeView, $hItem[$x], 1)
		For $y = 0 To 4
			$avChildItem[$iYItem][1] = StringFormat("[%02d] Дочерний", $iYItem)
			$avChildItem[$iYItem][0] = _GUICtrlTreeView_AddChild($hTreeView, $hItem[$x], $avChildItem[$iYItem][1], 0, 3)
			_GUICtrlTreeView_SetStateImageIndex($hTreeView, $avChildItem[$iYItem][0], 1)
			For $z = 1 To 5
				$avChildItem[$iYItem + $z][1] = StringFormat("[%02d] Дочерний Дочернего", $iYItem + $z)
				$avChildItem[$iYItem + $z][0] = _GUICtrlTreeView_AddChild($hTreeView, $avChildItem[$iYItem][0], $avChildItem[$iYItem + $z][1], 0, 3)
			Next
			$iYItem += 6
		Next
	Next
	_GUICtrlTreeView_EndUpdate($hTreeView)

; <<<<<<<<<<<<<<<<<<<<<<<<< П Р О В Е Р К А >>>>>>>>>>>>>>>>>>>>>>>>
	For $i = 0 To UBound($avChildItem) - 1 ; Проверяем массив
		If Not _GUICtrlTreeView_GetText($hTreeView, $avChildItem[$i][1]) Then Return 0
	Next
; <<<<<<<<<<<<<<<<<<<<<<<<< П Р О В Е Р К А >>>>>>>>>>>>>>>>>>>>>>>>

	; Цикл выполняется, пока окно не будет закрыто
;~ 	Do
;~ 	Until GUIGetMsg() = $GUI_EVENT_CLOSE
	GUIDelete()
	Return 1
EndFunc   ;==>_Main

Func _CreateNormalImageList()
	$hImage = _GUIImageList_Create(16, 16, 5, 3)
	_GUIImageList_AddIcon($hImage, "shell32.dll", 110)
	_GUIImageList_AddIcon($hImage, "shell32.dll", 131)
	_GUIImageList_AddIcon($hImage, "shell32.dll", 165)
	_GUIImageList_AddIcon($hImage, "shell32.dll", 168)
	_GUIImageList_AddIcon($hImage, "shell32.dll", 137)
	_GUIImageList_AddIcon($hImage, "shell32.dll", 146)
EndFunc   ;==>_CreateNormalImageList

Func _CreateStateImageList()
	$hStateImage = _GUIImageList_Create(16, 16, 5, 3)
	_GUIImageList_AddIcon($hStateImage, "shell32.dll", 3)
	_GUIImageList_AddIcon($hStateImage, "shell32.dll", 4)
EndFunc   ;==>_CreateStateImageList
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
Я не понял, а что дает форматированная строка?? Это как-то влияет на чтение хендла из массива??? И почему у вас проверка массива идет по второй колонке, в которой текст? Интересно то, что по обоим колонкам ошибок нет))
 
A

Alofa

Гость
musicstashall сказал(а):
Я не понял, а что дает форматированная строка??.
Я тоже не понял про что это вы?

musicstashall сказал(а):
... почему у вас проверка массива идет по второй колонке, в которой текст? Интересно то, что по обоим колонкам ошибок нет))
Не будет дескриптора элемента - не будет и текста.

А вообще идея последнего скрипта: не выстраивать свой массив пропуская его через _ArrayAdd() (в этой функции тоже еще надо разобраться какие преобразования происходят) на основе другого массива, а сразу создать нужный.




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

musicstashall
что общего между этими строками из ваших примеров?
musicstashall сказал(а):
Код:
_ArrayAdd($DATA, $hChildItem[$i] & '|' & 'Text: ' & _GUICtrlTreeView_GetText($hTreeView, $hChildItem[$i]))
musicstashall сказал(а):
Код:
_ArrayAdd($DATA, Eval($hChildItem[$i]) & '|' & 'Text: ' & _GUICtrlTreeView_GetText($hTreeView, Eval($hChildItem[$i])))
...а то, что какие бы вы данные не записывали во второй параметр _ArrayAdd() все равно это будет типом данных "строка".
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
musicstashall, зачем заполнять массив текстом элементов, если этот текст всегда можно получить по дескриптору элемента?
при создании дерева уже есть массив дескрипторов - $hChildItem
потом уже добавлять туда дескрипторы, если будут создаваться новые элементы дерева, но использовать не _ArrayAdd, а ReDim. То есть самому пересоздавать массив дескрипторов.


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

функция
Код:
_GUICtrlTreeView_GetText

переводит строку в дескриптор, так что его можно передать в виде строки
но лучше формировать массив с исходным типом данных
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
Отчаянно пытаюсь понять вас)) Давайте сначала. Вообще, текст мы здесь получали лишь для примера, текст нам по сути вообще не нужен, нам нужен хендл, чтобы выполнять все операции — вставить, переместить, удалить, определить уровень вложенности и тд..., потому что все они выполняются по хендлу. Теперь у нас появился хендл, но я не догоняю, откуда именно он появился в результате применения StringFormat. Объясните мне, как это в данном случае работает. Далее непосредсвенно кусок моего скрипта, который заработал при использовании Assign и Eval. В первую колонку я с самого начала записывал хендл создаваемого элемента, потом, когда обнаружились глюки, я создал четвертую колонку, куда записываю имя переменной с хендлом, а по первой колонке я по прежнему выполняю поиск нужного элемента. Что тоже интересно, в мой массив записывается еще один хендл $first в третью колонку, так он почему-то читался и читается без проблем.

Код:
Local $first
Func _GUICtrlCreateTree($Sortkey, $hTreeView, $hParent, $updateindex = -1)
	Local $Data, $Name, $Parent, $to = UBound($SortKey) - 1, $for = 0
	If $updateindex > -1 Then
		$for = $updateindex
		$to = $updateindex 
	EndIf
	For $i = $for To $to
		$Name = _GetNameTreeViewItem($SortKey[$i][0]) ; получаем имя элемента
		If $updateindex > -1 Then
			If $updateindex > 0 Then
				Local $j = _ArraySearch($CTRL_DATA, $Sortkey[$updateindex - 1][0], 0, 0, 0, 0, 1, 1)
				$Parent = _GUICtrlTreeView_InsertItem($hTreeView, $Name, $hParent, Eval($CTRL_DATA[$j][3]))	
			Else
				$Parent = _GUICtrlTreeView_AddChildFirst($hTreeView, $hParent, $Name)		
			EndIf
		Else
			$Parent = _GUICtrlTreeView_AddChild($hTreeView, $hParent, $Name)	
		EndIf
		_GUICtrl_SetIconInTree($SortKey[$i][0], $hTreeView, $Parent) ; получаем иконку
		If _GUICtrlTreeView_Level($hTreeView, $Parent) = 1 Then $first = $Parent
		Assign('hItem_' & UBound($CTRL_DATA), $Parent, 2)
		_ArrayAdd($CTRL_DATA, $Parent & '|' & $SortKey[$i][0] & '|' & $first & '|hItem_' & UBound($CTRL_DATA)) ; заносим элемент в массив
		If _RegValueExists($SortKey[$i][0], 'Extended') = 1 Then
				
		EndIf
		$Data = _GetSortCountKeyOfRegistry($SortKey[$i][0] & '\shell') ; получаем список всех подключей
		If UBound($Data) > 0 Then
			_GUICtrlCreateTree($Data, $hTreeView, $Parent)
		EndIf
	Next
	$CTRL_DATA[0][0] = UBound($CTRL_DATA) - 1
	Return $CTRL_DATA
EndFunc



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

Или вы как раз и создаете переменную, но с именем из текста элемента??

Код:
StringFormat("[%02d] Дочерний Дочернего", $iYItem + $z)



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

Всё понял)) Теперь нужно создать переменную с именем из хендла и поместить ее в массиве туда, куда изначально я и писал хендл — в первую колонку... Чтобы можно было по прежнему выполнять поиск элемента по этой колонке, так как у нас непосредственно хендл и имя переменной будут одинаковые.


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

Нет, все таки я не понял)) Помогайте...
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
musicstashall, теперь давай чётко по пунктам, что тебе нужно реализовать. Оказалось, что текст это далеко вторично в твоей задаче.
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
Ну вот, сделал у себя таким образом, тем же способом, только в качестве имени переменной использовал уже хендл в строковом представлении, и поместил его на прежнее место, где и раньше было — в первую колонку. Теперь по первой колонке можно и поиск выполнять, и переменную читать. В принципе меня всё пока устраивает, если вы не подскажете чего-то более простого или оригинального.

Код:
Local $first
Func _GUICtrlCreateTree($Sortkey, $hTreeView, $hParent, $updateindex = -1)
	Local $Data, $Name, $Parent, $to = UBound($SortKey) - 1, $for = 0
	If $updateindex > -1 Then
		$for = $updateindex
		$to = $updateindex 
	EndIf
	For $i = $for To $to
		$Name = _GetNameTreeViewItem($SortKey[$i][0]) ; получаем имя элемента
		If $updateindex > -1 Then
			If $updateindex > 0 Then
				Local $j = _ArraySearch($CTRL_DATA, $Sortkey[$updateindex - 1][0], 0, 0, 0, 0, 1, 1)
				$Parent = _GUICtrlTreeView_InsertItem($hTreeView, $Name, $hParent, Eval($CTRL_DATA[$j][0]))	
			Else
				$Parent = _GUICtrlTreeView_AddChildFirst($hTreeView, $hParent, $Name)		
			EndIf
		Else
			$Parent = _GUICtrlTreeView_AddChild($hTreeView, $hParent, $Name)	
		EndIf
		_GUICtrl_SetIconInTree($SortKey[$i][0], $hTreeView, $Parent) ; получаем иконку
		If _GUICtrlTreeView_Level($hTreeView, $Parent) = 1 Then $first = $Parent
		Assign($Parent, $Parent, 2)
		_ArrayAdd($CTRL_DATA, $Parent & '|' & $SortKey[$i][0] & '|' & $first) ; заносим элемент в массив
		If _RegValueExists($SortKey[$i][0], 'Extended') = 1 Then
				
		EndIf
		$Data = _GetSortCountKeyOfRegistry($SortKey[$i][0] & '\shell') ; получаем список всех подключей
		If UBound($Data) > 0 Then
			_GUICtrlCreateTree($Data, $hTreeView, $Parent)
		EndIf
	Next
	$CTRL_DATA[0][0] = UBound($CTRL_DATA) - 1
	Return $CTRL_DATA
EndFunc
 
Верх