Einzelnen Beitrag anzeigen

ASM

Registriert seit: 16. Aug 2004
165 Beiträge
 
Delphi 7 Enterprise
 
#3

AW: How to delete resource? - code don't working

  Alt 22. Mär 2011, 21:33
Der Hauptfehler, dass es mit Deinem Code nicht funktioniert, liegt daran, wie Du den Bezug auf RT_RCDATA verwendest.

RT_RCDATA darfst Du nicht selber als eigenen String 'RT_RCDATA' oder 'RCDATA'angeben. Vielmehr ist RT_RCDATA bereits in der Unit Types als Konstante deklariert (Unit Types wird über die Unit Windows eingebunden).

Es muss bei Dir also heißen (RT_RCDATA ohne Hochkommata!):
B := UpdateResource( (hResource, RT_RCDATA, 'PACKAGEINFO', 0, @lpData[0], Length(lpData));


Davon nunabhängig sind aber mehrere Fehler bzw. fragwürdige Ansätze in Deinem Code;
Du benutzt als Puffer zwar ein
Code:
 lpData: array [0..255] of Char;
aber übergibst dann in UpdateResource() die Adresse @lpData[1].
Wenn Du die Puffervariable als Array [0..x] .. deklarierst, musst Du dann aber auch entsprechend die Startaddresse des Arrays, also die Adresse @lpData[0] übergeben. Die Adresse @lpData[1] dagegen müsstest Du benutzen, wenn die Puffervariable als String deklariert wäre.

Weiterhin überschreibst Du den Inhalt der Resource auch noch ohne Rücksicht auf die wirkliche Länge der Resource mit der fest voreingestellten Länge des Arrays. Was passiert, wenn die Länge der Resource einmal kürzer ist als diese fest eingestellte Länge ?

Du solltest also die Länge der Puffervariablen auf die wirkliche Länge Deiner Resource setzen. Dazu musst Du entweder ein dynamisches Array hernehmen oder - meiner Meinung nach - besser die Puffervariable als String deklarieren und dessen Länge mit Setlength() auf die aktuelle Länge der Resource setzen

Zunächst solltest Du aber überhaupt grundsätzlich erst einmal prüfen, ob die jeweilige Resource eigentlich korrekt in das Memory geladen worden ist; dabei ermittelst Du auch gleich korrekt die Größe dieser Resource:

Code:
function ResourceEntryExist(ResourceName: string; const Filename: string; var ResSize: DWord): Boolean;
var
  EXE: cardinal;
  ResData: Cardinal;
  ResPtr: Pointer;
  ResHdl: HRSRC;
begin
  result := false;
  ResSize := 0;
  if trim(ResourceName) = '' then exit;
  ResourceName := uppercase(ResourceName);
  EXE := LoadLibrary(pchar(FileName));
  if EXE <> 0 then
  try
    ResPtr := nil;
    ResHdl := FindResource(EXE, pchar(ResourceName), RT_RCDATA);
    ResData := LoadResource(EXE, ResHdl);
    if ResData = 0 then
      raise EResNotFound.Create(format('Resource %s konnte nicht geladen werden!', [ResourceName]));
    ResPtr := LockResource(ResData);
    if ResPtr <> nil then
    begin
      ResSize := SizeofResource(Exe, ResHdl);
      result := true;
    end;
    FreeResource(ResData);
  finally
    freelibrary(EXE);
  end
  else raise Exception.Create(format('File %s konnte nicht geladen werden!', [FileName]));
end;
Den Wert der Resourcelänge, den Du dadurch erhälst (also in der Var ResSize zurückbekommst), setzt Du als Länge Deines dynamischen Pufferarrays ein (oder eben als Stringlänge per Setlength()) und füllst diesen Puffer per Fillchar() mit #0. Die Länge der Resource bleibt erhalten, nur der Inhalt wird eben gelöscht.
Alternativ könntest Du den Puffer auch grundsätzlich auf die Länge 1 setzen (lpData: array [0..0] of Char; oder besser: lpData: String=#0); dann wird die Länge der Resource auf 1 Byte gekürzt und ihr Inhalt gelöscht.

Geändert von ASM (22. Mär 2011 um 21:35 Uhr)
  Mit Zitat antworten Zitat