/////////////////////////////////////////////////////////////////////////////// // Schreiben/Lesen eines Variant HRESULT SetVariantData (CComVariant &rv, IDataObject *pIDO, const FORMATETC *pcfe) { // Stream mit Variant generieren WStream IStream; HRESULT hr = CreateStreamOnHGlobal (NULL, true, IStream.ppi()); if (FAILED(hr)) return hr; // Variant dort rein schreiben hr = rv.WriteToStream (IStream); if (FAILED(hr)) return hr; LARGE_INTEGER li; LISet32(li, 0L); hr = IStream -> Seek (li, SEEK_SET, NULL); if (FAILED(hr)) return hr; // diesen Stream im DataObject setzen STGMEDIUM stg; stg.tymed = TYMED_ISTREAM; stg.pstm = IStream.detach(); stg.pUnkForRelease = NULL; hr = pIDO -> SetData ((FORMATETC *)pcfe, &stg, true); if (FAILED(hr)) { ReleaseStgMedium (&stg); return hr; } return S_OK; }
// Serialisieren/DeSerialisieren eines IUnknowns // in diesem Falle ein IDataObject HRESULT CreateStreamOnHGlobalFromIUnknown ( IUnknown *pIUnk, REFCLSID rClsID, IStream **ppIStream) { ASSERT(NULL != pIUnk); ASSERT(NULL != ppIStream); *ppIStream = NULL; try { // neuen Stream anlegen, kreiert eine neuen Memoryblock der Größe NULL // wird selbstständig wieder freigegen (true) WStream IStream; THROW_FAILED_HRESULT(CreateStreamOnHGlobal (NULL, true, IStream.ppi())); // den Enumerator wegschreiben WPersistStream IPersStr (pIUnk); // throws hr THROW_FAILED_HRESULT(OleSaveToStream (IPersStr, IStream)); // wieder zurück positionieren LARGE_INTEGER li; LISet32 (li, 0L); THROW_FAILED_HRESULT(IStream -> Seek (li, STREAM_SEEK_SET, NULL)); *ppIStream = IStream.detach(); } catch (_com_error &e) { return _COM_ERROR(e); } return S_OK; }
// Erzeugen und initialisieren eines PropertyActionChoice-Objektes, welches die // vorgegebenen PropertyActions enthält HRESULT InitPropertyActionChoice ( LPCSTR pcDesc, CALPCLSID *pcaClsIds, IPropertyActionSequence **ppISeq) { USES_CONVERSION; if (NULL == ppISeq) return E_POINTER; *ppISeq = NULL; // für alle Fälle WPropertyActionSequence ISeq; HRESULT hr = E_FAIL; WStorage IStg; GetSubPropSeqStorage (IStg.ppi()); if (NULL != (IStorage *)IStg) { // evtl. gespeicherten Status laden WStream IStm; string strName = MakeStreamName(pcDesc); // Stream erzeugen hr = IStg -> OpenStream (A2OLE(strName.c_str()), NULL, STGM_READ|STGM_SHARE_EXCLUSIVE, 0L, IStm.ppi()); if (SUCCEEDED(hr)) { hr = OleLoadFromStream (IStm, IID_IPropertyActionSequence, ISeq.ppv()); if (SUCCEEDED(hr)) { *ppISeq = ISeq.detach(); return S_OK; } } } // wenn Status nicht geladen werden kann, dann neu initialisieren try { // Objekt erzeugen ISeq = WPropertyActionSequence (CLSID_PropertyChoice); // throws hr ISeq -> SetDescription (pcDesc); // Rücksetzen der AktionsFolge WPersistStreamInit Init = ISeq; // throws hr hr = Init -> InitNew(); if (FAILED(hr)) _com_issue_error(hr); } catch (_com_error& hr) { return _COM_ERROR(hr); } // hinzufügen der einzelnen Aktionen hr = ISeq -> AddActionsByCLSID (pcaClsIds); if (FAILED(hr)) return hr; *ppISeq = ISeq.detach(); return NOERROR; }
void PropertySequence_cmd_Save (ebHTHREAD hThread, int iNumArgs, ebARGS lpArgs) { BASIC_OP_TRACE(PropertySequence_cmd_Save); if (NULL != lpArgs[0]) // als Funktion gerufen ebSetBool (lpArgs, 0, 0); // für alle Fälle WPropertyActionSequence ISeq ((IPropertyActionSequence *)ebGetObject (lpArgs, 1)); HRESULT hr = E_FAIL; // Versuchen aus SubStream einzulesen try { // SubStorage eröffnen/erzeugen WStorage IStg; hr = GetSubPropSeqStorage (IStg.ppi(), true); if (FAILED(hr)) _com_issue_error(hr); // Description geben lassen char cbBuffer[_MAX_PATH]; hr = ISeq -> GetDescription (cbBuffer, _MAX_PATH, NULL); if (FAILED(hr)) _com_issue_error(hr); WStream IStm; WPersistStream IPersistStm (ISeq); // throw hr string strName = MakeStreamName(cbBuffer); // Stream erzeugen USES_CONVERSION; hr = IStg -> CreateStream (A2OLE(strName.c_str()), STGM_READWRITE|STGM_SHARE_EXCLUSIVE|STGM_CREATE, 0L, 0L, IStm.ppi()); if (FAILED(hr)) _com_issue_error(hr); hr = OleSaveToStream (IPersistStm, IStm); if (FAILED(hr)) _com_issue_error(hr); hr = IStg -> Commit (STGC_DEFAULT); if (FAILED(hr)) _com_issue_error(hr); DEX_SetDirtyGeoDB(true); } catch (...) { TRACE("Couldn't OleSaveToStream for IPropertyActionSequence\n"); return; // Fehler } if (NULL != lpArgs[0]) // als Funktion gerufen ebSetBool (lpArgs, 0, -1); }
static HRESULT SavePropSeq ( LPCSTR pcDesc, IPropertyActionSequence *pISeq, IStorage *pIStg) { HRESULT hr = E_FAIL; WStorage IStg (pIStg); USES_CONVERSION; if (NULL == pIStg) { // SubStorage anlegen, da es noch nicht existiert WStorage IRootStg; if (!DEX_GetProjectStorage(*IRootStg.ppv())) return E_FAIL; hr = IRootStg -> CreateStorage (A2OLE(g_cbPropertyChoices), STGM_READWRITE|STGM_SHARE_EXCLUSIVE|STGM_TRANSACTED, 0L, 0L, IStg.ppi()); if (FAILED(hr)) return hr; hr = WriteClassStg (IStg, CLSID_PropertyChoice); if (FAILED(hr)) return hr; } try { WStream IStm; WPersistStream IPersistStm (pISeq); // throws hr string strName = MakeStreamName(pcDesc); // Stream erzeugen hr = IStg -> CreateStream (A2OLE(strName.c_str()), STGM_READWRITE|STGM_SHARE_EXCLUSIVE|STGM_CREATE, 0L, 0L, IStm.ppi()); if (FAILED(hr)) _com_issue_error(hr); hr = OleSaveToStream (IPersistStm, IStm); // und wegschreiben if (FAILED(hr)) _com_issue_error(hr); hr = IStm -> Commit (STGC_DEFAULT); if (FAILED(hr)) _com_issue_error(hr); } catch (_com_error& hr) { return _COM_ERROR(hr); } hr = IStg -> Commit (STGC_DEFAULT); if (SUCCEEDED(hr)) DEX_SetDirtyGeoDB(true); return hr; }
// Hinzufügen eines EnumLONG zu einem IDataObject ----------------------------- HRESULT SetEnumLONGData (IEnum<LONG> *pEnum, REFCLSID rClsID, IDataObject *pDataObj) { ASSERT(pEnum); ASSERT(pDataObj); // Stream mit EnumLONG generieren WStream IStream; HRESULT hr = CreateStreamOnHGlobalFromIUnknown (pEnum, rClsID, IStream.ppi()); if (FAILED(hr)) return hr; // diesen Stream im DataObject setzen STGMEDIUM stg; stg.tymed = TYMED_ISTREAM; stg.pstm = IStream.detach(); stg.pUnkForRelease = NULL; hr = pDataObj -> SetData ((FORMATETC *)&c_feSelectedObjects, &stg, true); if (FAILED(hr)) return hr; return NOERROR; }
void PropertySequence_cmd_Load (ebHTHREAD hThread, int iNumArgs, ebARGS lpArgs) { BASIC_OP_TRACE(PropertySequence_cmd_Load); ebSetBool (lpArgs, 0, 0); // für alle Fälle WPropertyActionSequence ISeq ((IPropertyActionSequence *)ebGetObject (lpArgs, 1)); HRESULT hr = E_FAIL; // Versuchen aus SubStream einzulesen try { // SubStorage eröffnen WStorage IStg; hr = GetSubPropSeqStorage (IStg.ppi()); if (FAILED(hr)) _com_issue_error(hr); // Description wurde als Parameter übergeben string strDesc; ebHSUB hStr = ebGetString (lpArgs, 2); if (NULL != hStr) { strDesc = ebLockString (hThread, hStr); ebUnlockString (hThread, hStr); } WStream IStm; string strName = MakeStreamName(strDesc.c_str()); // Stream erzeugen USES_CONVERSION; hr = IStg -> OpenStream (A2OLE(strName.c_str()), NULL, STGM_READ|STGM_SHARE_EXCLUSIVE, 0L, IStm.ppi()); if (FAILED(hr)) _com_issue_error(hr); // ggf. XML-Version einlesen, testen nicht möglich // aktuelle Streamposition speichern LARGE_INTEGER liToPos; ULARGE_INTEGER liPos; liPos.QuadPart = liToPos.QuadPart = 0; if (FAILED(hr = IStm -> Seek(liToPos, STREAM_SEEK_CUR, &liPos))) _com_issue_error(hr); DWORD dwSignature = 0; DWORD dwVersion = 0; bool fMustReset = true; LoadData(IStm, dwSignature); if (dwSignature == PROPERTYSEQUENCE_SIGNATURE) { LoadData(IStm, dwVersion); if ((dwVersion & ~PROPERTYSEQUENCE_MINORVERSIONMASK) <= PROPERTYSEQUENCE_LASTKNOWNVERSION) { // Versionsvergleich ist möglich (wird hier aber nicht gemacht) os_string strVersion; LoadString(IStm, strVersion); fMustReset = false; } } if (fMustReset) { // Stream zurückpositionieren, damit alte Streams geladen werden können liToPos.QuadPart = liPos.QuadPart; if (FAILED(hr = IStm -> Seek(liToPos, STREAM_SEEK_SET, NULL))) _com_issue_error(hr); } // anstelle von OleLoadFromStrem ::Load direkt rufen, da Objekt // schon existiert CLSID clsId; hr = ReadClassStm (IStm, &clsId); if (FAILED(hr)) _com_issue_error(hr); if (!IsEqualCLSID(clsId, CLSID_PropertyActionSequence) && !IsEqualCLSID(clsId, CLSID_NULL)) { _com_issue_error(E_FAIL); } { WPersistStream PersStm (ISeq); // throws hr hr = PersStm -> Load (IStm); // Objekt laden if (FAILED(hr)) _com_issue_error(hr); } } catch (...) { TRACE("Couldn't OleLoadFromStream for IPropertyActionSequence\n"); return; // Fehler } ebSetBool (lpArgs, 0, -1); }
// Laden einer bestimmten PropertySequence HRESULT LoadPropertySequence (BSTR bstrName, IPropertyActionSequence **ppIPropertyActionSequence) { TEST_OUT_PARAM(ppIPropertyActionSequence); COM_TRY { WStorage Stg; if (FAILED(OpenPropSeqStorage (STGM_READ, Stg.ppi()))) return E_FAIL; CComBSTR bstrStreamName; WStream Strm; THROW_FAILED_HRESULT(MakeStreamName(bstrName, bstrStreamName)); if (FAILED(Stg -> OpenStream (bstrStreamName, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, Strm.ppi()))) return E_FAIL; WPropertyActionSequence Seq; THROW_FAILED_HRESULT(::OleLoadFromStream (Strm, Seq.GetIID(), Seq.ppv())); *ppIPropertyActionSequence = Seq.detach(); } COM_CATCH; return S_OK; }