unit UserDefinedProperties;
{$WARN SYMBOL_PLATFORM OFF}
interface
uses ComObj, ActiveX, LocalFiles_TLB, StdVcl;
type
TVariantNameValue=packed record Name:string; Value:Variant; end;
TVariantNameValueList=array of TVariantNameValue;
TUserDefinedProperties = class(TAutoObject, IUserDefinedProperties) private FFilePath:WideString; FNameValues:TVariantNameValueList; FCount:Integer; private procedure Set_FilePath(Value:WideString); procedure GetProperties; public procedure Initialize;override; protected function Get_Count: Integer; safecall; function Get_Name(Index: Integer): WideString; safecall; function Get_Value(Index: Integer): OleVariant; safecall; function Get_GetValueByName(const Name: WideString): OleVariant; safecall; procedure SetValueByName(const Name: WideString; Value: OleVariant); safecall; public property FilePath:WideString read FFilePath write Set_FilePath; end;
implementation
uses ComServ,Dialogs,SysUtils,Variants,Windows,Classes;
{ TUserDefinedProperties }
procedure TUserDefinedProperties.GetProperties; const FMTID_UserDefinedProperties:TGUID='{D5CDD505-2E9C-101B-9397-08002B2CF9AE}'; type TPropSpecArray=array[0..0] of TPropSpec; PPropSpecArray=^TPropSpecArray; TPropVariantArray=array[0..0] of TPropVariant; PPropVariantArray=^TPropVariantArray; TStatPropStgArray=array[0..0] of TStatPropStg; PStatPropStgArray=^TStatPropStgArray; var Storage:IStorage; PSStorage:IPropertySetStorage; PS:IPropertyStorage; Enum:IEnumSTATPROPSTG; PSArray:PPropSpecArray; PVArray:PPropVariantArray; SPS:PStatPropStgArray; LocalFileTime:TFileTime; Systime:TSystemTime; begin if StgOpenStorage(StringToOleStr(FFilePath),nil,STGM_READ or STGM_SHARE_EXCLUSIVE,nil,0,Storage)<>S_OK then Exit; PSStorage:=Storage as IPropertySetStorage; if PSStorage.Open(FMTID_UserDefinedProperties,STGM_READ or STGM_SHARE_EXCLUSIVE,PS)<>S_OK then Exit; // GetMem(PSArray,SizeOf(TPropSpec)); GetMem(PVArray,SizeOf(TPropVariant)); GetMem(SPS,SizeOf(TStatPropStg)); // if PS.Enum(Enum)<>S_OK then Exit; while Enum.Next(1,SPS[0],nil)=S_OK do begin Inc(FCount); PSArray[0].ulKind:=PRSPEC_PROPID; PSArray[0].propid:=SPS[0].propid; PS.ReadMultiple(1,@PSArray[0],@PVArray[0]); SetLength(FNameValues,FCount); FNameValues[FCount-1].Name:=WideCharToString(SPS[0].lpwstrName); case PVArray[0].vt of //整数 VT_I4:FNameValues[FCount-1].Value:=PVArray[0].lVal; //实数 VT_R8:FNameValues[FCount-1].Value:=PVArray[0].dblVal; //是否 VT_BOOL:FNameValues[FCount-1].Value:=PVArray[0].boolVal; //字符 VT_LPSTR:FNameValues[FCount-1].Value:=UTF8Decode(PVArray[0].pszVal);//一定要解码 //日期 VT_FILETIME: begin //日期要转换到当前时区 FileTimeToLocalFileTime(PVArray[0].filetime,LocalFileTime); FileTimeToSystemTime(LocalFileTime,Systime); FNameValues[FCount-1].Value:=SystemTimeToDateTime(Systime); end; end; end; // if PSArray<>nil then FreeMem(PSArray); if PVArray<>nil then FreeMem(PVArray); if SPS<>nil then FreeMem(SPS); // PS:=nil; PSStorage:=nil; end;
procedure TUserDefinedProperties.Initialize; begin inherited; FCount:=0; end;
procedure TUserDefinedProperties.Set_FilePath(Value: WideString); begin FFilePath:=Value; GetProperties; end;
function TUserDefinedProperties.Get_Count: Integer; begin Result:=FCount; end;
function TUserDefinedProperties.Get_Name(Index: Integer): WideString; begin if (Index>=0) and (Index<FCount) then Result:=FNameValues[Index].Name else Result:=''; end;
function TUserDefinedProperties.Get_Value(Index: Integer): OleVariant; begin if (Index>=0) and (Index<FCount) then Result:=FNameValues[Index].Value else Result:=NULL; end;
function TUserDefinedProperties.Get_GetValueByName( const Name: WideString): OleVariant; var Counter:Integer; begin for Counter:=0 to FCount-1 do if WideCompareText(Name,FNameValues[Counter].Name)=0 then begin Result:=FNameValues[Counter].Value; Exit; end; Result:=NULL; end;
procedure TUserDefinedProperties.SetValueByName(const Name: WideString; Value: OleVariant); const FMTID_UserDefinedProperties:TGUID='{D5CDD505-2E9C-101B-9397-08002B2CF9AE}'; type TPropSpecArray=array[0..0] of TPropSpec; PPropSpecArray=^TPropSpecArray; TPropVariantArray=array[0..0] of TPropVariant; PPropVariantArray=^TPropVariantArray; TStatPropStgArray=array[0..0] of TStatPropStg; PStatPropStgArray=^TStatPropStgArray; var Storage:IStorage; PSStorage:IPropertySetStorage; PS:IPropertyStorage; PSArray:PPropSpecArray; PVArray:PPropVariantArray; LocalFileTime:TFileTime; Systime:TSystemTime; begin if StgOpenStorage(StringToOleStr(FFilePath),nil,STGM_READWRITE or STGM_SHARE_EXCLUSIVE,nil,0,Storage)<>S_OK then Exit; PSStorage:=Storage as IPropertySetStorage; if PSStorage.Open(FMTID_UserDefinedProperties,STGM_READWRITE or STGM_SHARE_EXCLUSIVE,PS)<>S_OK then Exit; // GetMem(PSArray,SizeOf(TPropSpec)); GetMem(PVArray,SizeOf(TPropVariant)); // PSArray[0].ulKind:=PRSPEC_LPWSTR; PSArray[0].lpwstr:=PWideChar(Name); PVArray[0].vt:=VarType(Value); if PVArray[0].vt=VT_BSTR then PVArray[0].vt:=VT_LPSTR; if PVArray[0].vt=VT_DATE then PVArray[0].vt:=VT_FILETIME; // case PVArray[0].vt of //整数 VT_I4:PVArray[0].lVal:=Value; //实数 VT_R8:PVArray[0].dblVal:=Value; //是否 VT_BOOL:PVArray[0].boolVal:=Value; //字符 VT_LPSTR:PVArray[0].pszVal:=PAnsiChar(UTF8Encode(Value)); //日期 VT_FILETIME: begin DateTimeToSystemTime(Value,Systime); SystemTimeToFileTime(Systime,LocalFileTime); LocalFileTimeToFileTime(LocalFileTime,PVArray[0].filetime); end; end; case PVArray[0].vt of VT_I4,VT_R8,VT_BOOL,VT_LPSTR,VT_FILETIME: PS.WriteMultiple(1,@PSArray[0],@PVArray[0],2); end; // if PSArray<>nil then FreeMem(PSArray); if PVArray<>nil then FreeMem(PVArray); // PS:=nil; PSStorage:=nil; end;
initialization TAutoObjectFactory.Create(ComServer, TUserDefinedProperties, Class_UserDefinedProperties, ciMultiInstance, tmApartment); end.
|
请发表评论