AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Interface implementieren...

Ein Thema von barnti · begonnen am 20. Aug 2004 · letzter Beitrag vom 11. Jun 2005
Antwort Antwort
Seite 1 von 2  1 2      
barnti

Registriert seit: 15. Aug 2003
Ort: Mal hier mal da...
689 Beiträge
 
Delphi 7 Enterprise
 
#1

Interface implementieren...

  Alt 20. Aug 2004, 10:01
Hallo,
ich versuche immer noch meine Klasse für die 'FileInfo' zu erstellen. Hier ein Teil des Codes:
Delphi-Quellcode:
unit Versioninfo;

interface
uses
  Types,windows,SysUtils;
type
  TVersionInfo=class

  private
    FStandardKeys:array[0..9] of String; // Beinhaltet Alle FileInfos

    function GetVersioninfo(Index: Integer): String;
    function GetKey(KeyName: String): String;
    procedure SetVersionInfo(const Index: Integer; const Value: String);
    function GetBuildNumber: String;
  public
    constructor Create (ThisSourceFile: String);
    destructor Destroy; override;

    property Key[KeyName: String]: String read GetKey;

    property CompanyName: String index 0 read GetVersionInfo write SetVersionInfo;
    property FileDescription: String index 1 read GetVersionInfo;
    property FileVersion: String index 2 read GetVersionInfo;
    property InternalName: String index 3 read GetVersionInfo;
    property Copyright: String index 4 read GetVersionInfo;
    property TradeMarks: String index 5 read GetVersionInfo;
    property OriginalFileName: String index 6 read GetVersionInfo;
    property ProductName: String index 7 read GetVersionInfo write SetVersionInfo;
    property ProductVersion: String index 8 read GetVersionInfo write SetVersionInfo;
    property Comments: String index 9 read GetVersionInfo;
    property BuildNumber: String read GetBuildNumber;

    // Hier versuche ich auf die Eigenschaften zuzugreifen. Leider schlägt das Kompilieren fehl:
    // [Error] Versioninfo.pas(35): Incompatible types
    property StandardKeys[index: Integer]: String read GetVersionInfo write SetVersionInfo;
    
  end;

implementation

{ TVersionInfo }
const MaxVersionKeys= 9;
constructor TVersionInfo.Create(ThisSourceFile: String);
const
  VersionkeyNames: array[0..MaxVersionKeys] of String = ('CompanyName',
  'FileDescription','FileVersion','InternalName','Copyright','TradeMarks',
  'OriginalFileName','ProductName','ProductVersion','Comments');
var
  ThisInfo: Integer;
  InfoLength: UInt64;
  Len, Handle: DWord;
  PCharset: PLongint;
  LangCharset: String;
  InfoAvailable: Boolean;
begin
  inherited Create;

  // Get size of version info
  Len:= GetFileVersionInfoSize(PChar(ThisSourceFile),Handle);

  // Allocate VersionInfo buffer size
  SetLength(VersionInfo, Len+1);

  //Get version info
  if GetFileVersionInfo(PChar(ThisSourceFile), Handle,Len,Pointer(VersionInfo))
  then
  begin
    if VerQueryValue(Pointer(VersionInfo),'\VarFileInfo\Translation',
    Pointer(PCharSet),Len)then
    begin
      LangCharset:= Format('%.4x%.4x',[LoWord(PCharset^),HiWord(PCharset^)]);
      InfoAvailable:= true;
      for ThisInfo:=0 to MaxVersionKeys do
      begin
        // Hier sollen die Informationen übernommen werden...
        StandardKeys[ThisInfo]:= GetKey(VersionKeyNames[ThisInfo]);
      end;
    end;
 end;
end;

destructor TVersionInfo.Destroy;
begin

  inherited;
end;

function TVersionInfo.GetBuildNumber: String;
begin

end;

function TVersionInfo.GetKey(KeyName: String): String;
var
  
begin

end;

function TVersionInfo.GetVersioninfo(Index: Integer): String;
begin
  result:= FStandardKeys[Index]
end;

procedure TVersionInfo.SetVersionInfo(const Index: Integer;
  const Value: String);
begin
  FStandardKeys[Index]:= Value;
end;

end.
Kann jemand helfen? Ich versuche die File info im Konstruktor in die Variable 'StandardKeys' zu schreiben...
Gruß,

Barnti
  Mit Zitat antworten Zitat
MathiasSimmack
(Gast)

n/a Beiträge
 
#2

Re: Interface implementieren...

  Alt 20. Aug 2004, 10:09
Ich habe jetzt mal schnell eine alte Funktion rausgekramt (bitte auch hier den Patch beachten). Damit habe ich es mir relativ einfach gemacht, die Werte auszulesen, die ich brauche.

Evtl. kommst du mit einer ähnlichen Methode besser weg. Sprich: Aus dem Constructor würde ich den Code rausnehmen und lieber auslagern und dann die Properties gleich zuweisen. Ohne diesen Umweg über das Array "FStandardKeys".
  Mit Zitat antworten Zitat
barnti

Registriert seit: 15. Aug 2003
Ort: Mal hier mal da...
689 Beiträge
 
Delphi 7 Enterprise
 
#3

Re: Interface implementieren...

  Alt 20. Aug 2004, 10:14
Hi,
nett von Dir aber ich möchte es auf diese Weise implementieren. Kannst Du zu meinem Code etwas sagen? Wo liegt mein Fehler?
Gruß,

Barnti
  Mit Zitat antworten Zitat
MathiasSimmack
(Gast)

n/a Beiträge
 
#4

Re: Interface implementieren...

  Alt 20. Aug 2004, 11:34
Ich wollte dich keinesfalls in deinem Eifer bremsen. Wenn du mich nach deinem Code fragst, dann muss ich gestehen, dass ich den Sinn der Zeile
Zitat:
 property StandardKeys[index: Integer]: String read GetVersionInfo write SetVersionInfo;
nicht ganz verstehe. Warum führst du diese Variable heraus? Wozu soll das gut sein?

Ich habe eben mal auf der Basis deiner Unit eine Klasse zusammengezimmert, die sowohl mit einzelnen Strings als auch mit einem String-Array arbeitet (Compilerswitch). Was soll ich sagen? Keine Probleme.

btw: Das einzige, das mir im Moment wirklich als Problem auffällt, ist "Copyright". Das müsstest du in "LegalCopyright" ändern (im VersionkeyNames-Array), sonst liest du alles mögliche aus, aber nicht das Copyright.
  Mit Zitat antworten Zitat
barnti

Registriert seit: 15. Aug 2003
Ort: Mal hier mal da...
689 Beiträge
 
Delphi 7 Enterprise
 
#5

Re: Interface implementieren...

  Alt 20. Aug 2004, 11:40
Hallo,
ich habe deine Einwände bedacht und geändert. Kannst Du mir die 'zusammengezimmerte Klasse' einmal zeigen? Ich habe Probleme das so zu verstehen...
Danke!
Gruß,

Barnti
  Mit Zitat antworten Zitat
MathiasSimmack
(Gast)

n/a Beiträge
 
#6

Re: Interface implementieren...

  Alt 20. Aug 2004, 12:23
Delphi-Quellcode:
unit VersionInfo;

{.$DEFINE USEARRAY}

interface

uses
  Windows, SysUtils;

type
  TVersionInfo=class
  private
    FInfo : PVSFixedFileInfo;
{$IFDEF USEARRAY}
    FInfoKeys : array[0..9]of string;
{$ELSE}
    FCompanyName,
    FFileDescription,
    FFileVersion,
    FInternalName,
    FCopyright,
    FTrademarks,
    FOriginalFileName,
    FProductName,
    FProductVersion,
    FComments,
{$ENDIF}
    FVersionNumber : string;

    function FormatVersionNumber: string;
{$IFDEF USEARRAY}
    function GetKey(Idx: integer): string;
{$ENDIF}
  public
    constructor Create(const SourceFile: string);
    procedure LoadProperties(const SourceFile: string);

{$IFDEF USEARRAY}
    property CompanyName: string index 0 read GetKey;
    property FileDescription: string index 1 read GetKey;
    property FileVersion: string index 2 read GetKey;
    property InternalName: string index 3 read GetKey;
    property Copyright: string index 4read GetKey;
    property Trademarks: string index 5 read GetKey;
    property OriginalFileName: string index 6 read GetKey;
    property ProductName: string index 7 read GetKey;
    property ProductVersion: string index 8 read GetKey;
    property Comments: string index 9 read GetKey;
{$ELSE}
    property CompanyName: string read FCompanyName;
    property FileDescription: string read FFileDescription;
    property FileVersion: string read FFileVersion;
    property InternalName: string read FInternalName;
    property Copyright: string read FCopyright;
    property Trademarks: string read FTrademarks;
    property OriginalFileName: string read FOriginalFileName;
    property ProductName: string read FProductName;
    property ProductVersion: string read FProductVersion;
    property Comments: string read FComments;
{$ENDIF}
    property VersionNumber: string read FVersionNumber;
  end;

implementation

{$IFNDEF USEARRAY}
function GetFileInfo(const FileName, BlockKey: string): string;
var
  vis,
  dummy : dword;
  vi,
  translation,
  ip : pointer;
begin
  Result := '';
  vis := GetFileVersionInfoSize(pchar(FileName),dummy);
  if(vis > 0) then
  begin
    GetMem(vi,vis);
    try
      GetFileVersionInfo(pchar(Filename),0,vis,vi);
      if(vi = nil) then exit;

      // get language code
      VerQueryValue(vi,'\\VarFileInfo\\Translation',translation,vis);
      if(translation = nil) then exit;

      ip := nil;
      VerQueryValue(vi,
        pchar(Format('\\StringFileInfo\\%.4x%.4x\\%s',
          [LOWORD(longint(translation^)),HIWORD(longint(translation^)),
          BlockKey])),ip,vis);
      if(ip = nil) then exit;

      SetString(Result,pchar(ip),vis - 1);
    finally
      FreeMem(vi);
    end;
  end;
end;
{$ENDIF}

function GetDefaultFileInfo(const FileName: string): PVSFixedFileInfo;
var
  vis,
  dummy : dword;
  vi : pointer;
begin
  Result := nil;
  vis := GetFileVersionInfoSize(pchar(FileName),dummy);
  if(vis > 0) then
  begin
    GetMem(vi,vis);
    try
      GetFileVersionInfo(pchar(FileName),0,vis,vi);
      if(vi = nil) then exit;

      VerQueryValue(vi,'\\',pointer(Result),dummy);
    finally
      FreeMem(vi);
    end;
  end;
end;


// -- TVersionInfo -------------------------------------------------------------

constructor TVersionInfo.Create(const SourceFile: string);
begin
  inherited Create;
  self.LoadProperties(SourceFile);
end;

procedure TVersionInfo.LoadProperties(const SourceFile: string);
{$IFDEF USEARRAY}
const
  DefaultInfoKey : array[0..9]of string =
    ('CompanyName','FileDescription','FileVersion','InternalName',
     'LegalCopyright','TradeMarks','OriginalFileName','ProductName',
     'ProductVersion','Comments');
var
  vis,
  dummy : dword;
  vi,
  translation,
  ip : pointer;
  i : integer;
{$ENDIF}
begin
{$IFDEF USEARRAY}
  vis := GetFileVersionInfoSize(pchar(SourceFile),dummy);
  if(vis > 0) then
  begin
    GetMem(vi,vis);
    try
      GetFileVersionInfo(pchar(SourceFile),0,vis,vi);
      if(vi = nil) then exit;

      // get language code
      VerQueryValue(vi,'\\VarFileInfo\\Translation',translation,vis);
      if(translation = nil) then exit;

      for i := low(DefaultInfoKey) to high(DefaultInfoKey) do
      begin
        ip := nil;

        VerQueryValue(vi,
          pchar(Format('\\StringFileInfo\\%.4x%.4x\\%s',
            [LOWORD(longint(translation^)),HIWORD(longint(translation^)),
            DefaultInfoKey[i]])),ip,vis);
        if(ip = nil) then FInfoKeys[i] := ''
          else SetString(FInfoKeys[i],pchar(ip),vis - 1);
      end;
    finally
      FreeMem(vi);
    end;
  end;
{$ELSE}
  // fill properties
  FCompanyName := GetFileInfo(SourceFile,'CompanyName');
  FFileDescription := GetFileInfo(SourceFile,'FileDescription');
  FFileVersion := GetFileInfo(SourceFile,'FileVersion');
  FInternalName := GetFileInfo(SourceFile,'InternalName');
  FCopyright := GetFileInfo(SourceFile,'LegalCopyright');
  FTrademarks := GetFileInfo(SourceFile,'TradeMarks');
  FOriginalFileName := GetFileInfo(SourceFile,'OriginalFileName');
  FProductName := GetFileInfo(SourceFile,'ProductName');
  FProductVersion := GetFileInfo(SourceFile,'ProductVersion');
  FComments := GetFileInfo(SourceFile,'Comments');
{$ENDIF}

  FInfo := GetDefaultFileInfo(SourceFile);
  FVersionNumber := self.FormatVersionNumber;
end;

function TVersionInfo.FormatVersionNumber: string;
const
  FormatStr = '%d.%d.%d.%d';
begin
  Result := Format(FormatStr,
    [(FInfo^.dwFileVersionMS and $FFFF0000) shr 16,
      FInfo^.dwFileVersionMS and $0000FFFF,
     (FInfo^.dwFileVersionLS and $FFFF0000) shr 16,
      FInfo^.dwFileVersionLS and $0000FFFF]);
end;

{$IFDEF USEARRAY}
function TVersionInfo.GetKey(Idx: integer): string;
begin
  Result := FInfoKeys[Idx];
end;
{$ENDIF}

end.
Ich hoffe, du kommst mit den Compilerschaltern klar. Im Moment werden die einzelnen Strings benutzt. Willst du mit dem String-Array arbeiten, dann entferne den Punkt in der Zeile
{.$DEFINE USEARRAY} Ach so, ein Beispiel vllt. noch, damit du weißt warum ich das Laden der Properties in eine separate Funktion gepackt habe:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  vi : TVersionInfo;
begin
  vi := TVersionInfo.Create('c:\pctools\smc.exe');
  try
    Memo1.Lines.Add(vi.CompanyName);
    Memo1.Lines.Add(vi.VersionNumber);
    Memo1.Lines.Add('');

    vi.LoadProperties('c:\pctools\hed.exe');
    Memo1.Lines.Add(vi.ProductName);
    Memo1.Lines.Add(vi.Copyright);
  finally
    FreeAndNil(vi);
  end;
end;
btw: Weil du das MSDN-Library durchsuchenVS_FIXEDFILEINFO-Record in der privaten Variablen "FInfo" hast, könntest du auch auf andere Daten zugreifen, nicht bloß auf die Versionsnummer.
  Mit Zitat antworten Zitat
barnti

Registriert seit: 15. Aug 2003
Ort: Mal hier mal da...
689 Beiträge
 
Delphi 7 Enterprise
 
#7

Re: Interface implementieren...

  Alt 20. Aug 2004, 12:29
Hallo,
ich dachte Du hast das nach meinem Quellcode implementiert? Ich verfüge bereits über Beispiele, wie man die Info ermittelt.
Ich würde gern wissen wo mein Fehler in meinem Quellcode liegt!
Hast Du da einen Tip?
Quellcode:
siehe dieses post
Gruß,

Barnti
  Mit Zitat antworten Zitat
MathiasSimmack
(Gast)

n/a Beiträge
 
#8

Re: Interface implementieren...

  Alt 20. Aug 2004, 12:34
Natürlich war deine Unit die Grundlage. Bloß warum soll ich deine Fehler übernehmen? Ich hab´s so gestaltet, dass es für mich einfach zu handhaben war. Außerdem hast du mir immer noch nicht die Frage beantwortet, warum du unbedingt das String-Array als öffentliche Eigenschaft haben willst. Welchen Sinn soll das machen?
  Mit Zitat antworten Zitat
barnti

Registriert seit: 15. Aug 2003
Ort: Mal hier mal da...
689 Beiträge
 
Delphi 7 Enterprise
 
#9

Re: Interface implementieren...

  Alt 20. Aug 2004, 12:42
Hallo,
das habe ich bereits entfernt.
Ich verstehe, dass du wenig Arbeithaben willst aber mein Ziel ist es nicht anderen Code zu übernehmen sondern meinen zum Laufen zu kriegen...
Der Fehler steckt im Aufruf im Konstruktor:
Delphi-Quellcode:
... // Diese liefert mir immer false, obwohl Informationen vorhanden sind.
  if VerQueryValue(Pointer(ThisSourceFile),'\VarFileInfo\Translation',
       Pointer(PCharSet),Len) then
    begin
      //LangCharset:= Format('%.4x%.4x',[LoWord(PCharset^),HiWord(PCharset^)]);
      InfoAvailable:= true;
...
Ich denke die Wahl meiner Parameter und deren Initialisierung ist falsch. Ich weiß nur nicht was falsch ist. Auch nach durchsicht deines Codes habe ich den Fehler noch nicht gefunden.
Gruß,

Barnti
  Mit Zitat antworten Zitat
MathiasSimmack
(Gast)

n/a Beiträge
 
#10

Re: Interface implementieren...

  Alt 20. Aug 2004, 12:47
Ich finde das wirklich gut, dass du es allein hinbekommen willst. Das ist mehr, als manch andere wollen. Aber andererseits: Ich habe meine Umsetzung erst absichtlich nicht gepostet, eben weil du es selbst machen wolltest. Dann hast du darum gebeten, und ich hab sie dir gezeigt.

Und da ich keine Probleme mit dem Auslesen der Versionsnummer habe, und weil ich notgedrungen die gleichen Befehle verwenden muss wie du (logisch, oder? ), spricht IMHO nichts dagegen, wenn du dir einfach mal nur diesen Teil meiner Umsetzung ansiehst.
Genauer gesagt: Ich habe das Rückgabeergebnis von "VerQueryValue" ignoriert und stattdessen geschaut ob meine pointer-Variable ungleich nil ist.
Delphi-Quellcode:
      VerQueryValue(vi,
        pchar(Format('\\StringFileInfo\\%.4x%.4x\\%s',
          [LOWORD(longint(translation^)),HIWORD(longint(translation^)),
          BlockKey])),ip,vis);
      if(ip = nil) then exit;
Wie gesagt, Null Probleme.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 23: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