AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi How to delete resource? - code don't working
Thema durchsuchen
Ansicht
Themen-Optionen

How to delete resource? - code don't working

Ein Thema von WojTec · begonnen am 17. Mär 2011 · letzter Beitrag vom 22. Mär 2011
Antwort Antwort
WojTec

Registriert seit: 17. Mai 2007
480 Beiträge
 
Delphi XE6 Professional
 
#1

How to delete resource? - code don't working

  Alt 17. Mär 2011, 15:02
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
  Mit Zitat antworten Zitat
Benutzerbild von Assarbad
Assarbad

Registriert seit: 8. Okt 2010
Ort: Frankfurt am Main
1.234 Beiträge
 
#2

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

  Alt 17. Mär 2011, 17:12
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

(Same for MSDN-Library durchsuchenEndUpdateResource, btw)
Oliver
"... aber vertrauen Sie uns, die Physik stimmt." (Prof. Harald Lesch)
  Mit Zitat antworten Zitat
ASM

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

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

  Alt 22. Mär 2011, 20: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 20:35 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:53 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