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

Вниз

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

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


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


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


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


> Использование классов (очень понравился вариант). В нем
> я могу хранить много разных данных.

А параллельно с этим хранится ещё куча данных, унаследованных от TObject, а также служебной информации. Если хотите "много и просто", используйте лучше record. Если памятью для них управлять с помощью New и Dispose, никаких проблем с управляемыми типами внутри не возникает.

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

Там не PChar был, а PString. И в одну и ту же строку вы записывали разные значения. А AddObject просто сохраняет указатель, он не делает копию того, что вы передаёте. В результате вы каждый раз перезаписывали строку, уже добавленную в Objects.


 
Игорь Шевченко ©   (2009-11-13 13:42) [42]


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


http://ln.com.ua/~openxs/articles/smart-questions-ru.html

читать до полного просветления.


 
kyn66 ©   (2009-11-13 13:52) [43]


> А AddObject просто сохраняет указатель, он не делает копию
> того, что вы передаёте. В результате вы каждый раз перезаписывали
> строку, уже добавленную в Objects.


Согласен. Я уже и сам до этого додумался, посмотрев внимательно.

>  Если памятью для них управлять с помощью New и Dispose,
>  никаких проблем с управляемыми типами внутри не возникает.


Вот эта строка не совсем понятна. Речь идет о записях впринципе или о их содержимом?


 
Leonid Troyanovsky ©   (2009-11-13 14:18) [44]


> kyn66 ©   (13.11.09 13:52) [43]

> >  никаких проблем с управляемыми типами внутри не возникает.

> Вот эта строка не совсем понятна. Речь идет о записях впринципе
> или о их содержимом?

RTFM: Finalize procedure.

--
Regards, LVT.


 
Ухарь   (2009-11-13 14:19) [45]


> kyn66 ©   (13.11.09 13:52) [43]
>
>



> Речь идет о записях впринципе или о их содержимом?


Речь идет о том, что если использовать  New и Dispose, то мы будем иметь дело каждый раз с разной структурой (или строкой, или объектом - не важно, в общем - с разными областями памяти), и на каждом проходе получать новый указатель.
А не добавлять один и тот же адрес во все элементы списка.
В случае использования объекта и его конструктора ровным счетом то же самое и происходит, если такой подход по каким то причинам не устраивает, нужно сделать тоже самое, но руками


 
Григорьев Антон ©   (2009-11-13 14:30) [46]


> Вот эта строка не совсем понятна. Речь идет о записях впринципе
> или о их содержимом?

О содержимом. Если память под запись выделять и освобождать через GetMem/FreeMem, то освобождаться будет только память, выделенная под саму структуру, а содержищиеся в ней управляемые типы данных должным образом освобождены не будут. А если использовать New/Dispose, то будут, нато только при вызове Dispose не забывать приводить указатель к правильному типу. А вот если в записи есть неуправляемые ссылки на внешние данные (типа того же PChar), то тут уже в любом случае руками освобождать надо.


 
kyn66 ©   (2009-11-13 15:03) [47]

Вот этот пример http://k210.org/delphi/components/49/ можно отнести к классу правильного использования записей для хранения строковых данных?


 
Григорьев Антон ©   (2009-11-13 15:18) [48]


> kyn66 ©   (13.11.09 15:03) [47]

Вроде никаких ошибок я там не вижу.


 
kyn66 ©   (2009-11-13 15:51) [49]


> Григорьев Антон ©   (13.11.09 15:18) [48]
> Вроде никаких ошибок я там не вижу.
</I

Т.е. здесь и память правильно выделяется new(MyRec);, затем полю записи присваевается значение для "хранения" MyRec^.path:=OpenDialog1.FileName; и затем все грамотно высвобождается for i:=0 to ListView1.Items.Count-1 do
   Dispose(PMyRec(ListView1.Items[i].Data));
Здесь применительно к TListView. Значит если я хочу применить это к своему варианту с ComboBox(для него я думаю такая технология тоже подойдет) нужно сделать так(по типу [38])?


procedure TForm1.FormCreate(Sender: TObject);
begin
  new(MyRec);
   MyRec^.path:="FromObjectItem 1";
   ComboBox1.Items.AddObject("Item 1", Pointer(MyRec));
  new(MyRec);
   MyRec^.path:="FromObjectItem 2";
   ComboBox1.Items.AddObject("Item 2", Pointer(MyRec));
  new(MyRec);
   MyRec^.path:="FromObjectItem 3";
   ComboBox1.Items.AddObject("Item 3", Pointer(MyRec));
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 FreeObjects(ComboBox1.Items);// описана в [38]
end;


 
kyn66 ©   (2009-11-13 16:10) [50]

Проверил - все работает. Однако ошибка AV FreeObjects(ComboBox1.Items);// описана в [38]. Объекты не правильно удаляю.
Скорее всего вот так правильно?

 for i := 0 to ComboBox1.Items.Count - 1 do
  Dispose(PMyRec(ComboBox1.Items.Objects[i]));


 
Leonid Troyanovsky ©   (2009-11-13 17:39) [51]


> kyn66 ©   (13.11.09 16:10) [50]

> Проверил - все работает. Однако ошибка AV FreeObjects(ComboBox1.
> Items);// описана в [38].

Помылся б ты, ёжик.

--
Regards, LVT.


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


> Leonid Troyanovsky ©   (13.11.09 17:39) [51]


УмнО от мастера такое слышать. Не у одного меня такие проблемы, млин...

http://www.cyberforum.ru/delphi-beginners/thread49246.html


 
zlo   (2009-11-13 18:16) [53]


type
 PNameOldsRec = ^TNameOldsRec;
 TNameOldsRec = record
   Name: string;
   Olds: Integer;
 end;

function CombineNameAndOlds(AName: string; AOlds: Integer): TObject;
var
 P: PNameOldsRec;
begin
 New(PNameOldsRec(Result));
 with PNameOldsRec(Result)^ do
 begin
   Name := AName;
   Olds := AOlds;
 end;
end;

procedure TForm2.Button1Click(Sender: TObject);
var
 I: Integer;
begin
 ComboBox1.Items.AddObject("", CombineNameAndOlds("Строка 1", 1));
 ComboBox1.Items.AddObject("", CombineNameAndOlds("Строка 2", 2));

 for I := 0 to ComboBox1.Items.Count - 1 do
   with PNameOldsRec(ComboBox1.Items.Objects[I])^ do
     ShowMessageFmt("Name: %s; Olds: %d", [Name, Olds]);

 for I := 0 to ComboBox1.Items.Count - 1 do
   Dispose(PNameOldsRec(ComboBox1.Items.Objects[I]));
end;


 
zlo   (2009-11-13 18:18) [54]

забыл убрать var P: PNameOldsRec; из CombineNameAndOlds


 
kyn66 ©   (2009-11-13 20:06) [55]


> zlo   (13.11.09 18:16) [53]


Спасибо тебе, добрый человек! Это похоже на мои мысли [49] + [50], только оформлено более аккуратнее. Отлично. Сейчас проверю в деле...

ЗЫ:
Ник совсем не подходит ;).


 
kyn66 ©   (2009-11-13 20:41) [56]

Я думаю [53] следуе добавить очистку ComboBox после уничтожения объектов.

  for I := 0 to ComboBox1.Items.Count - 1 do
    Dispose(PNameOldsRec(ComboBox1.Items.Objects[I]));
  ComboBox1.Clear;


В противном случае

with PNameOldsRec(ComboBox1.Items.Objects[I])^ do
    ShowMessageFmt("Name: %s; Olds: %d", [Name, Olds]);

всеравно выполняется, но с мусором. Проверял разделив этот кусок кода  procedure TForm2.Button1Click на три раздельных для последовательности действий.

procedure TForm1.Button2Click(Sender: TObject);
begin
ComboBox2.Items.AddObject("Первая строка Комбо", CombineNameAndOlds("Строка 1", 1));
ComboBox2.Items.AddObject("Вторая строка Комбо", CombineNameAndOlds("Строка 2", 2));
end;

procedure TForm1.ComboBox2Change(Sender: TObject);
begin
 with PNameOldsRec(ComboBox2.Items.Objects[ComboBox2.ItemIndex])^ do
  ShowMessageFmt("Name: %s; Olds: %d", [Name, Olds]);
end;

procedure TForm1.Button3Click(Sender: TObject);
Var
 i : Integer;
begin
 for I := 0 to ComboBox2.Items.Count - 1 do
  Dispose(PNameOldsRec(ComboBox2.Items.Objects[I]));
 ComboBox2.Clear;
end;

Да и пустая добавляемая строка сперва сбила с толку, почему комбо пустой получается... ComboBox1.Items.AddObject("", CombineNameAndOlds("Строка 1", 1));

А так все прэлесно... :)


 
Дмитрий Белькевич   (2009-11-13 23:20) [57]

Я бы всё таки к [17] сколнялся. Слишком всё сложно - объекты, создание/разрушение, указатели, разыменовывание, следить за всем этим добром... Нафига? [17] - это две-три строки кода, безо всяких излишест.

В ComboBox1DrawItem что-то типа TextOut(Rect.Left,Rect.Top, ExtractFileName(Items[Index]));

Для общего случая вместо ExtractFileName можно каку-то другую функцию сделать, выделяющую нужный для отображения кусок строки.


 
Leonid Troyanovsky ©   (2009-11-13 23:51) [58]


> kyn66 ©   (13.11.09 17:52) [52]

> УмнО от мастера такое слышать. Не у одного меня такие проблемы

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

New&Free - где ж твой букварь?

--
Regards, LVT.


 
kyn66 ©   (2009-11-14 18:06) [59]


> Leonid Troyanovsky ©   (13.11.09 23:51) [58]


Осталось правильно расставить

Begin

end;


 
kyn66 ©   (2009-11-14 20:02) [60]


> Дмитрий Белькевич   (13.11.09 23:20) [57]


Ну тут уже подумать нужно что проще. Если все делается на одной форме и работаем с объектами, то в нужном месте их инициализируем, получаем/присваиваем данные, при закрытии формы уничтожаем. Все. Если же работать с частями строк[17], то здесь тоже не обойдется без дополнительных функций по извлечению и показу нужной части строки, извлечению, преобразованию к нужным типам данных (если числовой) и т.д. Т.е. в любом варианте есть свои нюансы. А если известен механизм, то уже можно придумать куда и как лучше его применить. Кстати, проверил отработку [56] совместно с AllocMemSize - все отлично. Механизм работает, утечки памяти отсутствуют. Что и требовалось получить в конечном итоге.


 
Дмитрий Белькевич   (2009-11-15 01:31) [61]

> Все.

А в случае бех объектов даже инициализировать/уничтожать ничего не нужно :)

>то здесь тоже не обойдется без дополнительных функций по извлечению и показу нужной части строки

Функция - одна, принимающая разделитель и строку на вход и отдающая одну или две части. Пишется минут за 5.

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

Так это и у тебя нужно. Как же ты собираешься сразу числовой тип отображать? :)

>Механизм работает, утечки памяти отсутствуют.

Ну так большая часть и отсюда: http://govnokod.ru/ вполне работает.


 
kyn66 ©   (2009-11-15 02:33) [62]


> Функция - одна, принимающая разделитель и строку на вход
> и отдающая одну или две части. Пишется минут за 5.


Я не сказал что это сложно. К тому же у RX есть хороший набор функций по работе со строками.


> Так это и у тебя нужно. Как же ты собираешься сразу числовой
> тип отображать? :)


Берем из объекта поле записи типа Integer и юзаем его :)


> Ну так большая часть и отсюда: http://govnokod.ru/ вполне
> работает.


:)


> А в случае бех объектов даже инициализировать/уничтожать
> ничего не нужно :)


Работа с простыми строками уже как бы известный механизм. Хотелость попробывать изучить работу объектов. Поправде говоря к указателям раньше ваще никогда не приходилось обращаться. А сейчас просто чисто из интереса. Хочется все же понять что это такое.


 
Германн ©   (2009-11-15 02:47) [63]


>
> Работа с простыми строками уже как бы известный механизм.
>  Хотелость попробывать изучить работу объектов. Поправде
> говоря к указателям раньше ваще никогда не приходилось обращаться.
>  А сейчас просто чисто из интереса.

Тогда читай книги (учебники).


 
имя   (2009-11-15 03:02) [64]

Удалено модератором


 
Юрий Зотов ©   (2009-11-15 10:34) [65]

> kyn66 ©   (15.11.09 02:33) [62]

> к указателям раньше ваще никогда не приходилось обращаться. А сейчас
> просто чисто из интереса. Хочется все же понять что это такое.

Дык... а что там понимать? Указатель - это переменная, содержащая адрес. Только и всего.

Кстати, длинные строки, динамические массивы, объекты - все это тоже указатели.


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


> Берем из объекта поле записи типа Integer и юзаем его :)


Если нужен и Integer (для последующего его применения) и строчка (для отображения) то строчка запихивается в комбобокс, integer - в указатель:

AddObject(s, Pointer(i))

>Поправде говоря к указателям раньше ваще никогда не приходилось обращаться. А сейчас просто чисто из интереса. Хочется все же понять что это такое.

Жаль только применение крайне неудачное.

Понять указатели? Ну можешь мои статьи посмотреть:

http://www.makhaon.com/articles/


 
kyn66 ©   (2009-11-15 21:59) [67]


> Юрий Зотов ©   (15.11.09 10:34) [65]
> .. а что там понимать? Указатель - это переменная, содержащая
> адрес. Только и всего.

Это сейчас я уже понял. Просто раньше небыло нужды в их изучении и ессно читать про это не хотелось. Сейчас заинтересовало.

>Кстати, длинные строки, динамические
> массивы, объекты - все это тоже указатели.

Да, но за их уничтожение отвечает Delphi.

Я вот тут статейку почтал интересную http://www.citforum.ru/programming/bp70_ug/bp70ug_08.shtml . Так вот там есть подраздел "Потери динамически распределяемой памяти" Так вот там не совсем понятен один момент

Общей причиной утечек памяти является переприсваивание динамических переменных без освобождения  предыдущих. Простейшим случаем является следующий:
   var IntPointer: ^Integer;
      begin
         New(IntPointer);
         New(IntPointer);
      end.


Это похоже на ситуацию как у меня в тестовом примере, где я инициализирую указатель под одним и тем же именем в цикле с последующими некоторыми действиями с ним.

type
  PMyRecord = ^TMyRecord;
  TMyRecord = record
    id: Integer;
    Name: string;
  end;
....
procedure TForm1.Button3Click(Sender: TObject);
var
 i: Integer;
 pRec: PMyRecord;
begin
 for i := 0 to 10 do
  begin
    new(pRec);
    pRec^.id := i;
    pRec^.Name := "Entry" + IntToStr(i);
    ListView1.AddItem("Entry" + IntToStr(i), Pointer(pRec));
  end;
end;


Не будет ли это нарушением? Точнее не спровацирetn kb это утечку? Хотя опять же проверял перед инициализацией и после удаления через  ShowMessage(IntToStr(AllocMemSize)); Все вроде нормально...


 
kyn66 ©   (2009-11-15 22:15) [68]


> Жаль только применение крайне неудачное.

Это частный случай, просто нужно было что-то привести в качестве примера, чтобы поняли что нужно.


> Понять указатели? Ну можешь мои статьи посмотреть:

Спасибо, посмотрю. Кстати, по поводу разыминования.... Только чур ногами не бить, чисто эксперимент. Если из вышеприведенного кода [67] в момент присваивания значений

new(pRec);
   pRec^.id := i;
   pRec^.Name := "Entry" + IntToStr(i);


Сперва я присвоил как в коде, потом убрал знак ^ и опять выполнил присваивание. Хотя понимаю, что pRec^.id - конкретно переменная, а pRec.id указатель на адрес в памяти, где эта меременная находится. После проверки обеих вариантов через

procedure TForm1.ListView1Click(Sender: TObject);
var
 i: Integer;
 xRec: PMyRecord;
begin
 for i := 0 to Listview1.Items.Count - 1 do
  if ListView1.Items[i].Selected then
   begin
     xRec := PMyRecord(ListView1.Items[i].Data);
     ShowMessage(Format("Record #%d Name: %s", [xRec.id, xRec.Name]));
   end;
end;


Значения были одинаковые. Совпадение?

PS
Касаемо литературы и прочих источников информации. Delphi World у меня как настольная книга, которая всегда под руками. Хочу сказать, что там не без ошибок коды приведены. А в книгах? Не может быть очепятки? Вот форум и помогает соединить все вопросы и дать правильный ответ.


 
Юрий Зотов ©   (2009-11-15 22:17) [69]

> kyn66 ©   (15.11.09 21:59) [67]

За освобождение объектов Delphi не отвечает, это должен делать программист. Правда, есть еще такая штука, как интерфейсы, там все хитрее - видимо, Вам теперь стоит разобраться и с ними, чтобы эту тему закрыть.

Что касается примеров кода, то между ними есть большая разница.

var
 IntPointer: ^Integer;
begin
  New(IntPointer);
  New(IntPointer);
end.

Здесь память выделяется дважды, но после второго New адрес первого выделенного блока будет безвозвратно потерян (затерт вторым адресом, потому что второй адрес пишется в ту же переменную, которая до этого хранила первый адрес). Теперь первому блоку нельзя сделать Dispose (нечего передать в параметре) - чистейшая утечка памяти.

procedure TForm1.Button3Click(Sender: TObject);
var
 i: Integer;
 pRec: PMyRecord;
begin
 for i := 0 to 10 do
 begin
    new(pRec);
    pRec^.id := i;
    pRec^.Name := "Entry" + IntToStr(i);
    ListView1.AddItem("Entry" + IntToStr(i), Pointer(pRec));
 end;
end;

Здесь для выделения 11 блоков памяти тоже использована одна переменная, которая, конечно, каждый раз затирается новым адресом. Но старый адрес при этом не теряется, потому что его копия запоминается в Items[i].Data и мы можем вызвать Dispose, используя эту копию.


 
Юрий Зотов ©   (2009-11-15 22:23) [70]

> kyn66 ©   (15.11.09 22:15) [68]

> pRec^.id - конкретно переменная,
> а pRec.id указатель на адрес в памяти

Обе формы записи равнозначны. Delphi автоматически разыменовывает указатели, поэтому значок ^ при разыменовании можно не писать. Но это не всегда хорошо (снижается читабельность кода), поэтому многие (и я в том числе) используют такое правило - разыменовывать указатели на объекты (то есть, переменные любого объектного типа) поручают компилятору, а остальные указатели разыменовывают явно, указывая значок ^.


 
kyn66 ©   (2009-11-15 22:56) [71]


> но после второго New адрес первого выделенного блока будет
> безвозвратно потерян

Он будет потерян, но выделенным так и останется(утечка памяти!). А в моем случае переменная одна и та же, но после инициализации она сделала "доброе дело", присвоив этому адресу некие данные, а уж потом получила новый адрес. Получается все открытые дыры будут заделаны (данными). И тогда

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
 i:integer;
begin
 for i:=0 to ListView1.Items.Count-1 do
   Dispose(PMyRecord(ListView1.Items[i].Data));
end;

наилучшим способом очистит память... Я все правильно понял?

> Delphi автоматически разыменовывает указатели, поэтому значок
> ^ при разыменовании можно не писать.

Вот так вот....

> поэтому многие (и я в том числе) используют такое правило
> - разыменовывать указатели на объекты

Что считается в программировании  - правилом хорошего тона...


 
Юрий Зотов ©   (2009-11-16 00:16) [72]

> kyn66 ©   (15.11.09 22:56) [71]

> А в моем случае переменная одна и та же, но после инициализации она
> сделала "доброе дело", присвоив этому адресу некие данные, а уж потом
> получила новый адрес.

Главное не это, а то, что перед тем, как переменная получила новое значение, ее старое значение было сохранено в Items[i].Datа. Поэтому адреса выделенных блоков не теряются и мы имеем возможность вызвать Dispose для всех блоков.

> Я все правильно понял?

Да, код верный.


 
Германн ©   (2009-11-16 02:25) [73]


> kyn66 ©

Везёт тебе! Постарайся не упустить это везение!


 
Leonid Troyanovsky ©   (2009-11-16 07:43) [74]


> Дмитрий Белькевич   (15.11.09 21:16) [66]

> Если нужен и Integer (для последующего его применения) и
> строчка (для отображения) то строчка запихивается в комбобокс,
>  integer - в указатель:

> AddObject(s, Pointer(i))

Integer не годится, бо stdctrls.pas

function TCustomComboBoxStrings.GetObject(Index: Integer): TObject;
begin
 Result := TObject(SendMessage(ComboBox.Handle, CB_GETITEMDATA, Index, 0));
 if Longint(Result) = CB_ERR then
   Error(SListIndexError, Index);
end;

-1 для классов LISTBOX & COMBOBOX - индикатор ошибки.

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2009-11-16 07:59) [75]


> kyn66 ©   (15.11.09 02:33) [62]

>  Хотелость попробывать изучить работу объектов.

Был хороший повод изучить "виртуальные" контролы.

> там не без ошибок коды приведены. А в книгах? Не может быть
> очепятки? Вот форум и помогает соединить все вопросы и дать
> правильный ответ.

Обсуждения позволяют избавиться от заблуждений.
Желающим, конечно.

--
Regards, LVT.


 
Anatoly Podgoretsky ©   (2009-11-16 09:02) [76]

> Leonid Troyanovsky  (16.11.2009 07:59:15)  [75]

Одного желания мало.


 
Leonid Troyanovsky ©   (2009-11-16 09:13) [77]


> Anatoly Podgoretsky ©   (16.11.09 09:02) [76]

> Одного желания мало.

Да, конечно.
Если нет способности к восприятию информации,
в т.ч. из-за слабой подготовки, то вместо диалога
получаются несвязные монологи.

--
Regards, LVT.


 
kyn66 ©   (2009-11-16 09:24) [78]


> Главное не это, а то, что перед тем, как переменная получила
> новое значение, ее старое значение было сохранено в Items[i].
> Datа. Поэтому адреса выделенных блоков не теряются и мы
> имеем возможность вызвать Dispose для всех блоков.


Получается так, что если память выделена, то ее обязательно нужно чем-то заполнить. Если же проходя в цикле не выполнить ListView1.AddItem("Entry" + IntToStr(i), Pointer(pRec)); то и в этом случае получится незаполненная дыра. И не выскочит ли тогда ошибка при удалении объектов

for i:=0 to ListView1.Items.Count-1 do
  Dispose(PMyRecord(ListView1.Items[i].Data));
end;

если предварительно не проверить

  if PMyRecord(ListView1.Items[i].Data)) <> nil
   ...


 
RWolf ©   (2009-11-16 09:29) [79]


> Получается так, что если память выделена, то ее обязательно
> нужно чем-то заполнить

К выделенной памяти только одно требование — её обязательно
нужно когда-нибудь освободить. А уж заполнять или нет — это на усмотрение программиста.


 
sniknik ©   (2009-11-16 09:30) [80]

> Dispose(PMyRecord(ListView1.Items[i].Data));
PMyRecord(ListView1.Items[i].Data).Free;



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

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

Наверх





Память: 0.65 MB
Время: 0.008 c
15-1257627991
Омлет
2009-11-08 00:06
2010.01.10
Убойная статистика


15-1257712925
POOP
2009-11-08 23:42
2010.01.10
При отражении длина световой волны меняется?


2-1258277671
abun
2009-11-15 12:34
2010.01.10
Определение расположения файла на диске (CD|DVD)


4-1226515228
АгатаКристи
2008-11-12 21:40
2010.01.10
Настройка TCP/IP


15-1257870273
И Павел
2009-11-10 19:24
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
Английский Французский Немецкий Итальянский Португальский Русский Испанский