Einzelnen Beitrag anzeigen

Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.103 Beiträge
 
Delphi 12 Athens
 
#7

AW: Windows Codepages - Kernel32.dll - EnumSystemCodePages

  Alt 22. Jun 2023, 16:30
Trotzdem stellt sich mir die Frage, wo der Vorteil ist? Die statische Klasse erstellt auch eine "globale" Variable, ja OK, nicht wirklich global, weil ich nur über die Klasse darauf zugreifen kann. Aber sie wird beim Start des Programmes über CreateClass erzeugt und erst beim Beenden des Programmes über DestroyClass wieder freigegeben und belegt somit für die komplette Laufzeit Speicher. Auch dann wenn die Klasse nur in irgendeinem Modul benötigt wird, das vielleicht gar nicht vom User verwendet wird. Gibt es da nicht eine elegantere Lösung für API Callback-Funktionen, die nur dann Speicher belegen wenn sie aufgerufen werden, also ohne globale Variable?
Also, es wird ja lediglich der Speicher für ein dynamisches Array - also ein Pointer - verwendet. Das sind in 64-Bit gerade mal 8 Byte. Ich glaube kaum, dass das ins Gewicht fällt.

Hier ein alternativer Ansatz, der auch mehrere Threads berücksichtig. Basiert noch auf deinem ursprünglichen Code für die Formatierung. (Vermutlich nicht relevant, aber der Form halber: StrToUIntDef)
Delphi-Quellcode:
type
  TCodePageEnumerator = class
  strict private
  class threadvar
    CodePageNumbers: TList<Cardinal>;
    class function EnumCodePagesProc(CodePage: PWideChar): Cardinal; static; stdcall;
  strict protected
    class function FormatCodePageName(AValue: Cardinal; const AName: string): string; virtual;
    class function GetCodePageName(CP:Cardinal): String;
  public
    class procedure GetCodepageList(CodePageList: TStrings);
  end;

class procedure TCodePageEnumerator.GetCodepageList(CodePageList: TStrings);
begin
  CodePageNumbers := TList<Cardinal>.Create;
  try
    CodePageList.Clear;
    EnumSystemCodePages(@EnumCodePagesProc, CP_SUPPORTED);
    for var codePageNumber in CodePageNumbers do
    begin
      if codePageNumber > 0 then
        CodepageList.Add(Format('%.5d: %s', [codePageNumber, GetCodePageName(codePageNumber)]));
    end;
  finally
    CodePageNumbers.Free;
    CodePageNumbers := nil;
  end;
end;

class function TCodePageEnumerator.EnumCodePagesProc(CodePage: PWideChar): Cardinal;
Var
  Cp: Cardinal;
begin
  Result := 0;
  if CodePageNumbers = nil then Exit;
  if (CodePage <> Nil) then
  begin
    if (Length(CodePage) > 0) then
    begin
      Cp := StrToUIntDef(CodePage, 0);
      if (Cp > 0) then
      begin
        CodePageNumbers.Add(Cp);
        Result := 1;
      end;
    end;
  end;
end;

class function TCodePageEnumerator.FormatCodePageName(AValue: Cardinal; const AName: string): string;
begin
  Result := AName.Remove(0, AValue.ToString.Length + 1).TrimLeft.Trim(['(', ')']);
end;

class function TCodePageEnumerator.GetCodePageName(CP:Cardinal): String;
var CpInfoEx : TCPInfoEx;
begin
  Result := '';
  if IsValidCodePage(Cp) then
  begin
    GetCPInfoEx(Cp, 0, CpInfoEx);
    Result := FormatCodePageName(CP, CpInfoEx.CodePageName);
  end;
end;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat