Einzelnen Beitrag anzeigen

Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.116 Beiträge
 
Delphi 11 Alexandria
 
#10

Re: LoadString macht Probleme

  Alt 13. Okt 2003, 23:53
Moin Planlos,

der dritte Parameter ist die Adresse einer Funktion (Callbackfunktion), die EnumResourceNames für jeden gefundenen Resourcennamen aufruft.
Wie die Funktion deklariert werden muss steht weiter oben im Thread schon beschrieben. (Wichtig bei Callbackfunktionen für Funktionen der Windows API ist die Aufrufkonvention stdcall).
Der vierte Parameter ist einfach ein Integer Wert, der frei verwendet werden kann, wie z.B. die Eigenschaft Tag bei vielen Controls.
Ich habe ihn dafür verwendet die Adresse eines TreeNodes zu verwenden, um die Ergebnisse der Funktion direkt in einen TreeView schreiben zu können.

Wird als Name der Resource um eine Int-Resource (IS_INTRESOURCE, s.o., gibt true zurück, oder der Name beginnt mit einem #), und handelt es sich um eine String Resource, so können sich dahinter bis zu 16 Strings verbergen.
Falls man also nicht exakt die Resource ID eines Strings hat, muss man alle 16 Möglichkeiten durchprobieren.
Entscheidend ist hierbei, dass die Funktion LoadString durchaus 0 zurückgeben kann, was eigentlich auf einen Fehler hindeutet, GetLastError aber trotzdem ERROR_SUCCES meldet.
Grund hierfür: Die ausprobierte Resource ID ist nicht als Resource in der Datei vorhanden, aber der Aufruf war kein Fehler, weil es grundsätzlich eine Stringtabelle in diesem Bereich gibt, nur eben keinen String mit exakt dieser ID.

Die realen Resource IDs für die Strings lassen sich übrigens einfacher Berechnen, als von sakura ermittelt:

(Keine Lauffähige Prozedur. Ich möchte nur die Berechnung der möglichen Stringresource IDs deutlich machen.)

Delphi-Quellcode:
var
  iResourceRoot : integer;
  i : integer;

begin
  iResourceRoot := (UebergebeneIntResourceIDeinerStringResource-1)*16;
  for i := iResourceRoot to iResourceRoot+15 do begin
    if LoadString(...,i,...,...) <> 0 then begin
    end else begin
      if GetLastError <> ERROR_SUCCESS then begin
        // Erst jetzt ist wirklich ein Fehler aufgetreten
      end;
    end;
  end;
end;
Die Schleife muss übrigens immer voll durchlaufen werden, da die Sub IDs nicht lückenlos verwendet werden müssen.

Übrigens schon einmal mein Dank an Dich, denn durch Deine Frage bin ich dazu gekommen, mich noch einmal mit den String Resourcen zu beschäftigen, was dann zu dieser vereinfachten Berechnung geführt hat.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat