Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   dynamischer Speicher füllen (https://www.delphipraxis.net/46103-dynamischer-speicher-fuellen.html)

Porter10 18. Mai 2005 15:33


dynamischer Speicher füllen
 
Hallo erstmal!

Bin neu hier im Forum bei Delphipraxis! Bin vor einiger Zeit gefragt worden, ob ich ein älteres Programm bei uns der Firma übernehmen könnte! Es ist leider in Delphi geschrieben, und da ich fast keine Delphi erfahrung habe, kommt es da natürlich des öfteren zu syntax problemen!

Lange Rede kurzer Sinn, ich habe probleme ein farb array (rgb = 3x Bytes) zu füllen! Der Speicher wurde mit allocmem reserviert!
Delphi-Quellcode:
procedure TPCX.get_palette(i: integer);
var
   ini: TiniFile;
   test: string;
   k: integer;
   testcolor: TColor;

begin
     if PXD_Descriptor.palette[i] <> NIL then begin
        ini:=TIniFile.Create(mainform.configpath+'\Einstellungen.ini');  // .ini wird erstellt

        ReglerRGB:= ini.Readstring('ReglerAuswahl','1','');
        ReglerReso:= ini.Readstring('ReglerAuswahl','2','');
           for k:=0 to 255 do begin
               test:= ini.Readstring(ReglerRGB,inttostr(k),'');
               testcolor:= stringtoColor(test);
 
               PXD_Descriptor.Palette[i].rgbBlue:= colortorgb(testcolor);

               PXD_Descriptor.Palette[i].rgbGreen:= colortorgb(testcolor);

               PXD_Descriptor.Palette[i].rgbRed:= colortorgb(testcolor);

           end;
        end;
        Ini.Free;
end;
Versuche eine Farbpalette in das Array zu schreiben, aber ich weiss nicht, wie ich die folgenden array punkte anspreche!
Da es ja kein pointer ist kann ich nicht mit inc(Pxd_Descriptor.Palette[i].rgbBlue); eine neue ebene schaffen!

Komme mir selber blöde vor, deshalb bitte nicht noch Salz in die Wunde streuen! Bitte!
Danke jedem schonmal für die Hilfe!
:cheers:

franktron 18. Mai 2005 15:37

Re: dynamischer Speicher füllen
 
Hatse mal die Deklartion von PXD_Descriptor

Porter10 18. Mai 2005 16:05

Re: dynamischer Speicher füllen
 
Delphi-Quellcode:
   TPXD_Descriptor = packed record
      NumPictures : WORD;
      NumData : array[0..MAX_PIC-1] of WORD;
      PicName : array[0..MAX_PIC-1] of array[0..8] of char;
      TabName : array[0..MAX_PIC-1] of array[0..8] of char;
      DataPtr : array[0..MAX_PIC-1] of PPCX_DATA;
      ///////////////ab hier neuer Teil/////////////////////////////////////
      ReglerType : word;
      AnzColors : array[0..MAX_PIC-1] of word;
      Palette : array[0..MAX_PIC-1] of PRGB_TYPE;
      Komment : array[0..MAX_PIC-1] of array[0..40] of char;
      dst_name : array[0..MAX_PIC-1] of array[0..8] of char;
      type_name : array[0..MAX_PIC-1] of array[0..3] of char;
      PicType : array[0..MAX_PIC-1] of word;
   end;


Delphi-Quellcode:
  TRGB_TYPE = packed record
      rgbBlue : Byte;
      rgbGreen : Byte;
      rgbRed : Byte;
   end;
Hier sind die Records! Danke aber schonmal fuer die schnelle Antwort!

marabu 18. Mai 2005 16:24

Re: dynamischer Speicher füllen
 
Ist es das, was du suchst?

Delphi-Quellcode:
// damit erhöhst du nur den RGB-Wert für Blau:
inc(Pxd_Descriptor.Palette[i].rgbBlue);

// so kannst du auf die nächste Palette zugreifen:
Inc(i);
Pxd_Descriptor.Palette[i].rgbBlue := BlauWert;
Pxd_Descriptor.Palette[i].rgbGreen := GruenWert;
Pxd_Descriptor.Palette[i].rgbRed := RotWert;

// Oder auch so:
with Pxd_Descriptor.Palette[i] do begin
  rgbBlue := BlauWert;
  rgbGreen := GruenWert;
  rgbRed := RotWert;
end;
Grüße vom marabu

franktron 18. Mai 2005 18:55

Re: dynamischer Speicher füllen
 
Du must nur den wert der Constante MAX_PIC erhöhen die gibt nämlich den max wert an

Porter10 19. Mai 2005 12:38

Re: dynamischer Speicher füllen
 
Die Anzahl von Bildern soll und muss so bleiben! Ich möchte eine Farbpalette fuer jedes Bild hinterlegen wo jeweils die Rot Blau und Grün anteile drin stehen! Daher rechne ich die Anzahl der Farben mal 3 Byte, um die Farbanteile da rein zu schreiben! Mit
Delphi-Quellcode:
inc(Pxd_Descriptor.Palette[i].rgbBlue);
habe ich es schon versucht! Was aber anscheinend nur bei Pointern funktioniert! Oder es addiert nur eine 1 hinzu! Ich möchte wissen wie ich bei 255 * 3 Byte Speicherreservierung, da rauf zu greife!
Delphi-Quellcode:
MemSize := SizeOf(TRGB_TYPE) * PXD_Descriptor.AnzColors[i];
         PXD_Descriptor.Palette[i] := AllocMem(MemSize*2);
Aber schonmal Danke fuer die Hilfen! Wusste auch nicht genau wie ich das Problem umschreiben soll! Bin Forums neuling! :coder:

franktron 19. Mai 2005 12:45

Re: dynamischer Speicher füllen
 
Erstmal Herzlich Willkommen in der DP (ganz vergessen :oops: )

Du kannst das so machen um deine Farbpalette zu speichern

Delphi-Quellcode:
Palette : array[0..MAX_PIC-1] of Array[0..255] of PRGB_TYPE;

marabu 19. Mai 2005 12:49

Re: dynamischer Speicher füllen
 
Porter10, du denkst zu sehr in C.

PXD_Descriptor.Palette ist Teil einer Struktur, der ganze packed record TPXD_Descriptor ist ein struct. Wenn du irgendwas dynamisch anlegen willst, dann nur den ganzen Deskriptor.

Delphi-Quellcode:
var
  PXD_Descriptor: TPXD_Descriptor; // statisch
  PPXD_Descriptor: ^TPXD_Descriptor;
begin
  PPXD_Descriptor := AllocMem(SizeOf(TPXD_Descriptor)); //dynamisch
end;
Grüße vom marabu

marabu 19. Mai 2005 15:42

Re: dynamischer Speicher füllen
 
Hallo Porter10,

manchmal dauert es etwas länger. Wenn PRGB_TYPE ein Pointer auf TRGB_TYPE ist, dann ist Palette ein Zeigerfeld. Du forderst den gesamten für die Paletten benötigten Speicher mit einem AllocMem() an. Kann man machen, ist auch irgendwo ökonomisch, aber dann musst du trotzdem die einzelnen Pointer initialisieren. Oder du forderst den Speicher für jede Palette einzeln an.

Delphi-Quellcode:

var
  i: integer;
  p: PRGB_TYPE;
begin
  // Einzelanforderung
  for i := 0 to MAX_PIC - 1 do
    New(Palette[i]);

  // Blockanforderung
  p := AllocMem(...);
  for i := 0 to MAX_PIC - 1 do begin
    Palette[i] := p;
    Inc(p);
  end;
end;
Grüße vom marabu

Porter10 22. Mai 2005 11:59

Re: dynamischer Speicher füllen
 
@Marabu

Danke fuer deine Antworten! Habe eben echt leider noch recht wenig Delphi Erfahrung!
Werde es morgen direkt mal auf der Arbeit ausprobieren! Melde mich dann noch mal ob es geklappt hat oder nicht!

Alles Gute! :cheers:

Porter10 24. Mai 2005 13:54

Re: dynamischer Speicher füllen
 
Komme leider immer noch nicht viel weiter! Gebe mal die Kompletten funktionen frei, vielleicht könnt ihr mir dann vielleicht doch noch besser Hilfe geben! Habe es mal versucht, wie Marabu es mir beschrieben hat, aber leider ohne Erfolg! Also der Speicher wird ja durch AllocMem reserviert, und mit nullen gefüllt! Aber anscheinend habe ich nur den Speicher in der Größe von 3 * 256 Bytes = 768 Bytes reserviert! Wie bekomme ich jetzt aus dem Allocierten Speicher ein beschreibbares und auslesbares array gestrickt?

Dies ist die Procedure die genutzt wird um den Speicher zu reservieren!
Delphi-Quellcode:
procedure TPCX.GetMemory;
var
   i,l : integer;
   MemSize : integer;
   p: PRGB_TYPE;

begin
   for i := 0 to PXD_Descriptor.NumPictures-1 do begin
      MemSize := SizeOf(TPcx_Data) * PXD_Descriptor.NumData[i];
      PXD_Descriptor.DataPtr[i] := AllocMem(MemSize);
   end;


   for i := 0 to PXD_Descriptor.NumPictures -1 do begin
      if PXD_Descriptor.AnzColors[i] >= 0 then begin
         MemSize := SizeOf(TRGB_TYPE) * PXD_Descriptor.AnzColors[i];
                p:= AllocMem(MemSize*2);
                PXD_Descriptor.Palette[i] := p;
                 
        for l := 0 to 255 do begin
           get_palette(i,l);
           Inc(p);
        end;

        end;

   end;
end;
Get_palette habe ich neu geschrieben, um die Farbtabelle aus einer ini Datei auszulesen, um Sie dann in das dynamische Array hineinzuschreiben! Kann hier aber nur auf die erste Ebene zugreifen!

@Franktron
Dein Vorschlag mit dem festen array ist gar nicht mal so schlecht! Will aber noch nicht zu dieser Lösung tendieren, da ich es lieber dynamisch haette! Da wir bei unserem alten Regler auch noch mit 16 Farben Bildern arbeiten! Würde aber auch gehen, da ich die ersten 16 Farben eh identisch gehalten habe!

Delphi-Quellcode:
//////////////////////////neu Palette einlesen aus der .ini datei///////////
procedure TPCX.get_palette(i,l: integer);
var
   ini: TiniFile;
   test: string;
   k: integer;
   testcolor: TColor;
   rgbtest: Byte;
   PRGB: PRGB_TYPE;

begin
     if PXD_Descriptor.palette[i] <> NIL then begin
        ini:=TIniFile.Create(mainform.configpath+'\Einstellungen.ini');  // .ini wird erstellt

        ReglerRGB:= ini.Readstring('ReglerAuswahl','1','');
        ReglerReso:= ini.Readstring('ReglerAuswahl','2','');
      //  for k:=0 to 255 do begin
               test:= ini.Readstring(ReglerRGB,inttostr(l),'');
               testcolor:= stringtoColor(test);

               PXD_Descriptor.Palette[i].rgbBlue:= colortorgb(testcolor);

               PXD_Descriptor.Palette[i].rgbGreen:= colortorgb(testcolor);

               PXD_Descriptor.Palette[i].rgbRed:= colortorgb(testcolor);

       // end;
     end;
        Ini.Free;
end;
Vielleicht kann mir ja doch jemand den entscheidenden Hinweis geben! Man kann mir das vielleicht an der Hand eines kleines Beispeils verdeutlichen wo mein Denkfehler ist!
:wall:

Danke!!!

franktron 24. Mai 2005 14:01

Re: dynamischer Speicher füllen
 
Dann machs so

Delphi-Quellcode:
Palette : array[0..MAX_PIC-1] of Array of PRGB_TYPE;

und dann mit Setlength(Palette[i],AnzFarben) die grösse setzen

marabu 24. Mai 2005 21:27

Re: dynamischer Speicher füllen
 
Hallo porter10,

ich nehme an, dass an deinem Code nicht viel geändert werden darf, also habe ich mich darauf beschränkt die Mängel zu beheben, die ich erkennen konnte. Vielleicht schaut ja noch jemand drüber. Getestet habe ich nicht. Wenn dir etwas spanisch vorkommt können wir drüber reden.

Delphi-Quellcode:
procedure TPCX.GetMemory;
var
  i, l: integer;
  memSize: integer;
  p: PRGB_TYPE;
  ini: TiniFile;
begin
  ini := TIniFile.Create(mainform.configpath + '\Einstellungen.ini');

  for i := 0 to PXD_Descriptor.NumPictures - 1 do begin
    memSize := SizeOf(TPcx_Data) * PXD_Descriptor.NumData[i];
    PXD_Descriptor.DataPtr[i] := AllocMem(MemSize);

    if PXD_Descriptor.AnzColors[i] >= 0 then begin
      MemSize := SizeOf(TRGB_TYPE) * PXD_Descriptor.AnzColors[i];
      p := AllocMem(MemSize);          
      PXD_Descriptor.Palette[i] := p;
         
      for l := 0 to PXD_Descriptor.AnzColors[i] - 1 do begin
        get_palette(ini, p, l);        
        Inc(p);                    
      end;
    end;

  end;

  Ini.Free;
end;


procedure TPCX.get_palette(ini: TIniFile; p: PRGB_TYPE; l: integer);
var
  test: string;
  testcolor: TColor;
begin
  ReglerRGB := ini.Readstring('ReglerAuswahl', '1', '');  // global var?
  ReglerReso := ini.Readstring('ReglerAuswahl', '2', ''); // global var?
  test := ini.Readstring(ReglerRGB, inttostr(l), '');
  testcolor := stringtoColor(test);
  p^.rgbBlue := colortorgb(testcolor);
  p^.rgbGreen := colortorgb(testcolor);
  p^.rgbRed := colortorgb(testcolor);
end;
Grüße vom marabu

Porter10 27. Mai 2005 14:06

Re: dynamischer Speicher füllen
 
@Marabu

Danke vielen Dank! Hast mir sehr geholfen, war ein guter denk anstoss!
Habe also das Problem gelöst, und schon baut sich ein neues auf! Weist du vielleicht noch eine gute Methode um Hexadezimale Farbwerte in rot gruen und blau anteil aufzuteilen! Wie du ja bereits gesehen hast, hatte ich das versucht mit ColortoRGB, aber das liefert mir ja nur einen longint windowsrgb wert wieder, so wie ich das verstanden habe! :wall:
Wie könnte ich vorgehen, wenn ich $800080 in 128-0-128 haben wollte!

Wollte andere Helfer nicht verprellen, nur weil ich jetzt direkt an Marabu geschrieben habe das Problem! Wenn wer anderes auch einen Rat fuer mich hat, bin ich sehr dankbar!

:coder2:

marabu 27. Mai 2005 14:41

Re: dynamischer Speicher füllen
 
Hilft dir das weiter?

Delphi-Quellcode:
function SetRGB(var RGB: TRGB_TYPE; colorString: string): boolean;
var
  c: TColor;
  a: array [1..3] of byte absolute c;
begin
  c := StringToColor(colorString);
  rgb.rgbRed := a[1];
  rgb.rgbGreen := a[2];
  rgb.rgbBlue := a[3];
end;

procedure TPCX.get_palette(ini: TIniFile; p: PRGB_TYPE; l: integer);
var
  test: string;
begin
  ReglerRGB := ini.Readstring('ReglerAuswahl', '1', '');  // global var?
  ReglerReso := ini.Readstring('ReglerAuswahl', '2', ''); // global var?
  test := ini.Readstring(ReglerRGB, inttostr(l), '');
  SetRGB(p^, test);
end;
Du müsstest dir nur noch Gedanken über die Absicherung deines Codes machen. Was soll passieren, wenn unsinnige Werte in der Steuerdatei stehen?

Grüße vom marabu


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:32 Uhr.

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