Что нового

Ассоциативное значение

Cytrus

Новичок
Сообщения
110
Репутация
3
Привет.

Разъясните, плиз, кто в состоянии, что такое ассоциативное значение, определяемое приложением.

Их можно получить, и их можно назначить.

Я встречаю в справке такие вещи, и не совсем понимаю их назначение.

А также, что такое context help identifier.
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
у меня толковых объяснений не так много, точнее, почти нет :smile:
при создании элемента в окне ему присваивается уникальный идентификатор или дескриптор.
Пример TreeView
при каждом запуске дескрипторы пунктов дерева меняются. Но есть функция, которая помогает присвоить любому пункту дерева свое значение(идентификатор), который можно будет сохранять и назначать при загрузке программы и самого дерева. Можно менять его. Как я это использовал?
Создавая дерево я присваивал каждому пункту уникальное значение. Это же значение я использовал как имя ключа в объекте Scripting.Dictionary
Уже по ходу взаимодействия с деревом я присваивал значения каждому пункту в виде массива. Как? Получал значение пункта дерева, а это значение является именем ключа в Scripting.Dictionary, вызывал этот ключ и вносил туда данные. таким образом, я мог каждому пункту назначить свои массивы(структуры) данных и получать их по мере надобности. Прописал функцию сохранения данных дерева в файл. И при каждой загрузке дерева программа присваивала ему его уникальное значение(из файла) и создавала ключ в Scripting.Dictionary с этим именем, загружая в него данные из файла
короче, объяснил как мог ;D
 
Автор
Cytrus

Cytrus

Новичок
Сообщения
110
Репутация
3
Я так понимаю, что любому дескриптору мы можем присвоить любые другие идентификаторы?
Мы можем создавать dummy, получать из них хендлы, и присваивать им любые свои идентификаторы?
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
Cytrus
Некоторые элементы GUI Windows являются контейнерами. Например, список, дерево, меню. Эти контейнеры содержат пункты. Пункты описываются в виде структур. В этих структурах есть определённое поле: у списка и дерева поле Param, у меню поле ItemData. В это поле разработчик может записать число типа int, чем ассоциировать данный конкретный пункт с этим числом. Затем, прочитав это поле, по этому (уникальному) числу можно точно определить пункт.

AutoIt тоже пользуется этими полями. Например, когда вы через GUICtrlCreateListViewItem создаёте пункт списка, в это поле AutoIt заносит ID, которым вы в дальнейшем и пользуетесь и которым пользуется сам AutoIt. Поэтому не рекомендуется менять значения этих полей для пунктов, созданных внутренними функциями AutoIt. Вот пример
Код:
#include <GuiListView.au3>

GUICreate("")
$LV = GUICtrlCreateListView("", 0, 0)

; создание ListViewItem
$Item = GUICtrlCreateListViewItem("test", $LV)
ConsoleWrite("Идентификатор пункта: " & $Item & @CRLF)
ConsoleWrite("Имя пункта: " & GUICtrlRead($Item) & @CRLF)

; чтение Param
$Param = _GUICtrlListView_GetItemParam(GUICtrlGetHandle($LV), 0)
ConsoleWrite("Значение Param: " & $Param & @CRLF)

; изменение Param
_GUICtrlListView_SetItemParam(GUICtrlGetHandle($LV), 0, 5)
ConsoleWrite("Имя пункта после изменения Param: " & GUICtrlRead($Item) & @CRLF)

; возврат Param
_GUICtrlListView_SetItemParam(GUICtrlGetHandle($LV), 0, 4)
ConsoleWrite("Имя пункта после возврата Param: " & GUICtrlRead($Item) & @CRLF)


Вывод. Ассоциативные значения, т.е. числа в определённом поле структуры пункта, можно использовать для работы через UDF. Для работы встроенными функциями эти поля трогать не нужно.
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
примерная иллюстрация как можно это применить. хотя можно и пофантазировать
во всяком случае, мне не встречались коды, где используется ассоциативное значение
Код:
#include <GUIConstantsEx.au3>
#include <GuiTreeView.au3>
#include <WindowsConstants.au3>


Local $GUI, $Item[10]
Global $hTreeView, $nParam, $np
Local $iStyle = BitOR($TVS_HASBUTTONS, $TVS_EDITLABELS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS)

$GUI = GUICreate("Устанавливает параметр пункта (UDF)", 400, 300)

$hTreeView = _GUICtrlTreeView_Create($GUI, 2, 2, 396, 268, $iStyle, $WS_EX_CLIENTEDGE)
GUISetState()
_GUICtrlTreeView_BeginUpdate($hTreeView)
For $x = 0 To 9
	$Item[$x] = _GUICtrlTreeView_Add($hTreeView, 0, StringFormat("[%01d] Пункт", $x))
	_GUICtrlTreeView_SetItemParam($hTreeView, $Item[$x], $x + 1)
;~ 	$np += 1
;~ 	Assign(Eval('np'), '_msg()', 2); создаем переменную с тем же именем, что и ассоциативное значение пункта
Next
_GUICtrlTreeView_EndUpdate($hTreeView)
GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')

Do
	If $nParam Then
;~ 		Execute(Eval($nParam)); по ассоциативному значению пункта вызываем функцию из переменной с таким же именем
		_msg()
		$nParam = 0
	EndIf
Until GUIGetMsg() = $GUI_EVENT_CLOSE


Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
	#forceref $hWnd, $iMsg, $wParam
	Local $tStruct = DllStructCreate('struct;hwnd hWndFrom;uint_ptr IDFrom;INT Code;endstruct;' & _
			'uint Action;struct;uint OldMask;handle OldhItem;uint OldState;uint OldStateMask;' & _
			'ptr OldText;int OldTextMax;int OldImage;int OldSelectedImage;int OldChildren;lparam OldParam;endstruct;' & _
			'struct;uint NewMask;handle NewhItem;uint NewState;uint NewStateMask;' & _
			'ptr NewText;int NewTextMax;int NewImage;int NewSelectedImage;int NewChildren;lparam NewParam;endstruct;' & _
			'struct;long PointX;long PointY;endstruct', $lParam)
	Local $hWndFrom = DllStructGetData($tStruct, 'hWndFrom')
	If $hWndFrom = $hTreeView Then
		Switch DllStructGetData($tStruct, 'Code')
			Case $TVN_SELCHANGEDA, $TVN_SELCHANGEDW
				$nParam = DllStructGetData($tStruct, 'NewParam') ; ассоциативное значение
		EndSwitch
	EndIf
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func _msg()
	Switch $nParam
		Case 1
			FileOpenDialog('', '', '(*)')
		Case 2
			FileSelectFolder('', '')
		Case 3
			Run('cmd.exe')
		Case Else
			MsgBox(64, '', $nParam)
	EndSwitch
EndFunc   ;==>_msg
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
joiner [?]
мне не встречались коды, где используется ассоциативное значение
Для списка (сохранение значения цвета текста/фона пункта): http://autoit-script.ru/index.php?topic=6570.0
Для дерева (сохранение индекса элемента массива): http://autoit-script.ru/index.php?topic=3725.0
Есть и ещё примеры, в основном Yashied'а.

В списках можно использовать для уникальных сортировок типа "по популярности". Например, при клике на пункт увеличивать ассоциативное число и затем сортировать по этому полю.
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
InnI
эти примеры не попались на глаза. когда разрабатывал программу JMPACK(есть на форуме), то возникла необходимость идентифицировать пункты дерева просмотра. сразу взял инструмент из справки.
дополнил пример выше
 
Автор
Cytrus

Cytrus

Новичок
Сообщения
110
Репутация
3
InnI
Да, Yashied сделал мощный скрипт с деревом.
Только я не понял, откуда он берёт это число.
 
Автор
Cytrus

Cytrus

Новичок
Сообщения
110
Репутация
3
А как можно сделать так, чтобы программа "забыла" все назначенные значения?
Может есть какое-то сообщение или API-функция?
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
Cytrus [?]
сделать так, чтобы программа "забыла" все назначенные значения
А зачем? Не нужно - не пользуйтесь.
Но если очень хочется, то можно в цикле обнулить.
 
Верх