Freigeben über


Verwenden von OLE in Rich Edit-Steuerelementen

Dieser Abschnitt enthält Informationen zur Verwendung von Objektverknüpfung und Einbettung (OLE) in umfangreichen Bearbeitungssteuerelementen.

Wichtige Informationen

Technologien

Voraussetzungen

  • C/C++
  • Programmierung der Windows-Benutzeroberfläche

Anweisungen

Verwenden einer umfassenden Bearbeitungsschnittstelle

Umfangreiche Bearbeitungssteuerelemente machen einen Teil ihrer Funktionalität über COM-Schnittstellen (Component Object Model) verfügbar. Durch das Abrufen einer Schnittstelle aus 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 Textobjektmodell verwendet werden.

Eine weitere 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 umfangreiches Bearbeitungssteuerelement 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.

  1. Rufen Sie die IRichEditOle-Schnittstelle ab.

    BOOL InsertObject(HWND hRichEdit, LPCTSTR pszFileName)
    {
        HRESULT hr;
    
        LPRICHEDITOLE pRichEditOle;
        SendMessage(hRichEdit, EM_GETOLEINTERFACE, 0, (LPARAM)&pRichEditOle);
    
        ...
    
  2. 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);
        ...
    
  3. Richten Sie das Datenformat ein.

        FORMATETC formatEtc;
    
        formatEtc.cfFormat = 0;
        formatEtc.ptd      = NULL;
        formatEtc.dwAspect = DVASPECT_CONTENT;
        formatEtc.lindex   = -1;
        formatEtc.tymed    = TYMED_NULL;
    
        ...
    
  4. Rufen Sie einen Zeiger auf die Anzeigewebsite ab.

        LPOLECLIENTSITE pClientSite;
        hr = pRichEditOle->GetClientSite(&pClientSite);
    
        ...
    
  5. 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();
    
        ...
    
  6. Rufen Sie die IOleObject-Schnittstelle für das -Objekt ab.

        LPOLEOBJECT pObject;
    
        hr = pUnk->QueryInterface(IID_IOleObject, (void**)&pObject);
    
        pUnk->Release();
    
        ...
    
  7. Um sicherzustellen, dass Verweise ordnungsgemäß gezählt werden, benachrichtigen Sie das Objekt, dass es enthalten ist.

        OleSetContainedObject(pObject, TRUE);
    
        ...
    
  8. 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;
    
        ...
    
  9. 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"); 
    
        ...
    
  10. Fügen Sie das -Objekt ein.

        hr = pRichEditOle->InsertObject(&reobject);
    
        ...
    
  11. 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 die Implementierung der Schnittstelle dem -Steuerelement zu, indem Sie eine EM_SETOLECALLBACK Nachricht senden. Das Steuerelement ruft dann bei Bedarf Methoden für die Implementierung der Schnittstelle auf.

Beispielsweise wird QueryAcceptData aufgerufen, wenn der Benutzer versucht, ein Objekt in das Steuerelement zu ziehen oder einzufügen. Wenn Ihre Anwendung die Daten akzeptieren kann, gibt Ihre Implementierung der Methode S_OK zurück. Andernfalls wird ein Fehlercode zurückgegeben. Die -Methode kann auch eine andere Aktion ausführen, z. B. eine Warnung des Benutzers, 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;
}

Verwenden von Rich Edit-Steuerelementen

Demo zu allgemeinen Windows-Steuerelementen (CppWindowsCommonControls)