Delen via


Hoe OLE te Gebruiken in Rich Edit-Controles

Deze sectie bevat informatie over het gebruik van OLE (Object Linking and Embedding) in rijke bewerkingselementen.

Wat u moet weten

Technologieën

Voorwaarden

  • C/C++
  • Programmeren van Windows-gebruikersinterface

Aanwijzingen

Een uitgebreide bewerkingsinterface gebruiken

Rich-bewerkingsbesturingselementen maken een deel van hun functionaliteit beschikbaar via Component Object Model (COM) interfaces. Door een interface van een besturingselement te verkrijgen, krijgt u de mogelijkheid om met andere objecten in het besturingselement te werken. U kunt deze interface verkrijgen door het EM_GETOLEINTERFACE bericht te verzenden. Vanuit de interface IRichEditOle kunt u vervolgens interfaces verkrijgen die worden gebruikt in het Text Object Model.

Een andere interface, IRichEditOleCallback, wordt geïmplementeerd door toepassingen om het gedrag van het besturingselement te definiëren wanneer deze communiceert met objecten.

Een object invoegen in een Rich Text-bewerkingscontrole

In het volgende codevoorbeeld wordt een bestandsobject ingevoegd in een uitgebreid besturingselement voor bewerken. Als een programma is gekoppeld aan het bestandstype op de computer van de gebruiker (bijvoorbeeld Microsoft Excel voor een .xls bestand), wordt de inhoud van het bestand weergegeven in het besturingselement; anders wordt er een pictogram weergegeven.

  1. Verkrijg de interface IRichEditOle.

    BOOL InsertObject(HWND hRichEdit, LPCTSTR pszFileName)
    {
        HRESULT hr;
    
        LPRICHEDITOLE pRichEditOle;
        SendMessage(hRichEdit, EM_GETOLEINTERFACE, 0, (LPARAM)&pRichEditOle);
    
        ...
    
  2. Maak gestructureerde opslag.

        LPLOCKBYTES pLockBytes = NULL;
        hr = CreateILockBytesOnHGlobal(NULL, TRUE, &pLockBytes);
    
        LPSTORAGE pStorage;
        hr = StgCreateDocfileOnILockBytes(pLockBytes, 
                                          STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 
                                          0, &pStorage);
        ...
    
  3. Stel de gegevensindeling in.

        FORMATETC formatEtc;
    
        formatEtc.cfFormat = 0;
        formatEtc.ptd      = NULL;
        formatEtc.dwAspect = DVASPECT_CONTENT;
        formatEtc.lindex   = -1;
        formatEtc.tymed    = TYMED_NULL;
    
        ...
    
  4. Een aanwijzer ophalen naar de weergavesite.

        LPOLECLIENTSITE pClientSite;
        hr = pRichEditOle->GetClientSite(&pClientSite);
    
        ...
    
  5. Maak het object en haal de bijbehorende IUnknown interface op.

        LPUNKNOWN pUnk;
        CLSID clsid = CLSID_NULL;
    
        hr = OleCreateFromFile(clsid, 
                               pszFileName, 
                               IID_IUnknown, 
                               OLERENDER_DRAW, 
                               &formatEtc, 
                               pClientSite, 
                               pStorage, 
                               (void**)&pUnk);
    
        pClientSite->Release();
    
        ...
    
  6. Haal de IOleObject-interface op voor het object.

        LPOLEOBJECT pObject;
    
        hr = pUnk->QueryInterface(IID_IOleObject, (void**)&pObject);
    
        pUnk->Release();
    
        ...
    
  7. Om ervoor te zorgen dat verwijzingen correct worden geteld, maakt u het object bekend dat het is opgenomen.

        OleSetContainedObject(pObject, TRUE);
    
        ...
    
  8. Objectgegevens instellen.

        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. Verplaats de caret naar het einde van de tekst en voeg een return toe.

        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. Voeg het object in.

        hr = pRichEditOle->InsertObject(&reobject);
    
        ...
    
  11. Opschonen.

        pObject->Release();
    
        pRichEditOle->Release();
    
        return TRUE;
    
    }
    

IRichEditOleCallback gebruiken

Toepassingen implementeren de IRichEditOleCallback-interface om te reageren op OLE-gerelateerde query's of acties die worden uitgevoerd door een uitgebreid besturingselement voor bewerken. U koppelt uw implementatie van de interface aan het besturingselement door een EM_SETOLECALLBACK bericht te verzenden. Het besturingselement roept vervolgens methoden aan voor uw implementatie van de interface, indien van toepassing.

QueryAcceptData wordt bijvoorbeeld aangeroepen wanneer de gebruiker probeert een object naar het besturingselement te slepen of erin te plakken. Als uw toepassing de gegevens kan accepteren, retourneert uw implementatie van de methode S_OK; anders wordt er een foutcode geretourneerd. De methode kan ook een andere actie ondernemen, zoals de gebruiker waarschuwen dat bestanden van dat type niet in het controle-element kunnen worden geplaatst.

De voorbeeldfunctie InsertObject voltooien

In het volgende codevoorbeeld ziet u de vorige codefragmenten die zijn gecombineerd tot één volledige functie met foutafhandeling.

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;
}

Gebruik maken van Rich Edit-besturingselementen

demo van algemene besturingselementen van Windows (CppWindowsCommonControls)