Announcement

Collapse
No announcement yet.

Dateiinfo

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Dateiinfo

    Hallo zusammen,
    ich suche eine Möglichkeit die Informationen über eine Datei abzufragen, die man erhält, wenn man im Explorer im Kontextmenü die Eigenschaften einer Datei öffnet und sich dort das Dateiinfo anzeigen läßt, also z.B. Titel, Betreff, Autor.
    Über die ShellApi-Funktion SHGetFileInfo scheint man nicht an diese Informationen zu kommen(oder verstehe ich die FileInfoDatenstruktur nur nicht richtig?). Hat jemand vielleicht einen Tipp für mich?
    Schon im voraus

    Vielen Dank

    Heinz-Peter

  • #2
    Hallo,

    das folgende Beispiel aus meinem Buch <i>COM/DCOM/COM+ mit Delphi</i> demonstriert das Auslesen dieser Infos:

    <pre>

    { ************************************************** **************
    Source File Name : DocSummaryFrm
    Typ : Objekt-Unit
    Autor : Andreas Kosch
    Compiler : Delphi 5.01 Enterprise UpdatePack 1
    Betriebssystem : Windows 98
    Beschreibung : IPropertyStorage liest SummaryInformation
    aus einer Structured Storage-Datei aus
    (hier am Beispiel Microsoft Word-Dokument)
    ************************************************** ************** }

    unit OSDocSum;

    interface

    uses SysUtils, Classes, Windows, ActiveX;

    type
    TOSDocSummary = class
    private
    FPSpec : PPropSpec;
    FDummy : PPropVariant;
    FAuthor : String;
    FTitle : String;
    FSubject : String;
    FLastAuthor : String;
    FTemplate : String;
    FLastSaved : String;
    procedure FillPropertySpec(aPropID : TPropID);
    public
    constructor Create;
    destructor Destroy; override;
    function GetSummaryInfo(sFileName: String): Boolean;
    published
    property Author: String read FAuthor;
    property Title: String read FTitle;
    property Subject : String read FSubject;
    property LastAuthor: String read FLastAuthor;
    property Template: String read FTemplate;
    property LastSaved: String read FLastSaved;
    end;

    implementation

    uses AxCtrls, ComObj, Dialogs;

    resourcestring
    sErrorNoDocFile = 'Die Datei »%s« ist keine OLE-Structured-Storage-Datei!';
    const
    FMTID_SummaryInformation: TGUID = '{F29F85E0-4FF9-1068-AB91-08002B27B3D9}';

    { TOSDocSummary }

    { Der letze Parameter von IPropertySetStorage.ReadMultiple ist in der
    Unit "ActiveX" falsch deklariert. Daher muß für die Zeigervariable FDummy
    die Speichergröße der korrekten Struktur angefordert werden.
    Bei der Auswertung der Ergebnisse sorgt ein Typecasting dafür, daß
    trotzdem die richtigen Daten abrufbar sind. }

    constructor TOSDocSummary.Create;
    begin
    inherited Create;
    FPSpec := New(PPropSpec);
    GetMem(FDummy, SizeOf(TPropVariant));
    end;

    destructor TOSDocSummary.Destroy;
    begin
    Dispose(FPSpec);
    FreeMem(FDummy, SizeOf(TPropVariant));
    inherited Destroy;
    end;

    { Microsoft Word verwendet OLE-Structurd-Storage-Dateien, bei
    denen gemäß dem OLE-Standard die Zusammenfassung in einem
    Stream (0x05SummaryInformation) in der Wurzel-Storage
    gespeichert werden. Alle mit "0x05" beginnenden Streams
    definieren sogenannte "Shared properties", d.h. unter Win32
    kann das Betriebssystem diese Zusammenfassung ohne Mithilfe
    des Anwendungsprogramms auslesen (d.h. Word muß nicht
    installiert sein, um die Zusammenfassung der DOC-Datei aus-
    lesen zu können.

    Dazu stehen 2 Wege zur Verfügung:
    a) Universeller, komplizierter Weg für alle Win32-Versionen
    (siehe VC++98, Demoprogramm DRAWCL = 50 Seiten C++),
    indem die dokumentierte Datenstruktur des Streams in
    die einzelnen Bestandteile aufgesplittet wird. Microsoft
    hat dazu 2 Hilfsklassen für die MFC (also C++) in einem
    Demo-Programm zu VisualC++ 98 ausgeliefert.
    b) Neuer, einfacher Weg für aktuelle Win32-Versionen (d.h.
    Windows NT 4 SP3, Win95+IE4; Win95+DCOM for Windows95)
    über das neue IPropertyStorage-Interface. Da mittlerweile
    wohl die meisten auf den Internet Explorer 4 bzw. DCOM
    umgestiegen sind, verwendet das folgende Beispiel den
    einfachen Weg.

    Problem Delphi 4:
    - FMTID_SummaryInformation wird nicht deklariert, daher
    muß die CLSID direkt aus "Inside OLE" (MSDN Okt.98)
    übernommen werden
    - letzer Parameter von IPropertySetStorage.ReadMultiple ist
    in der Unit "ActiveX" falsch deklariert !!!
    Lösung:
    - direktes Typcasting der Zeigervariable }

    function TOSDocSummary.GetSummaryInfo(sFileName: String): Boolean;
    var
    swFileName : WideString;
    aRoot : IStorage;
    aPropSet : IPropertySetStorage;
    aPropStor : IPropertyStorage;
    pLocaleFT : _FileTime;
    pST : _SystemTime;
    begin
    Result := False;
    swFileName := sFileName;
    // gültige OLE-Structured-Storage-Datei ?
    if (StgIsStorageFile(PWideChar(swFileName)) <> S_OK) then
    begin
    MessageBeep(MB_ICONEXCLAMATION);
    ShowMessage(Format(sErrorNoDocFile, [sFileName]));
    Abort;
    end;
    OleCheck(StgOpenStorage(PWideChar(swFileName), nil, STGM_READWRITE or
    STGM_DIRECT or STGM_SHARE_EXCLUSIVE, nil, 0, aRoot));
    aPropSet := aRoot as IPropertySetStorage;
    // Shared Property "\0x05SummaryInformation" über die FMTID anfordern
    OleCheck(aPropSet.Open(FMTID_SummaryInformation,
    STGM_READ or STGM_SHARE_EXCLUSIVE, aPropStor));
    // Property "AUTHOR"
    FillPropertySpec(PIDSI_AUTHOR);
    OleCheck(aPropStor.ReadMultiple(1, FPSpec, FDummy));
    FAuthor := TPropVariant(Pointer(FDummy)^).pszVal;
    // Property "TITLE"
    FillPropertySpec(PIDSI_TITLE);
    OleCheck(aPropStor.ReadMultiple(1, FPSpec, FDummy));
    FTitle := TPropVariant(Pointer(FDummy)^).pszVal;
    // Property "SUBJECT"
    FillPropertySpec(PIDSI_SUBJECT);
    OleCheck(aPropStor.ReadMultiple(1, FPSpec, FDummy));
    FSubject := TPropVariant(Pointer(FDummy)^).pszVal;
    // Property "LASTAUTHOR"
    FillPropertySpec(PIDSI_LASTAUTHOR);
    OleCheck(aPropStor.ReadMultiple(1, FPSpec, FDummy));
    FLastAuthor := TPropVariant(Pointer(FDummy)^).pszVal;
    // Property "TEMPLATE"
    FillPropertySpec(PIDSI_TEMPLATE);
    OleCheck(aPropStor.ReadMultiple(1, FPSpec, FDummy));
    FTemplate := TPropVariant(Pointer(FDummy)^).pszVal;
    // Property "LASTSAVE_DTM"
    FillPropertySpec(PIDSI_LASTSAVE_DTM);
    OleCheck(aPropStor.ReadMultiple(1, FPSpec, FDummy));
    // Dateidatum konvertieren
    FileTimeToLocalFileTime(TPropVariant(Pointer(FDumm y)^).FileTime, pLocaleFT);
    FileTimeToSystemTime(pLocaleFT, pST);
    FLastSaved := Format('%d.%d.%d um %d:%d Uhr',
    [pST.wDay, pST.wMonth, pST.wYear,
    pST.wHour, pST.wMinute]);
    Result := True;
    end;

    { Festlegen, was zurückgeliefert werden soll. Das gesuchte Property
    kann entweder über den Namen oder über seine Property-ID definiert
    werden (siehe Unit "ActiveX"). Dieses Objekt verwendet nur die
    Property-IDs. Die Struktur muß vor der Übergabe durch den Aufrufer
    initialisiert werden. }

    procedure TOSDocSummary.FillPropertySpec(aPropID : TPropID);
    begin
    FillChar(FPSpec^, SizeOf(TPropSpec), #0);
    with FPSpec^ do
    begin
    ulKind := PRSPEC_PROPID;
    PropID := aPropID;
    end;
    end;

    end.

    </pre&gt

    Comment


    • #3
      Hallo Herr Kosch,

      und wie schreibt/liest man die Thumbnail-Informationen in/aus den SummeryInformationen?

      Gruß

      Dieter Keune

      Comment

      Working...
      X