Урок Delphi 7
Работа с файлами в Delphi

Компоненты для работы с файлами в Delphi


Компоненты работающие с файлами
Классическая работа с файлами
Диалоги выбора файлов
Определение размера файла
Поиск файлов
Таблица функций






Уроки Delphi
  1.  Первая программа
  2.  Использование компонентов
  3.  События Delphi
  4.  Типы данных Delphi
  5.  Создание своих типов данных
  6.  Выражения и операторы
  7.  Работа с файлами в Delphi
  8.  Дополнительные формы
  9.  Подпрограммы в Delphi
  10. Исключительные ситуации
  11. Взаимодействие приложения с пользователем
  12. Указатели в Delphi
  13. Обзор компонентов
  14. Работа со строками
  15. Создание интерфейса
  16. Графика в Delphi
  17. Многопоточность в Delphi
  18. Динамическое создание
        компонентов
Поиск по сайту




 Это важно:
   Метод Application.ProcessMessages;

 Это полезно:
   Параметр Sender в обработчиках событий;










Бояться не надо



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

   Для "лирического" вступления нужно упомянуть компоненты Delphi, которые умеют работать с файлами. Они читают и сохраняют своё содержимое, строки типа String, в файл текстового формата. Это компоненты ListBox, ComboBox и Memo, расположенные на первой же вкладке палитры компонентов.

   Каждая строка компонентов ListBox и ComboBox является объектом Items[i], а Memo - Lines[i], где i - номер строки, который отсчитывается от нуля. Добавление строк в компоненты выполняется методами Add и Insert:

Компоненты сохраняющие содержимое
  begin
   Memo1.Lines.Add('Первая строка');
   ComboBox1.Items.Add('Первая строка');
   ComboBox1.Items.Add('Вторая строка');
   ListBox1.Items.Add('Первая строка');
   ListBox1.Items.Add('Вторая строка');
  end ;



Метод Add добавляет новую строку в конец. Метод Insert имеет дополнительный параметр, указывающий, после какой строки разместить новую строку. Доступ к строкам осуществляется так:

   ComboBox1.Items[0] := 'Первая строка изменилась' ;
   ListBox1.Items[1] := 'Вторая строка изменилась' ;

У компонента ComboBox дополнительно есть свойство Text, где (как и у компонента Edit) находится вводимый текст:

   ComboBox1.Text := ' Вводимый текст ';

На выделенную в данный момент строку компонента ComboBox указывает свойство ItemIndex типа Integer, то есть это номер выделенной строки. Следовательно, получить саму выделенную строку компонента ComboBox можно следующей конструкцией:

   S:=ComboBox1.Items[ComboBox1.ItemIndex];

или, пользуясь оператором присоединения

   With ComboBox1 do
    S:=Items[ItemIndex];

Вот как по нажатию клавиши Enter можно заносить в этот компонент вводимую в строку информацию и удалять нажатием Escape:
Выделите на Форме ComboBox и перейдите в Инспектор объектов, на вкладку Events. Щёлкните дважды по обработчику OnKeyPress. Система Delphi создаст заготовку обработчика. Напишите:

  begin
   if Key=#13 then
      ComboBox1.Items.Add(ComboBox1.Text);
   if Key=#27 then
      ComboBox1.Items.Delete(ComboBox1.Items.Count-1);
  end ;

Key - определённая в этом обработчике переменная, содержащая код нажатой клавиши, #13 и #27 - коды клавиш Enter и Escape соответственно. Items.Count - количество содержащихся в компоненте строк. Так как отсчёт строк идёт от нуля, мы отнимаем единицу. После очередного удаления количество строк меняется, таким образом, Items.Count-1 всегда указывает на последнюю строку. Последовательно нажимая Escape, мы можем удалить все строки. Командой
   ComboBox1.Items.Delete(0);
можно добиться того же эффекта, только удаляться будут первые строки. Впрочем, чтобы стереть всё сразу, есть метод Clear!

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

   ListBox1.Items.SaveToFile(' Имя_файла.txt ') ;

Впрочем, расширение можно поставить любое по желанию, не обязательно .txt, как и вообще без него обойтись. Но расширение .txt позволит легко открыть файл стандартным виндовским Блокнотом, что бывает очень удобно на этапе написания программы!
Для загрузки служит метод LoadFromFile:

   ListBox1.Items.LoadFromFile(' Имя_файла.txt ') ;

Что делать, если в своей программе мы не работаем с компонентами Combobox, ListBox или Memo, а сохранять информацию нужно? Берём один из компонентов и делаем его невидимым, для этого в Инспекторе Объектов ставим в свойство Visible значение False. Функциональность его от этого не изменится!

Последний штрих - создадим программу, сохраняющую своё положение на экране в момент закрытия и там же открывающуюся. Нам нужно сохранить два параметра - значения свойств Формы Left и Top, это расстояние от левого и верхнего краёв экрана соответственно. Значения эти выражаются в пикселах и имеют тип Integer. Необходимо перевести эти числа в строку (тип String) с помощью оператора IntToStr. Итак, разместите на Форме невидимый ListBox, щёлкните по пустому месту Формы, чтобы её свйства появились в Инспекторе объектов, и перейдите на вкладку Events. Щёлкните по обработчику OnClose и в созданной заготовке напишите:

  begin
   ListBox1.Items.Clear;
   ListBox1.Items.Add(IntToStr(Form1.Left));
   ListBox1.Items.Add(IntToStr(Form1.Top));
   ListBox1.Items.SaveToFile('MyFormPos.txt');
  end ;

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

  begin
   if FileExists('MyFormPos.txt') then
    begin
     ListBox1.Items.LoadFromFile('MyFormPos.txt');
     Form1.Left:=StrToInt(ListBox1.Items[0]);
     Form1.Top:=StrToInt(ListBox1.Items[1]);
    end ;
  end ;

   В первой строке происходит проверка на существование файла, ведь если его не будет, произойдёт ошибка. Впрочем, программа после выдачи предупреждения откроется в том месте, где была на этапе проектирования, а при закрытии нужный файл будет воссоздан!
   Затем в логических скобках begin / end содержится сам код, который будет выполнен только приналичии файла MyFormPos.txt в папке с программой, так как используется относительный путь. Можно указать конкретное местоположение, например, C:\Program Files\MyProg\MyFormPos.txt.

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

Конечно, профессиональные программы сохраняют своё положение в Реестре Windows. Но всему своё время.

   А пока "лирическое" вступление окончено.
Продолжение. Прямая работа с файлами.
Окончание. Диалоги открытия и сохранения файлов.


Выражения и операторы Delphi           В начало урока          Работа с дополнительными формами  

Уроки Delphi начинающим



Вопросы и комментарии (84)      Решение задач в Delphi

Leha, добавлено 27.07.09, 09:30:54 
Да. Великолепный пост. Добавил в мемориз.
Mihan, добавлено 29.07.09, 08:24:43 
Мда... Примерно тоже самое прочитал на севендей.ру. Уже много раз замечал. Такое ощущение, что они просто переписывают посты. Хотя... может меня и подглючивает .
Автор, добавлено 29.07.09, 11:21:21 
Робяты, ну никак понять не могу, почему все имена по-английски пишут!

Raven, добавлено 3.08.09, 14:49:46 
Соглашусь с первым автором,и хочу сразу же задать вопрос.У меня в listbox выводится Имя а потом Номер в скобках тоесть вот так к примеру Елена(920*******) как сделать чтобы при нажатии на Елену в Edit записывался только номер
Ответ, добавлено 3.08.09, 17:23:19 
Можно вычислить номер символа "(" и скопировать текст от этого номера плюс один до номера символа ")" минус один. Как это делается, объяснять?
Raven, добавлено 4.08.09, 11:10:38 
Да объяснять=).Спасибо что ответили,я самоучка просто.Читаю книжку в данный момет библия для программиста в среде делфи,но пока ответа на свой вопрос там не нашел.Расскажите пожалуйста вы если не сложно.Заранее спасибо.
Продолжаем разговор!, добавлено 4.08.09, 14:13:45 
Нужно освоить работу со строками. Есть функция Pos, которая даёт позицию первого вхождения нужного символа. Копирование части строки производится функцией Copy. Вот как:

procedure TForm1.ListBox1Click(Sender: TObject);
var N1, N2, N3: Integer;
 S: String;
begin
  S:=ListBox1.Items[ListBox1.ItemIndex];
  N1:=Pos('(', S); //Позиция символа (
  N2:=Pos(')', S); //Позиция символа )
  N3:=N2-N1; //Количество копируемых символов
  Edit1.Text:=Copy(S, N1, N3);
end;

В программе есть ошибочки, чтобы самому грамм подумать, что произошло и как исправить! Не сможешь, ну, подскажу...
Raven, добавлено 4.08.09, 15:42:35 
Спасибо огромное за помощь,как раз то что нужно!Побольше бы таких людей как вы=) а данную ошибку справил следющим образом
procedure TForm1.ListBox1DblClick(Sender: TObject);
var
N1, N2, N3: Integer;
S: String;
begin
S:=ListBox1.Items[ListBox1.ItemIndex];
N1:=Pos('(', S);
N2:=Pos(')', S);
N1:=N1+1;
N3:=N2-N1;
Edit1.Text:=Copy(S, N1, N3);
end;

LoX, добавлено 15.01.10, 14:06:37 
Спасибо за материал
николай, добавлено 16.02.10, 11:01:49 
отлично, просто и все что нужно
Сергей, добавлено 7.04.10, 00:37:14 
... если в своей программе мы не работаем с компонентами Combobox, ListBox или Memo, а сохранять информацию нужно?...
Элементы Items указанных компонент имеют тип TStrings, который и поддерживает операции сохранения/восстановления в/из файла. Поэтому не обязательно использовать указанные компоненты, делая их невидимыми, а можно ввести переменную типа TStrings. Преимуществом данного метода была бы экономия системных ресурсов Windows (ведь если окно не видимо - это не означает что его нет)
Хотя, дайте ста программистам написать простейшую программку, и каждый из них напишет ее своим способом.
Спасибо, автор, за материал. Для старта - "то что надо" (с)Сюткин Валерий
Автор, добавлено 7.04.10, 05:35:16 
Именно исходя из простоты и дан такой способ. Но и данный Вами также добавлю, как вариант. Также спасибо Вам за комментарий!
станислав, добавлено 16.04.10, 14:21:10 
вот я сделал все как сказано,диалог сохранения есть,
жму ок но не сохраняет!
Сергей, добавлено 18.05.10, 01:58:25 
Подскажите пожалуйста как в текстовом файле заментиь необходимый символ в строке на любой другой.
Автор, добавлено 18.05.10, 06:52:38 
Нужно считать файл например компонентом Memo, заменить символы, затем сохранить новый текст. Как считать и сохранить, написано выше, а вот процедура замены. Я решил символы, которые заменяем, вводить в компоненты Edit (так более универсально). Вы можете ввести их непосредственно в текст ('a', 'б' вместо Edit1.Text[1], Edit2.Text[1]):

procedure TForm1.Button1Click(Sender: TObject);
var i: Integer;
 S: String;
begin
  S:=Memo1.Text;
  for i:=0 to Length(S) do
    if S[i]=Edit1.Text[1]
      then S[i]:=Edit2.Text[1];
  Memo1.Text:=S;
end;

Сергей, добавлено 18.05.10, 11:54:01 
Спасибо. Все получилось. А как заменить символ в какой-то одной строке, а не во всех?
Постараюсь объяснить в чем у меня проблема:
делаю программу обучения - есть электронный учебник, тест по нему и естественно авторизация для пользователей.
Программа считает время, проведенное за учебником и баллы за тест.
Не могу только понять как это забить в один файл.
При регистрации создается файл такого типа
0*0&0$0# т.е.
первое число перед символом - логин, второе - пароль, третье - время, четвертое - баллы.
Вопрос в том, как определить какой прользователь вошел в программу и записать данные именно для него? Или можно какой-то другой способ использовать?
Заранее спасибо!
Автор, добавлено 18.05.10, 12:50:53 
Мне сложно судить, как Вам решить Вашу задачу.
Доступ же к строке i компонента Memo получается как Memo1.Lines[i-1]. Там всё и меняется.
Сергей, добавлено 18.05.10, 15:20:36 
Хорошо, буду что-нибудь думать.
Сергей, добавлено 18.05.10, 18:12:58 
В принципе почти дошло до меня.
var
s:string;
t:textfile;
c, d:char;
begin
s:='';
assignfile(t,'bd\result6.txt');
if fileexists('bd\result6.txt') then
begin reset(t);
while(not(eof(t))) do
begin
read(t,d);//читаем логин
if d=zagl.Edit1.Text then
begin
read(t,c);
if c='*' then
s:=d+s+'*'+Form1.Label2.Caption+'&'
else exit;
end;
end;
end;
closefile(t);
assignfile(t,'bd\result6.txt');
rewrite(t);
write(t,s);
closefile(t);
Form1.Close;
end;
Вроде бы все нормально. Определяется строка с логином пользователь, который вошел в систему. Баллы набранные в тесте записываются.
Логины в файле записываются виде "логин*".
Так вот при перезаписи файла остается только текущий пользователь и баллы:
5*3&.
Подскажите как записать остальные строки.
Автор, добавлено 18.05.10, 18:46:59 
Я сейчас в отъезде, завтра попробую ответить.
Автор, добавлено 18.05.10, 18:53:45 
Хотя, функция rewrite стирает файл, и на его месте создает новый. Поробуйте просто её убрать.
Сергей, добавлено 18.05.10, 19:50:42 
Это понятно, что перезаписывает, но без него файл вообще не меняется. Я просто не могу разобраться как сделать чтобы только с выбранной строкой работать и ее перезаписывать, либо весь файл перезаписывать, но тогда остальные строки нужно собрать. А у меня это не выходит.
Автор, добавлено 19.05.10, 10:39:25 
Я бы перезаписывал весь файл и не заморачивался. Считывал бы файл компонентом Memo, искал нужную строку, менял бы её, и сохранял текст целиком.
В противном случае, если это неэффективно (много пользователей и параллельная работа), писал бы уже полноценную базу данных.
Ольга, добавлено 17.12.10, 06:52:29 
Здравствуйте, я делаю сохранение в файл, изначально того файла не существует, я сделала так, чтобы он создавал ее и записывал туда информацию, но я не помню как сделать чтобы если данный файл уже существует, чтобы он добавлял в нее информацию, а не заного создавал его..
Автор, добавлено 17.12.10, 07:53:12 
Ольга, почитайте тему следующего урока "Классическая работа с файлами", а я чуть позже отвечу.
Кирил, добавлено 26.12.10, 02:40:40 
Почему то здесь у меня программа выдает ошибку???
следующей конструкцией:
  S:=ComboBox1.Items[ComboBox1.ItemIndex];
или, пользуясь оператором присоединения
  With ComboBox1 do
  S:=Items[ItemIndex];
В обоих случаях, курсор стоит после ;
переменная объявлена, в чем дело не пойму???

Кирил, добавлено 26.12.10, 02:49:53 
Прошу прощения, разобрался, оказывается ItemIndex имеет тип String, а я думал integer.
Автор, добавлено 26.12.10, 05:52:11 
Кирилл, надеюсь, вы и в самом деле разберётесь...
ItemIndex - это номер выделенной строки в компоненте ComboBox, и номер никак не может иметь тип String.
Да и вообще, откуда ошибка, я просто копирую этот оператор, вставляю в обрабатчик нажатия на кнопку, и - никаких ошибок. Вот переменная S да, её действительно нужно объявить как

var S: String;

Павел, добавлено 10.02.11, 21:43:06 
Хорощий материал, СПАСИБО!!!
Ринат, добавлено 26.07.11, 12:28:22 
Здравствуйте!
очень хороший сайт!
объясните один момент куда все это( begin
  Memo1.Lines.Add('Первая строка');
  ComboBox1.Items.Add('Первая строка');
  ComboBox1.Items.Add('Вторая строка');
  ListBox1.Items.Add('Первая строка');
  ListBox1.Items.Add('Вторая строка');
  end ;
) записывать?Раньше я делал это через Object TreeView.
Заранее спасибо!
Автор, добавлено 26.07.11, 12:34:42 
Не совсем вас понял. Мы обсуждаем возможность сохранить в файле текст, содержащийся в компонентах Memo и ListBox. Как туда этот текст попадёт, неважно. Можно написать руками. А можно программно - в обработчике какого-либо события, например, нажатия на кнопку или любого другого. И любая процедура содержит begin/end. Туда и пишем эти методы для добавления текста в компоненты.
Ринат, добавлено 26.07.11, 13:01:06 
То есть просто нужно в процедуры записывать я так и делаю))Но у меня выходить только пустые listbox combobox and memo то есть в них ничего не написано кроме свойства caption
Автор, добавлено 26.07.11, 13:06:32 
Да, но нужно чтобы эти процедуры ещё и исполнялись. То есть, в случае кнопки - нужно на кнопку нажать, тогда в компонентах появится содержимое.
Ринат, добавлено 26.07.11, 13:29:06 
Я так и делаю. но при открывании боксов нет никакого содержимого
Автор, добавлено 26.07.11, 13:34:14 
тщательнЕЕ нужно. Просто скопируйте и вставьте в пустой обработчик нажатия кнопки:

Memo1.Lines.Add('Первая строка');
ComboBox1.Items.Add('Первая строка');
ComboBox1.Items.Add('Вторая строка');
ListBox1.Items.Add('Первая строка');
ListBox1.Items.Add('Вторая строка');

Не вышло?
Ринат, добавлено 26.07.11, 14:18:08 
Все получилось!!!
спасибо а как сделать чтоб сразу появлялась? без нажатия кнопки?
Автор, добавлено 26.07.11, 14:26:54 
Я так понимаю, что Delphi вы впервые видите. Так вот, в Delphi ничего само по себе не появляется. Всё происходит при выполнении какого-либо события. Нажатие кнопки Button, или кнопки на клавиатуре, или кнопки мышки, момента появления Формы на экране, изменения текста в компоненте и т.д.

Так что вы имеете в виду под словом "сразу"? В самом начале, при появлении программы?
Ринат, добавлено 26.07.11, 21:04:38 
Да, вы правы, с программированием я столкнулся впервые.
Я имел ввиду при появление формы на экране.
Автор, добавлено 26.07.11, 21:16:14 
Появление Формы на экране - это события такого объекта, ну или компонента, как Форма. Посмотрите, щёлкнув по пустому месту на Форме, слева Инспектор Объектов, в него загружены свойства Формы. В Инспекторе Объектов две вкладки - Properties (свойства) и Properties (события). Так вот, те события, на которые может реагировать Форма, находятся на вкладке Properties. За появление Формы на экране отвечает событие OnActivate, хотя лучше всё же воспользоваться OnCreate - событием создания Формы. Поместите в обработчик этого события вышеуказанные операторы.

И всё же лучше бы начать изучение с Урока 1, а не 7...
Ринат, добавлено 5.10.11, 12:29:37 
как данные из одной процедуры перенести в другую?нужно открыть файл указал вот так WinExec(PChar('loc1'),SW_SHOWDEFAULT); где loc1 есть переменная описанная в глобальном варе. вот как она получается var ws:windowssize;
loc:location;
fs,f:Tfilestream;
 //ïåðåìåííóþ ëîê ÿ îáÿâèë â îáùåì âàðå
begin
if fileexists('size.dat')then
  begin
  fs:=Tfilestream.create('size.dat',fmopenread);
  fs.Read(ws,sizeof(ws));
  left:=ws.Left;
  top:=ws.Top;
  height:=ws.Height;
  Width:=ws.Width;
  fs.Free;
  end;
if fileexists('cons.bat')then begin
  f:=Tfilestream.Create('const.bat',fmopenread);
  f.Read(loc,sizeof(loc));
  loc1:=loc.file1;
  end;
РИНАТ, добавлено 5.10.11, 14:20:40 
СПАСИБО РАЗОБРАЛСЯ)
Саша, добавлено 10.11.11, 17:11:16 
Здраствуйте!
У меня есть вот какой вопрос:
Мне на лабораторных занятиях дали задание написать программу для открытия 5 форматов (*.mp3, *.avi, *.txt, *.jpg и *.3ds). Проблем с *.txt и *.jpg у меня не возникло, а вот с остальными туговато... Не могли бы Вы подсказать как это реализировать? Особенно меня беспокоит *.3ds. Зарание спасибо.
Сергей, добавлено 10.11.11, 17:26:20 
Здравствуйте подскажите пожалуйста как сохранить пароль *.txt файле ,но перед этим его надо зашифровать?
Автор, добавлено 10.11.11, 17:47:03 
Для Сергея: есть статья Пароль, где в конце есть описание шифрования с помощью функции md5.
Саша, добавлено 10.11.11, 18:05:26 
А для меня будут какие-то советы?
Автор, добавлено 10.11.11, 18:08:12 
Для Саши: Форматы mp3 и avi открываются с помощью компонента MediaPlayer. Вот mp3:

procedure TForm1.Button1Click(Sender: TObject);
begin
MP1.DeviceType:=dtAutoSelect;
MP1.FileName:='имя_файла';
if not MP1.AutoOpen then MP1.Open;
MP1.Play;
end;

AVI сейчас допишу.
Саша, добавлено 10.11.11, 18:19:55 
А для этого не надо добавлять какие-то компоненты наподобие таймера или ещё чего-то?
Автор, добавлено 10.11.11, 18:41:07 
Чтобы просто был звук - больше ничего не надо. Но если вы хотите создать полноценный плейер, то конечно придётся что-то придумывать.

Вот видео:

procedure TForm1.Button2Click(Sender: TObject);
begin
MP1.Display:=Panel1;
with OpenDialog1 do
  if Execute then
    begin
      MP1.FileName:=FileName;
      MP1.Open;
      MP1.Play;
    end;
end;

Тут нужно добавить OpenDialog, можно и в предыдущий пример его вставить. И ещё. Размер области воспроизведения, то бишь панели, нужно посмотреть заранее в свойствах файла, на вкладке "Сведения". Но лучше сделать панель побольше, и установить её свойство BevelInner и BevelOuter в bvNone, чтобы её было не видно. А то размеры у файлов разные...

Что касается формата *.3ds, то я не умею работать с 3d видео... Цельная книжка есть про это. Но, блин, изучению надо жизнь посвятить. Но если с вас требуют лабораторку, то наверное преподавали...
Вот, нашёл что нужно иметь модуль GLFile3DS. Он необходим для работы с форматом 3DS.
Саша, добавлено 10.11.11, 19:17:47 
Спасибо огромное! А что касается *.3ds то как я разговаривал с преподом, то он сказал что надо только показать грудо говоря jpg (или какую-то ещё) проэкцию этого файла но не редактировать его. может тут не надо того модуля?
Автор, добавлено 10.11.11, 19:19:09 
Не смогу по 3ds подсказать ничего... Звиняйте.

А про avi ещё. Чтобы масштабировать изображение, нужно воспользоваться свойством медиаплейера DispleyRect. Оно доступно только программно.
Саша, добавлено 15.11.11, 04:10:29 
Я случайно заметил одну особенность: если не создавать панель (Panel1) и не присваивать панели ничего дисплею, то видео выводится в отдельном окне со своим родным расширением.

Но без вопроса не обойдётся =) : как настроить полосу прокрутки для видео или же хотя бы для аудио? Понятно что нужен таймер и и ProgresBar, но как связать это всё во едино?
Автор, добавлено 15.11.11, 09:00:43 
Когда файл открыт, то свойство Mediaplayer.Length возвращает продолжительность трека в специфическом формате. Лучше всего предварительно задать отображение этой величины в миллисекундах:

MediaPlayer.TimeFormat:=tfMilliSeconds;

Ну далее переводим в часы, минуты и секунды с помощью функции

function taim(Length: Integer): String;
var chas, min, sec: Integer;
  function mode(Length: Integer): String;
  begin
    Result:=IntToStr(Length);
    if Length<10 then Result:='0'+Result;
  end;
begin
 sec:=Length div 1000;
 min:=sec div 60;
 chas:=min div 60;
 min:=min - chas*60;
 sec:=sec - min*60 - chas*3600;
 Result:=IntToStr(chas)+':'+mode(min)+':'+mode(sec);
end;

Это что касается длины. А текущую позицию возвращает свойство... - правильно, Position! Измеряем по срабатыванию таймера и выводим в ProgressBar (лучше возьмите TrackBar). Опять же, свойство TrackBar.Max предварительно установите равным Mediaplayer.Length.

Есть проблемка с прокруткой. Чтобы прокрутить, нужно сначала остановить плеер, и таймер. А затем запустить с другим значением:

MediaPlayer.Position:=TrackBar1.Position;

Я был удивлён, но TrackBar не имееет событий мыши... А то можно было бы останавливать по событию OnMouseDown. А впрочем, можно пользоваться событием OnEnter! Но запускать всё равно потом приходится.

А чтобы менять кадры при перемотке мышкой, придётся ввести второй таймер, чтобы работал когда воспроизведение останавливается, и задавал

MediaPlayer.Position:=TrackBar.Position;

Время срабатывания естественно сделать поменьше, а то будет тормозить.

Саша, добавлено 16.11.11, 18:59:41 
Спасибо! =)
Саша, добавлено 17.11.11, 01:24:40 
Здравствуйте в очередной раз) Вот какая у меня проблема, когда открываю видео с помощью MedaiPlayer1, то функция Mediaplayer1.Length возвращяет уауое-то кривое значение (например продолжительность видео 40 мин. а возвращает значение примерно 1,17 мин.), но в случае с аудио файлами всё происходит нормально (то есть значение правильное). Но что самое интересное - видео проигрывается свыше возвращенного значения. В чём может быть дело?
Автор, добавлено 17.11.11, 02:03:44 
Странно. У меня фильм в программе определяется как 1 час 26 минут 55 секунд, с такой программой как Media Player Classic разница несущественная. Вот полный текст программы:

function taim(Length: Integer): String;
var chas, min, sec: Integer;
  function mode(Length: Integer): String;
  begin
  Result:=IntToStr(Length);
  if Length<10 then Result:='0'+Result;
  end;
begin
 sec:=Length div 1000;
 min:=sec div 60;
 chas:=min div 60;
 min:=min - chas*60;
 sec:=sec - min*60 - chas*3600;
 Result:=IntToStr(chas)+':'+mode(min)+':'+mode(sec);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
MP1.Display:=Panel1;
with OpenDialog1 do
  if Execute then
  begin
  MP1.FileName:=FileName;
  MP1.Open;
  MP1.TimeFormat:=tfmilliseconds;
  Form1.Caption:=taim(MP1.Length);
  MP1.Play;
  end;
end;

Может вы забыли формат длительности задать? Я закомментировал этот оператор, и продолжительность вместо полутора часов стала две минуты.
Саша, добавлено 17.11.11, 03:32:39 
Нет, он описан в процедуре TForm1.FormCreate. Но после того, как я удалил его от туда и прописал отдельно для каждой кнопки вызова медиа плеера - всё встало на свои места) Так-что спасибо)
Саша, добавлено 20.11.11, 21:56:43 
Автор, большое Вам спасибо за этот прекрасный сайт а особенно за ваши ответы на задаваемые вопросы! Я закончил то задание с *.3ds форматом, но дело сдвинулось с мёртвой точки только после того, как Вы написали что нуден модуль GLFile3DS. Как оказалось - это не совсем "сам по себе" модуль) Это часть проекта GLScene. Советую Вам хотя бы не много им поинтересоваться. Полезная вещь. Ещё раз огромное Вам спасибо за помощь и поддержку в трудной ситуации!

ПС
Если надумаете всё таки заняться этим GLScene-ом - то хорошо ищите как правильно его устанавливать. Даже на оф. сайте инструкция не совсем точная.
Андрей, добавлено 18.12.11, 02:33:53 
помогите, не получается сохранить файл.
пишу такод код, файла нет, ошибок тоже нет:
procedure TForm1.N3Click(Sender: TObject);
begin
 with SaveDialog1, Memo1 do
  if Execute then
  Lines.SaveToFile('ф.txt');
  CloseFile(SaveF);
end;
Автор, добавлено 18.12.11, 06:59:18 
Зачем вам диалог, если вы сохраняете в файл 'ф.txt' - его и ищите.
Андрей, добавлено 18.12.11, 11:17:05 
если писать вместо ф.txt, FilEname, как в вашем уроке, то файл не сохраняется. Помогите, что я не так делаю.
Автор, добавлено 18.12.11, 15:44:10 
Вот написали бы именно как делаете, я бы посмотрел. А так приходится гадать. Может, вы Filename в кавычках пишете. Тогда файл будет называться не как в диалоге вы задали, а именно Filename.txt
Владимир, добавлено 11.01.12, 23:19:26 
Спасибо за уроки начал недавно но кое что уже получается. Изучение затеял с целью
написания электронных тестов для учеников по химии. Однако столкнулся с такой проблемой как на форме разместить например H2O но чтобы 2 была маленькой. Понимаю что вопрос не в тему и может быть не простой но интересует общее направление поиска, больше не кого спросить. Заранее спасибо.
Автор, добавлено 12.01.12, 08:30:21 
Владимир, вариантов масса. В зависимости от того, как конструктивно построен тест, на каких компонентах. Ведь можно три метки Label рядом стоящие, размер - любой. Или можно картинку нарисовать и поместить в нужное место - компонент Image, или даже просто по Форме написать, на её канве.
Владимир, добавлено 12.01.12, 21:23:09 
Спасибо буду пробовать.
Александр, добавлено 1.05.12, 14:03:59 
создал на форме все как положенно, с такимеже названиями.
в код после implementation вставил
 begin
  Memo1.Lines.Add('Первая строка');
  ComboBox1.Items.Add('Первая строка');
  ComboBox1.Items.Add('Вторая строка');
  ListBox1.Items.Add('Первая строка');
  ListBox1.Items.Add('Вторая строка');
  end ;

но почему-то не работает, при запуске выдает ошибку
Александр, добавлено 1.05.12, 15:31:21 
аааааааа, надо по форме два раза щелкнуть и писать, понял!!
Александр, добавлено 1.05.12, 17:11:13 
выручайте.

написал через add все отлично, затем использовал команду Insert.

 вылетает ошибка "Debugger exception notification Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 0056D0FD in modul 'Project1.exe'.Read of address 0000030C.Process stopped. Use Step or Run to continue."


Аноним, добавлено 1.05.12, 17:36:26 
В ошибках разбираться недосуг. Вот как надо:

Memo1.Lines.Insert(0, 'Первая строка');

Александр, добавлено 1.05.12, 17:44:33 
вы же в самом начале урока говорите что вот так:

  ComboBox1.Items[0] := 'Первая строка изменилась' ;
  ListBox1.Items[1] := 'Вторая строка изменилась' ;

я это копирю вставляю в программу и вылазит ошибка
Александр, добавлено 1.05.12, 17:54:49 
и не понятно почему

когда пишу Memo1.Lines.Insert(0, 'Первая строка'); или там comboBox1.Items.Insert (0, 'ваолоашло')

все отлично, но стит написать "Memo2.Lines.Insert(1, 'вторая трока');" без "Memo1.Lines.Insert(0, 'Первая строка');" то вылазит опядже таже ошибка.

то есть что бы мне написать "Memo2.Lines.Insert(6, 'шестая трока');" мне надо предыдущи строки написать?
Автор, добавлено 1.05.12, 18:02:12 
Если вы вставляете что-то командой Insert, то позаботьтесь чтобы были строки после которых вы это вставляете. Если всего например строк - 2 штуки, то как можно вставить что-то после шестой строки???
Александр, добавлено 1.05.12, 18:39:37 
теперь мне все стало в жизни понятно, спасибо!
Аноним, добавлено 2.07.12, 14:35:15 
для чего невидимые компоненты? напишите про TStringList!
Автор, добавлено 2.07.12, 14:41:04 
StringList это не компонент, это объект. То есть его нельзя взять из палитры Delphi, нужно создавать самому.
Николай, добавлено 18.10.13, 09:52:27 
Едрен батон!я понимаю так - это как бы написано для начинающих?! с перва все хорошо шло! четко и понятно, автор подсказывал пошагово что нажимать и куда писать ... но с 6 занятия автор куда то разогнался...забылся что ли, что пишет для начинающих! И в итоге уже не уследить что делать ...и вообще то описывает теорию, а потом оказывается что нужно было это уже реализовать в тестовой программке ... теперь упустив момент придется перечитывать с 6 занятия!!!
Автор, добавлено 18.10.13, 10:01:36 
Хм... Спасибо за замечание. Перечитал 6 урок, видимо, придётся несколько изменить изложение...
Николай, добавлено 18.10.13, 11:10:18 
Спасибо за быструю реакцию , я начинающий (не много программировал в 1С , но синтаксисом там пользуюсь на уровне интуиции и копирования из каких то готовых модулей с последующей допилкой напильником под нужную задачу) , изучал по книгам...там кроме теории много практики , и практический каждый шаг подкреплен фото или готовым текстом кода с выделением изменений , вообщем легко изучать (начинающий же не всегда понимает смысл сделаного - первое время большую часть инфы не может переварить и просто копирует, понимание приходит позже , например после того как код отрабоотает и получится результат) ... Начал читать ваши статьи еще вчера ночью - без компа (просто в уме как бы обыгрывал), материал хватался на лету .дошел до 7 урока...сегодня начал все за ново но с компом...и уже после 6 урока начал терять линию где теория где практика... Ну а в целом вполне доступно расказывается. от простого к сложному
Сергей, добавлено 1.01.14, 15:43:37 
В текстовом файле найден номер строки содержащий искомую подстроку.
Подскажите как вывести определенное количество строк начиная с найденной.
Какой функцией возможно воспользоваться?
Автор, добавлено 1.01.14, 15:53:48 
Как нашли строку? Сначала считали файл целиком? Или читали построчно? Чтение построчно Readln, вот и читайте. Установка на строку seek(f, n), f - файловая переменная, n - номер строки. А если считали файл, например, в компонент Memo, тоже нет проблем.
Сергей, добавлено 1.01.14, 16:01:18 
В данном текстовом файле 2447 строк.
Читал построчно. Нашел, что искомая подстрока найдена в 2058 строке.
Как дать инструкцию Readln, чтобы считалась именно 2058 строка и следующие за ней n-строк по определнному условию?
Сергей, добавлено 1.01.14, 16:16:30 
Прошу прощенья не обновил. Спасибо за помощь.
Сергей, добавлено 1.01.14, 19:55:15 
нет, к сожалению, не получается...
Сергей, добавлено 2.01.14, 11:30:27 
Функция seek(f, n) не предназначена для текстовых файлов. В том-то и беда.
Автор, добавлено 2.01.14, 11:34:31 
Получается, что в текстовом файле нет возможности начать читать с нужной строки. Придётся прочитать с начала файла до нужной строки, потом ещё сколько нужно.
Оставить комментарий:

Имя  

Текст комментария

  





Интернет-магазин электрооборудования