Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Array , Löschen von selben verhindern. (https://www.delphipraxis.net/79764-array-loeschen-von-selben-verhindern.html)

EWeiss 28. Okt 2006 06:52

Re: Array , Löschen von selben verhindern.
 
Zitat:

Zitat von SirThornberry
Das erste was mir auffiel ist das du ein dynamsiches Array übergibst was aber delphispezifisch ist. Ich kann mir nicht vorstellen das Winamp ein Delphiarray erwartet.

Das Array wird nicht an Winamp übergeben.
Lediglich der Header und das Modul welche sich in PWinampVisInfo befindet
werden aus dem Plugin geladen

Delphi-Quellcode:
   
VisHeader:     PWinampVisHeader;
VisModule:     PWinampVisModule;
aber auch diese haben nichts mit Winamp zu tun.

Das Array selbst ist Privat.

Gruß

marabu 28. Okt 2006 10:04

Re: Array , Löschen von selben verhindern.
 
Guten Morgen Emil,

eines ist sicher: der Fehler steckt nicht in den vier Zeilen Code, die du gezeigt hast. Mit denen forderst du nur Speicher an und initialisierst ihn. Interessanter ist dein Code, mit dem du nach dem Löschen eines Eintrags die nachfolgenden Einträge verschiebst. Eventuell wird dabei der Counter nicht rechtzeitig dekrementiert - oder garnicht?.

Freundliche Grüße
von Domstadt zu Domstadt

DP-Maintenance 28. Okt 2006 15:51

DP-Maintenance
 
Dieses Thema wurde von "alcaeus" von "Programmieren allgemein" nach "Sonstige Fragen zu Delphi" verschoben.

EWeiss 28. Okt 2006 16:02

Re: Array , Löschen von selben verhindern.
 
Zitat:

Zitat von marabu
Guten Morgen Emil,

eines ist sicher: der Fehler steckt nicht in den vier Zeilen Code, die du gezeigt hast. Mit denen forderst du nur Speicher an und initialisierst ihn.

Freundliche Grüße
von Domstadt zu Domstadt

Hi marabu

Ja .. das ist mein problem das redimensionieren (verschieben) der Einträge.
Habe es mit ReAllocMem versucht und keinen Erfolg gehabt.

Delphi-Quellcode:
function BASS_WINAMPVIS_CreateVis(f: PChar; module, flags: DWORD; AppHandle: DWORD; AppHDC: boolean; VisCounter: integer): HVIS; stdcall;
var
  mbi:    MEMORY_BASIC_INFORMATION;
  winampVisGetHeader: function: PWinampVisHeader; cdecl;

begin

  Result := 0;
  // Winamp Emulator Fenster HWND
  VisDllHandle := 0;

  // Wenn True Plugin in der Applikation
  // oder eigenen Skin visualisieren
  AppParenthDC := AppHDC;

  // Voller Pfad des Plugin
  FileName := StrPas(f);

  // HWND von der ausführenden Application
  AppParentHandle := AppHandle;

  if (not FileExists(PChar(FileName))) then
  begin
    BassFuncs^.SetError(BASS_ERROR_FILEOPEN);
    Exit;
  end;

  if VisCounter = 0 then
   VisWinCounter := VisCounter;

  try
    GetMem(VisInfo[VisCounter], SizeOf(TWinampVisInfo));
    ZeroMemory(VisInfo[VisCounter], SizeOf(TWinampVisInfo));
  except
    BassFuncs^.SetError(BASS_ERROR_MEM);
    Exit;
  end;

  try
    SetCurrentDirectory(PChar(FileName));
    VisDllHandle := LoadLibrary(PChar(FileName));

  except
    if (VisDllHandle <> 0) then
      FreeLibrary(VisDllHandle);
    FreeMem(VisInfo[VisCounter]);

    BassFuncs^.SetError(BASS_ERROR_START);
    Exit;
  end;

  if (VisDllHandle = 0) then
  begin
    FreeMem(VisInfo[VisCounter]);

    BassFuncs^.SetError(BASS_ERROR_START);
    Exit;
  end;

  @winampVisGetHeader := GetProcAddress(VisDllHandle, 'winampVisGetHeader');
  if (@winampVisGetHeader = nil) then
  begin
    FreeLibrary(VisDllHandle);
    FreeMem(VisInfo[VisCounter]);

    BassFuncs^.SetError(BASS_ERROR_HANDLE);
    Exit;
  end;

  VisInfo[VisCounter]^.VisHeader := winampVisGetHeader;
  if (VisInfo[VisCounter]^.VisHeader = nil) then
  begin
    FreeLibrary(VisDllHandle);
    FreeMem(VisInfo[VisCounter]);

    BassFuncs^.SetError(BASS_ERROR_START);
    Exit;
  end;

  VisInfo[VisCounter]^.VisModule := VisInfo[VisCounter]^.VisHeader^.getModule(module);
  if (VisInfo[VisCounter]^.VisModule = nil) then
  begin
    FreeLibrary(VisDllHandle);
    FreeMem(VisInfo[VisCounter]);

    BassFuncs^.SetError(BASS_ERROR_START);
    Exit;
  end;

  // Überprüfe ob eine neue Instanz erstellt werden soll
  VisInfo[VisCounter]^.Init := ((flags and BASS_VIS_NOINIT) <> BASS_VIS_NOINIT);
  VisInfo[VisCounter]^.DllInstance := VisDllHandle;

  if (VisInfo[VisCounter]^.Init) then

  begin
    VisWinCounter := VisCounter;
    VisInfo[VisWinCounter]^.VisInfoCount := VisWinCounter;

    // Neuen Thread erstellen
    ThreadHandle := BeginThread(nil, 0, @WinampVisWin, VisInfo[VisWinCounter], 0, ThreadId);

    // DLL aus Speicher entfernen wenn ThreadHandle = 0
    if (ThreadHandle = 0) then
    begin
      FreeLibrary(VisDllHandle);
      FreeMem(VisInfo[VisWinCounter]);

      BassFuncs^.SetError(BASS_ERROR_INIT);
      Exit;
    end;
    // Thread schließen
    CloseHandle(ThreadHandle);

  end;


  VirtualQuery(VisInfo[VisCounter]^.VisHeader.description, mbi, SizeOf(MEMORY_BASIC_INFORMATION));
  VisInfo[VisCounter]^.PluginId := DWORD(mbi.AllocationBase);

  W_AppendHandle(DWORD(VisInfo[VisCounter]));
  BassFuncs^.SetError(BASS_OK);


  Result := DWORD(VisInfo[VisCounter]);

end;
Wie schon gesagt es funktioniert alles (und ist keine übersetzung) von einer anderen Quelle

Hier
Delphi-Quellcode:
  try
    GetMem(VisInfo[VisCounter], SizeOf(TWinampVisInfo));
    ZeroMemory(VisInfo[VisCounter], SizeOf(TWinampVisInfo));
  except
    BassFuncs^.SetError(BASS_ERROR_MEM);
    Exit;
  end;
müßte der speicher verschoben werden wenn VisCounter > 1 daran bin ich gescheitert.

EDIT:
Zitat:

Interessanter ist dein Code, mit dem du nach dem Löschen eines Eintrags die nachfolgenden Einträge verschiebst. Eventuell wird dabei der Counter nicht rechtzeitig dekrementiert - oder garnicht?.
Denke das ist in Ordnung
Der Counter bzw.. das plugin was entladen weden soll wird aus der
Hauptanwendung übergeben.

Delphi-Quellcode:
function BASS_WINAMPVIS_Free(handle: HVIS; VisCounter: Integer): boolean; stdcall;


begin
  Result := False;
  VisWinCounter := VisCounter;

  if (not W_ValidHandle(handle)) then
  begin
    BassFuncs^.SetError(BASS_ERROR_HANDLE);
    Exit;
  end;

  VisInfo[VisCounter] := PWinampVisInfo(handle);

  if (VisInfo[VisCounter]^.Init) then
  begin
    PostMessage(VisInfo[VisCounter]^.WinHandle, WM_QUIT, 0, 0);
    FreeLibrary(VisDllHandle);
  end
  else
  begin
    W_RemoveHandle(DWORD(VisInfo[VisCounter]));

    FreeLibrary(VisInfo[VisCounter]^.DllInstance);
    FreeMem(VisInfo[VisCounter]);
  end;
  BassFuncs^.SetError(BASS_OK);
  Result := True;
end;
gruß

marabu 28. Okt 2006 17:33

Re: Array , Löschen von selben verhindern.
 
Hallo Emil,

Delphi-Quellcode:
// Voller Pfad des Plugin
FileName := StrPas(f);
das muss nicht sein. In der Regel weiß Delphi zwischen PChar und String automatisch zu konvertieren.

Delphi-Quellcode:
if not FileExists(PChar(FileName)) then
f oder FileName genügt - kein casting nötig.

Delphi-Quellcode:
if VisCounter = 0 then
 VisWinCounter := VisCounter;
das ist nicht verständlich - auch weil du so viele globale Variablen benutzt.

Delphi-Quellcode:
  try
    GetMem(VisInfo[VisCounter], SizeOf(TWinampVisInfo));
    ZeroMemory(VisInfo[VisCounter], SizeOf(TWinampVisInfo));
  except
    BassFuncs^.SetError(BASS_ERROR_MEM);
    Exit;
  end;
Wenn VisInfo als statisches Array deklariert ist (siehe Beitrag #1), dann greift der Code hier bei VisCounter = 0 ins Leere.
Kannst du nicht ein dynamisches Array verwenden?

Delphi-Quellcode:
type
  TVisInfo = array of PWinampVisInfo;
var
  VisInfo: TVisInfo;

function AddVisInfo(var vi: TVisInfo): TVisInfo;
begin
  index := Length(vi);
  SetLength(vi, Succ(index));
  New(vi[index]); // Freigabe mit Dispose(vi[index]) - Borland empfiehlt es
  ZeroMemory(vi[index], SizeOf(vi[index]^));
end;

procedure DeleteVisInfo(var vi: TVisInfo; p: PWinampVisInfo);
var
  index, iFound: Integer;
begin
  // locate pointer
  iFound := -1; // not found
  for index := Low(vi) to Length(vi) do
    if (index < Length(vi)) and (vi[index] = p) then
    begin
      iFound := index;
      Break;
    end;

  if iFound <> -1 then
  // fill the gap
  begin
    Dispose(vi[index]);
    if index <> High(vi) then
      vi[index] := vi[High(vi)];
    SetLength(vi, High(vi));
  end;
end;
An die Stelle der globalen Variable VisCounter könnte dann Length(VisInfo) treten. Wenn du ein statisches Array benutzen musst, dann müsstest du aber ähnlich vorgehen.

Delphi-Quellcode:
// ...
    // SetCurrentDirectory(PChar(FileName));
    // vielleicht besser so:
    SetCurrentDirectory(ExtractFilePath(f));
Jetzt muss ich erstmal eine Pause machen - deine Probleme sind immer so umfangreich...

Freundliche Grüße

EWeiss 28. Okt 2006 18:25

Re: Array , Löschen von selben verhindern.
 
Zitat:

Delphi-Quellcode:
if VisCounter = 0 then
VisWinCounter := VisCounter;
das ist nicht verständlich - auch weil du so viele globale Variablen benutzt.
Schwierig zu erklären ich versuchs aber trotzdem mal.

VisCounter = 0 ist reserviert für Plugins welche nicht initialisiert(gestartet) wurden.
VisWinCounter ist der zähler welcher übergreifend im ganzen Code zur identifizierung des in
der PluginListe angeklickten Plugin gilt.
Wurde das Plugin nicht gestartet dann ist VisWinCounter immer null.
Muss also wie oben den wert 0 bekommen.
Dadurch kann ich die configuration der Plugins starten editieren welche selbst nicht initialisiert(gestartet) wurden.

Code:
tmpvis = BASS_WINAMPVIS_CreateVis(alist(IntI), module, BASS_VIS_NOINIT, 0, False, "0")
Hier wird aus der Hauptanwendung tmpvis ermittelt.
BASS_VIS_NOINIT bedeutet das das Plugin nicht gestartet wird deshalb wird VisCounter mit 0 übergeben.

Nun kann ich alle namen der module und des Plugins selbst ermitteln ohne das ein Plugin gestartet wurde.
VisCounter = 0 geht also nie ins leere ..
Wenn 0 dann kann ich mit allen Plugins arbeiten .. config usw.. ohne das die gestarteten
Plugins davon betroffen oder beeinflusst werden.

VisWinCounter wird zweimal übergeben einmal 0 wenn kein Plugin gestartet wird
und hier
Delphi-Quellcode:
  if (VisInfo[VisCounter]^.Init) then

  begin
    VisWinCounter := VisCounter;
    VisInfo[VisWinCounter]^.VisInfoCount := VisWinCounter;
wenn eins gestartet wurde. erst dann wird es hochgezählt.

Zitat:

Jetzt muss ich erstmal eine Pause machen - deine Probleme sind immer so umfangreich...
In diesen Fall bis auf die kleinen konvertierungsfehler eigentlich nicht.
Bin halt übervorsichtig :)

Also beim ersten start 1 Plugin läuft gibt es keinen AV keine anderen Fehler!
Beim zweiten Plugin muss ich nur dafür sorgen das der erste eintrag Array(1) nicht von Array(2) überschrieben wird.

Andere probs habe ich nicht.

gruß

EWeiss 29. Okt 2006 19:39

Re: Array , Löschen von selben verhindern.
 
Niemand eine Ahnung?

Es muss doch möglich sein ähnlich wie dieser Code (funktioniert nicht ganz)

Delphi-Quellcode:
  if VisCounter = 0 then
   begin
   VisWinCounter := VisCounter;

  try
    GetMem(VisInfo[VisCounter], SizeOf(TWinampVisInfo));
    ZeroMemory(VisInfo[VisCounter], SizeOf(TWinampVisInfo));
  except
    BassFuncs^.SetError(BASS_ERROR_MEM);
    Exit;
  end;
   end else
   begin
   ReAllocMem(VisInfo[VisCounter], VisCounter * SizeOf(TWinampVisInfo));
   end;
im Array(2) die Daten vom 2 plugin zu integrieren.
ohne das Array(1) Daten vom 1 Plugin überschrieben oder gelöscht werden.

gruß

alzaimar 29. Okt 2006 19:54

Re: Array , Löschen von selben verhindern.
 
Das Array ist ein Array of Pxxxxx, Und Du initialisierst jedes Element, in dem Du SizeOf(Txxxxx) Bytes überschreibst.....

Jedes Element des Arrays enthält doch aber nur SizeOF (Pxxxxx) Bytes, oder?

EWeiss 29. Okt 2006 20:08

Re: Array , Löschen von selben verhindern.
 
Zitat:

Zitat von alzaimar
Das Array ist ein Array of Pxxxxx, Und Du initialisierst jedes Element, in dem Du SizeOf(Txxxxx) Bytes überschreibst.....

Jedes Element des Arrays enthält doch aber nur SizeOF (Pxxxxx) Bytes, oder?

Jedes Element des Arrays enthält alle Daten(record) von TWinampVisInfo oder was meinst du ?

zum ersten ja! Nochmal die Type welche als Array ausgelegt ist.
Delphi-Quellcode:
Type
  PWinampVisInfo = ^TWinampVisInfo;
  TWinampVisInfo = Packed record
    Title:         PChar;
    FileName:      PChar;
    PlaylistLength: integer;
    PlaylistPos:   integer;
    Pos, Len:      QWORD;
    VisHeader:     PWinampVisHeader;
    VisModule:     PWinampVisModule;
    Init, Init2, Rendering: boolean;
    DllInstance:   THandle;
    WinHandle:     THandle;
    PluginId:      DWORD;
    ParentHandle:  DWORD;
    Vis_Atom_Emu:  ATOM;
    Vis_Window_Emu: HWND;
    VisInfoCount:  Integer;
  end;

Var
  VisInfo: array [1..5] of PWinampVisInfo;
so wie in meinen letzten Beispiel müßte es eigentlich gehen was noch fehlt wäre
Das Array(1) zu kopieren wenn ein neues Plugin gestartet wird
Das Array(2) mit den Daten vom Plugin 2 zu füllen
und die kopierten Daten von Array(1) zurück zuschreiben wenn dieses überschrieben wird.(das wird es ja... mein Problem!)

Weiss sonst nicht wie ich das erklären soll.

gruß

Sunlight7 29. Okt 2006 20:11

Re: Array , Löschen von selben verhindern.
 
Zitat:

Zitat von alzaimar
Jedes Element des Arrays enthält doch aber nur SizeOF (Pxxxxx) Bytes, oder?

Das ergibt doch die Größe der Speicheradresse der Variable, anstatt der Strukturgröße :gruebel:

Edit: Also wenn's echt nur ums kopieren geht: CopyMemory
EDit²: Die fehlenden roten Kasten können einem ganz schön durcheinander bringen :roteyes:


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:32 Uhr.
Seite 2 von 3     12 3      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz