Ich muss mal diesen Beitrag aus der Versenkung holen, weil mich ein paar Dinge interessieren -
Ich nehme mal an, dass du, @Luckie, die Funktion "GetFileSummaryInfo" so beschnitten hast, dass sie grundsätzlich den Kommentar zurückliefert. Ich wollte mir auch andere Werte anzeigen lassen und musste die Funktion dafür erst einmal öffnen. Dabei ist mir aufgefallen, dass die Funktion nichts anzeigt, wenn man die gewünschte Eigenschaft vorher mit Bordmitteln (sprich: Rechtsklick auf die Datei -> Eigenschaften -> Dateiinfos) setzt.
Erst wenn ich bspw. mit dem Programm den Kommentar eintragen lasse, wird er hinterher von "GetFileSummaryInfo" auch angezeigt. Der Witz dabei: Wenn ich jetzt andere Eigenschaften über den Windows-Dialog eintrage, dann werden mir die auch von der Funktion angezeigt.
Das wäre das erste Problem, über das man diskutieren müsste. @mirage: Vorschläge?
Der zweite Punkt ist kein Problem sondern ein Vorschlag. Die Funktion aus deinem Programm, @Luckie, lässt sich nämlich wie folgt verkürzen
Delphi-Quellcode:
function GetFileSummaryInfo(const FileName: WideString;
GUID_SummaryType: TGUID; PID_InfoType: cardinal): WideString;
var
Stg : IStorage;
PropSetStg : IPropertySetStorage;
PropStg : IPropertyStorage;
PropSpec : TPropSpec;
PropVariant : TPropVariant;
begin
Result := '';
if(StgOpenStorageEx(pwidechar(FileName),STGM_READ or STGM_SHARE_DENY_WRITE,
STGFMT_FILE,0,nil,nil,@IID_IPropertySetStorage,Stg) = S_OK) then
begin
PropSetStg := Stg as IPropertySetStorage;
if(PropSetStg.Open(GUID_SummaryType,STGM_READ or
STGM_SHARE_EXCLUSIVE,PropStg) = S_OK) then
begin
PropSpec.ulKind := PRSPEC_PROPID;
PropSpec.propid := PID_InfoType;
if(PropStg.ReadMultiple(1,@PropSpec,@PropVariant) = S_OK) and
(PropVariant.vt = VT_LPWSTR) and
(PropVariant.pwszVal <> nil) then
Result := PropVariant.pwszVal;
end;
end;
end;
und funktioniert trotzdem noch.
Vorteil: Man kann auch die gewünschte
GUID übergeben, um bspw. die Kategorie auszulesen:
Delphi-Quellcode:
dummy := GetFileSummaryInfo('MeineDatei.txt',FMTID_DocSummaryInformation,
PID_CATEGORY);
MessageBoxW(self.handle,pwidechar(dummy),nil,0);
Weiter -
In der Funktion "SetFileSummaryInfo" gibt es
IMHO das Problem, dass
Delphi-Quellcode:
OleCheck(PropSetStg.Create(FmtID_SummaryInformation, FmtID_SummaryInformation,
PROPSETFLAG_DEFAULT,
STGM_CREATE or STGM_READWRITE or STGM_SHARE_EXCLUSIVE, PropStg));
verwendet wurde. Laut
PSDK wird durch "Create" ein neues Property-Set angelegt, und das hat zur Folge, dass die anderen Werte (in dem Fall Autor, Titel und Betreff) gelöscht werden. Nach ein bisschen Herumspielen bin ich der Meinung, dass die Funktion besser so aussehen sollte:
Delphi-Quellcode:
function SetFileSummaryInfo(const FileName: WideString; GUID_InfoType: TGUID;
PID_InfoType: Cardinal; InfoStr: WideString): boolean;
var
PropSetStg : IPropertySetStorage;
PropSpec : TPropSpec;
hr : HRESULT;
PropStg : IPropertyStorage;
PropVariant : TPropVariant;
Stg : IStorage;
begin
Result := false;
if(StgOpenStorageEx(pwidechar(FileName),STGM_SHARE_EXCLUSIVE or
STGM_READWRITE,STGFMT_ANY,0,nil,nil,@IID_IPropertySetStorage,stg) =
S_OK) then
begin
PropSetStg := Stg as IPropertySetStorage;
// try to open an existing Property set
hr := PropSetStg.Open(GUID_InfoType,STGM_READWRITE or
STGM_SHARE_EXCLUSIVE,PropStg);
// create a new set
if(hr <> S_OK) then
hr := PropSetStg.Create(GUID_InfoType,GUID_InfoType,
PROPSETFLAG_DEFAULT,STGM_CREATE or STGM_READWRITE or
STGM_SHARE_EXCLUSIVE,PropStg);
if(hr = S_OK) then
begin
PropSpec.ulKind := PRSPEC_PROPID;
PropSpec.propid := PID_InfoType;
PropVariant.vt := VT_LPWSTR;
PropVariant.pwszVal := PWideChar(InfoStr);
if(PropStg.WriteMultiple(1,@PropSpec,@PropVariant,2) = S_OK) then
begin
Result := (PropStg.Commit(STGC_DEFAULT) = S_OK);
end;
end;
end;
end;
Damit bleiben die alten Werte erhalten, und man kann auch wieder andere Eigenschaften wählen, indem man die passende
GUID angibt (s. oben beim Beispiel der Kategorie). Und der Rückgabewert ist gleich vom bool-Typ.
So, das war´s erst mal von meiner Seite.