Ole2 Storage.

0

Wie moze ktos gdzie moge znalezc cos na temat OLE2 Storage i czy sa jakies moduly oblugujace ten format plikow?

0

W delphi znajdziesz plik ole2.pas.
Tam jest coś takiego:

{ IStorage interface }

  TSNB = ^POleStr;

  {$EXTERNALSYM IStorage}
  IStorage = class(IUnknown)
  public
    function CreateStream(pwcsName: POleStr; grfMode: Longint; reserved1: Longint;
      reserved2: Longint; var stm: IStream): HResult; virtual; stdcall; abstract;
    function OpenStream(pwcsName: POleStr; reserved1: Pointer; grfMode: Longint;
      reserved2: Longint; var stm: IStream): HResult; virtual; stdcall; abstract;
    function CreateStorage(pwcsName: POleStr; grfMode: Longint;
      dwStgFmt: Longint; reserved2: Longint; var stg: IStorage): HResult;
      virtual; stdcall; abstract;
    function OpenStorage(pwcsName: POleStr; stgPriority: IStorage;
      grfMode: Longint; snbExclude: TSNB; reserved: Longint;
      var stg: IStorage): HResult; virtual; stdcall; abstract;
    function CopyTo(ciidExclude: Longint; rgiidExclude: PIID;
      snbExclude: TSNB; stgDest: IStorage): HResult; virtual; stdcall; abstract;
    function MoveElementTo(pwcsName: POleStr; stgDest: IStorage;
      pwcsNewName: POleStr; grfFlags: Longint): HResult; virtual; stdcall; abstract;
    function Commit(grfCommitFlags: Longint): HResult; virtual; stdcall; abstract;
    function Revert: HResult; virtual; stdcall; abstract;
    function EnumElements(reserved1: Longint; reserved2: Pointer; reserved3: Longint;
      var enm: IEnumStatStg): HResult; virtual; stdcall; abstract;
    function DestroyElement(pwcsName: POleStr): HResult; virtual; stdcall; abstract;
    function RenameElement(pwcsOldName: POleStr;
      pwcsNewName: POleStr): HResult; virtual; stdcall; abstract;
    function SetElementTimes(pwcsName: POleStr; const ctime: TFileTime;
      const atime: TFileTime; const mtime: TFileTime): HResult;
      virtual; stdcall; abstract;
    function SetClass(const clsid: TCLSID): HResult; virtual; stdcall; abstract;
    function SetStateBits(grfStateBits: Longint; grfMask: Longint): HResult;
      virtual; stdcall; abstract;
    function Stat(var statstg: TStatStg; grfStatFlag: Longint): HResult;
      virtual; stdcall; abstract;
  end;

Opis tego, to chyba najlepiej w MSDN Library.

IStorage : IUnknownThis interface provides methods for creating and managing the root storage, child storage, and stream objects. These methods can create, open, enumerate, move, copy, rename, or delete the elements in the storage object.

The IStorage interface supports the creation and management of structured storage objects. Structured storage allows hierarchical storage of information within a single file, and is often referred to as ?a file system within a file?. Elements of a structured storage object are storages and streams. Storages are analogous to directories, and streams are analogous to files. Within a structured storage there will be a primary storage object that may contain substorages, possibly nested, and streams. Storages provide the structure of the object, and streams contain the data, which is manipulated through the IStream interface.

(...)

Pozdrrawiam..

0

Wilekie dzieki zaraz sie do roboty biore :D. Niestety to co mi podales jest dla c i nie przeklada sie to na delphi wiec jakby ktos wiedzial gdzie mozna znalezc takie cos ale dla dlephi to bede wdzieczny.

0

Natknolem sie na kolejny problem... przy wywolywaniu metody OpenStorage z klasy IStorage wyskakuje mi Abstract Error.

procedure TForm1.Button1Click(Sender: TObject);
var
  fName   : array[0..100] of WideChar;
  data : IStorage;
begin
  data:=IStorage.Create;
  StringToWideChar(edit1.Text, fName, Length(edit1.Text)+1);
  data.OpenStorage(fName,nil,STGM_READ,nil,0,data);
end;
0
stopak napisał(a)

Natknolem sie na kolejny problem... przy wywolywaniu metody OpenStorage z klasy IStorage wyskakuje mi Abstract Error.

procedure TForm1.Button1Click(Sender: TObject);
var
  fName   : array[0..100] of WideChar;
  data : IStorage;
begin
  data:=IStorage.Create;
  StringToWideChar(edit1.Text, fName, Length(edit1.Text)+1);
  data.OpenStorage(fName,nil,STGM_READ,nil,0,data);
end;
IStorage

jest klasą abstrakcyjną (interface) i nie możesz utworzyć jej instancji. Spróbuj skorzystać z StgCreateStorageEx lub StgOpenStorageEx.

PS. Poczytaj jeszcze o IUnknown::AddRef i IUnknown::Release

0

Można też w ten sposób:
Nie jestem 100% pewien, ale chyba działa.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,activex;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


procedure TForm1.Button1Click(Sender: TObject);
var
  PStorage      : IStorage;
  PPersistStream: IPersistStream;
  PStream       : IStream;
  WideName,StreamName      : array[0..1023] of WideChar;
  Hr            : HRESULT;

begin
CoInitialize(nil);
  PStorage       := nil;
  PStream        := nil;
  StringToWideChar(edit1.Text, WideName, Length(edit1.Text)+1);
  StringToWideChar('Stream1', WideName, Length('Stream1')+1);


  hr := StgCreateDocfile(@WideName,
        STGM_CREATE or STGM_TRANSACTED or STGM_READWRITE or STGM_SHARE_EXCLUSIVE,
        0, PStorage);

  if Failed(Hr) then  Exit;


  hr := PStorage.CreateStream(@StreamName,
        STGM_WRITE or STGM_CREATE or STGM_SHARE_EXCLUSIVE,
        0, 0, PStream);


  if Failed(Hr) then  Exit;

//na koniec
PStream  := nil;
PStorage := nil;
CoUninitialize();
end;

end.
0

wielkie dzieki zaraz sprawdze czy dziala i odpisze :D.

0

I powstal nastepny problem :D dlaczego jak drugi raz wywoluje read z klasy IStream to wywala mi blad?

procedure TForm1.Button1Click(Sender: TObject);
var
  fName,sName   : array[0..100] of WideChar;
  hr: HRESULT;
  data: IStorage;
  stream: IStream;
  Id: head;
  sdata:byte;
begin
  StringToWideChar(edit1.Text, fName, Length(edit1.Text)+1);
  StringToWideChar('Workbook', sName, Length('Workbook')+1);
  if (StgIsStorageFile(fName) = S_OK) then
  begin
        hr := StgOpenStorage(fName,Nil,STGM_READ or STGM_SHARE_EXCLUSIVE or STGM_DIRECT,Nil,0,data);
        if (hr <> S_OK) then
        begin
                ShowMessage('Cannot open storage file.');
                Exit;
        end;
        hr := data.OpenStream(sName,nil,STGM_READ or STGM_SHARE_EXCLUSIVE or STGM_DIRECT,0,stream);
        if (hr <> S_OK) then
        begin
                ShowMessage('Cannot open data stream.');
                Exit;
        end;
        hr := stream.Read(@id,4,nil);
        stream.Read(@sdata,2,nil);
        if (hr <> S_OK) then
        begin
                ShowMessage('Cannot read data from stream.');
                Exit;
        end;
        Memo1.Lines.Add(IntToStr(id.Id));
        Memo1.Lines.Add(IntToStr(id.DSize));
        Memo1.Lines.Add(IntToStr(Sdata));
  end
  else
        ShowMessage('There is no storage file like: '+WideCharToString(fName));
end;
0

Nie wiem, być może się myle (nie programuje w Delphi) ale zadeklarowałeś

 sdata:byte;

a czytasz tak stream.read(@SDATA,2,nil);

. Czyli zapisujesz do 1-bajtowej zmiennej dwa bajty i tu pewnie ten błąd ;)
0

Może te 2 funkcje jakoś pomogą:

function SaveGraphFile(pGraph: IGraphBuilder; wszPath: WideString): HRESULT;
var
  Storage: IStorage;
  Stream: IStream;
  Persist: IPersistStream;
begin
  Result := StgCreateDocfile(
        PWideChar(wszPath),
        STGM_CREATE or STGM_TRANSACTED or STGM_READWRITE or STGM_SHARE_EXCLUSIVE,
        0, Storage);
  if FAILED(Result) then Exit;

  Result := Storage.CreateStream(
        PWideChar(wszStreamName),
        STGM_WRITE or STGM_CREATE or STGM_SHARE_EXCLUSIVE,
        0, 0, Stream);
  if FAILED(Result) then Exit;

  pGraph.QueryInterface(IID_IPersistStream, Persist);
  Result := Persist.Save(Stream, True);
  Stream := nil;
  Persist := nil;
  if SUCCEEDED(Result) then Result := Storage.Commit(STGC_DEFAULT);
  Storage := nil;
end;

//------------------*******************-------------------

function LoadGraphFile(pGraph: IGraphBuilder; const wszName: WideString): HRESULT;
var
  Storage: IStorage;
  Stream: IStream;
  PersistStream: IPersistStream;
begin
  if (S_OK <> StgIsStorageFile(PWideChar(wszName))) then
  begin
    Result := E_FAIL;
    Exit;
  end;

  Result := StgOpenStorage(PWideChar(wszName), nil,
        STGM_TRANSACTED or STGM_READ or STGM_SHARE_DENY_WRITE,
        nil, 0, Storage);

  if FAILED(Result) then Exit;

  Result := pGraph.QueryInterface(IID_IPersistStream, PersistStream);

  if (SUCCEEDED(Result)) then
  begin
    Result := Storage.OpenStream(PWideChar(wszStreamName), nil,
            STGM_READ or STGM_SHARE_EXCLUSIVE, 0, Stream);
    if SUCCEEDED(Result) then
    begin
      Result := PersistStream.Load(Stream);
      Stream := nil;
    end;
    PersistStream := nil;
  end;

  Storage := nil;
end;
0

No moze teraz ciut od tematu odbiegne ale mam pytanie co nalezy robic po wczytaniu streamu Workbook BOF o nazwie = workbook globals? oczywiscie mowimy tu o formacie plikow excela .xls

0

Oj, tu by sie przydała jakaś książka typu (Excel 2003 VBA Programmer's Reference)
Ja jedynie mogę polecić lekturę MSDN.

EXCELlent Office Adventures
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnofftalk/html/office01042001.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnexvba/html/odc_5709_chap05idx.asp

itp.

0

Tutaj raczej chodzi o Opis Formatu Excelowskiego mam ten z openoffice ale tam tego nie moge znalezc :(.

0

Udalo mi sie zdobyc najnowszy Opis Formatu Excela ale mam taki problem kiedy wczytuje kolejny rekord po BOF dostaje wartość hexadecymalna 00E1 ktora nie wystepuje w tym opsie co robic??

1 użytkowników online, w tym zalogowanych: 0, gości: 1