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

Вниз

Строку в объект   Найти похожие ветки 

 
kyn66 ©   (2009-11-12 16:11) [0]

Подскажите, каким способом можно строку вставить в объект , ну например ComboBox ? Нужно к примеру просканировать текущий каталог диска, найденные файлы записать в Combobox, а полный путь к файлу сохранить в объекте. Помню со строками есть проблемы при сохранении в объект. Есть вот такой вариант

....
var
 PS: PString;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
 new(PS);
 PS^ := "Hello world 1";
 ComboBox1.Items.AddObject("Item1", TObject(PS));
 PS^ := "Hello world 2";
 ComboBox1.Items.AddObject("Item2", TObject(PS));
 PS^ := "Hello world 3";
 ComboBox1.Items.AddObject("Item3", TObject(PS));
...

procedure TForm1.FormDestroy(Sender: TObject);
begin
 Dispose(PS);
end;


При доступе к объекту

procedure TForm1.ComboBox1Change(Sender: TObject);
begin
 ShowMessage(PString(Combobox1.Items.Objects[0])^); //Hello world 1
end;


возникает ошибка (AV)


 
Dennis I. Komarov ©   (2009-11-12 16:20) [1]

Даже и не знаю, чего тут поделать можно...

срочно "на дерево"...


 
kyn66 ©   (2009-11-12 16:22) [2]

Насчет AV разобрался(в ComboBox.Strings изначально были строки). Однако при извлечении строки - данные неверные, точнее <"Hello world 3"/B> везде присутствует. Вот так извлекаю

 ShowMessage(PString(Combobox1.Items.Objects[Combobox1.ItemIndex])^);


 
Юрий Зотов ©   (2009-11-12 16:54) [3]

Уберите указатели, работайте напрямую со строками и пишите их прямо в Combobox.Items (через Add, а не через AddObject)


 
kyn66 ©   (2009-11-12 17:07) [4]

Мне не Items составляет проблему. Туда строку и так запишу. Получается , что в ComboBox нужно две строки внести, типа

ComboBox1.AddObjects("Строка 1", Pointer(kodstr))


Только вместо Pointer(kodstr) нужно записать строку. Эта запись будет верна, если бы kodstr = Integer/ Мне же строка нужна.


 
kyn66 ©   (2009-11-12 17:10) [5]

Это нужно к тому, чтобы каждый Items ComboBox-а содержал в себе двойную информацию(две строки). Как вариант параллельно заводил переменную TStringList и в нее вносил вторые интересуемые строки, а потом сопостовлял их по ItemIndex. Но ведь это не есть лучший вариант?


 
LDV   (2009-11-12 17:14) [6]

Вот так:


procedure TForm1.Button2Click(Sender: TObject);
begin

 ComboBox1.Items.AddObject("Строка 1", TObject(Application.ExeName));

 ShowMessage(string(ComboBox1.Items.Objects[0]));

end;


 
Юрий Зотов ©   (2009-11-12 17:17) [7]

> kyn66 ©   (12.11.09 17:10) [5]

В смысле безопасности кода - возможно, лучший.

Без обид - Вы недостаточно знакомы с реализацией длинных строк в Delphi, поэтому и налетаете на ошибки работы с памятью.


 
RWolf ©   (2009-11-12 17:28) [8]

Чтоб не ходить по граблям:
type
 TMyContainer=class
    s:string;
    ...
 end;

...
container := TMyContainer.Create;
container.s := "this is a string";
ComboBox1.Items.AddObject("Item3", container);

...

ShowMessage(TMyContainer(Combobox1.Items.Objects[0]).s);

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


 
kyn66 ©   (2009-11-12 17:53) [9]


> RWolf ©   (12.11.09 17:28) [8]


Очень даже интересный вариант. Помнится кто то уже предлагал такой. Это код при условии если вводим один Item. А если их много? Как в данном случае container.s будет принимать значения и передавать их ComboBox ? Как обращаться к нему для получения конкретного значения по ItemIndex ?


 
Игорь Шевченко ©   (2009-11-12 17:54) [10]

у тебя столько вопросов, может, тебе проще программиста найти ?


 
kyn66 ©   (2009-11-12 17:55) [11]


Юрий Зотов ©   (12.11.09 17:17) [7]
> Без обид - Вы недостаточно знакомы с реализацией длинных
> строк в Delphi, поэтому и налетаете на ошибки работы с памятью.
>


Даже и близко нету. Поэтому и советуюсь с мастерами.


 
Dennis I. Komarov ©   (2009-11-12 17:55) [12]


> kyn66 ©   (12.11.09 17:53) [9]

array?


 
kyn66 ©   (2009-11-12 17:57) [13]


> Игорь Шевченко ©   (12.11.09 17:54) [10]
> у тебя столько вопросов, может, тебе проще программиста
> найти ?


Трудно отвечать? Вопросы возникают по мере необходимости реализации ситуации. Хочу знать больше. Это плохо? или я не в ту ветку постучался?


 
Игорь Шевченко ©   (2009-11-12 18:03) [14]


> Хочу знать больше.


Любите книгу - источник знаний


 
zlo   (2009-11-12 18:09) [15]


> А если их много? Как в данном случае container.s будет принимать
> значения и передавать их ComboBox ? Как обращаться к нему
> для получения конкретного значения по ItemIndex ?



type
 TStr = class
 private
   FStr: string;
   procedure SetStr(const Value: string);

 public
   constructor Create(AStr: string);

 property Str: string read FStr write SetStr;
 end;



{ TStr }

constructor TStr.Create(AStr: string);
begin
 Str := AStr;
end;

procedure TStr.SetStr(const Value: string);
begin
 if FStr <> Value then FStr := Value;
end;



{ TForm1 }

procedure TForm1.Button2Click(Sender: TObject);
begin
 ComboBox1.Items.AddObject("Item 1", TStr.Create("ObjectItem 1"));
 ComboBox1.Items.AddObject("Item 2", TStr.Create("ObjectItem 2"));
 ComboBox1.Items.AddObject("Item 3", TStr.Create("ObjectItem 3"));

 ShowMessage(TStr(ComboBox1.Items.Objects[0]).Str);
 ShowMessage(TStr(ComboBox1.Items.Objects[1]).Str);
 ShowMessage(TStr(ComboBox1.Items.Objects[2]).Str);
end;


 
Дмитрий Белькевич   (2009-11-12 18:21) [16]

Глобально:

1. Забыть (в большинстве случаев) New/Dispose.
2. Забыть (в большинстве случаев, кроме работы с сишными строками) при работе со строками/символами про указатели и нуль-терминированные строки.
3. Переписать с учетом забытого.


 
Leonid Troyanovsky ©   (2009-11-12 18:36) [17]


> kyn66 ©   (12.11.09 17:10) [5]

> Это нужно к тому, чтобы каждый Items ComboBox-а содержал
> в себе двойную информацию(две строки).

Такое делают, используя стили cbOwnerDraw*.
Item составляют из двух строк, разделенных неким разделителем,
например "|" or tab, а рисуют лишь одну из половин.

Но, в случае с файлами нет нужды хранить все в одном.
Проще хранить в одном комбобоксе имя устройства, во
втором - имена папок на нем, а в третьем ее содержимое.

Ну, и CB_DIR тебе в руки.

--
Regards, LVT.


 
Amoeba ©   (2009-11-12 22:30) [18]


> kyn66 ©   (12.11.09 16:11)
>
> Подскажите, каким способом можно строку вставить в объект
>

лучше промолчу, иначе гарантированное пожизненное  RO получу.


 
Leonid Troyanovsky ©   (2009-11-12 22:49) [19]


> Amoeba ©   (12.11.09 22:30) [18]

> лучше промолчу

Господа офицеры!
Как договорились - ни слова о ..

--
Regards, LVT.


 
kyn66 ©   (2009-11-12 23:02) [20]


> zlo   (12.11.09 18:09) [15]


Я думаю это то что нужно.


> Leonid Troyanovsky ©   (12.11.09 18:36) [17]


Да не о визуальном представлении идет речь, а о хранении данных(Имя файла - Items; Полный путь - Объект).


 
Leonid Troyanovsky ©   (2009-11-12 23:11) [21]


> kyn66 ©   (12.11.09 23:02) [20]

> Да не о визуальном представлении идет речь,

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

Все остальное лишь кажется.

--
Regards, LVT.


 
kyn66 ©   (2009-11-12 23:13) [22]


> zlo   (12.11.09 18:09) [15]


Здается мне здесь еще нужно предусмотреть освобождение памяти после использования объектов.


 
kyn66 ©   (2009-11-12 23:28) [23]


> Leonid Troyanovsky ©   (12.11.09 23:11) [21]


А применение к нему AddObject как Сергей говорит каран запрещает? :)


 
Германн ©   (2009-11-13 01:42) [24]


> А применение к нему AddObject как Сергей говорит каран запрещает?
>  :)

Во-первых Сергей говорит кОран. А во-вторых что ты так зациклился на AddObject, что другие варианты не признаёшь?

Ну и плюс

> Юрий Зотов ©   (12.11.09 17:17) [7]
>
> > kyn66 ©   (12.11.09 17:10) [5]
>
> Без обид - Вы недостаточно знакомы с реализацией длинных
> строк в Delphi, поэтому и налетаете на ошибки работы с памятью.


 
{RASkov} ©   (2009-11-13 07:58) [25]

> [20] kyn66 ©   (12.11.09 23:02)
> Да не о визуальном представлении идет речь, а о хранении
> данных(Имя файла - Items; Полный путь - Объект).

Ну так и выбери другой контейнер для хранения двух строк.
Зачем мазахизмом заниматься?
type
 TDualStr = record
  NameFile, PathFile: String;
 end;
 TDualStrs: array of TDualStr;
Если нужно отоброжать то любой контрол с виртуальным режимом...


 
Юрий Зотов ©   (2009-11-13 08:38) [26]

> kyn66 ©   (12.11.09 23:28) [23]

Теперь прикиньте: Вы все же упорно хотите для хранения второй строки использовать свойство Objects и ради этого готовы "обернуть" эту вторую строку в специальный объект, за которым Вам еще придется "следить" - то есть вовремя создавать и уничтожать. Это дополнительный расход памяти, дополнительный код и дополнительный риск ошибок в этом коде.

А зачем? Разве не проще и не безопаснее (в смысле ошибок) делать именно так, как Вы вначале и делали - хранить вторые строки в отдельном списке и сопоставлять их по индексу?

Кроме того: если Вы собираетесь хранить списки файлов и каталогов, то, возможно, Вам подойдут готовые компоненты TDirectoryListBox и TFileListBox. Тогда, возможно, ничего программировать и не нужно будет.


 
kyn66 ©   (2009-11-13 09:12) [27]


> Юрий Зотов ©   (13.11.09 08:38) [26]



> А зачем? Разве не проще и не безопаснее (в смысле ошибок)
> делать именно так, как Вы вначале и делали - хранить вторые
> строки в отдельном списке и сопоставлять их по индексу?


Этот вариант был придуман давно. Просто я не думал что он совсем грамотный и "современный". А раз Мастер его утверждает, то на нем и останусь.


> А во-вторых что ты так зациклился на AddObject, что другие
> варианты не признаёшь?


Да нет, просто хотелось его иметь в своей копилке вариантов применения в определенных ситуациях. Когда нас учили в институте, то говорили, что инженер не обязан все держать в голове. Он должен знать и быстро определить где сможет получить ответ на тот или иной вопрос. Вот для этого копилка наработок и присутствует.


 
Dennis I. Komarov ©   (2009-11-13 09:48) [28]


> Он должен знать и быстро определить где сможет получить
> ответ на тот или иной вопрос.

delphimaster.ru :)


 
kyn66 ©   (2009-11-13 09:48) [29]


> Юрий Зотов ©   (13.11.09 08:38) [26]


Вот она, задумка - http://delphi.about.com/od/vclusing/a/items_addobject.htm
store one more additional string along the one displayed to the user.


 
kyn66 ©   (2009-11-13 09:49) [30]


> Dennis I. Komarov ©   (13.11.09 09:48) [28]
>
> delphimaster.ru :)


В том числе... ;)


 
Dennis I. Komarov ©   (2009-11-13 10:05) [31]


> kyn66 ©   (13.11.09 09:49) [30]

Ты не познал сути учения...


 
kyn66 ©   (2009-11-13 10:09) [32]


> Dennis I. Komarov ©   (13.11.09 10:05) [31]
> > kyn66 ©   (13.11.09 09:49) [30] Ты не познал сути учения.
> ..


Это как понять?


 
Dennis I. Komarov ©   (2009-11-13 10:53) [33]

Так и понимай, то что до тебя хотели донести этой фразой ты не осознал...


 
kyn66 ©   (2009-11-13 11:08) [34]


> Dennis I. Komarov ©   (13.11.09 10:53) [33]
> Так и понимай, то что до тебя хотели донести этой фразой
> ты не осознал...


Какой этой фразой ? Что вы все загадками говорите? Или нормально сказать гонор не позволяет?

В конечном итоге решение найдено. Цель достигнута после [15], спасибо автору за наводку + прочитка материала http://delphi.about.com/od/vclusing/a/items_addobject.htm . Тему можно закрыть . Всем спасибо!


 
Dennis I. Komarov ©   (2009-11-13 11:28) [35]


> Какой этой фразой ?

[28]

> Что вы все загадками говорите?

Ну не все же разжевывать...


 
kyn66 ©   (2009-11-13 11:35) [36]


> Ну не все же разжевывать...


Если по поводу частых обращений на  delphimaster.ru, то  уже сто раз говорил, что нато это и форум, чтобы здесь задавать вопросы и если кто считает нужным - на них отвечать. А не писать глупые ухмылочные намеки! Тем более ветка выбрана не для вундеркиндов. (Не все знаете учились на программистов... Некоторые учились этому через книги, вопросы, форумы и т.д.). Т.ч. коллеги, давайте не будем умничать, а отвечать по существу, если есть желание !!!


 
Григорьев Антон ©   (2009-11-13 12:57) [37]


> kyn66 ©   (13.11.09 11:35) [36]
> (Не все знаете учились на программистов... Некоторые учились
> этому через книги, вопросы, форумы и т.д.

Я вот тоже не учился на программиста :) Поэтому давайте с самого начала и вместе :)

Ваши строки искажаются потому, что string - это управлемый тип, т.е. компилятор следит за тем, сколько ссылок есть на строку, и при уничтожении всех ссылок освобождает память, выделенную под строку. Но интеллекта компилятора хватает только на то, чтобы отслеживать ссылки, явно объявленные как string. Когда вы приводите строку к TObject, вы получаете ещё одну фактическую ссылку на эту строку, но так она не имеет тип string, то компилятор игнорирует её при подсчёте. Теперь, как только все остальные ссылки будут освобождены, память, выделенная для строки, будет помечена как неиспользуемая, и в любой момент она может быть распределена для других нужд. А ссылка на эту память у вас осталась. В результате, когда вы обращаетесь по ней, то получаете более-менее случайный мусор.

Чтоюы этого не происходило, надо не приводить управляемые ссылки к левым типам. Одно из решений вам подсказали: использование классов. Классы - типы неуправляемые, никто ссылки на них не считает, сами никогда не удалятся, так что левые ссылки на них хранить достаточно безопасно. А уж в класс можно засунуть явно объявленную string, и компилятор правильно её посчитает. Но это - лишний расход ресурсов, как вам уже сказали.

Чтобы этого избежать, можно записывать в Objects ссылку на неуправляемую строку, т.е. на PChar. Только надо не забываь перед этим выделять для такой строки память (с помощью, например, StrNew), а потом, когда строка станет ненужной, удалять. Если вы не удалите такую ссылку вручную, то получите утечку памяти. Так что этот вариант требует некоторой внимательности. Как, впрочем, и вариант с использованием дополнительного TStringList: там тоже надо следить, чтобы списки были синхронизированы.


 
kyn66 ©   (2009-11-13 13:14) [38]


> Григорьев Антон ©   (13.11.09 12:57) [37]


Спасибо Антон за ликбез. Приятно читать умные слова. Из всего здесь выше сказанного я принял для себя  2 варианта. 1) Параллельное хранение данных в TStringList ; 2) Использование классов (очень понравился вариант). В нем я могу хранить много разных данных. Главное не забывать удалять ссылки на объекты. Вот такой вариан применил себе. Испробовано на 2-х типах данных. ВОт тестовый пример. Ничего лишнего и все работает на ура!

...
type
 TStr = class
   private
     FName : string;
     FOlds : Integer;
   public
     property Name: String read FName;
     property Olds: Integer read FOlds;
     constructor Create(Const name: string; Const olds : Integer);
 end;
...
 procedure FreeObjects(const strings: TStrings) ;
implementation

{$R *.dfm}

constructor TStr.Create(Const name: string; Const olds : Integer);
begin
 FName := name;
 FOlds := olds;
end;

procedure TForm1.FreeObjects(const strings: TStrings) ;
var
 idx : integer;
begin
 for idx := 0 to Pred(strings.Count) do
 begin
   strings.Objects[idx].Free;
   strings.Objects[idx] := nil;
 end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 FreeObjects(ComboBox1.Items);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 ComboBox1.Items.AddObject("Item 1", TStr.Create("ObjectItem 1", 1));
 ComboBox1.Items.AddObject("Item 2", TStr.Create("ObjectItem 2", 2));
 ComboBox1.Items.AddObject("Item 3", TStr.Create("ObjectItem 3", 3));
end;

procedure TForm1.ComboBox1Change(Sender: TObject);
begin
 ShowMessage(TStr(ComboBox1.Items.Objects[ComboBox1.ItemIndex]).Name + #10#13 +
             IntToStr(TStr(ComboBox1.Items.Objects[ComboBox1.ItemIndex]).Olds));
end;
....

А вот по поводу PChar, то вроде в [0] все с этого и начиналось.

> Ваши строки искажаются потому, что string - это управлемый
> тип, т.е.

Не совсем искажаются, а при кликах по любому Items выдает одно и то же значение "объекта"

Да и сообщение [16] как то насторожило и заставило подумать почему так?

В конечном итоге можно было остановиться на использовании TStringList с синхронизацией.... Но хочется изучить и применить нечто новое. Интересовали новые, другие доступные механизмы.


 
SergP ©   (2009-11-13 13:25) [39]


> Подскажите, каким способом можно строку вставить в объект
> , ну например ComboBox ? Нужно к примеру просканировать
> текущий каталог диска, найденные файлы записать в Combobox,
>  а полный путь к файлу сохранить в объекте. Помню со строками
> есть проблемы при сохранении в объект.


А зачем все это?
Если рассуждать в пределах данного примера, то:
полный путь к файлу = путь к каталогу +"\" +имя файла
А если ты сканируешь определенный каталог, то значит путь к этому каталогу  для всех файлов одинаковый...

Или у тебя просто пример неудачный?


 
kyn66 ©   (2009-11-13 13:32) [40]


> SergP ©   (13.11.09 13:25) [39]
>
>Или у тебя просто пример неудачный?


ТОбою не понята суть вопроса. Вопрос был из области AddObject с передачей строки в качестве параметра. Он впринципе уже решен. Почитай ветку полностью, могет пригодится ;)



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

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

Наверх





Память: 0.57 MB
Время: 0.046 c
2-1258544870
tonich
2009-11-18 14:47
2010.01.10
скрыть метод предка


10-1162211576
Max Ivanych
2006-10-30 15:32
2010.01.10
Защита диапазона ячеек в Excel


2-1258692158
d@nger
2009-11-20 07:42
2010.01.10
Запрос SQL: INSERT INTO .... SELECT


2-1258478697
&#8467;o&#8467;
2009-11-17 20:24
2010.01.10
Получение сообщения о нажатии клавищи


2-1258287355
sagitt
2009-11-15 15:15
2010.01.10
Не работает отладчик





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский