Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.
Другий параметр TResourceStream.Create - назва ресурсу, не файлу ('SКуб', здається, ви писали)
Ви не увійшли. Будь ласка, увійдіть або зареєструйтесь.
Ласкаво просимо вас на україномовний форум з програмування, веб-дизайну, SEO та всього пов'язаного з інтернетом та комп'ютерами.
Будемо вдячні, якщо ви поділитись посиланням на Replace.org.ua на інших ресурсах.
Для того щоб створювати теми та надсилати повідомлення вам потрібно Зареєструватись.
Український форум програмістів → Pascal/Delphi → Програма розв'язування задач з фізики! Для учнів 7-го класу.
Сторінки Попередня 1 … 16 17 18 19 20 … 26 Наступна
Для відправлення відповіді ви повинні увійти або зареєструватися
Другий параметр TResourceStream.Create - назва ресурсу, не файлу ('SКуб', здається, ви писали)
Другий параметр TResourceStream.Create - назва ресурсу, не файлу ('SКуб', здається, ви писали)
На жаль ні, не допомогло, все та ж помилка ресурс не знайдено
S := TResourceStream.Create(HInstance, 'SКуб', RT_RCDATA);
Ось коди конструкторів:
constructor TResourceStream.Create(Instance: THandle; const ResName: string;
ResType: PChar);
begin
inherited Create;
Initialize(Instance, PChar(ResName), ResType);
end;
constructor TResourceStream.CreateFromID(Instance: THandle; ResID: Integer;
ResType: PChar);
begin
inherited Create;
Initialize(Instance, PChar(ResID), ResType);
end;
Я вже не розумію чому воно не находить ні файлу ресурсу ні самого ресурсу. Остання надія, можливо документи *.txt потрібно англійськими писати SКуб.txt => SKube.txt І тільки тоді в рестораторі створювати файл GeometryText.res
Вибачте, так файл зветься 'SКуб' чи 'SКуб.txt'?
Вибачте, так файл зветься 'SКуб' чи 'SКуб.txt'?
Текстові файли мали розширення .txt як і звукові файли мали розширення .wav, але функцією
PlaySound('Куб', 0, SND_RESOURCE or SND_ASYNC);
ресурс 'Куб' я викликаю без розширення .wav. Я думаю і текстовий файл так само потрібно викликати просто вказавши 'SКуб'. Я створюю файл *res в програмі Restopator там в усіх файлах (наприклад) з розширенням *wav розширення пропадає і лишається тільки назва ресурсу Куб, а в текстових відповідно SКуб. Та навіть якщо я прописую
S := TResourceStream.Create(HInstance, 'SКуб. txt', RT_RCDATA);
все рівно не знаходить ресурсу.
А він точно з пробілом називається?
А він точно з пробілом називається?
Пробіл тільки я тут написав в програмі його не має.
Я спробую тест провести не в Delphi 10.3, а не в 7-й версії можливо там вийде щось з ресурсу.
Якщо з пробілом, тоді повне ім'я буде у вигляді: SКуб. txt.txt
Я спробую тест провести не в Delphi 10.3, а не в ...
Гадаю зміна версій не допоможе.
Чи здатна функція PlaySound програвати файли через ресурс?
Чи здатна функція PlaySound програвати файли через ресурс?
Звичайно здатна. І розширення там зникає, його не потрібно писати.
PlaySound('Куб', 0, SND_RESOURCE or SND_ASYNC);
А якщо так:
PlaySound('Куб', HInstance, SND_RESOURCE or SND_ASYNC);
або навіть так:
PlaySound('S2', HInstance, SND_RESOURCE or SND_ASYNC);
може кирилицю не розуміє?
В ресурсах немає ніяких розширень, а є лише секції. Декілька типів секцій є спеціалізованими, наприклад для іконок, картинок, курсорів, wav-файлів. А для усього іншого є секція RCDATA. Тому вказувати ім'я ресурсу треба без розширення.
res-файли є проміжним сховищем для даних. Коли ви компілюєте програму, то весь вміст res-файлу копіюється в exe-файл. Відкрийте своїм редактором ресурсів готовий exe, і самі усе побачите.
Відкрийте своїм редактором ресурсів готовий exe, і самі усе побачите.
Дякую пане Torbins!!! Дійсьно коли робив GeometryText.res файл я закидав туди текстові файли з розширенням *txt. Редактор робив в файлі GeometryText.res папку ТХТ і в ній вже були ресурси з текстовими файлами. Проблема була в назві папки ТХТ який стандартно створював редактор. Переназвавши папку ТХТ на RCData все стало на свої місця.
Вечір добрий панове! Підкажіть будь-ласка як прописати функцію DefinitionText на випадок якщо користувач ввів в Edit1 текст який не співпвдає з назвою ресурсу. Як в такому випадку прописати умову?
implementation
{$R *.dfm}
{$R GeometryText.res}
{$R PhysicsText.res}
{$R GeometrySound.res}
{$R PhysicsSound.res}
Function DefinitionText(Text: String): TResourceStream;
var
s: TResourceStream;
begin
try
s := TResourceStream.Create(HInstance, 'T ' + Text, RT_RCData);
result := s;
finally
s.Free;
s.Destroy;
end;
end;
procedure TForm2.Button1Click(Sender: TObject);
var
a: string;
begin
a := Edit1.Text;
RichEdit1.Lines.LoadFromStream(DefinitionText(a));
PlaySound(PChar('S ' + a), 0, SND_RESOURCE or SND_ASYNC);
end;
P.S Наприклад користувач ввів слово температура, а це явище вивчається не в сьомому класі а в восьмому. Програма видасть помилку: Ресурс не знайдено!
Вечір добрий панове! Підкажіть будь-ласка як прописати функцію DefinitionText на випадок якщо користувач ввів в Edit1 текст який не співпвдає з назвою ресурсу. Як в такому випадку прописати умову?
Function DefinitionText(Text: String): TResourceStream; var s: TResourceStream; begin try s := TResourceStream.Create(HInstance, 'T ' + Text, RT_RCData); result := s; finally s.Free; s.Destroy; end; end; procedure TForm2.Button1Click(Sender: TObject); var a: string; begin a := Edit1.Text; RichEdit1.Lines.LoadFromStream(DefinitionText(a)); PlaySound(PChar('S ' + a), 0, SND_RESOURCE or SND_ASYNC); end;
У вас тут зараз є використання об'єкта після його видалення. Рядок "result := s;" не копіює сам об'єкт, а лише посилання на той самий об'єкт. В кінці функції у вас об'єкт уже видалений через "s.Free;" і result містить посилання кудись у космос. У багатьох випадках програма іще не встигла повторно використати ту пам'ять, тому воно працюватиме, але інколи буде глючити.
Якщо виправити цю помилку, і додати перевірку на існування ресурсу, то має бути щось таке:
procedure DefinitionText(Text: String; AMemo: TCustomMemo);
var
s: TResourceStream;
begin
s := nil;
try
try
s := TResourceStream.Create(HInstance, 'T ' + Text, RT_RCData);
except
on e: EResNotFound do
begin
ShowMessage(Text + ' не підтримується');
Exit;
end;
end;
AMemo.Lines.LoadFromStream(s);
finally
s.Free;
end;
PlaySound(PChar('S ' + Text), 0, SND_RESOURCE or SND_ASYNC);
end;
procedure TForm2.Button1Click(Sender: TObject);
begin
DefinitionText(Edit1.Text, RichEdit1);
end;
1. Обробка помилок. Це окрема велика тема, тут не лише про виключні ситуації (try - except - finally).
Код функції TForm2.Button1Click (ви людські назви колись об'єктам даватимете?) взагалі не передбачає можливості помилки; загалом, це може бути правильним рішенням, виключні ситуації для цього й придумали. Але тоді виходить, що ви обробляєте виключну ситуацію "немає ресурсу" в DefinitionText, а потім даєте результат (який може бути неправильним!) у TForm2.Button1Click. У цьому випадку, гадаю, оптимальний варіант - пропустити виключну ситуацію, хай її стандартний обробник жує (він табличку показує).
2. Обробка того, що вводить користувач.
Ви дозволяєте користувачам вводити імена ресурсів. Не треба так робити. Я вже мовчу про регістр (великі-маленькі літери); але уявіть собі, що ви колись додасте тести в програму, і хтось дізнається імена назв ресурсів цих тестів. Ви даєте користувачу інтерфейс для сканування ресурсів вашої програми. Хоча б перевіряйте, що введено, і трохи перетворюйте (викидайте пробіли, робіть всі літери маленькими і т.д.)
3. finally. Схоже, ви скопіювали код деінде і не розбиралися, що там таке. finally означає "виконати в будь-якому випадку, була виключна ситуація чи ні" і потрібен, зокрема, щоб гарантовано знищити ресурс перед завершенням функції - тоді він виглядає десь так. Але ж ваша функція не має знищувати ресурс, навпаки, вона має його повернути.
Пане koala в функції DefinitionText потрібно було скласти умову якщо назва ресурсу не співпадає з вхідним текстом то вивести ресурс з текстом: Визначення не знайдено! От і все! А на рахунок людських назв об'єктів, це тестова програма. Не варто гаяти час на придумування назв об'єкттів. В самій функції немає ніяких назв об'єктів, туда передається тільки текст і не ваєживо з відки він чи з Edit1, Edit2 чи навіть з Memo1, RichEdit1 або Label1.
І до речі наскільки я тестував цю функцію, регістр тут не важливий.
Якщо виправити цю помилку, і додати перевірку на існування ресурсу, то має бути щось таке:
procedure DefinitionText(Text: String; AMemo: TCustomMemo); var s: TResourceStream; begin s := nil; try try s := TResourceStream.Create(HInstance, 'T ' + Text, RT_RCData); except on e: EResNotFound do begin ShowMessage(Text + ' не підтримується'); Exit; end; end; AMemo.Lines.LoadFromStream(s); finally s.Free; end; PlaySound(PChar('S ' + Text), 0, SND_RESOURCE or SND_ASYNC); end;
Пане Torbins а якщо у випадку незнайденого ресурсу результату функції присвоювати текст: (Визначення не знайдено!). Це можливо якось зробити? Можливо так я уникну помилки в роботі програми?
Function DefinitionText(Text: String): TResourceStream;
var
s: TResourceStream;
begin
s := Nil;
try
s := TResourceStream.Create(HInstance, 'T ' + Text, RT_RCData);
Result := s;
except
on e: EResNotFound do
begin
{Якщо ресурс не знайдено тут потрібно результату функції присвоїти
текст: (Визначення не знайдено!). Як це прописати кодом???}
// s := 'Визначення не знайдено!';
// Result := s;
{Так буде не правильно, тому що не сумісні типи String та Stream}
end;
end;
end;
P.S Поки пропустимо процедуру PlaySound.
Питання знято по функції Function DefinitionText(Text: String): TResourceStream;
Здається вже нічого не глючить. Ввів додатковий ресурс (T Визначення не знайдено) з текстом Визначення не знайдено! зараз коли ресурсу не знаходить результату функції присвоюється цей текст.
Function DefinitionText(Text: String): TResourceStream;
var
s: TResourceStream;
begin
s := Nil;
try
s := TResourceStream.Create(HInstance, 'T ' + Text, RT_RCData);
Result := s;
except
on e: EResNotFound do
begin
s := TResourceStream.Create(HInstance, 'T Визначення не знайдено', RT_RCData);
Result := s;
Exit;
end;
end;
end;
А процедура PlaySound взагалі не видає ніякої помилки коли немає відповідного ресурсу.
Пане Torbins а якщо у випадку незнайденого ресурсу результату функції присвоювати текст: (Визначення не знайдено!). Це можливо якось зробити? Можливо так я уникну помилки в роботі програми?
Function DefinitionText(Text: String): TResourceStream; var s: TResourceStream; begin s := Nil; try s := TResourceStream.Create(HInstance, 'T ' + Text, RT_RCData); Result := s; except on e: EResNotFound do begin {Якщо ресурс не знайдено тут потрібно результату функції присвоїти текст: (Визначення не знайдено!). Як це прописати кодом???} // s := 'Визначення не знайдено!'; // Result := s; {Так буде не правильно, тому що не сумісні типи String та Stream} end; end; end;
Якщо хочете повернути з функції рядок, то так і пишіть: "Function DefinitionText(Text: String): String". І, відповідно, потім
RichEdit1.Lines.Add(DefinitionText(s));
Питання знято по функції Function DefinitionText(Text: String): TResourceStream;
Здається вже нічого не глючить. Ввів додатковий ресурс (T Визначення не знайдено) з текстом Визначення не знайдено! зараз коли ресурсу не знаходить результату функції присвоюється цей текст.Function DefinitionText(Text: String): TResourceStream; var s: TResourceStream; begin s := Nil; try s := TResourceStream.Create(HInstance, 'T ' + Text, RT_RCData); Result := s; except on e: EResNotFound do begin s := TResourceStream.Create(HInstance, 'T Визначення не знайдено', RT_RCData); Result := s; Exit; end; end; end;
Покажіть, будь ласка, який у вас тепер код в TForm2.Button1Click.
Покажіть, будь ласка, який у вас тепер код в TForm2.Button1Click.
Там поки що нічого не змінилось:
procedure TForm2.Button1Click(Sender: TObject);
var
a: string;
begin
a := Edit1.Text;
RichEdit1.Lines.LoadFromStream(DefinitionText(a));
PlaySound(PChar('S ' + a), 0, SND_RESOURCE or SND_ASYNC);
end;
Я напевно таку саму умову можу використати і для функції PlaySound: try ... except on e: EResNotFound do ... end.