利用IStorage和IStream存储自定义数据到Inventor文件 (C++)

来源:互联网 发布:mac 隐藏文件夹显示 编辑:程序博客网 时间:2024/04/30 12:24

我去年在全球博客就写了此文章,还有一个姊妹篇(用.NET写的),突然发现竟然没有贴到这里 :(  

我们知道,如果想存储一些自定义数据到文档的,自定义iProperties和Attribute是最先想到的方案。其实还有利用Inventor提供的操作IStorage和IStream的机制。利用到的是Windows的IStorage和IStream,因为Inventor文件也是一种Windows文件,Inventor API包装了相关方法。

全球博客上写的很详细。

http://adndevblog.typepad.com/manufacturing/2012/08/how-to-use-private-storage-and-stream-in-c.html

这里简要说一下流程:

一个文件里有多个Storage,而一个Storage里可以添加Stream。Inventor自己的数据也是这种组织结构。Inventor 封装的主要的方法

-  GetPrivateStorage: 获取文件的自定义Storage入口

CreateStream: 创建自定义Stream

IStream.Write: 写入自定义数据到Stream

-OpenStream: 访问自定义Stream

IStream.Read: 读取Stream自定义数据

DestroyElement: 删除自定义数据

下面的代码演示了在一个文档里创建,访问,删除自定义数据的过程。假定Inventor已经启动,而且某文档已经打开

// manipulate Private Streamstatic HRESULT PrivateStream(){     HRESULT Result=NOERROR;     Result = ::CoInitialize (NULL);     // get active inventor application   CLSID clsid;   ::CLSIDFromProgID(L"Inventor.Application",                        &clsid);    CComPtr<IUnknown> pUnk;   ::GetActiveObject(clsid,NULL,&pUnk);    CComPtr<Application> pApp;   Result = pUnk->QueryInterface(__uuidof(Application),                                (void**)&pApp);    // Get active Document   CComPtr<Document> pDoc;   Result = pApp->get_ActiveDocument(&pDoc);     char outData[256];    //COM Stream    Result = CreatePrivateStorageAndStream(pDoc,                                "MyPrvStorage1",                                "MyStream1",                                "Some private stored data");    if(Result != S_OK)  {      //ERROR: unable to create Stream      return Result;  }    Result = ReadPrivateStorageAndStream(pDoc,                                    "MyPrvStorage1",                                    "MyStream1",                                                                       outData);    if(Result != S_OK)  {      //ERROR: unable to read Stream      return Result;  } Result = DeletePrivateStream(pDoc,                        "MyPrvStorage1",                        "MyStream1");  if(Result != S_OK){  //ERROR: unable to delete Stream  return Result;}  //Set document to Dirty prior to perform the Save //otherwise the stream won't be save through sessionspDoc->Dirty = VARIANT_TRUE;pDoc->Save();  wrapup:::CoUninitialize();}
//Create Private Storage And Stream static HRESULT CreatePrivateStorageAndStream(                            CComPtr<Document> pDoc,                             constchar* StorageName,                             constchar* StreamName,                             constchar* data){     HRESULT hr;     //Try to get Private Storage, if does not exist try to create    CComPtr<IUnknown> pUnk;    hr=pDoc->GetPrivateStorage(CComBSTR(StorageName),                                 VARIANT_TRUE,&pUnk);    if(hr != S_OK)  {       //ERROR: unable to create or open Storage       return hr;  }   CComQIPtr<IStorage> pStg(pUnk);   //Create stream within private storage  CComPtr<IStream> pStream = NULL;  hr=pStg->CreateStream(CComBSTR(StreamName),                            STGM_DIRECT|STGM_CREATE|                            STGM_READWRITE|STGM_SHARE_EXCLUSIVE,                            0, 0, &pStream);   if(hr != S_OK)  {       //ERROR: unable to create Stream      return hr;}   ULONG lsize=0;  lsize = strlen(data);  hr=pStream->Write( &lsize,sizeof(int), NULL ) ;  hr=pStream->Write( data, strlen(data), NULL ) ;  // Save the data  hr=pStream->Commit(STGC_DEFAULT|STGC_OVERWRITE);    //Don't forget to commit changes also in storage   hr=pStg->Commit(STGC_DEFAULT|STGC_OVERWRITE);    return hr;} // Read Private Storage And Streamstatic HRESULT ReadPrivateStorageAndStream(CComPtr<Document> pDoc,                                constchar* StorageName,                                constchar* StreamName,                                char* outData){     HRESULT hr;     //Try to get Private Storage, if does not exist fail    CComPtr<IUnknown> pUnk;    hr = pDoc->GetPrivateStorage(CComBSTR(StorageName),                                    VARIANT_FALSE,&pUnk);    if(hr != S_OK)   {      //ERROR: unable to open Storage      return hr;   }    CComQIPtr<IStorage> pStg(pUnk);    // Open stream within private storage   CComPtr<IStream> pStream = NULL;   hr = pStg->OpenStream(CComBSTR(StreamName),0,                                    STGM_DIRECT|STGM_READ|                                    STGM_SHARE_EXCLUSIVE, 0,                                    &pStream);    if(hr != S_OK)  {      //ERROR: unable to open Stream      return hr;   }    ULONG lsize = 0;   hr = pStream->Read( &lsize,sizeof(int), NULL);   hr = pStream->Read( outData,lsize, NULL ) ;    outData[lsize] = '\0';    return hr;} // Delete Private Streamstatic HRESULT DeletePrivateStream(CComPtr<Document> pDoc,                                constchar* StorageName,                                constchar* Stream2Delete){    HRESULT hr ;     CComPtr<IUnknown> pUnk;    hr = pDoc->GetPrivateStorage(CComBSTR(StorageName),                                VARIANT_FALSE,&pUnk);    if(hr != S_OK)  {      //ERROR: unable to open Storage      return hr;   }    CComQIPtr<IStorage> pStg(pUnk);    //Perform deletion of the stream element   hr = pStg->DestroyElement(CComBSTR(Stream2Delete));    pStg->Commit(STGC_DEFAULT);    return hr;}



0 0
原创粉丝点击