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

Вниз

Хранение Integer в Combobox   Найти похожие ветки 

 
Влад Утюмов   (2002-09-27 07:55) [0]

Подскажите новичку, плз наиболее прямой способ решения задачи.
Есть комбобокс на форме. В нем, кроме строк, хочется хранить целочисленные значения (ключи таблицы в БД, но это не важно). Из документации выясняю, что есть

AddItem(Item: String, AObject: TObject)

Вроде то что надо. То что Integer это не TObject - не беда, полминуты - готова обертка вокруг Integer, унаследованная от TObject

И тут натыкаюсь на то, что TStrings не владеет обжектами, что их надо самому удалять. А чтобы самому удалять, надо их еще где-то хранить, и получается уже бред.

Лезут в голову разные мысли, типа поменять поведение TComboBox путем наследования или складывать ссылки на обжекты в отдельную корзину, а потом вытряыхивать разом, или хранить ключи вообще отдельно, в массиве каком-нибудь.

Но думается, что у такой тривиальной и распространенной, ИМХО, задачи не должно быть сложного и уродливого решения. Душа желает простоты.

Влад.


 
sask   (2002-09-27 08:15) [1]

IntToStr и StrToInt...


 
Separator   (2002-09-27 08:20) [2]

ComboBox1.Items.Add(IntToStr(N)); {N: integer}
N:= StrToInt(ComboBox1.Items.Strings[i]); {но тока если в i-той ячейке храниться число, иначе ошибка}


 
Song   (2002-09-27 08:33) [3]

Всю ифнормацию можете хранить в этих же строках. Однако рисовать итемы самому не выводя эту служебную информацию.


 
MBo   (2002-09-27 08:34) [4]

ComboBox1.Items.AddObject(AString,Pointer(AInteger));

j:=Integer(ComboBox1.Items.Objects[i]);

Ничего в этом случае выделять не надо, Integer как раз помещается в 4 байтах, уже имеющихся под указатель


 
kronprince   (2002-09-27 09:49) [5]

2MBo © (27.09.02 08:34)
Можно и так если быть увереннным что integer не станет снова каким-то Smallint или Int64

Я для этих целей сделал объект TDictionary, если хош скину


 
MBo   (2002-09-27 09:50) [6]

>что integer не станет снова каким-то Smallint или Int64
Почему он должен ими стать????


 
Толик   (2002-09-27 10:02) [7]

to MBo © (27.09.02 09:50)
Ну ведь был же integer двухбайтовым, сейчас он четырёхбайтовый. И очень вероятно, что грядут времена восьмибайтовых интов...


 
qube   (2002-09-27 10:08) [8]

>Ну ведь был же integer двухбайтовым, сейчас он четырёхбайтовый. И >очень вероятно, что грядут времена восьмибайтовых интов...

Тогда, вероятно, и указатели станут 8-байтовыми, а кроме того, вопрос был о комбобоксе, и кажется мне, что добавлять туда числа порядка 2-х миллиардов никто не собирается.


 
KSergey   (2002-09-27 10:22) [9]

2 Толик © (27.09.02 10:02)

В принципе вы правы, но как правило программа пишется под определенную версию D, где на таких нюансах вполне можно сыграть (я имею в виду совпадение размеров). При этом если станет small - не страшно, все равно влезет.


 
Anatoly Podgoretsky   (2002-09-27 10:26) [10]

MBo © (27.09.02 09:50)
Это generic тип, так что такая возможность очень вероятноь и расчитывать на соместимость по размеру, преобразованию лучше не стоит


 
Юрий Зотов   (2002-09-27 10:27) [11]

> Ну ведь был же integer двухбайтовым, сейчас он
> четырёхбайтовый. И очень вероятно, что грядут времена
> восьмибайтовых интов...

И ничего не изменится. Во все времена Integer соответствовал машинному слову. Pointer тоже. Так было и так будет, поскольку это один из основополагающих принципов. Поэтому размеры Integer и Pointer всегда будут совпадать, а только это и требуется.

Но вот плодить объектную оболочку вокруг Integer...

Можно, конечно, и гвозди табуреткой забивать. Но молотком лучше.


 
KIR   (2002-09-27 10:31) [12]

Я вообще в этом случае (конкретно когда надо в ComboBox выводить какое либо поле из БД и еще где хранить ключ) делаю так:

Предположим есть некий запрос из которого и надо брать требуемые поля (MyQuery);
Объявляю глобальную переменную IDList: TStringList;
по событию формы OnCreate -> IDList := TStringList.Create;
Затем:


procedure TForm.FillComboBox;
var
IDList: TStringList;
begin
IDList.Clear;
ComboBox1.Clear;
MyQuery.Close;
MyQuery.ExecSQL;
MyQuery.Open;
MyQuery.First;
While not MyQuery.Eof do
begin
ComboBox1.Items.Add(MyQuery["StringField"]);
IDList.Items.Add(IntToStr(MyQuery["ID"]));
MyQuery.Next;
end;
end;

А затем по событию OnClick ComboBox"a:
IDList.ItemIndex := ComboBox1.ItemIndex;

В результате в IDList всегда имею ID нужной записи (ну естественно ID := StrToInt(IDList.Items[IDList.ItemIndex]);


 
kronprince   (2002-09-27 10:32) [13]

2Юрий Зотов © (27.09.02 10:27)
>Но вот плодить объектную оболочку вокруг Integer...

Извините, плодить - да, всего лишь с целью запихивания повторяющихся кусков кода и популярных методов работы в один класс


 
KIR   (2002-09-27 10:33) [14]

var
IDList: TStringList

в предыдущем ответе конечно лишнее, sorry :)


 
Anatoly Podgoretsky   (2002-09-27 10:37) [15]

Юрий Зотов © (27.09.02 10:27)
Это не совсем так, возьмем для примера 8 битные процессоры, пускай даже от фирмц Интел, адресация была и 12 бит и 16 бит.
Кроме того если посмотрим 16 бит и процессоры 86, 286, 386

Адресная шина 16, 20, 32
Указатель 32 бита seg:ofs

Имподьзовать приведение конечно можно, но следует понимать, что возможно это не будет работать в других версиях


 
Юрий Зотов   (2002-09-27 10:56) [16]

> всего лишь с целью запихивания повторяющихся кусков кода и
> популярных методов работы в один класс

Для Integer Ваши "повторяющиеся куски кода и популярные методы работы" сводятся всего лишь к арифметическим операциям.

Хотите написать класс и вызывать его метод Add - пожалуйста, флаг Вам в руки. А я, с Вашего разрешения, уж как-нибудь буду писать по-старинке - просто "+". Думаю, мой вариант будет порождать машинный код примерно на три порядка короче и на пять порядков быстрее. Потому что я предпочитаю писать понятный и эффективный код, а не говорить красивые слова об объектах и технологиях "вообще", безотносительно конкретной задачи.

Поскольку понимаю, что гвозди лучше забивать действительно молотком, а не табуреткой. А вот для сидения молоток как-то не приспособлен, для сидения как раз табуретка лучше.

Не верите? Проверьте.
:о)


 
Юрий Зотов   (2002-09-27 11:11) [17]

> Anatoly Podgoretsky © (27.09.02 10:37)

Давайте уточним позиции.

Вы полагаете, что возврат к сегментной адресации возможен? Или к любой ей подобной - то есть, не прямой flat?

Если да - Вы правы. Если нет - прав я.

Потому что, как Вы прекрасно понимаете, никаких Pointer"ов железо вообще не знает - только целые числа, интерпретируемые, как адреса. И понятно, что наибольшая производительность (а к ней, естественно, всегда стремятся) достигается тогда, когда эти числа есть родные машинные слова, и когда используется flat-адресация.

Ведь адресация Seg:Offs появилась не от хорошей жизни, а просто потому, что 64-х Кб, когда-то считавшихся для персоналок достаточными, вдруг оказалось мало. И надо было быстро ликвидировать противоречие, не переделывая в корне разрядность.

А как только пошла 32-битная разрядность, так противоречие автоматически устранилось и снова вернулись к flat. И, думаю, теперь уже навсегда.


 
Влад Утюмов   (2002-09-27 11:17) [18]

Неожидал такой бурной дискуссии =)

Внесу немного ясности в спор об размерности Integer.

У меня это ключ таблицы БД. В настоящий момент он имеет размерность 32 бита, но в некоторых ситуациях может оказаться и 64 (распределенные БД например, или очень большие). Поэтому я определил

type oid_t = integer;

(надеюсь не ошибся при переводе с С++ на паскаль), оставив себе пути к отступлению. Этот oid_t я и хочу хранить в комбо, сорри за то то ввел публику в заблуждение.

Получается: кастить его к указателю нежелательно.

Если же число хранить в строке то где хранить сами строки. Или же использовать кодирование типа

15|Строка которую хочу показать

или вообще строки хранить отдельно (уж лучше отдельно хранить цифирьки).

Спасибо всем. Понял.


 
Юрий Зотов   (2002-09-27 11:26) [19]

AddObject(строка, TObject(число));

Чтение: Integer(Objects[i]).

Вот и все проблемы. Таким же образом можно вместе со строкой хранить любые данные длиной не более SizeOf(TObject) - то есть, на сегодня 32 бита. Хоть числа, хоть boolean.


 
kronprince   (2002-09-27 11:34) [20]

2Юрий Зотов © (27.09.02 10:56)
Извините Юрий - но задача была не про сложение integer а облегчение работы ComboBox с некоторым полем из базы :-\
И в этом случае лучше использовать именно класс
Т.к. может понадобиться не только integer но например Extended или Currency


 
Anatoly Podgoretsky   (2002-09-27 11:56) [21]

Юрий Зотов © (27.09.02 11:11)
Давайте, но начнем с того, что суть моего замечания состоит в том, что закладываться на внутрннее представление не стоит, тем более на что то еще не существуещее. Возможно будет достаточно и этого замечания


Давайте уточним позиции.

Вы полагаете, что возврат к сегментной адресации возможен? Или к любой ей подобной - то есть, не прямой flat?


Ходят и такие слухи про новые 64 битные процессоры, но я не думаю, зато гораздо важнее другое, перенос между платформами


Если да - Вы правы. Если нет - прав я.
Потому что, как Вы прекрасно понимаете, никаких Pointer"ов железо вообще не знает - только целые числа, интерпретируемые, как адреса. И понятно, что наибольшая производительность (а к ней, естественно, всегда стремятся) достигается тогда, когда эти числа есть родные машинные слова, и когда используется flat-адресация.


Прекрасно это понимаю, но Integer и Pointer не обязательно должны быть одинаковый длины.


Ведь адресация Seg:Offs появилась не от хорошей жизни, а просто потому, что 64-х Кб, когда-то считавшихся для персоналок достаточными, вдруг оказалось мало. И надо было быстро ликвидировать противоречие, не переделывая в корне разрядность.


Я знаю откуда это и почему, и также знаю почему не спешили делать другое. Д1 наглядный пример.


А как только пошла 32-битная разрядность, так противоречие автоматически устранилось и снова вернулись к flat. И, думаю, теперь уже навсегда.


Я тоже очень на это надеюсь, хотя если взглянуть глубже, от сегментных регистров мы никуда не делись, просто они напрямую не используются и запрещены к использованию, на самом деле мы имеем селектор+смещение в 32 бита (упрощенно конечно), первая половина нас не интересует, если мы не работает на чрезвычайно низком уровне.
Так для информации: 386 процессор в состоянии адресовать до 14 террабайт виртуальной памяти, не знаю используется где либо такая возможность.

Ну и в заключение, то что в начале, для безопасного кода не стоит ставить знак равенства между Integer и Pointer. Думаю с выделенным ты согласен. И второй момент безопасности здесь Integer & TObject тоже не хорошо, хотя практика распространенная.


 
TTCustomDelphiMaster   (2002-09-27 12:02) [22]

kronprince © (27.09.02 11:34)

Класс не надо. Можно массив.


 
kronprince   (2002-09-27 12:08) [23]

TTCustomDelphiMaster © (27.09.02 12:02)

TDictionary = class
protected
sFieldID :string;
sFieldName:string;
private
aiRec : TAInteger; // ID_REC
asName: TAString; //


 
MBo   (2002-09-27 12:35) [24]

Хорошо, пусть потребуется хранить не 4-байтовое, а другое (больше размера указателя).
Опять же класс ни к чему

type PInt64=^Int64;

var p:PIint64;

new(p);
p^:=12345678901234;
Items.AddObject("ww",TObject(p));
...
Int64Var:=Pint64(Items.Objects[i])^;

точно так же и с записями - определяем тип указателя на нее и вперед.

Класс же нужен в тех случаях, когда соотв. объект (в широком смысле) должен быть активен или обеспечивать нетривиальный доступ к своим полям.



 
TTCustomDelphiMaster   (2002-09-27 12:38) [25]

kronprince © (27.09.02 12:08)


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



 
kronprince   (2002-09-27 12:59) [26]

TTCustomDelphiMaster © (27.09.02 12:38)

Это как Вы заметили писалось для специфичных нужд
Вырезать легче :)



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

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

Наверх





Память: 0.52 MB
Время: 0.008 c
1-21036
Саша
2002-09-27 08:17
2002.10.07
Как положить Splitter.


7-21290
flegma
2002-07-29 01:56
2002.10.07
Как сделать форму невидимой сразу после запуска приложения?


1-21037
Babay_S
2002-09-27 11:29
2002.10.07
Проблема с TUpDown


4-21343
RealDummy
2002-08-22 02:51
2002.10.07
Как ставить хук на минимизацию чужого окна?


1-21030
Zemal
2002-09-26 13:08
2002.10.07
Большие объёмы данных тормозят клиента.





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