Strukturierter Speicher in MAPI
Gilt für: Outlook 2013 | Outlook 2016
Strukturierter Speicher bezieht sich auf die hierarchische organization von Speicher, die mit COM eingeführt wurde. In einer strukturierten Speicherumgebung ist der Speicher in zwei oder drei Arten von Objekten organisiert:
Stream-Objekte
Sperren von Bytes-Objekten
Speicherobjekte
Stream und Sperrbytes sind Objekte auf niedrigerer Ebene, die direkt auf die Daten zugreifen. Stream -Objekte implementieren die IStream-Schnittstelle, die Methoden zum Lesen, Schreiben, Positionieren und Kopieren von Datenbytes definiert. Sperren von Bytes-Objekten implementieren eine weitere COM-Schnittstelle, ILockBytes, für den Zugriff auf Daten mit einem Bytearray. Bytearrays werden in der Regel verwendet, um benutzerdefinierten Zugriff auf den zugrunde liegenden Speicher bereitzustellen.
Speicherobjekte werden über den Datenstrom- oder Sperrbyteobjekten überlagert. sie können eines oder mehrere dieser Objekte sowie andere Speicherobjekte enthalten. Speicherobjekte implementieren die IStorage-Schnittstelle , die Methoden zum Erstellen, Zugreifen auf und Verwalten geschachtelter Objekte definiert.
Da es sich bei IStream, ILockBytes und IStorage um COM-Schnittstellen und nicht um MAPI-Schnittstellen handelt, geben ihre Methoden COM-Fehlerwerte anstelle von MAPI-Werten zurück. Clients und Dienstanbieter, die Methoden in diesen Schnittstellen aufrufen, müssen die API-Funktion MapStorageSCode verwenden, um diese Werte in MAPI-Fehlerwerte zu übersetzen. Weitere Informationen finden Sie unter MapStorageSCode.
Clients und Dienstanbieter verwenden strukturierten Speicher für die Arbeit mit Eigenschaften, die zu groß sind, um sie mit den IMAPIProp-Methoden zu verwalten, in der Regel große Zeichenfolgen und binäre Eigenschaften. Eine der gängigen Möglichkeiten, wie Clients oder Dienstanbieter darauf zugreifen, ist die Angabe von IStream oder IStorage als Schnittstellenbezeichner in einem Aufruf der IMAPIProp::OpenProperty-Methode . Beispielsweise rufen Clients OpenProperty mit PR_ATTACH_DATA_BIN als Eigenschaftstag und IID_IStream als Schnittstellenbezeichner auf, um auf eine binäre Anlage in einer Nachricht zuzugreifen.
Clients und Dienstanbieter können eigene Datenstrom- und Speicherobjekte implementieren oder API-Funktionen aufrufen, um auf implementierungen zuzugreifen, die von MAPI oder COM bereitgestellt werden. Da die bereitgestellten Implementierungen den meisten Zwecken dienen, müssen Clients und Dienstanbieter selten eigene erstellen.
Wenn ein Client OpenProperty für ein MAPI-Objekt aufruft, um über ein Speicherobjekt auf eine seiner Eigenschaften zuzugreifen, öffnet der Dienstanbieter das Speicherobjekt in der Regel im direkten Modus. Dies ist jedoch ein typisches und nicht erforderliches Verhalten. Clients sollten davon ausgehen, dass alle Speicherobjekte, die von Dienstanbietern geöffnet oder erstellt werden, transaktioniert werden und einen Aufruf von IStorage::Commit erfordern. Sie sollten auch daran denken, dass Änderungen an Speicherobjekten erst dauerhaft werden, wenn sie IMAPIProp::SaveChanges nach dem endgültigenCommit zum Speichern des MAPI-Objekts aufrufen. Weitere Informationen finden Sie unter IMAPIProp::SaveChanges.
MAPI und COM bieten mehrere API-Funktionen zum Definieren oder Zugreifen auf Speicher- und Streamobjekte. Die häufig verwendeten Funktionen werden in der folgenden Tabelle beschrieben.
Funktionen für den Zugriff auf Speicher und Stream-Objekte
Funktion | Beschreibung |
---|---|
HrIStorageFromStream |
Erstellt ein Speicherobjekt für den Zugriff auf ein Stream- oder Sperrbyteobjekt. |
OpenIMsgOnIStg |
Erstellt ein Nachrichtenobjekt für den Zugriff auf ein Speicherobjekt. |
OpenStreamOnFile |
Erstellt ein Streamobjekt für den Zugriff auf eine Datei. |
WrapCompressedRTFStream |
Erstellt ein Streamobjekt, das die komprimierte oder unkomprimierte Version eines Datenstroms enthält, der den Rich-Text einer Nachricht enthält. |
So rufen Sie die Namen der Datenströme in einem bestimmten Unterspeicher ab
Rufen Sie die IStorage::EnumElements-Methode des Unterspeichers auf, um eine IEnumSTATSTG-Schnittstelle abzurufen.
Rufen Sie IEnumSTATSTG::Next mit möglichst vielen STATSTG-Strukturen auf. Wenn Sie nach 100 fragen, gibt Next in der Regel S_FALSE zurück, wobei der Inhalt von pceltFetched auf die Tatsächlich abgerufene Zahl festgelegt ist.
Überprüfen Sie die STATSTG-Strukturen , die mit STGTY_STREAM gekennzeichnet sind.
Geben Sie den pwcsName-Parameter frei.
So erstellen Sie ein Speicherobjekt für den Zugriff auf ein vorhandenes Stream- oder Sperrbyteobjekt
- Clients rufen HrIStorageFromStream auf.
So erstellen Sie ein Nachrichtenobjekt für den Zugriff auf ein vorhandenes Speicherobjekt
- Dienstanbieter und Clients rufen OpenIMsgOnIStg auf. Das erstellte Nachrichtenobjekt unterscheidet sich von den Nachrichtenobjekten, die normalerweise von Nachrichtenspeicheranbietern erstellt werden, darin, dass es nicht alle IMessage: IMAPIProp-Schnittstellenmethoden unterstützt, z. B. IMessage::SubmitMessage. Ein optionaler Eingabeparameter für OpenIMsgOnIStg ist eine Rückruffunktion, die dem MSGCALLRELEASE-Prototyp entspricht. Diese Funktion wird vom neuen Nachrichtenobjekt aufgerufen, wenn die Verweisanzahl der Nachricht 0 (null) erreicht. Die Implementierung einer MSGCALLRELEASE-Funktion kann nützlich sein, um die endgültige Verarbeitung durchzuführen, bevor die neue Nachricht vollständig entfernt wird.
OpenStreamOnFile wird häufig zum Speichern von Dateianlagen verwendet, da es einen Stream erstellt, der aus einer Datei liest und in diese schreibt. OpenProperty mit PR_ATTACH_DATA_BIN , da das Eigenschaftentag einen Datenstrom zum Speichern binärer Anlagendaten erstellt.
So komprimieren oder entpacken Sie einen Stream, der Nachrichtentext im Rich-Text-Format enthält
- Clients rufen WrapCompressedRTFStream auf. WrapCompressedRTFStream erstellt einen Stream, der den RTF-Stream umschließt. Der Wrapperstream implementiert nicht alle IStream-Methoden . Die folgenden Methoden sind ausgeschlossen: Seek, SetSize, Revert, LockRegion, UnlockRegion, Stat und Clone. Dies liegt daran, dass die von WrapCompressedRTFStream erstellten Streamobjekte weder SetSize noch Stat unterstützen. Es gibt keine einfache Möglichkeit, ihre Größe zu erweitern oder abzurufen. Die beste Strategie besteht darin, eine angemessene Puffergröße zu wählen und in einer Schleife zu lesen oder zu schreiben.
Hinweis
COM verfügt über eine Speicherobjektimplementierung, die auf einem Bytearray basiert, das ein IEnumSTATSTG-Objekt aus der problematischen EnumElements-Methode zurückgibt. Insbesondere funktioniert die QueryInterface-Methode nicht ordnungsgemäß. Dienstanbieter, die ihre eigenen Speicherobjekte mithilfe der COM-Implementierung implementieren, sollten einen schlanken Wrapper für das IEnumSTATSTG-Objekt erstellen, der Aufrufe an die zugrunde liegenden IEnumSTATSTG-Methoden weiterleitet, aber eigene AddRef-, Release-, QueryInterface- und Clone-Methoden implementiert.