381

Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.

ProgramBandera
TDictionary - підходить лише для випадків, коли ви плануєте змінювати список впродовж роботи програми. Якщо протягом роботи список залишатиметься незмінним, то набагато краще обійтися константами:

type
  TSIPrefixes = (yocto(*йокто*), zepto(*зепто*), atto(*ато*), ...);
const
  SIPrefixText: array[TSIPrefixes] of string = ('йокто', 'зепто', 'ато', ...);
...
WriteLn(SIPrefixText[yocto]);
Подякували: ProgramBandera1

382

Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.

Torbins написав:

ProgramBandera
TDictionary - підходить лише для випадків, коли ви плануєте змінювати список впродовж роботи програми. Якщо протягом роботи список залишатиметься незмінним, то набагато краще обійтися константами:

type
  TSIPrefixes = (yocto(*йокто*), zepto(*зепто*), atto(*ато*), ...);
const
  SIPrefixText: array[TSIPrefixes] of string = ('йокто', 'зепто', 'ато', ...);
...
WriteLn(SIPrefixText[yocto]);

Ні список не буде мінятися під час виконання програми. Дякую пане Торбінс.

383

Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.

*FACEPALM*

384

Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.

Пане ProgramBandera, а звідки взагалі виникла така задача? У вас програма робить якісь обчислення. Обчислення, як нас (і я певен вас теж) вчили, треба робити в одній системі одиниць (зазвичай СІ). Всі ці префікси потрібні для запису чисел перед і після обчислень, всередині вони заважають. Тобто вам потрібні функції перетворення з префіксних одиниць у одиниці СІ і навпаки, і все? Чи я чогось не розумію?

Подякували: ProgramBandera1

385 Востаннє редагувалося ProgramBandera (16.11.2021 22:42:32)

Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.

Доброго вечора усім! Панове скажіть будь-ласка чи можу я з цієї бібліотеки DLL Physics_Resource цією процедурою DefinitionTextPlay витягнути динамічно в проекті текстові ресурси в RichEdit та звукові {$R PhysicsText.res} {$R PhysicsSound.res}.

library Physics_Resource; // 08.Листопада.2021
                          // 16.Листопада.2021

uses
  ShareMem,
  Winapi.Windows,
  System.SysUtils,
  Vcl.StdCtrls,
  Vcl.ComCtrls,
  Winapi.MMSystem,
  System.Classes;

{$R *.res}
{$R PhysicsText.res}
{$R PhysicsSound.res}

 {*****************************************************************************}
procedure DefinitionTextPlay(ResourceName: String; Play: Boolean;
                                                  Editor: TCustomMemo); StdCall;
var
 Text: TResourceStream;
 Buffer: TRichEdit;
begin
 Buffer := Nil;
 Text := Nil;
 try
  try
   Text := TResourceStream.Create(HInstance, 'T ' + ResourceName,
                                  RT_RCData); // Завантажуємо в змінну Text текстовий ресурс
  except
   on e: EResNotFound do               // Якщо ресурс не знайдено!
   begin
    Text := TResourceStream.Create(HInstance, 'T Визначення не знайдено',
                                   RT_RCData); // Завантажуємо в змінну Text текстовий ресурс
   end;
  end;
  Buffer := TRichEdit.Create(Editor);  // Створюємо динамічний компонент RichEdit ВЛАСНИК (Owner) Editor
  Buffer.Parent := Editor;             // Змінній Buffer присвоюємо властивість БАТЬКІВСЬКИЙ (Parent) Editor
  Buffer.Visible := True;
  Buffer.Lines.LoadFromStream(Text);   // Завантажуємо змінну Text в RichEdit
  Editor.Lines.Add(Buffer.Text);       // Додаємо текст в редакторі
  Editor.Lines.Add('');                // Додаємо порожній рядок в редакторі
 finally
  Buffer.Free;                         // звільняємо пам'ять змінної Buffer
  Text.Free;                           // звільняємо пам'ять змінної Text
 end;

 if Play = True then // Якщо Zvuk увімкнено і змінна Play має значення істина то...
                   // Програємо ресурс з назвою яку зберігаз змінна ResourceName
  PlaySound(PChar('S ' + ResourceName), 0, SND_RESOURCE or SND_ASYNC)
 else                         // Інакше якщо змінна Play має значення хиба то...
                              // Програємо ресурс

  if Play = False then
  PlaySound('S Визначення не знайдено', 0, SND_RESOURCE or SND_ASYNC);
end;
 {*****************************************************************************}

  Exports
    DefinitionTextPlay;

begin

end.

Якщо ні, то як тоді витягуються звукові файли з ресурсу {$R PhysicsSound.res} в DLL?

386

Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.

ProgramBandera
Якщо EXE і Dll скомпільовані в одній версії делфі з галочкою Use runtime packages, то можете без проблем.
Якщо ні, то ShareMem не допоможе. В цьому випадку доведеться думати, як передати вміст TResourceStream.
Альтернативний варіант взагалі не запускати код із Dll. В EXE треба буде зберегти значення, яке вам повертає LoadLibrary. І потім це значення використати замість HInstance в конструкторі TResourceStream. Також його можна буде підставити другим параметром в PlaySound.

Подякували: ProgramBandera, leofun012

387 Востаннє редагувалося ProgramBandera (17.11.2021 23:50:11)

Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.

Torbins написав:

ProgramBandera
В EXE треба буде зберегти значення, яке вам повертає LoadLibrary. І потім це значення використати замість HInstance в конструкторі TResourceStream. Також його можна буде підставити другим параметром в PlaySound.

Пане Torbins Я щось пробую кодувати та звук всерівно не іде. Можливо ви щось підкажите.
Ось код бібліотеки без процедури.

library Physics_Resource; // 08.Листопада.2021
                          // 16.Листопада.2021

uses
  ShareMem,
  Winapi.Windows,
  System.SysUtils,
  Vcl.StdCtrls,
  Vcl.ComCtrls,
  Winapi.MMSystem,
  System.Classes;

{$R *.res}
{$R PhysicsText.res}
{$R PhysicsSound.res}

begin

end.

А ось код яким я пробую витягнути поки що звук в програму, без тексту, та нічого не виходить на жаль!

procedure TForm1.Button2Click(Sender: TObject);
var
  DLLHandle: integer;
  hRes: THandle;
  pRes: Pointer;
begin
  DLLHandle := LoadLibrary('Physics_Resource.dll');
  hRes := LoadResource(DLLHandle, FindResource(DLLHandle, 'S_ПОЛЕ', RT_RCDATA));
  try
    pRes := Nil;
    pRes := LockResource(hRes);
    if pRes = nil then
     begin
      if pRes = Nil then
        ShowMessage('pRes = Nil');
        ShowMessage('Ресурс не найдено!');
      Exit;
     end;
    PlaySound(pRes, 0, SND_RESOURCE or SND_ASYNC);
  finally
    FreeResource(hRes);
    FreeLibrary(DLLHandle);
  end;
end;

Пише що pRes = Nil Ресурс не знайдено!

388

Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.

Спробуйте тут перевіряти результати усіх викликів, на кшталт

DLLHandle := LoadLibrary('Physics_Resource.dll');
if DLLHandle = nil then begin
    ShowMessage(Format('LoadLibrary(%s) повернув помилку %d', ['Physics_Resource.dll', GetLastError()]));
    Exit;
end;
Resource := FindResource(DLLHandle, 'S_ПОЛЕ', RT_RCDATA);
if Resource = nil then begin
    ShowMessage(Format('FindResource(%p, %s, %s) повернув помилку %d', [DLLHandle, 'S_ПОЛЕ', 'RT_RCDATA', GetLastError()]));
    Exit;
end;
hRes := LoadResource(DLLHandle, Resource);
if hRes = nil then begin

і т.д.

Подякували: ProgramBandera, leofun012

389

Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.

koala написав:

Спробуйте тут перевіряти результати усіх викликів, на кшталт

Дякую пане koala!!! Спробую вже завтра, согодні пізно і від коду болить голова. Приємно здивований, ви цього разу спробували допомогти без того щоб погнобити мене. І ще раз дякую!

390

Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.

У мене отакий приклад працює нормально:

procedure TForm1.Button2Click(Sender: TObject);
var
  lib: HMODULE;
  rs: TResourceStream;
  ss: TStringStream;
begin
  lib := LoadLibrary('ResLib.dll');
  PlaySound('mess', lib, SND_RESOURCE or SND_SYNC);
  rs := nil;
  ss := nil;
  try
    rs := TResourceStream.Create(lib, 'log', RT_RCDATA);
    ss := TStringStream.Create;
    ss.CopyFrom(rs);
    Memo1.Text := ss.DataString;
  finally
    rs.Free;
    ss.Free;
  end;
  FreeLibrary(lib);
end;

Хоча якщо в Dll зовсім не буде коду, тоді простіше замінити її на zip-архів з усіма потрібними файлами.

Подякували: ProgramBandera1

391

Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.

Взагалі я підозрюю, що файл кодований не юнікодом, а відповідно, 'S_ПОЛЕ' містить зовсім не той набір байтів, що в DLL, але то я тільки здогадуватися можу.

392 Востаннє редагувалося ProgramBandera (21.11.2021 15:54:40)

Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.

Torbins написав:

У мене отакий приклад працює нормально:

procedure TForm1.Button2Click(Sender: TObject);
var
  lib: HMODULE;
  rs: TResourceStream;
  ss: TStringStream;
begin
  lib := LoadLibrary('ResLib.dll');
  PlaySound('mess', lib, SND_RESOURCE or SND_SYNC);
  rs := nil;
  ss := nil;
  try
    rs := TResourceStream.Create(lib, 'log', RT_RCDATA);
    ss := TStringStream.Create;
    ss.CopyFrom(rs);
    Memo1.Text := ss.DataString;
  finally
    rs.Free;
    ss.Free;
  end;
  FreeLibrary(lib);
end;

Пане Torbins в методі ss.CopyFrom(rs); пише що має бути другий параметр.

CopyFrom – метод призначений для копіювання з іншого потоку. Він має два параметри: покажчик на потік, з якого треба копіювати, і число, що показує розмір даних, що підлягають копіюванню;

То що там другим параметром прописати одиницю? Тобто я ж не знаю розмір кожного ресурсу. Щось в цьому рядку я нічого не розумію.

Але хоч звук пішов! Це вже дуже длбре!

procedure TForm1.Button2Click(Sender: TObject);
var
  lib: HMODULE;
  rs: TResourceStream;
  ss: TStringStream;
begin
  lib := LoadLibrary('Physics_Resource.dll');
  PlaySound('S АЛЬТИМЕТРИ', lib, SND_RESOURCE or SND_SYNC);
  rs := nil;
  ss := nil;
  try
    rs := TResourceStream.Create(lib, 'T АЛЬТИМЕТРИ', RT_RCData);
    ss := TStringStream.Create;
    ss.CopyFrom(rs,1);
    RichEdit1.Text := ss.DataString;
  finally
    rs.Free;
    ss.Free;
  end;
  FreeLibrary(lib);
end;

І ще - програма після програвання звуку аварійно завершується!
Можливо щось в самій DLL?

library Physics_Resource; // 08.Листопада.2021
                          // 21.Листопада.2021

uses
  ShareMem,
  Winapi.Windows,
  System.SysUtils,
  Vcl.StdCtrls,
  Vcl.ComCtrls,
  Winapi.MMSystem,
  System.Classes;

{$R *.res}
{$R PhysicsText1.res}
{$R PhysicsSound1.res}

begin

end.

393

Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.

https://docwiki.embarcadero.com/Librari … m.CopyFrom
Якщо другий параметр CopyFrom, то буде скопійовано весь потік. Хоча має працювати і без нього.

Подякували: ProgramBandera1

394

Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.

koala написав:

https://docwiki.embarcadero.com/Librari … m.CopyFrom
Якщо другий параметр CopyFrom, то буде скопійовано весь потік. Хоча має працювати і без нього.

Не компілюється! Пише недостатньо фактичних параметрів.

395

Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.

ProgramBandera написав:

Пане Torbins в методі ss.CopyFrom(rs); пише що має бути другий параметр.

CopyFrom – метод призначений для копіювання з іншого потоку. Він має два параметри: покажчик на потік, з якого треба копіювати, і число, що показує розмір даних, що підлягають копіюванню;

То що там другим параметром прописати одиницю? Тобто я ж не знаю розмір кожного ресурсу. Щось в цьому рядку я нічого не розумію.

Ви завжди можете подивитись розмір даних: rs.Size. Тільки перед копіюванням варто посунути поточну позицію rs.Position := 0;

ProgramBandera написав:
procedure TForm1.Button2Click(Sender: TObject);
var
  lib: HMODULE;
  rs: TResourceStream;
  ss: TStringStream;
begin
  lib := LoadLibrary('Physics_Resource.dll');
  PlaySound('S АЛЬТИМЕТРИ', lib, SND_RESOURCE or SND_SYNC);
  rs := nil;
  ss := nil;
  try
    rs := TResourceStream.Create(lib, 'T АЛЬТИМЕТРИ', RT_RCData);
    ss := TStringStream.Create;
    ss.CopyFrom(rs,1);
    RichEdit1.Text := ss.DataString;
  finally
    rs.Free;
    ss.Free;
  end;
  FreeLibrary(lib);
end;

І ще - програма після програвання звуку аварійно завершується!
Можливо щось в самій DLL?

Можливо проблема просто в тому, що у вас рядок з одного байту, а юнікодні рядки завжди мають парну кількість байт.

ProgramBandera написав:
koala написав:

https://docwiki.embarcadero.com/Librari … m.CopyFrom
Якщо другий параметр CopyFrom, то буде скопійовано весь потік. Хоча має працювати і без нього.

Не компілюється! Пише недостатньо фактичних параметрів.

У мене все нормально. Яка у вас версія Делфі?

396 Востаннє редагувалося ProgramBandera (21.11.2021 19:51:11)

Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.

Torbins написав:

У мене все нормально. Яка у вас версія Делфі?

У мене версія Delphi Community Edition 10.3.
Та поки зачекайте з рядками, тут вилітає програма після програвання звуку чомусь.
Тобто до копіювання текстового ресурсу (Перевірив на Button1)

procedure TForm1.Button1Click(Sender: TObject);
var
  lib: HMODULE;
begin
  try
  lib := LoadLibrary('Physics_Resource.dll');
  PlaySound(Pchar('S ' + Edit1.Text), lib, SND_RESOURCE or SND_SYNC);
  finally
    FreeLibrary(lib);
  end;
end;

https://replace.org.ua/uploads/images/6671/bc7f7cfb7b40ef8b637434d5d27c61ff.bmp

397

Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.

Пане ProgramBandera, а ви знайомі з технікою зневадження (дебаггінгу)? Якщо ні, то саме час познайомитися.

Подякували: leofun011

398

Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.

koala написав:

Пане ProgramBandera, а ви знайомі з технікою зневадження (дебаггінгу)? Якщо ні, то саме час познайомитися.

Ні пане koala! Якщо маєте час то киньте посилання де про це можна почитати.

399

Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.

Напевно причина у великому файлі ресурсу! Бо коли в ресурсі залишаю пару звукових файлів то програма не вилітає.

400

Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.

ProgramBandera написав:

Напевно причина у великому файлі ресурсу! Бо коли в ресурсі залишаю пару звукових файлів то програма не вилітає.

Ото ви індус!

Подякували: leofun011