Что нового

Странное поведение _GUICtrlListView_FindText()

The Dream

Новичок
Сообщения
393
Репутация
3
Подскажите пожалуйста, почему при использовании ф-ции:

Код:
_GUICtrlListView_FindText($hListView, $sText)


- то рано или поздно происходит крах в программе. Если же использовать конструкцию:

Код:
For $b = 0 To _GUICtrlListView_GetItemCount($hListView) - 1
		If _GUICtrlListView_GetItemText($hListView, $b) = $sText Then
			$iItem = $b
			ExitLoop
		EndIf
	Next


То все хорошо - проверил на десятичасовой работой программы. Почему так? И еще - может дело в дополнительных параметрах:

_
Код:
_GUICtrlListView_FindText($hListView, $sText,0,0)


Правда я все же не очень понимаю их значения.. :whistle:
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
30 раз нажал, ни краха ни увеличения размера процесса. WinXP SP3

The Dream [?]
Правда я все же не очень понимаю их значения
из справки
$fPartialOK [необязательный] Если True, то соответствие будет выполнятся, если начало текста пункта соответствует искомому
$fWrapOK [необязательный] Если True, то поиск продолжится от первого пункта, если ни одного соответствия не найдено
Итак, первый означает при поиске слова "текст" найдётся и "текстовый" потому что начало совпадает
второй: если текущий пункт 100, то от него проверит вниз, а первые 99 не проверит и поиск не полноценный, но нужный в случае пошагового поиска следующего значения. При True проверит все пункты, а не только конец.
 
Автор
T

The Dream

Новичок
Сообщения
393
Репутация
3
AZJIO, спасибо за разъяснение.

Но поверьте, так как я написал - так и есть, то есть ошибка краха программы была именно в этом. Может быть это связано еще с WM_NOTIFY, где я устанавливаю цвет каждой строке и sub-блоку..
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
The Dream
Напишите в баг трекер если так.
:
Вы случайно не используете GUICtrlCreateListViewItem
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
The Dream [?]
Может быть это связано еще с WM_NOTIFY, где я устанавливаю цвет каждой строке и sub-блоку..
Нужно видеть полный пример кода, где у тебя воспроизводится данная проблема.
 
Автор
T

The Dream

Новичок
Сообщения
393
Репутация
3
inververs, конечно нет, ведь я использую _GUICtrlListView_*
CreatoR, конечно, если бы это было возможно - я бы не раздумывая показал код. Все же я склоняюсь к тому, что это конфликт с WM_NOFITY, так как там отлов события изменения ячейки в ListView - любого изменения, но и правильно объяснить причем тут это - тоже трудно. Просто кажется. В любом случае, факт остается фактом - какой бы не был код и каким бы он не был правильным или нет, конфликт есть, программа работала без единого сбоя всю ночь с заменой, что я привел в первом сообщении.

Я даже для этого написал вторую утилиту, которая перезапускала основную программу и записывала время. Не было ни одного перезапуска. В то время, как с прежним вариантом (я о ф-ции) - то через час, то через два, то через четыре.

Это наверно конфликт все же.. мне так кажется :whistle:
7 дней мучался, пока не решился все же искать ошибку с помощью самого Autoit.
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
The Dream
Пишите лог на каждое подозрительное действие. Например произошло событие - записывается время и код или номер строки. Каждую минуту в лог писать размер процесса. Лог пишется в открытый дескриптор со сбросом буфера (FileFlush), чтобы в момент падения вся информация была зафиксирована. По логу можно определить какая последняя операция выполнялась. Если много инфы пишется, то с лога можно каждые 30 минут удалять инфу, кроме последних 10 строк.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
The Dream [?]
если бы это было возможно - я бы не раздумывая показал код
Это возможно. Не обязательно выкладывать свой код, можно воспроизвести такое же поведение на примерочном коде.

В любом случае, факт остается фактом - какой бы не был код и каким бы он не был правильным или нет, конфликт есть
Его нужно увидеть не для оценки правильности, а для того чтобы понять в чём проблема :smile:.
 
Автор
T

The Dream

Новичок
Сообщения
393
Репутация
3
AZJIO, с помощью такого "логирования", я и выявил ошибку.
CreatoR - все верно, но я не знаю что именно конфликтует и вызывает эту ошибку. Поэтому в примере скорее всего все бы работало.

Да и кто это из Вас будет проверять код не один час? :whistle:
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
The Dream [?]
я не знаю что именно конфликтует и вызывает эту ошибку. Поэтому в примере скорее всего все бы работало.
У меня вопрос - насколько тебе важно найти в чём проблема?
Если очень важно, то ты составишь пример на основе своего скрипта, где будет проявляться подобная проблема, а в процессе создания примера, глядишь и сам найдёшь в чём причина ;).
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
Если бы эта была отсебятинская функция то можно было бы подозревать, так ведь нет, сообщение $LVM_FINDITEM
 
Автор
T

The Dream

Новичок
Сообщения
393
Репутация
3
CreatoR, мне было очень важно. Именно поэтому я и поставил во многих местах "флаги", с помощью которых и определял в каких местах происходит крах программы. Потом я поставил еще больше флагов (запись была в ini-файл) и так много, что даже программа работала медленно, но оно того стоило. И за ночь получилось так, что было 4 краха (еще работал скрипт, который отлавливал окно с ошибкой и перезапускал программу) и все в одном месте. Когда заменил на иную конструкцию, которую выше упомянул - краха не было ни одного. Мог сделать пример, изучать, и с Вами советоваться - но времени не было :smile: .

AZJIO, если под понятием "отсебятинская" имеется ввиду не официальная ф-ция - то в этом случае, я понимал бы в чем дело (а именно в ф-ции).

Ладно, пожалуй на этом все, всем спасибо, проблема как бы решена.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
The Dream [?]
проблема как бы решена
Если скрипт что то крашит, то проблема не решена.
Я бы так быстро не сдавался, и нашёл бы в чём дело, т.к это поможет и другим в дальнейшем не столкнуться с подобной проблемой.
 
Автор
T

The Dream

Новичок
Сообщения
393
Репутация
3
CreatoR, хорошо, как ты видишь решение проблемы? Написать пример скрипта, воспроизводящий крах программы? Это логично. Но кто будет его проверять часами? Также может быть это из-за "медленного" компьютера.

Все таки трудно представить что это баг в ф-ции.

Вот вся ф-ция из-за которой был крах системы и в которой я изменил концепцию поиска:

Код:
Func _GUICtrlListView_AddSubItemEx($sUrl, $sText = '', $iSubItem = 0, $iEnsureVisible = 1)

	If $iSubItem <> 0 And $sText <> '' Then
		;Local $iItem = _GUICtrlListView_FindText($hListView, $sUrl,0,0)
		$iItem = -1
		For $b = 0 To _GUICtrlListView_GetItemCount($hListView) - 1
			If _GUICtrlListView_GetItemText($hListView, $b) = $sUrl Then
				$iItem = $b
				ExitLoop
			EndIf
		Next

		If $iItem <> -1 Then
			If StringInStr($sText, '[]') Then $sText = _GUICtrlListView_GetItemText($hListView, $iItem, $iSubItem) & StringReplace($sText, '[]', '')
			Select
				Case StringInStr($sText, '[True]')
					$sText = StringReplace($sText, '[True]', '')
					$pParam = _GUICtrlListView_GetItemParam($hListView, $iItem)
					$tParam = DllStructCreate('int[10]', $pParam)
					DllStructSetData($tParam, 1, 0x95FF9F, $iSubItem + 1)
				Case StringInStr($sText, '[False]')
					$sText = StringReplace($sText, '[False]', '')
					$pParam = _GUICtrlListView_GetItemParam($hListView, $iItem)
					$tParam = DllStructCreate('int[10]', $pParam)
					DllStructSetData($tParam, 1, 0xFF9595, $iSubItem + 1)
				Case StringInStr($sText, '[Warning]')
					$sText = StringReplace($sText, '[Warning]', '')
					$pParam = _GUICtrlListView_GetItemParam($hListView, $iItem)
					$tParam = DllStructCreate('int[10]', $pParam)
					DllStructSetData($tParam, 1, 0xFFDD95, $iSubItem + 1)
			EndSelect
			_GUICtrlListView_AddSubItem($hListView, $iItem, $sText, $iSubItem)
			If $iEnsureVisible = 1 Then _GUICtrlListView_EnsureVisible($hListView, $iItem)
		EndIf
	EndIf
	Return False
EndFunc   ;==>_GUICtrlListView_AddSubItemEx


Конечно этот способ - это не дело, но это временно. Номер строки будет хранится в массиве, в общем я обошел проблему и выиграл в быстродействии.

Может я сделаю пример, и может получится воспроизвести крах ошибки.
Но опять же. Я же поставил везде "флаги" - а именно везде в цикле и в этой ф-ции и последний флаг был всегда тот, что стоит в прямом смысле перед ф-цией _GUICtrlListView_FindText(). Не почти, а всегда.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
The Dream [?]
Написать пример скрипта, воспроизводящий крах программы? Это логично. Но кто будет его проверять часами?
Не нужно проверять часами, эту проблему вызывает что то конкретное, нужно это выявить (методом отсеивания, проб и ошибок).

Вот вся ф-ция из-за которой был крах системы и в которой я изменил концепцию поиска
Ну вот, уже продвигаемся :smile:.

Пару вопросов чтобы попытаться выйти на чистую воду...

* $hListView это Handle или ID?
* Какие могут быть варианты параметра $sUrl? я имею в виду тип данных, макс. длина, спец. символы в строке и т.п.
* Для чего используется $tParam и т.д? При создании структуры указывается указатель, но разве _GUICtrlListView_GetItemParam обязательно возвращает указатель?
 
Автор
T

The Dream

Новичок
Сообщения
393
Репутация
3
CreatoR, $hListView это конечно handle. $sUrl - конечно строка, спец. символы - как в адресной строке.

с помощью $tParam я как бы заполняю то, что находится в памяти (посредством DllStructCreate), указатель на которую (область) уже занесен в дополнительный параметр строки. Изначально был создан буфер (область памяти) и указатель был записан при создании строки и потом мы только работаем с ним.

Плюс ко всему еще WM_NOFITY:

Код:
Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)

		Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
		Local $hWndFrom = DllStructGetData($tNMHDR, 'hWndFrom')
		Local $iCode = DllStructGetData($tNMHDR, 'Code')

		Switch $hWndFrom
			Case $hListView
				Switch $iCode
					Case $NM_CUSTOMDRAW
						Local $tNMLVCD = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam)
						Local $iDrawStage = DllStructGetData($tNMLVCD, 'dwDrawStage')
						Local $iItem = DllStructGetData($tNMLVCD, 'dwItemSpec')
						Local $iSubItem = DllStructGetData($tNMLVCD, 'iSubItem')
						Switch $iDrawStage
							Case $CDDS_PREPAINT
								Return $CDRF_NOTIFYITEMDRAW
							Case $CDDS_ITEMPREPAINT
								Return $CDRF_NOTIFYSUBITEMDRAW
							Case BitOR($CDDS_ITEMPREPAINT, $CDDS_SUBITEM)
								$pParam = _GUICtrlListView_GetItemParam($hWndFrom, $iItem)
								$tParam = DllStructCreate('int[10]', $pParam)
								$iColor = DllStructGetData($tParam, 1, $iSubItem + 1)
								If $iColor = 0 Then $iColor = 0xFDFFB9
								DllStructSetData($tNMLVCD, 'clrTextBk', _BGRColor($iColor))
								Return $CDRF_NEWFONT
						EndSwitch
					Case $NM_CLICK ; Sent by a list-view control when the user moves the mouse over an item
						$tInfo = DllStructCreate($tagNMLISTVIEW, $lParam)
						$iSubItem = DllStructGetData($tInfo, "SubItem")
						If $iSubItem <> $iSubItemLast Then
							If $iSubItemLast = 0 Then
								$iWidth = 180
							Else
								$iWidth = 100
							EndIf
							_GUICtrlListView_SetColumnWidth($hListView, $iSubItemLast, $iWidth)
							_GUICtrlListView_SetColumnWidth($hListView, $iSubItem, 180)
							_GUICtrlListView_BeginUpdate($hListView)
							_GUICtrlListView_EndUpdate($hListView)
							$iSubItemLast = $iSubItem
						EndIf
					Case $NM_RCLICK
						$aIndex = _GUICtrlListView_GetSelectedIndices($hListView, True)
						If $aIndex[0] <> 0 Then
							_ShowMenu($hGui, $hMenu, $hListView)
						EndIf
				EndSwitch
		EndSwitch
		Return $GUI_RUNDEFMSG

	EndFunc   ;==>WM_NOTIFY


:smile:


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

Поверь, я неделю сидел за кодом - такой я уж человек, иду до конца. На форуме о проблеме сообщил только через неделю, когда уже не было сил. А только сейчас, потому что понимал что вряд ли это баг. Это скорее всего дело в коде. Да и продемонстрировать ошибку я вряд ли бы смог. Я учитывал все. Мне кажется - все :whistle:
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
The Dream [?]
$sUrl - конечно строка, спец. символы - как в адресной строке.
Какой длины она может достигать? И откуда берётся строка?

с помощью $tParam я как бы заполняю то, что находится в памяти
Оно действительно так необходимо?

Плюс ко всему еще WM_NOFITY:
В справке написано:
[box title=http://autoit-script.ru/autoit3_docs/functions/GUIRegisterMsg.htm]Внимание: блокировка выполняющейся пользовательской функции, например командой "Msgbox()" может привести к непредсказуемому поведению, вернуть управление системе нужно как можно быстрее !!![/box]

_ShowMenu(...) этому не способствует ;).


Я учитывал все. Мне кажется - все
Естественно кажется, т.к предусмотреть всё невозможно, это факт.
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
А так разве можно int[10] ?
О, нашёл на офсайте такой вариант, значит можно.
 
Автор
T

The Dream

Новичок
Сообщения
393
Репутация
3
CreatoR [?]
Какой длины она может достигать? И откуда берётся строка?


Строка берется из списка в ListView (по циклу for). Длина стандартного url - никак не больше чем на форуме. Спец. символы вроде @ - отсутствую, наверно их и не встретить а адресной строке.

Оно действительно так необходимо?

К сожалению да, там массив цветов item/sub-item.

В справке написано:

Вот здесь не совсем понял. Вроде бы моя ф-ция не блокировала на длительный промежуток (больше 1/4 с).. :whistle:

:smile:


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

AZJIO [?]
А так разве можно int[10] ?


А почему нет? :whistle:
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
The Dream [?]
Вот здесь не совсем понял. Вроде бы моя ф-ция не блокировала на длительный промежуток
Что делает _ShowMenu?
Есть подозрение, что эта функция показывает контекстное меню (TrackPopupMenu), в таком случае, скрипт на ней блокируется, пока меню не закроется.
 
Верх