Verwenden von OLE in Rich Edit-Steuerelementen
Dieser Abschnitt enthält Informationen zur Verwendung von Objektverknüpfung und Einbettung (OLE) in Rich-Edit-Steuerelementen.
Wichtige Informationen
Technologien
Voraussetzungen
- C/C++
- Windows Benutzeroberfläche-Programmierung
Instructions
Verwenden einer Rich Edit-Schnittstelle
Umfangreiche Bearbeitungssteuerelemente machen einige ihrer Funktionen über com-Schnittstellen (Component Object Model) verfügbar. Durch das Abrufen einer Schnittstelle von einem Steuerelement erhalten Sie die Möglichkeit, mit anderen Objekten innerhalb des Steuerelements zu arbeiten. Sie können diese Schnittstelle abrufen, indem Sie die EM _ GETOLEINTERFACE-Nachricht senden. Über die IRichEditOle-Schnittstelle können Sie dann Schnittstellen abrufen, die im Textobjektmodellverwendet werden.
Eine andere Schnittstelle, IRichEditOleCallback,wird von Anwendungen implementiert, um das Verhalten des Steuerelements zu definieren, wenn es mit Objekten interagiert.
Einfügen eines Objekts in ein Rich Edit-Steuerelement
Im folgenden Codebeispiel wird ein Dateiobjekt in ein Rich-Edit-Steuerelement eingefügt. Wenn ein Programm dem Dateityp auf dem Computer des Benutzers zugeordnet ist (z. B. Microsoft Excel für eine .xls-Datei), wird der Inhalt der Datei im -Steuerelement angezeigt. Andernfalls wird ein Symbol angezeigt.
Abrufen der IRichEditOle-Schnittstelle.
BOOL InsertObject(HWND hRichEdit, LPCTSTR pszFileName) { HRESULT hr; LPRICHEDITOLE pRichEditOle; SendMessage(hRichEdit, EM_GETOLEINTERFACE, 0, (LPARAM)&pRichEditOle); ...Erstellen Sie strukturierten Speicher.
LPLOCKBYTES pLockBytes = NULL; hr = CreateILockBytesOnHGlobal(NULL, TRUE, &pLockBytes); LPSTORAGE pStorage; hr = StgCreateDocfileOnILockBytes(pLockBytes, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, &pStorage); ...Richten Sie das Datenformat ein.
FORMATETC formatEtc; formatEtc.cfFormat = 0; formatEtc.ptd = NULL; formatEtc.dwAspect = DVASPECT_CONTENT; formatEtc.lindex = -1; formatEtc.tymed = TYMED_NULL; ...Abrufen eines Zeigers auf die Anzeigewebsite.
LPOLECLIENTSITE pClientSite; hr = pRichEditOle->GetClientSite(&pClientSite); ...Erstellen Sie das Objekt, und rufen Sie dessen IUnknown-Schnittstelle ab.
LPUNKNOWN pUnk; CLSID clsid = CLSID_NULL; hr = OleCreateFromFile(clsid, pszFileName, IID_IUnknown, OLERENDER_DRAW, &formatEtc, pClientSite, pStorage, (void**)&pUnk); pClientSite->Release(); ...Abrufen der IOleObject-Schnittstelle für das Objekt.
LPOLEOBJECT pObject; hr = pUnk->QueryInterface(IID_IOleObject, (void**)&pObject); pUnk->Release(); ...Um sicherzustellen, dass Verweise richtig gezählt werden, benachrichtigen Sie das Objekt, dass es enthalten ist.
OleSetContainedObject(pObject, TRUE); ...Richten Sie Objektinformationen ein.
REOBJECT reobject = { sizeof(REOBJECT)}; hr = pObject->GetUserClassID(&clsid); reobject.clsid = clsid; reobject.cp = REO_CP_SELECTION; reobject.dvaspect = DVASPECT_CONTENT; reobject.dwFlags = REO_RESIZABLE | REO_BELOWBASELINE; reobject.dwUser = 0; reobject.poleobj = pObject; reobject.polesite = pClientSite; reobject.pstg = pStorage; SIZEL sizel = { 0 }; reobject.sizel = sizel; ...Verschieben Sie das Caretzeichen an das Ende des Texts, und fügen Sie einen Wagenrücklauf hinzu.
SendMessage(hRichEdit, EM_SETSEL, 0, -1); DWORD dwStart, dwEnd; SendMessage(hRichEdit, EM_GETSEL, (WPARAM)&dwStart, (LPARAM)&dwEnd); SendMessage(hRichEdit, EM_SETSEL, dwEnd+1, dwEnd+1); SendMessage(hRichEdit, EM_REPLACESEL, TRUE, (WPARAM)L"\n"); ...Fügen Sie das -Objekt ein.
hr = pRichEditOle->InsertObject(&reobject); ...Bereinigen
pObject->Release(); pRichEditOle->Release(); return TRUE; }
Verwenden von IRichEditOleCallback
Anwendungen implementieren die IRichEditOleCallback-Schnittstelle, um auf OLE-bezogene Abfragen oder Aktionen zu reagieren, die von einem umfangreichen Bearbeitungssteuerelement ausgeführt werden. Sie ordnen Ihre Implementierung der -Schnittstelle dem -Steuerelement zu, indem Sie eine EM _ SETOLECALLBACK-Nachricht senden. Das -Steuerelement ruft dann die Methoden für die Implementierung der -Schnittstelle nach Bedarf auf.
For example, QueryAcceptData is called when the user attempts to drag or paste an object into the control. Wenn Ihre Anwendung die Daten akzeptieren kann, gibt die Implementierung der -Methode S _ OK zurück. Andernfalls wird ein Fehlercode zurückgegeben. Die -Methode kann auch eine andere Aktion ergreifen, z. B. den Benutzer warnen, dass Dateien dieses Typs nicht im Steuerelement platziert werden können.
Vollständige InsertObject-Beispielfunktion
Im folgenden Codebeispiel werden die vorherigen Codeausschnitte in einer vollständigen Funktion kombiniert, die die Fehlerbehandlung umfasst.
BOOL InsertObject(HWND hRichEdit, LPCTSTR pszFileName)
{
HRESULT hr;
LPRICHEDITOLE pRichEditOle;
SendMessage(hRichEdit, EM_GETOLEINTERFACE, 0, (LPARAM)&pRichEditOle);
if (pRichEditOle == NULL)
{
return FALSE;
}
LPLOCKBYTES pLockBytes = NULL;
hr = CreateILockBytesOnHGlobal(NULL, TRUE, &pLockBytes);
if (FAILED(hr))
{
return FALSE;
}
LPSTORAGE pStorage;
hr = StgCreateDocfileOnILockBytes(pLockBytes,
STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE,
0, &pStorage);
if (FAILED(hr))
{
return FALSE;
}
FORMATETC formatEtc;
formatEtc.cfFormat = 0;
formatEtc.ptd = NULL;
formatEtc.dwAspect = DVASPECT_CONTENT;
formatEtc.lindex = -1;
formatEtc.tymed = TYMED_NULL;
LPOLECLIENTSITE pClientSite;
hr = pRichEditOle->GetClientSite(&pClientSite);
if (FAILED(hr))
{
return FALSE;
}
LPUNKNOWN pUnk;
CLSID clsid = CLSID_NULL;
hr = OleCreateFromFile(clsid, pszFileName, IID_IUnknown, OLERENDER_DRAW,
&formatEtc, pClientSite, pStorage, (void**)&pUnk);
pClientSite->Release();
if (FAILED(hr))
{
return FALSE;
}
LPOLEOBJECT pObject;
hr = pUnk->QueryInterface(IID_IOleObject, (void**)&pObject);
pUnk->Release();
if (FAILED(hr))
{
return FALSE;
}
OleSetContainedObject(pObject, TRUE);
REOBJECT reobject = { sizeof(REOBJECT)};
hr = pObject->GetUserClassID(&clsid);
if (FAILED(hr))
{
pObject->Release();
return FALSE;
}
reobject.clsid = clsid;
reobject.cp = REO_CP_SELECTION;
reobject.dvaspect = DVASPECT_CONTENT;
reobject.dwFlags = REO_RESIZABLE | REO_BELOWBASELINE;
reobject.dwUser = 0;
reobject.poleobj = pObject;
reobject.polesite = pClientSite;
reobject.pstg = pStorage;
SIZEL sizel = { 0 };
reobject.sizel = sizel;
SendMessage(hRichEdit, EM_SETSEL, 0, -1);
DWORD dwStart, dwEnd;
SendMessage(hRichEdit, EM_GETSEL, (WPARAM)&dwStart, (LPARAM)&dwEnd);
SendMessage(hRichEdit, EM_SETSEL, dwEnd+1, dwEnd+1);
SendMessage(hRichEdit, EM_REPLACESEL, TRUE, (WPARAM)L"\n");
hr = pRichEditOle->InsertObject(&reobject);
pObject->Release();
pRichEditOle->Release();
if (FAILED(hr))
{
return FALSE;
}
return TRUE;
}