Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2007.05.06;
Скачать: [xml.tar.bz2];

Вниз

TValueListEditor, тот что с вкладки Additional   Найти похожие ветки 

 
Servelat ©   (2007-03-12 20:09) [0]

Написал замечательную прогу по заданию из универа, где использовал сабжевый компонент. Сегодня, скомпилировав ее на университетском компьютере, словил AV (ничего особенно удивительного ^^). В итоге, выяснилось, что ошибка возникает при следующей конструкции:

Пусть на форме лежит сабжевый компонент с именем, для краткости VL. Положим рядом кнопку и в ее обработчике пишем:

VL.Strings.Add("123=123");

При нажатии на кнопку в некоторых версиях Дельфи ловим AV.

Однако, дома у меня стоит BDS, где никаких ошибок не возникает :). Специально поставил Delphi 7, в ней ошибка наблюдается. В хелпе я упоминаний о такой проблеме не нашел.

Внимание, вопрос: как исправить приведенный код так, чтобы ошибки не возникало, либо какие сервис-паки на 6й делфи (тот, на котором я должен все это продемонстрировать на лабораторной работе) необходимо установить для решения проблемы. Также приветствуются любые соображения почему такая ошибка вообще имеет место быть.

ЗЫ Копать исходники VCL мне до следующих выходных скорее всего будет некогда, да и не то, чтобы сильно хотелось :). Так что надеюсь на вашу помощь.

ЗЗЫ Под отладкой посмотрел, указатели VL и VL.Strings ненулевые (хотя с чего бы).


 
Loginov Dmitry ©   (2007-03-12 23:08) [1]

Выбрось TValueListEditor нафик, и не рассказывай про это убожество никому!


 
Servelat ©   (2007-03-12 23:38) [2]

> [1]

Радикально. Однако, отсутствует аргументация, почему он убожество.

Моя работа демонстрирует использование RTTI, и сабжевый компонент используется в качестве сильно упрощенного "инспектора объектов" для неких геометрических фигур на форме. Я не могу придумать, как с меньшими затратами усилий и сравнимым удобством для пользователя организовать редактор свойств. И все замечательно работает, но только не на 6й, 7й Дельфи, чем я и озадачен. Неужели никто не пользовался этим компонентом на протяжении 2х версий Делфи (=. Может быть я им пользуюсь как то не так, но вроде все по-честному (выдержка из хелпа для Дельфи 7)

Use Strings to access the string list that the value list editor displays. Strings should be a TStrings descendant that contains strings of the form Name=Value.

At design time, add values to the Strings property using the string list editor. At runtime, you can use the methods of TStrings to add strings to the list one by one, or assign an existing TStrings descendant to the Strings property. When you set Strings at runtime, TValueListEditor copies the strings from the TStrings object you assign: it does not take ownership of the object itself.

When Strings is assigned, the value list editor displays the name portion (TStrings.Names) of the strings in its key column and the value portion (TStrings.Values) in the value column.


 
Knight ©   (2007-03-13 00:05) [3]

ValueListEditor1.InsertRow(F1)


 
Knight ©   (2007-03-13 00:31) [4]

А вот так работает и в D6...

procedure TForm1.Button3Click(Sender: TObject);
begin
 ValueListEditor1.Strings.BeginUpdate;
 try
   ValueListEditor1.Strings.Add("sdfsdf=sdfsdfdsf");
 finally
   ValueListEditor1.Strings.EndUpdate;
 end;
end;


 
Knight ©   (2007-03-13 00:34) [5]

Причём без BeginUpdate...EndUpdate; ошибка только при добавлении первой строки, если её добавить через Роу, то потом ошибки нет... а с бегин-энд ошибки нет вообще... %)


 
Servelat ©   (2007-03-13 00:46) [6]

> ошибка только при добавлении первой строки


Да я заметил, однако причины такого странного поведения мне неясны, имхо баг :).

Спасибо за советы, перепишу код с учетом [4].


 
Knight ©   (2007-03-13 00:55) [7]

Тогда уж лучше с учётом [3]... универсальнее и надёжнее.


 
Knight ©   (2007-03-13 00:58) [8]

К тому-же [4] является её частью :)

function TValueListEditor.InsertRow(const KeyName, Value: string;  Append: Boolean): Integer;
begin
 Result := Row;
 { If row is empty, use it, otherwise add a new row }
 if (Result > Strings.Count) or not IsEmptyRow then
 begin
   Strings.BeginUpdate;
   try
     if Append then
       Result := Strings.Add(FormatLine(KeyName, Value))
+ FixedRows else
       Strings.Insert(Result - FixedRows, FormatLine(KeyName, Value));
   finally
     Strings.EndUpdate;
   end;
 end else
 begin
   Cells[0, Result] := KeyName;
   Cells[1, Result] := Value;
 end;
end;


 
Loginov Dmitry ©   (2007-03-13 07:43) [9]

> Я не могу придумать, как с меньшими затратами усилий и сравнимым
> удобством для пользователя организовать редактор свойств.


Обычный TStringList, имхо, обойдется гораздо проще и удобнее (нервы по крайней мере сэкономишь). Правда я не пользовался TValueListEditor старше, чем у семерки, но там это действительно галимое убожество.


 
Knight ©   (2007-03-13 08:19) [10]

Объясните лучше почему с Update-скобками оно работает, а без них сбоит.. никогда не думал, что это может быть так критично.


 
ЮЮ ©   (2007-03-13 09:53) [11]

> Объясните лучше почему


А под отладчиком выяснить "почему" сложно?
Потому что без скобок он тут же пытается отрисоваться, а в методе TValueListStrings.FindItemProp "небезопасный код". В выделенной строке - Index = 0, а динамический массив FItemProps - ещё пуст.

function TValueListStrings.FindItemProp(const KeyOrIndex: Variant;
 Create: Boolean = False): TItemProp;
var
 Index: Integer;
begin
 if Count > 0 then
 begin
   if VarIsOrdinal(KeyOrIndex) then
     Index := KeyOrIndex
   else
   begin
     Index := IndexOfName(KeyOrIndex);
     if Create and (Index = -1) then
       raise Exception.CreateResFmt(@SKeyNotFound, [KeyOrIndex]);
   end;
   Result := FItemProps[Index];
   if Create and not Assigned(Result) then
   begin
     Result := TItemProp.Create(FEditor);
     FItemProps[Index] := Result;
   end;
 end
 else
   Result := nil;
end;


Заключая в скобки, ты не попадаешь в этот метод до полного завершения метода InsertItem, когда увеличиття не только Count, но и заполнится FItemProps


 
Knight ©   (2007-03-13 10:23) [12]

Спасибо :)


 
REA   (2007-03-13 10:56) [13]

А чего бы не писать Values["123"] := "123?


 
GrayFace ©   (2007-03-13 12:42) [14]

Я это тоже исправлял: http://www.grayface.nm.ru/RSPak.rar
И еще 1 баг с тем что Validate и SelectCell(кажется) иногда не вызывались.


 
Servelat ©   (2007-03-13 17:23) [15]

> А под отладчиком выяснить "почему" сложно?

Полагаю, что не так уж сложно, просто сложился стереотип (у меня), что борладовский код работает без нареканий, а ошибки появляются по причине кривых рук программиста. Однако, и боги грешны, Борланд не всемогущ (=. Усвою на будущее.


> А чего бы не писать Values["123"] := "123?

А чего бы не писать так, как в [0]? Хелп, насколько я его понимаю, разрешает оба варианта.

Выражаю всем принявшим участие в дискусии свою безграничную признательность.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2007.05.06;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.045 c
1-1173694564
mavrtuva
2007-03-12 13:16
2007.05.06
Quantum Grid


11-1158055111
[e]Bu$ter
2006-09-12 13:58
2007.05.06
Как отловить потерю фокуса у формы


2-1176626953
ppcumax
2007-04-15 12:49
2007.05.06
Как создать динамические переменные?


1-1173430622
SamProf
2007-03-09 11:57
2007.05.06
Как использовать IGlobalInterfaceTable ?


2-1176668202
Strate
2007-04-16 00:16
2007.05.06
Быстра сортировка в TListView





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский