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

Вниз

Хранение второго значения в ListBox.   Найти похожие ветки 

 
allucard   (2007-04-12 11:27) [0]

Доброго дня.

Есть список пользователей(ListBox), у каждого пользователя есть свой пароль а также время регистрации, эти данные можно хранить как то в этом-же ListBox?
Или обязательно база данных?
Спасиб за варианты.


 
allucard   (2007-04-12 11:46) [1]

Или где можно хранить три столбца данных но выводить один, чтоб был метод SaveToFile?


 
_Аноним   (2007-04-12 11:51) [2]

Можно хранить привязанные объекты (свой экземпляр на каждый элемент списка)
см. ListBox.Items.Objects

что касается сохранения в файл - то это ручками.


 
allucard   (2007-04-12 11:54) [3]

А если создать свой класс(или тип как лучше) с тремя переменными и записывать его как обьект: ListBox1.AddItem();
?


 
PZ   (2007-04-12 11:54) [4]

Приблизительно так можно:
S := "Иванов"+"  "+Parol+"  11.04.2007";
ListBox.Items.Add(S);


 
clickmaker ©   (2007-04-12 11:55) [5]


> [3] allucard   (12.04.07 11:54)

а не это ли предложено в [2]?


 
allucard   (2007-04-12 11:55) [6]

ListBox1.Items.Values - а это что?


 
allucard   (2007-04-12 11:56) [7]

>clickmaker ©   (12.04.07 11:55) [5]

Так лучше тип или класс?


 
clickmaker ©   (2007-04-12 11:57) [8]


> [7] allucard   (12.04.07 11:56)

а что по-твоему тип, а что - класс?


 
allucard   (2007-04-12 12:00) [9]

type record end; - тип

Type
sdfssdg = class
end; - класс


 
allucard   (2007-04-12 12:03) [10]

Да вообще можно и второй ListBox невидимым сделать и туда писать пароль.


 
clickmaker ©   (2007-04-12 12:07) [11]


>  [10] allucard   (12.04.07 12:03)

ага. Отличное решение. А для даты - третий и т.д.?


 
_Аноним   (2007-04-12 12:09) [12]


> Так лучше тип или класс?


Если под "типом" понимать рекрод, то для данного случая - особо без разницы. Там можно хранить как указатель на экземпляр, так и указатель на структуру.


> Да вообще можно и второй ListBox невидимым сделать и туда
> писать пароль.


А вот это несерьезно


 
allucard   (2007-04-12 12:11) [13]

Ну, пробую создать класс.

А как проверить тек. значение ListBox?
Что то ItemIndex немогу найти.


 
_Аноним   (2007-04-12 12:14) [14]


> Что то ItemIndex немогу найти.

А он есть.


 
allucard   (2007-04-12 12:25) [15]

А может сам ListBox дописать?


 
allucard   (2007-04-12 12:33) [16]

Ой.
Это если я создаю класс, для работы с ним нужно создать рабочий экземпляр (выполнить конструктор), заполнить поля, потом освобождать.

Ну я так сделал:

 TUser = class
   username: string;
   password: string;
 private
   { Private declarations }
 public
   { Public declarations }
 end;


 
clickmaker ©   (2007-04-12 12:34) [17]


> нужно создать рабочий экземпляр (выполнить конструктор),
> заполнить поля, потом освобождать

а ты думал - в сказку попал?


 
allucard   (2007-04-12 12:38) [18]

Вопрос:

Как динамически во время выполнения программы добавлять экземпляры класса?

Я ведь в конечном итоге не знаю сколько пользователей будет?


 
clickmaker ©   (2007-04-12 12:46) [19]


> [18] allucard   (12.04.07 12:38)

цитирую тебя же
"нужно создать рабочий экземпляр (выполнить конструктор), заполнить поля"


 
allucard   (2007-04-12 12:53) [20]


> clickmaker ©   (12.04.07 12:46) [19]

ну эт я понял.

А если у меня 1000 пользователей, то обьявлять 1000 переменных класса TUser в разделе var модуля?
а если 10000? :) И каждую записывать в TListBox?

Нет.
Кажется можно создавать экземпляры класса и описывать их во время работы программы, но как?


 
Virgo_Style ©   (2007-04-12 13:14) [21]

allucard   (12.04.07 12:53) [20]
А если у меня 1000 пользователей, то обьявлять 1000 переменных класса TUser в разделе var модуля?


Ты про массивы слышал?)))


 
Virgo_Style ©   (2007-04-12 13:17) [22]

Или можно еще пару TStringList"ов внутри хранить, реализация попроще должна получиться.


 
clickmaker ©   (2007-04-12 13:17) [23]


> [20] allucard   (12.04.07 12:53)

зачем тебе переменные? Они у тебя будут в Objects
Потом, когда станут не нужны, нужно пробежаться по этому списку и поубивать


 
_Аноним   (2007-04-12 13:19) [24]


> А если у меня 1000 пользователей, то обьявлять 1000 переменных
> класса TUser в разделе var модуля?


не нужно. Используй одну переменную (причем локальную), она в цикле будет последовательно указывать на разные экземпляры.

var
 User : TUser ;
for I:=0 to 1000 do
begin
 User :=TUser.Create;
 User.UserName:="Вася №" + INtToStr(I);
 User.Password:="12345";
 ListBox.Items.AddObject(User.UserName, User);
end;

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


 
allucard   (2007-04-12 13:22) [25]


> Ты про массивы слышал?)))

Про массивы да, про массивы обьектов - нет? а такое есть?

>Virgo_Style ©   (12.04.07 13:17) [22]
Идея.

>clickmaker ©   (12.04.07 13:17) [23]
Чтоб экземпляр класса можно было создать, его необходимо обьявить в розделе VAR.


 
allucard   (2007-04-12 13:23) [26]


> _Аноним   (12.04.07 13:19) [24]

прикольно.


 
clickmaker ©   (2007-04-12 13:23) [27]


> Чтоб экземпляр класса можно было создать, его необходимо
> обьявить в розделе VAR

ну так и объяви, в чем проблема?


 
clickmaker ©   (2007-04-12 13:27) [28]


> его необходимо обьявить в розделе VAR

да, кстати, и не необходимо. Вопрос удобства и реализации самого класса.
ListBox.Add(UserName, TUser.Create(Password, RegTime));


 
allucard   (2007-04-12 13:29) [29]

>_Аноним   (12.04.07 13:19) [24]

procedure TForm2.Button1Click(Sender: TObject);
begin
 User := TUser.Create;
 User.username := Edit1.Text;
 User.password := Edit2.Text;
 User.realname := Edit3.Text;
 ListBox1.Items.AddObject(user.realname; user);
 user.free;
end;

Пишет ошибку:
Not enough actual parameters.


 
clickmaker ©   (2007-04-12 13:30) [30]


> ListBox1.Items.AddObject(user.realname; user);
>  user.free;

зачем вторая строка?


 
allucard   (2007-04-12 13:32) [31]


> clickmaker ©   (12.04.07 13:30) [30]

Без неё всёравно ошибка.

Пробовал метод AddItem, таже ошибка.


 
allucard   (2007-04-12 13:42) [32]

По ходу нельзя свой окласс зафигарить в методом AddObject, даже если его сделать дочерним TObject.


 
clickmaker ©   (2007-04-12 13:48) [33]


> [32] allucard   (12.04.07 13:42)
> По ходу нельзя свой окласс зафигарить

а мужики-то и не знают.
И фигарят и фигарят себе...


 
allucard   (2007-04-12 13:50) [34]


> clickmaker ©   (12.04.07 13:48) [33]


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


 
clickmaker ©   (2007-04-12 13:52) [35]


> [34] allucard   (12.04.07 13:50)

Цитрамону выпей.
Тебе в [24] дали готовый код, какие еще мысли нужны?


 
allucard   (2007-04-12 14:14) [36]


> clickmaker ©   (12.04.07 13:52) [35]

Это глюк какой-то.
Вот так работает и не пишет никакой ошибки:

procedure TForm2.Button1Click(Sender: TObject);
var sl: TStringList;
begin
 User := TUser.Create;
 User.username := Edit1.Text;
 User.password := Edit2.Text;
 User.realname := Edit3.Text;
 sl:= TStringList.Create;
 sl.AddObject(user.realname,user);
 user.free;
 sl.Free;
end;


 
_Аноним   (2007-04-12 14:26) [37]

У тебя там было
ListBox1.Items.AddObject(user.realname; user);

фактические параметры разделяются запятой, формальные - точкой с запятой


 
allucard   (2007-04-12 14:49) [38]


> _Аноним   (12.04.07 14:26) [37]

Ой, е.
Сенькс.
Пошёл писать дальше.


 
allucard   (2007-04-12 20:03) [39]


> _Аноним   (12.04.07 13:19) [24]

А как с ними потом работать.
Как загрузить из этих обьектов их данные из списка ListBox.


 
allucard   (2007-04-13 09:29) [40]

Но как теперь эти обьекты записать в файл?

Пишу так:
ListBox1.Items.SaveToFile(ExtractFilePath(ParamStr(0))+"data\users.dat");

Но сохраняются только названия а не обьекты:
ListBox1.Items.AddObject(user.realname, user);

Т.е. при загрузке
ListBox1.Items.LoadFromFile(ExtractFilePath(ParamStr(0))+"data\users.dat");
Получаю только названия записей user.realname.


 
Сергей М. ©   (2007-04-13 09:35) [41]


> как .. обьекты записать в файл?


Запись объекта есть ничто иное как запись св-в этого объекта.


 
allucard   (2007-04-13 09:38) [42]


> Сергей М. ©   (13.04.07 09:35) [41]

есть метод специально для сохранения обьектов ListBox"a в файл?


 
Сергей М. ©   (2007-04-13 09:44) [43]


> allucard   (13.04.07 09:38) [42]


Нет такого.
Самому писать придется.
И если класс TUser сделать наследником TComponent, это ощутимо облегчит решение.


 
allucard   (2007-04-13 09:54) [44]


> Сергей М. ©   (13.04.07 09:44) [43]

Сделал наследником TUser.

Подскажи хоть с чего начать.
Я таким ещё не занимался.

Дописывать к методам TListBox или создавать новый метод своего класса TUser?

Если к TListBox, делать новый метод(напр. SaveObjectToFile) и писать в нём Inherited SaveToFile.
Если к своему методу то я даже не знаю как унаследовать метод от TListBox, т.к. он не является дочерним.


 
allucard   (2007-04-13 10:09) [45]

Я что-то совсем завис.

Неужели нельзя записать в файл структуру данных(в моём случае класс) вместе со свойствами?


 
clickmaker ©   (2007-04-13 10:10) [46]


> [45] allucard   (13.04.07 10:09)

CreateFile(), WriteFile()


 
allucard   (2007-04-13 10:14) [47]


> clickmaker ©   (13.04.07 10:10) [46]

Это создаст файл и запишет что-то в него.
А как класс со свойствами туда вихнуть?


 
clickmaker ©   (2007-04-13 10:36) [48]


>  [47] allucard   (13.04.07 10:14)

записать как набор байт, а как еще?
Если записи переменной длины (имена юзеров), то сначала пишешь размер записи, потом собственно данные.
При чтении сначала читаешь размер, потом собственно данные, потом позиционируешься на следующую запись (тек. поз. + размер)
SetFilePointer(), например
Но можно все это и через TFileStream
Т.е. получается что-то типа простенькой базы данных


 
allucard   (2007-04-13 11:05) [49]


> clickmaker ©   (13.04.07 10:36) [48]

Идею понял, реализацию нет.

делаю так:

 try
   AssignFile (F, ExtractFilePath(ParamStr(0))+"data\users.dat");
   Rewrite(F);
   if IOResult=0 then
     begin
       for i:=0 to ListBox1.Count - 1 do
         begin
           write(f, (ListBox1.Items.Objects[i] as TUser));
         end;
     end;
   CloseFile(F);
 except
 end;

но пишет в строке write(f, (ListBox1.Items.Objects[i] as TUser)); ошибку
Variable required.
Что за ошибка?


 
clickmaker ©   (2007-04-13 11:22) [50]


> [49] allucard   (13.04.07 11:05)

ты вообще представляешь, что такое объект? Что такое класс, а что такое экземпляр класса? И как они в памяти хранятся?
Например, как компилятор, а затем и среда выполнения интерпретирует ListBox1.Items.Objects[i]?


 
allucard   (2007-04-13 11:46) [51]


> clickmaker ©   (13.04.07 11:22) [50]

что такое объект?
Это тип данных сочетающий в себе свойства и методы.
Короче экземпляр класса.

>Что такое класс
Тип данных, переменная соотв. типа.

> что такое экземпляр класса?
Выделенная область в памяти для хранения свойств, методов.

Как в памяти хранится не понимаю.

ListBox1.Items.Objects[i] - это по всей видимости ссылка на структуру, т.е. обьект.
Обьясни что не так.

Напиши коротенький примерчик.


 
Сергей М. ©   (2007-04-13 11:48) [52]


> allucard   (12.04.07 11:27)


А тебя что так на TListBox"е заклинило ?

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

Пушкин              <- юзер №1
  СанчоПушкин       <- RealName
  Pushkin                <- Username
  ВеликийНегритянскийПоэт  <- Password
Пупкин               <- юзер №2
  ВасяПупкин         <- RealName
  Pupkin                 <- Username
  ПарольВасиПупкина           <- Password


 
clickmaker ©   (2007-04-13 11:51) [53]


> [51] allucard   (13.04.07 11:46)
> ListBox1.Items.Objects[i] - это по всей видимости ссылка на структуру

ну правильно. А что такое ссылка?
Тогда вот этой строкой
write(f, (ListBox1.Items.Objects[i] as TUser));
ты что делаешь?


 
allucard   (2007-04-13 12:01) [54]


> clickmaker ©   (13.04.07 11:51) [53]

Указываю записать в файл F, только вот не пойму почему - но по ходу:
ссылку на структуру данных или саму структуру.

Но в ListBox1.Items.Objects[i] должен быть рабочий экземпляр класса?


> Сергей М. ©   (13.04.07 11:48) [52]

Я бы давно с двумя ListBox"aми сделал, но нужно же понимать что я делаю.


 
Сергей М. ©   (2007-04-13 12:05) [55]


> нужно же понимать что я делаю


И это правильно !)

Берешь исходник TTreeView и смотришь, что там происходит при файловой загрузке/выгрузке.


 
clickmaker ©   (2007-04-13 12:06) [56]


> в ListBox1.Items.Objects[i] должен быть рабочий экземпляр
> класса?

ну с точки зрения предметной области - да. Но с точки зрения кода - нет. Там указатель. 4 байта в 32-разрядной ОС.
Эти 4 байта ты и пытаешься писать в файл.
Чтобы сохранить объект, нужно последовательно записать все его свойства в файл. Формат - это уже твое дело


 
allucard   (2007-04-13 12:49) [57]


> 4 байта в 32-разрядной ОС.
> Эти 4 байта ты и пытаешься писать в файл.

Ну, вообще-то он их и записывает.
Только вот почему для каждого из элеиентов [i] он был одинаковый?
Ведь это указатель на данные или на структуру данных?


 
Сергей М. ©   (2007-04-13 13:49) [58]


> это указатель на данные или на структуру данных?


На данные.

А уж структурированы эти данные или нет - эт другой коленкор)


 
allucard   (2007-04-13 13:57) [59]

А если записать в файл не 4-байта указателя, а байты по этому указателю?
Точнее как такое сделать?

>clickmaker ©   (13.04.07 10:36) [48]

записать как набор байт, а как еще?
Если записи переменной длины (имена юзеров), то сначала пишешь размер записи, потом собственно данные.
При чтении сначала читаешь размер, потом собственно данные, потом позиционируешься на следующую запись (тек. поз. + размер)
SetFilePointer(), например
Но можно все это и через TFileStream


Как через TFileStream?


 
Сергей М. ©   (2007-04-13 14:01) [60]


> А если записать в файл не 4-байта указателя, а байты по
> этому указателю?


А среди этих "байт по указателю" обязательно найдутся еще куча "четверок" байт, также являющих собой указатели - ты об этом подумал ?)


 
{RASkov}   (2007-04-13 14:15) [61]

var U: TUser; S: String;
..............
try
  AssignFile (F, ExtractFilePath(ParamStr(0))+"data\users.dat");
  Rewrite(F);
  try
   for i:=0 to ListBox1.Count - 1 do begin
    U:=TUser(ListBox1.Items.Objects[i]);
    if U=nil then Continue;
    S:=Format("%s;%s;%s", [U.username,U.realname, U.password");
    WriteLn(f, S);
   end;
  finally CloseFile(F); end;
except
  ShowMessage("Блин, косяк при сохранении пассвордов..:(");
end;


Читать из этого файла и загружать в ListBox сам придумай как.... не сложно.
ЗЫ Можно и шифровать пароли если нужно....


 
allucard   (2007-04-13 14:16) [62]


> Сергей М. ©   (13.04.07 14:01) [60]

Указатели на указатели ?)
Да уж.
Класс экземпляр класса никак не запишешь, свой так точно.
Хотя стоп!

  FileStream.WriteComponent(self);


 
Сергей М. ©   (2007-04-13 15:13) [63]


> allucard   (13.04.07 14:16) [62]


> Указатели на указатели ?)


А это что, нонсенс ?)
И такое бывает)

Хотя редкость)

А вот тебе обычный пример - на некую форму "кинули" некий "батон".
В рез-те ты имеешь:

 TfrmReportParams = class(TForm)
   Button1: TButton; <- вот он, указатель на структурированные данные, появившийся в результате "батонокидательства" !)
   ..
 end;


 
allucard   (2007-04-16 11:06) [64]

Сделал так:
Запись компонента:

FileStream := TFileStream.Create("users.dat", fmCreate);
FileStream.WriteComponent(Form2.ListBox1);
FileStream.Free;

Чтение:

 if (FileExists("users.dat")) then
   begin
     FileStream := TFileStream.Create("users.dat", fmOpenRead);
     FileStream.ReadComponent(Form2.ListBox1);
     FileStream.Free;
   end;

Но при чтении свойств обьектов внутри TListBox1 сволочь пишет AccessViolation.
Что на этот раз то?


 
Сергей М. ©   (2007-04-16 11:10) [65]


> Что на этот раз то?


Либо Form2 либо Form2.ListBox1 содержат nil или "мусор".


 
allucard   (2007-04-16 11:40) [66]


> Сергей М. ©   (16.04.07 11:10) [65]

По ходу, я добавляю в ListBox1 пару обьектов, потом сохраняю его в файл.
И если не закрывать приложение то компоненты активируются нормально.

Короче FileStream.WriteComponent(Form2.ListBox1)  не записывает компоненты, находящиеся внутри ListBox1.


 
allucard   (2007-04-16 11:41) [67]

В общем как я понял мир познания устроен по кругу, после недельного разбирательства так и не понятным осталось как в компонент ListBox запхнуть ещё хотя бы два параметра для каждой записи.
:(
Грустно.


 
Сергей М. ©   (2007-04-16 11:44) [68]


> FileStream.WriteComponent(Form2.ListBox1)  не записывает
> компоненты, находящиеся внутри ListBox1


Да , не записывает. И не должен.
Но в дан.случае AV-исключение при выполнении ReadComponent не имеет к этому  никакого отношения.


 
Сергей М. ©   (2007-04-16 11:47) [69]


> allucard   (16.04.07 11:41) [67]


Чем тебе TreeView не угодил ?

В случае с ним вообще ничего "запихивать" не нужно - компонент сделает все сам.


 
allucard   (2007-04-16 11:47) [70]


> Но в дан.случае AV-исключение при выполнении ReadComponent
> не имеет к этому  никакого отношения.

Понятное дело, когда читаешь по адресу то, чего не существует там.


 
allucard   (2007-04-16 11:49) [71]


> Сергей М. ©   (16.04.07 11:47) [69]

Сейчас буду розбираться.
В принцыпе цель - это познание.

Так что Respect всем помогающим.
Понял многое.


 
Сергей М. ©   (2007-04-16 11:50) [72]


> читаешь по адресу то, чего не существует там


Ну вот для начала и прими меры к тому, чтобы это самое "то, чего не существует" начало существовать "там".


 
allucard   (2007-04-16 11:53) [73]

Где описан ListBox?


 
Сергей М. ©   (2007-04-16 11:54) [74]

Открываешь окно справки, вводишь стороку поиска фразы TListBox..


 
allucard   (2007-04-16 12:09) [75]

А что лучше подойдёт:

TreeView или ListView?


 
Сергей М. ©   (2007-04-16 12:11) [76]

TTreeView


 
{RASkov}   (2007-04-16 12:13) [77]

> [67] allucard   (16.04.07 11:41)


> [69] Сергей М. ©   (16.04.07 11:47)
> Чем тебе TreeView не угодил ?

Или как вариант ListView:

> запхнуть ещё хотя бы два параметра для каждой записи.

Для каждой записи там есть еще дополнительный (SubItem)Strings и пихай в него сколько угодно параметров...строковых.
Тоже, вроде, умеет сохранять все сам... может вру.


 
{RASkov}   (2007-04-16 12:14) [78]

> [76] Сергей М. ©   (16.04.07 12:11)

Сорри... не успел, я вплотную незнаком не с TreeView не с ListView, а чем лучше TreeView?


 
Сергей М. ©   (2007-04-16 12:16) [79]


> {RASkov}   (16.04.07 12:14) [78]



> чем лучше TreeView?


Тем что там уже все "запихнуто".


 
{RASkov}   (2007-04-16 12:34) [80]

> [79] Сергей М. ©   (16.04.07 12:16)

Ясно. Спасибо.



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

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

Наверх





Память: 0.65 MB
Время: 0.044 c
3-1171802805
Rav
2007-02-18 15:46
2007.05.06
TAdoQuery - "обновление"??? при удалении записи


2-1176705003
проходил мимо решил заглянуть
2007-04-16 10:30
2007.05.06
Insert и DBGrid


1-1173789487
oleg__
2007-03-13 15:38
2007.05.06
TChart


3-1171141190
Grant
2007-02-10 23:59
2007.05.06
TQuery и память


2-1176817310
Gentos
2007-04-17 17:41
2007.05.06
DBImage1: TDBImage; - с какой компонентой проще всего работать ?





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