Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi How to delete resource? - code don't working (https://www.delphipraxis.net/159191-how-delete-resource-code-dont-working.html)

WojTec 17. Mär 2011 15:02

How to delete resource? - code don't working
 
I have this:

Delphi-Quellcode:
var
  hResource: THandle;
  lpData: array [0..255] of Char;
  B: Boolean;
begin
  lpData := '';
  hResource := BeginUpdateResource(PChar(Edit1.Text), False);
  B := UpdateResource(hResource, 'RCDATA', 'DVCLAL', 0, @lpData[1], Length(lpData));
  EndUpdateResource(hResource, False);

  lpData := '';
  hResource := BeginUpdateResource(PChar(Edit1.Text), False);
  UpdateResource(hResource, 'RCDATA', 'PACKAGEINFO', MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), @lpData[1], Length(lpData));
  EndUpdateResource(hResource,False);
end;
File updated, but resource still inside :( I tried also with RT_RCDATA, but don't working too :(

Assarbad 17. Mär 2011 17:12

AW: How to delete resource? - code don't working
 
It may seem like magic, but MSDN-Library durchsuchenUpdateResource has a return value. And when it fails MSDN-Library durchsuchenGetLastError offers more information. And suddenly we might be able to give you some clue as well :zwinker:

(Same for MSDN-Library durchsuchenEndUpdateResource, btw)

ASM 22. Mär 2011 20:33

AW: How to delete resource? - code don't working
 
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.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:50 Uhr.

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