DLL-ből képek, hangok elérése

DLL-ből képek, hangok elérése
2005-03-02T13:12:56+01:00
2005-03-04T22:51:09+01:00
2022-10-24T04:00:50+02:00
SonicY3K
Sziasztok!

Delphis problémám a következő lenne:
Egy programot készítek, amelyben van egy csomó kép (gomb, háttérkép stb). Szerkesztési időben töltöttem be a képeket TImagebe. Így a program lefordítási ideje igen nagy lett. Jobban járok, ha futási időben olvasom be a képeket. Igenám, de ez 20-30 képet jelentene és nem akarom külön-külön tárolni azokat. Ezért egy DLL-be pakoltam őket. Így műxik is rendesen, de:
Mivel a program hangokat is tartalmaz, ezért arra gondoltam, miért ne lehetne az is benne ugyanabban a DLL-ben?
Nah itt le is ragadtam.
Eddig vegyesen használtam wav-ot és mp3-at. Az FMod tökéletesen megfelelt a célnak, de a DLL-ből sehogy nem tudom kiolvasni. Se az mp3-at, se a wavot.
Továbbá van eredménytáblám is (a 30 legjobb bekerül az eredménylistába).
Ez is külön állományban van.

Nah ennyi bevezetés után a kérdés:
Hogyan tudok a DLL-ben lévő BMP, JPEG, MP3, WAV és eredménytáblámhoz (tömb) hozzáférni?

Ugye a képeket/hangokat csak olvasnom kellene, de az eredményt olvasni és írni is egyaránt.

Vagyis ameddig idáig eljutottam: bmp-t tudok kiolvasni a DLL-ből :o(

A segítségeket előre is köszönöm.

.:: Sonic ::.

Ui.: már találtam egy pár témát itt a prog.hu-n, de egyik sem hozta meg a megoldást.

Amit használok: Delphi7, FMOD
Mutasd a teljes hozzászólást!
Bocsi, egyszerűsítettem a MainForm-ban a lejátszást:

unit MainFrm; {$WARN SYMBOL_PLATFORM OFF} interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, FModUtils, fmod, fmodtypes; type TMainForm = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; Button4: TButton; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Edit4: TEdit; Edit5: TEdit; Edit6: TEdit; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } FFileName: string; FResourceStream: TResourceStream; FModStream: Pointer; FModule: HMODULE; procedure LoadModule; procedure PlaySound(const ResName, ResType: string); procedure ReleaseModStream; procedure ReleaseModule; public { Public declarations } end; var MainForm: TMainForm; implementation {$R *.dfm} type TEredmeny = record Nick : String[10]; Pont : Integer; Datum : TDate; LepesDB : Integer; JatekIdo : Integer; CsereDB : Integer; end; TEredmenyek = Array[1..30] Of TEredmeny; procedure TMainForm.Button1Click(Sender: TObject); begin PlaySound('CC', 'wav'); end; procedure TMainForm.Button2Click(Sender: TObject); begin PlaySound('DD', 'mp3'); end; procedure TMainForm.Button3Click(Sender: TObject); var E: TEredmenyek; FHandle: THandle; I: Integer; begin ReleaseModStream; // cannot update while playing ReleaseModule; FillChar(E, SizeOf(E), 0); for I := Low(E) to High(E) do try with E[I] do begin Nick := Copy(Edit1.Text, 1, 8) + IntToStr(I); Pont := StrToInt(Edit2.Text) * I; Datum := Now; // nem t'om milyen exception dobna, ugrom LepesDB := StrToInt(Edit4.Text) * I; JatekIdo := StrToInt(Edit5.Text) * I; CsereDB := StrToInt(Edit6.Text) * I; end; except on EConvertError do; // most ezzel nem foglalkozom end; FHandle := BeginUpdateResource(PChar(FFileName), False); Win32Check(FHandle <> 0); try Win32Check(UpdateResource(FHandle, 'TXT', 'EE', 0, @E, SizeOf(E))); Win32Check(EndUpdateResource(FHandle, False)); except on EOSError do raise else begin Win32Check(EndUpdateResource(FHandle, True)); raise; end; end; end; procedure TMainForm.Button4Click(Sender: TObject); var E: TEredmenyek; begin LoadModule; with TResourceStream.Create(FModule, 'EE', 'TXT') do try ReadBuffer(E, SizeOf(E)); finally Free; end; with E[1] do begin Edit1.Text := Nick; Edit2.Text := IntToStr(Pont); Edit3.Text := DateToStr(Datum); Edit4.Text := IntToStr(LepesDB); Edit5.Text := IntToStr(JatekIdo); Edit6.Text := IntToStr(CsereDB); end; end; procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction); begin ReleaseModStream; ReleaseModule; end; procedure TMainForm.FormCreate(Sender: TObject); begin FFileName := Format('%sDllStg.dll', [ExtractFilePath(ParamStr(0))]); Edit1.Clear; Edit2.Clear; Edit3.Clear; Edit4.Clear; Edit5.Clear; Edit6.Clear; end; procedure TMainForm.LoadModule; begin if FModule = 0 then begin FModule := LoadLibrary(PChar(FFileName)); Win32Check(FModule <> 0); end; end; procedure TMainForm.PlaySound(const ResName, ResType: string); var Channel: Integer; begin ReleaseModStream; LoadModule; FResourceStream := TResourceStream.Create(FModule, ResName, PChar(ResType)); FModStream := FSOUND_Stream_Open(FResourceStream.Memory, FSOUND_LOADMEMORY or FSOUND_LOOP_NORMAL or FSOUND_NORMAL, 0, FResourceStream.Size); FModCheck(FModStream <> nil); Channel := FSOUND_Stream_Play(FSOUND_FREE, FModStream); FModCheck(Channel > 0); end; procedure TMainForm.ReleaseModStream; begin if FModStream <> nil then FSOUND_Stream_Close(FModStream); FreeAndNil(FResourceStream); end; procedure TMainForm.ReleaseModule; begin if FModule <> 0 then begin Win32Check(FreeLibrary(FModule)); FModule := 0; end; end; end.
Mutasd a teljes hozzászólást!

  • TResourceStream nem elég (ld. Help)?

    Írni a BeginUpdateResource, EndUpdateResource függvényekkel lehet: Adding, Deleting, and Replacing Resources
    Mutasd a teljes hozzászólást!
  • Megnéztem. Egy kicsit bonyolultnak tűnik számomra.
    BMP képet ilyen egyszerűen be tudok tölteni:

    Image1.Picture.Bitmap.Handle:= LoadBitmap(lib, 'képnév a dll-ben');

    JPG-t már nem tudok betölteni. És a többi (wav, mp3) miért nem ilyen egyszerű?

    .:: Sonic ::.
    Mutasd a teljes hozzászólást!
  • És a többi (wav, mp3) miért nem ilyen egyszerű?


    wav-ot le lehet játszani resource-ból a PlaySound függvénnyel (erre volt már topic), mp3-at nem tudom, ki lehet próbálni. Csak ezekről az adatformátumokról lenne szó, amit leírtál?

    A jpeg-ek elvileg spec. bitmap-ként vannak tárolva, de ezeket nem t'om, hogy a LoadBitmap-pel be lehet-e tölteni. Mást viszont nem ismerek, megoldhatod kézzel. Nincs mindenre egyszerű megoldás. További doksik a témában:
    1. Bitmaps
    2. JPEG and PNG Extensions for Specific Bitmap Functions and Structures

    Írásra nem ismerek speciális függvényt, de még ha lenne is, a saját "eredménytábládra" mindenképp ezeket kellene használnod (UpdateResource és társai). Az eredménytáblád olvasására pedig szerintem nincs jobb megoldás a TResourceStream-nél.
    Mutasd a teljes hozzászólást!
  • Igen, jelenleg ezt a négy formátumot kéne ismernie: WAV, MP3, BMP, JPEG. Ha az eredménytábla ennyire bonyolult, akkor inkább azt külön állományba teszem (ha valóban nincs rá egyszerű megoldás).
    Azt tudom, hogy a wav-ot a PlaySound-dal tudom lejátszani, de az ugye nem az FMOD része. Ezeket nem akarom keverni. Mert sokat nem érek a dll-lel, ha csak bmp-ket tudok kiolvasni belőle. Akkor még mindig ott van egy rakás jpeg, mp3, wav külön-külön.
    Mutasd a teljes hozzászólást!
  • Figyu, nem értem, mi a para oka: custom resource-ként bármit elmenthetsz, akár jpeg-et is, össz 3 függvényhívásról van szó:

    BeginUpdateResource(); try UpdateResource(<myjpegdata>); finally EndUpdateResource() end;

    Olvasás:

    begin Stream := TResourceStream.Create(<myjpegdata>); try MyObject.LoadFromStream(Stream); // vagy Stream.ReadBuffer(); finally Stream.Free; end; end;

    Ha sietsz, akkor felejtsd el ezt az egészet, de ha egy kis időt tudsz szánni rá, érdemes megtanulni. Az egy dolog, hogy most nem tudok neked idelökni egy konkrét példát, mert nincs kéznél, írni meg nincs időm, de egyébként egyáltalán nem olyan nagy durranás az egész. Egyszer el kell olvasni, és kész.
    Mutasd a teljes hozzászólást!
  • Nah, már fél sikerem van (vagyis egyharmad). Már tudok képet (bmp, jpeg) beolvasni dll-ből.
    Már csak mp3-at és wav-ot kéne, és a tömböt.

    Tudom, hogy már volt példa wav-ra, de nekem az FMOD-hoz kéne. Sehogy nem sikerül. Próbáltam FSOUND_Stream_Create-tel, de az csak állományból tud beolvasni. És már ötletem sincs.
    Mutasd a teljes hozzászólást!
  • Nah, már fél sikerem van (vagyis egyharmad). Már tudok képet (bmp, jpeg) beolvasni dll-ből.


    Na, látod.

    Már csak mp3-at és wav-ot kéne, és a tömböt.


    A tömbbel nem tudom, mi lehet a problémád, az TResourceStream-mel és az UpdateResource-szal abszolút kezelhető.

    Tudom, hogy durva, de csinálhatsz temp file-t az mp3-nak és a wav-nak. Nekem sajnos, halvány fogalmam nincs, mi az az FMOD, de ha egy kicsit súgsz, lehet, hogy megpróbálok utánanézni a dolognak.
    Mutasd a teljes hozzászólást!
  • Az fmod-dal le lehet könnyedén játszani wav, mp3 és még egy csomó zeneformátumot.
    fmod

    Idézet az oldalból:
    FMOD supports 3d sound, midi, mods, mp3, ogg vorbis, wma, aiff, recording, obstruction/occlusion, cd playback (analog or digital), cd ripping, mmx, internet streaming, dsp effects, spectrum analysis, user created samples and streams, synchronization support, ASIO, EAX 2&3, C/C++/VB/Delphi and more.
    FMOD is not only the best cross platform audio engine for your needs, but it is the best audio engine available on each platform.


    Nagyon király, nekem bejött.
    Azért írtam, hogy még hátravan a tömb, mert azzal még nem tudtam foglalkozni. De ma tovább folytatpm a kutakodást/próbálkozást.
    Sokat segített, amit eddig írtál.
    Mutasd a teljes hozzászólást!
  • csinálhatsz temp file-t az mp3-nak és a wav-nak

    Na, pont ezt akarom elkerülni. Nem akarom kétszer letárolni az mp3-akat.
    Eddig nem sokat haladtam előre, sőt igazából semmit.
    Nem tudok kódot írni, hogy hol akadtam el, mert minden próbálkozásom befuccsolt. Amit találtam az fmod.pas-ban:

    { Note: Use FSOUND_LOADMEMORY flag with FSOUND_Stream_Open to stream from memory. } function FSOUND_Stream_Open(const name_or_data: PChar; Mode: Cardinal; Offset: Integer; Length: Integer): PFSoundStream; {$IFDEF LINUX} cdecl {$ELSE} stdcall {$ENDIF};

    Akárhogy próbálkozok, mindig állományból akarja beolvasni a zenét. Vagyis ezek szerint, ha a memóriában van, akkor FSOUND_LOADMEMORY-t kéne használnom. De ezt már beírtam vagy 3 helyre, de semmi.

    A tömbös megoldás is egyelőre zsákutcába vezetett.
    Mutasd a teljes hozzászólást!
  • A tömbös megoldás is egyelőre zsákutcába vezetett


    Konkrétabban? Milyen tömböt használsz: statikus, dinamikus? Milyen típusúak az elemek?

    Részletesen (próbálgatás, kódolás) leghamarabb este tudok a témával foglalkozni. Addig persze begyűjteném tőled a szükséges info-kat.
    Mutasd a teljes hozzászólást!
  • TEredmeny = record Nick : String[10]; Pont : Integer; Datum : TDate; LepesDB : Integer; JatekIdo : Integer; CsereDB : Integer; end; Eredmenyek: Array[1..30] Of TEredmeny;

    Vagyis statikus tömbről van szó. És ezt a dll-ben akarom tárolni a képek és a hangok mellett.

    Már semmi ötletem nincs.
    Mutasd a teljes hozzászólást!
  • Az ötletem idáig az volt, hogy így csinálom:

    adatok.rc tartalma:
    AA BITMAP "kep1.bmp" BB JPEG "kep2.jpg" CC WAV "hang1.wav" DD MP3 "hang2.mp3" EE TXT "score.txt"

    A score.txt jelenleg akkora méretű, amekkora a tömb mérete, és space-ekkel van feltöltve. Ebből készítek dll-t:

    adat.dpr tartalma:
    library adat; {$R adatok.res} end.

    Persze jobb lenne, ha itt, az adat.dpr-ben hoznám létre a tömböt, mert akkor azt egyből befordítja a dll-be. Ez a két megoldás jutott eszembe eddig.
    Nah, ekkor kész lett az adat.dll.
    Ebből ki tudom olvasni a jpg-t és a bmp-t.
    Az fmod-nak nem tudom átadni a wav-ot sem és az mp3-at sem, a tömböt már sikerült előcsalogatni, de nem tudom a változásokat módosítani.
    Úgy műxik, ha a dll-ből kimentem egy állományba a wav-ot és így adom át az fmod-nak, de ezt nem akarom. A memóriában akarom átadni neki.

    Eddig jutottam idáig.
    Mutasd a teljes hozzászólást!
  • 1. A tömbbel nem volt semmi gondom
    2. A doksit el kell olvasni, és nem árt megnézni a példákat sem (FMOD).

    Íme a részletes példa (lehet rajta fenni bőven), nekem müxik:

    1. adatok.rc (a txt-t kihagytam belőle, futásidőben megírom, ezt a DllStg.dll-be raktam)

    AA BITMAP "kep1.bmp" BB JPEG "kep2.jpg" CC WAV "hang1.wav" DD MP3 "hang2.mp3" // EE TXT "score.txt"

    2. FModUtils.pas

    unit FModUtils; interface uses Windows, SysUtils, fmod, fmoderrors, fmodtypes; type EFModError = class(Exception); procedure FModCheck(const Succeeded: Boolean); implementation procedure FModCheck(const Succeeded: Boolean); begin if not Succeeded then raise EFModError.Create(FMOD_ErrorString(FSOUND_GetError)); end; procedure InitFMod; begin try FModCheck(FSOUND_Init(44100, 16, 0)); except FSOUND_Close; MessageBox(0, 'FMod initialization failed.', 'Error', MB_ICONERROR); Halt($FFFF); end; end; procedure DoneFMod; begin FSOUND_Close; end; initialization InitFMod; finalization DoneFMod; end.

    3. MainFrm.pas

    unit MainFrm; {$WARN SYMBOL_PLATFORM OFF} interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, FModUtils, fmod, fmodtypes; type TMainForm = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; Button4: TButton; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Edit4: TEdit; Edit5: TEdit; Edit6: TEdit; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } FFileName: string; FModStream: Pointer; FModule: HMODULE; procedure LoadModule; procedure PlaySound(const ResName, ResType: string); procedure ReleaseModStream; procedure ReleaseModule; public { Public declarations } end; var MainForm: TMainForm; implementation {$R *.dfm} type TEredmeny = record Nick : String[10]; Pont : Integer; Datum : TDate; LepesDB : Integer; JatekIdo : Integer; CsereDB : Integer; end; TEredmenyek = Array[1..30] Of TEredmeny; procedure TMainForm.Button1Click(Sender: TObject); begin PlaySound('CC', 'wav'); end; procedure TMainForm.Button2Click(Sender: TObject); begin PlaySound('DD', 'mp3'); end; procedure TMainForm.Button3Click(Sender: TObject); var E: TEredmenyek; FHandle: THandle; I: Integer; begin ReleaseModStream; // cannot update while playing ReleaseModule; FillChar(E, SizeOf(E), 0); for I := Low(E) to High(E) do try with E[I] do begin Nick := Copy(Edit1.Text, 1, 8) + IntToStr(I); Pont := StrToInt(Edit2.Text) * I; Datum := Now; // nem t'om milyen exception dobna, ugrom LepesDB := StrToInt(Edit4.Text) * I; JatekIdo := StrToInt(Edit5.Text) * I; CsereDB := StrToInt(Edit6.Text) * I; end; except on EConvertError do; // most ezzel nem foglalkozom end; FHandle := BeginUpdateResource(PChar(FFileName), False); Win32Check(FHandle <> 0); try Win32Check(UpdateResource(FHandle, 'TXT', 'EE', 0, @E, SizeOf(E))); Win32Check(EndUpdateResource(FHandle, False)); except on EOSError do raise else begin Win32Check(EndUpdateResource(FHandle, True)); raise; end; end; end; procedure TMainForm.Button4Click(Sender: TObject); var E: TEredmenyek; begin LoadModule; with TResourceStream.Create(FModule, 'EE', 'TXT') do try ReadBuffer(E, SizeOf(E)); finally Free; end; with E[1] do begin Edit1.Text := Nick; Edit2.Text := IntToStr(Pont); Edit3.Text := DateToStr(Datum); Edit4.Text := IntToStr(LepesDB); Edit5.Text := IntToStr(JatekIdo); Edit6.Text := IntToStr(CsereDB); end; end; procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction); begin ReleaseModStream; ReleaseModule; end; procedure TMainForm.FormCreate(Sender: TObject); begin FFileName := Format('%sDllStg.dll', [ExtractFilePath(ParamStr(0))]); Edit1.Clear; Edit2.Clear; Edit3.Clear; Edit4.Clear; Edit5.Clear; Edit6.Clear; end; procedure TMainForm.LoadModule; begin if FModule = 0 then begin FModule := LoadLibrary(PChar(FFileName)); Win32Check(FModule <> 0); end; end; procedure TMainForm.PlaySound(const ResName, ResType: string); var Channel: Integer; Data: Pointer; ResInfo: HRSRC; Res: HGLOBAL; Size: Cardinal; begin ReleaseModStream; LoadModule; { WinAPI } ResInfo := FindResource(FModule, PChar(ResName), PChar(ResType)); Win32Check(ResInfo <> 0); Res := LoadResource(FModule, ResInfo); Win32Check(Res <> 0); Data := LockResource(Res); if Data = nil then raise Exception.CreateFmt('Cannot lock resource %s', [ResName]) else begin Size := SizeofResource(FModule, ResInfo); Win32Check(Size <> 0); { FMOD API } FModStream := FSOUND_Stream_Open( Data, FSOUND_LOADMEMORY or FSOUND_LOOP_NORMAL or FSOUND_NORMAL, 0, Size); FModCheck(FModStream <> nil); Channel := FSOUND_Stream_Play(FSOUND_FREE, FModStream); FModCheck(Channel > 0); end; end; procedure TMainForm.ReleaseModStream; begin if FModStream <> nil then FSOUND_Stream_Close(FModStream); end; procedure TMainForm.ReleaseModule; begin if FModule <> 0 then begin Win32Check(FreeLibrary(FModule)); FModule := 0; end; end; end.
    Mutasd a teljes hozzászólást!
  • Bocsi, egyszerűsítettem a MainForm-ban a lejátszást:

    unit MainFrm; {$WARN SYMBOL_PLATFORM OFF} interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, FModUtils, fmod, fmodtypes; type TMainForm = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; Button4: TButton; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Edit4: TEdit; Edit5: TEdit; Edit6: TEdit; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } FFileName: string; FResourceStream: TResourceStream; FModStream: Pointer; FModule: HMODULE; procedure LoadModule; procedure PlaySound(const ResName, ResType: string); procedure ReleaseModStream; procedure ReleaseModule; public { Public declarations } end; var MainForm: TMainForm; implementation {$R *.dfm} type TEredmeny = record Nick : String[10]; Pont : Integer; Datum : TDate; LepesDB : Integer; JatekIdo : Integer; CsereDB : Integer; end; TEredmenyek = Array[1..30] Of TEredmeny; procedure TMainForm.Button1Click(Sender: TObject); begin PlaySound('CC', 'wav'); end; procedure TMainForm.Button2Click(Sender: TObject); begin PlaySound('DD', 'mp3'); end; procedure TMainForm.Button3Click(Sender: TObject); var E: TEredmenyek; FHandle: THandle; I: Integer; begin ReleaseModStream; // cannot update while playing ReleaseModule; FillChar(E, SizeOf(E), 0); for I := Low(E) to High(E) do try with E[I] do begin Nick := Copy(Edit1.Text, 1, 8) + IntToStr(I); Pont := StrToInt(Edit2.Text) * I; Datum := Now; // nem t'om milyen exception dobna, ugrom LepesDB := StrToInt(Edit4.Text) * I; JatekIdo := StrToInt(Edit5.Text) * I; CsereDB := StrToInt(Edit6.Text) * I; end; except on EConvertError do; // most ezzel nem foglalkozom end; FHandle := BeginUpdateResource(PChar(FFileName), False); Win32Check(FHandle <> 0); try Win32Check(UpdateResource(FHandle, 'TXT', 'EE', 0, @E, SizeOf(E))); Win32Check(EndUpdateResource(FHandle, False)); except on EOSError do raise else begin Win32Check(EndUpdateResource(FHandle, True)); raise; end; end; end; procedure TMainForm.Button4Click(Sender: TObject); var E: TEredmenyek; begin LoadModule; with TResourceStream.Create(FModule, 'EE', 'TXT') do try ReadBuffer(E, SizeOf(E)); finally Free; end; with E[1] do begin Edit1.Text := Nick; Edit2.Text := IntToStr(Pont); Edit3.Text := DateToStr(Datum); Edit4.Text := IntToStr(LepesDB); Edit5.Text := IntToStr(JatekIdo); Edit6.Text := IntToStr(CsereDB); end; end; procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction); begin ReleaseModStream; ReleaseModule; end; procedure TMainForm.FormCreate(Sender: TObject); begin FFileName := Format('%sDllStg.dll', [ExtractFilePath(ParamStr(0))]); Edit1.Clear; Edit2.Clear; Edit3.Clear; Edit4.Clear; Edit5.Clear; Edit6.Clear; end; procedure TMainForm.LoadModule; begin if FModule = 0 then begin FModule := LoadLibrary(PChar(FFileName)); Win32Check(FModule <> 0); end; end; procedure TMainForm.PlaySound(const ResName, ResType: string); var Channel: Integer; begin ReleaseModStream; LoadModule; FResourceStream := TResourceStream.Create(FModule, ResName, PChar(ResType)); FModStream := FSOUND_Stream_Open(FResourceStream.Memory, FSOUND_LOADMEMORY or FSOUND_LOOP_NORMAL or FSOUND_NORMAL, 0, FResourceStream.Size); FModCheck(FModStream <> nil); Channel := FSOUND_Stream_Play(FSOUND_FREE, FModStream); FModCheck(Channel > 0); end; procedure TMainForm.ReleaseModStream; begin if FModStream <> nil then FSOUND_Stream_Close(FModStream); FreeAndNil(FResourceStream); end; procedure TMainForm.ReleaseModule; begin if FModule <> 0 then begin Win32Check(FreeLibrary(FModule)); FModule := 0; end; end; end.
    Mutasd a teljes hozzászólást!
  • Nagyon köszönöm.

    Közben én is dolgoztam rajta, csak nem voltam netközelben.
    Elolvastam a doksikat és a példákat is megnéztem (fmod). És most, hogy olvastam a kódodat, rájöttem, hogy mit rontottam el .
    A Te kódod:

    FModStream:= FSOUND_Stream_Open(FResourceStream.Memory, FSOUND_LOADMEMORY or FSOUND_LOOP_NORMAL or FSOUND_NORMAL, 0, FResourceStream.Size);

    Az én kódom pedig:
    FModStream:= FSOUND_Stream_Open(FResourceStream.Memory, FSOUND_LOADMEMORY or FSOUND_NORMAL, 0, 0);

    Vagyis nem olvastam be semmit. Hibát nem írt ki, de nem is szólalt meg.

    Az UpdateResource területén viszont sehova sem jutottam.

    Akkor tehát futás időben bármit bele tudok írni a dll-be.

    Még kicsit tesztelem, és utána küldöm a pontot. Bár ez 50 pontot ér számomra, hanem a többszörösét .

    Mégegyszer köszönöm a sok időt és a példaprogit is.

    .:: Sonic ::.
    Mutasd a teljes hozzászólást!
  • Utolsó kérdésem a témakörben, csak, hogy teljes legyen a kép: ki is lehet törölni a tömböt a dll-ből (nem úgy gondolom, hogy lenullázom a tartalmát)? Próbáltam, hogy lecseréltem az
    UpdateResource(FHandle, 'TXT', 'EE', 0, @E, SizeOf(E));

    kódot

    UpdateResource(FHandle, 'TXT', 'EE', 0, nil, 0);
    kódra. Erre EOSError Code: 87 hibakódot kaptam.

    Majd reggel tovább próbálkozom.
    Mutasd a teljes hozzászólást!
  • A doksi szerint lehet resource-ot törölni a lpData nil-re állításával, úgy, ahogy te csináltad. Majd este, vagy a hétvégén megnézem.
    Mutasd a teljes hozzászólást!
  • Nagyon megköszönném, mert már
    Mutasd a teljes hozzászólást!
  • Rossz (?) hírem van: hozzáadtam a fent idézett példához egy újabb Button-t, az eventhandler gond nélkül törölte a resource-ot. Utána sure for sure kipróbáltam a tömb olvasását, és rendesen dobta is, hogy EResNotFound: resource 'EE' not found.

    procedure TMainForm.Button5Click(Sender: TObject); var FHandle: THandle; begin ReleaseModStream; // cannot update while playing ReleaseModule; FHandle := BeginUpdateResource(PChar(FFileName), False); Win32Check(FHandle <> 0); try Win32Check(UpdateResource(FHandle, 'TXT', 'EE', 0, nil, 0)); Win32Check(EndUpdateResource(FHandle, False)); except on EOSError do raise else begin Win32Check(EndUpdateResource(FHandle, True)); raise; end; end; end;

    Szóval, az én kódommal működik a dolog, valamit elszúrsz. Pl. nem árt, ha előtte elengedsz egy FreeLibrary-t, meg befejezed a lejátszást (bár, ha ez lenne a baja, vlsz. nem ezt mondaná). Én legalábbis így teszek.

    Ill., korábban a CreateProcess függvénynél kaptam hasonló hibaüzenetet mint te (invalid parameter / a paraméter érvénytelen), eddig fel nem tárt okokból - a kód korábban jól működött, sőt, másik rendszeren most is jól megy...
    Mutasd a teljes hozzászólást!
  • és rendesen dobta is


    Az lehet, hogy nem férsz hozzá legközelebb az erőforráshoz, de a dll mérete ugyanakkora maradt. Vagyis csak logikai törlés történt. De arra lennék kíváncsi, hogy fizikailag hogy lehet kitörölni az erőforrást.
    Bocsánat, ha túl sokat akarok.

    .:: Sonic ::.
    Mutasd a teljes hozzászólást!
  • 1. Az "eredeti" problémád az volt, hogy amikor törölni próbáltad a resource-ot, akkor az nem sikerült egyáltalán, mert OSError-ral elszállt.

    Csak arra a kérdésre tudok válaszolni, amit felteszel.

    2. Próbáltam egy CopyFile-t, de nem nyomta össze. Felhívnám a figyelmedet, hogy a dll-eket nem azért találták ki, hogy mindenféle dinamikus adatot tároljanak benne. Az nem adatbázis, nem is ini fájl. Akkor miért akarod, hogy még ezt optimalizálja is??? Szerintem a tömböd tárolására igenis egy saját fájlformátumot kellene csinálni, azaz, egyszerűen kiírni egy fájlba TFileStream-mel. Ez lenne a korrekt megoldás.

    A dll "kézi" tömörítését csak úgy tudnám elképzelni, ha ismernénk a dll pontos felépítését. *.res fájlnál megoldható a dolog, mert annak az MSSDK-ban dokumentálva van a teljes felépítése. Dll-ből viszont csak a resource list kinyerését ismerem, tehát a fájlon belüli elhelyezkedést nem, így nem tudom megkeresni az esetleges "üres" resource-ot sem.

    Részemről szeretném lezárni az ügyet
    Mutasd a teljes hozzászólást!
  • Maximálisan megértelek és köszönöm szépen az eddigi rengeteg segítségedet. Tudom, hogy a dll-t nem dinamikus adatok tárolására találták ki, csak érdekelt, hogy megoldható-e. Természetesen az eredeti kérdést maximálisan megválaszoltad.

    Még egyszer köszönöm szépen.

    .:: Sonic ::.
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd