Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Problem mir StringResourcen... (https://www.delphipraxis.net/52409-problem-mir-stringresourcen.html)

marabu 30. Aug 2005 09:49

Re: Problem mir StringResourcen...
 
Warum hältst du die maximale ID nicht auch als Resource vor?

marabu

FriFra 30. Aug 2005 09:56

Re: Problem mir StringResourcen...
 
Dann könnt ich auch gleich hergehen und jedes mal die entspr. Schleife in meinem Programm anpassen....
Nein, ich will das nicht statisch lösen, sondern zur Laufzeit ermitteln :x ... Das es irgendwie gehen muß zeigen ja div. Resourcehacker, welche die Testresourcen auch exakt ermitteln können :gruebel: ...

marabu 30. Aug 2005 10:02

Re: Problem mir StringResourcen...
 
Die resource hacker analysieren die binären Daten der Resource. Übrigens, das mit deinen empty strings macht mich nachdenklich. Das WIN32 API kann nicht zwischen leeren oder fehlenden string resourcen unterscheiden - deshalb mein code weiter oben...

marabu

PS: Auch wenn LoadString für leere und fehlende string resourcen die Länge 0 ermittelt - natürlich liefert GetLastError ERROR_RESOURCE_NAME_NOT_FOUND (1814) wenn nötig:

Delphi-Quellcode:
// funktioniert nur bei fortlaufender ID
function GetMaxStringID(start: integer): integer;
begin
  Result := start;
  repeat
    if (LoadStr(Result) = '')
    and (GetLastError = ERROR_RESOURCE_NAME_NOT_FOUND)
      then Break
      else Inc(Result);
  until false;
  if Result = start
    then Result := -1
    else Result := Pred(Result);
end;
Aber du hast ja dein Problem gelöst...

Flocke 30. Aug 2005 10:03

Re: Problem mir StringResourcen...
 
Zitat:

Zitat von FriFra
Selbst wenn ich mit EnumResourceNames alle Resourcen ermittle und versuche jede "Teilresource" zu laden um bei einem möglichen Fehler (nicht vorhanden) abzubrechen liefert mir GetLastError trotz definitiv nicht vorhandener ID ein ERROR_SUCCESS, deshalb komme ich auch so auf 175 statt 163 :roll:

Da in einer String-Ressource *IMMER* 16 Strings drin sind, kann Windows gar nicht mehr unterscheiden, ob du einzelne davon definiert hast oder nicht. Vielleicht schneidest du einfach die letzten leeren ab da diese ja offensichtlich nicht definiert sind.

//EDIT: schon wieder kein roter Kasten :evil:

marabu 30. Aug 2005 10:23

Re: Problem mir StringResourcen...
 
Hallo Flocke,

Zitat:

Zitat von Flocke
Da in einer String-Ressource *IMMER* 16 Strings drin sind

Du meinst bestimmt eine section, oder? Eine string resource ist genau ein string und eine STRINGTABLE kann Tausende von strings enthalten. Die section ist eine rein interne Verwaltungsstruktur, die nach außen (fast) keine Bedeutung hat. Eine section kann auch nur eine einzige string resource enthalten.

Freundliche Grüße vom marabu

FriFra 30. Aug 2005 10:40

Re: Problem mir StringResourcen...
 
Also Reshack "merkt" auch nicht, wenn eine leere Stringresource (163 und 165) da ist:
http://www.frifra.de/Temp/resreshack.jpg

Ich hab jetzt meine Funktion angepasst und nun läuft sie korrekt:
Delphi-Quellcode:
  function GetMaxResID: integer;
    function EnumResourceNamesProc(Module: HMODULE; ResType: PChar; ResID:
      Integer; lParam: TStringList): Integer; stdcall;
      function Fill(Wert: string): string;
      begin
        Result := Wert;
        while Length(Result) < 6 do
          Result := '0' + Result;
      end;
    var
      i: integer;
      Buffer: array[0..MAX_PATH] of Char;
    begin
      lParam.Add(Fill(IntToStr(ResId)));
      Result := 1;
    end;
  var
    Buffer: array[0..MAX_PATH] of Char;
    n, LastSection: integer;
    MyList: TStringList;
  begin
    LastSection := 0;
    MyList := TStringList.Create;
    MyList.Sorted := True;
    windows.EnumResourceNames(hinstance, RT_STRING, @EnumResourceNamesProc,
      Integer(MyList));
    if (MyList.Count > 0) and (StrToIntDef(MyList[0], -1) = 1) then
    begin
      Result := 0;
      LastSection := 1;
      for n := 1 to MyList.Count - 1 do
      begin
        if StrToIntDef(MyList[n], -1) = StrToIntDef(MyList[n - 1], -1) + 1 then
          LastSection := StrToIntDef(MyList[n], -1)
        else
          break;
      end;
      for n := (LastSection - 1) * 16 to (LastSection) * 16 do
        if LoadString(hinstance, n, @Buffer, MAX_PATH) > 0 then
          Result := n;
    end
    else
      Result := 0;
    MyList.Free;
  end;

Olli 30. Aug 2005 12:00

Re: Problem mir StringResourcen...
 
Tcha, dann gibt es die entweder nicht, weil sie leer sind (und das Ergebnis bei LoadString bleibt sich ja sowieso gleich), oder man muß es direkt über die Strukturen der PE-Datei versuschen.

Flocke 30. Aug 2005 12:30

Re: Problem mir StringResourcen...
 
Zitat:

Zitat von marabu
Hallo Flocke,

Zitat:

Zitat von Flocke
Da in einer String-Ressource *IMMER* 16 Strings drin sind

Du meinst bestimmt eine section, oder? Eine string resource ist genau ein string und eine STRINGTABLE kann Tausende von strings enthalten. Die section ist eine rein interne Verwaltungsstruktur, die nach außen (fast) keine Bedeutung hat. Eine section kann auch nur eine einzige string resource enthalten.

Freundliche Grüße vom marabu

Was ich meine ist genau eine Binärressource, die man mit FindResource finden und mit LoadResource laden kann. Vielleicht meinst du ja diesen Block mit "section". Dieser Datenblock beinhaltet immer (auf jeden Fall in den Beispielen die ich gesehen habe) 16 Unicode-Strings mit Längenprefix, also 16 Päckchen á (Länge, String[Länge]).

Der String, den man mit LoadString(N) lädt, steht in der Ressource vom Typ RT_STRING mit dem Namen MAKEINTRESOURCE((N div 16)+1) an Position (N mod 16). Wenn also der String 3 definiert ist, dann kann man rein technisch nicht mehr unterscheiden ob die Strings 0-2 und 4-15 auch definiert waren (eben leer) oder nicht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:48 Uhr.
Seite 2 von 2     12   

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