Udostępnij za pośrednictwem


Konwertowanie obiektu tuszowego tekstu na tusz

Implementacja konwertowania z obiektu pisma odręcznego (tInk) na pismo odręczne.

Aby przekonwertować obiekt tekstu pismowego na atrament

  1. Użyj interfejsu IPersistStream, aby zapisać zawartość obiektu pisma oddyskowego do strumienia. Obiekt tekstu atramentu używa zserializowanego formatu atramentu do zapisu w strumieniu.
  2. Odczytaj zawartość strumienia do tablicy BYTE.
  3. Użyj metody Load obiektu InkDisp, aby załadować zawartość strumienia do obiektu InkDisp.

Przykład obiektu pisma odkowego do obiektu pisma odkowego

Poniższy fragment kodu konwertuje obiekt atramentu tekstowego na atrament.

Najpierw kod uzyskuje obiekt rozpoznawania pisma ręcznego.

/* Create a variable to hold the text ink object */
CComPtr<IInkObject *> spITextInk;

/* Obtain the text ink object */

Następnie kod tworzy wskaźnik dla strumienia, który przechowuje zawartość obiektu tekstu atramentu.

// Create a Stream pointer to hold the saved object
CComPtr<IStream *> spStream = NULL; 

Następnie kod uzyskuje interfejs IPersistStream z obiektu z atramentem tekstowym.

// Declare the IPersistStream to be used for retrieving the saved data from the text ink
CComPtr<IPersistStream *> spIPersistStream = NULL;
// Get the actual IPersistStream interface off of the TextInk
HRESULT hr = pITextInk->QueryInterface(IID_IPersistStream, (void **)&spIPersistStream);
ASSERT(SUCCEEDED(hr) && spIPersistStream);

Następnie kod używa interfejsu IPersistStream, aby zapisać zawartość obiektu atramentu tekstowego do strumienia.

if( SUCCEEDED(hr) && pIPersistStream )
{
    // Create the stream 
    if( SUCCEEDED(hr=CreateStreamOnHGlobal(NULL, TRUE, &spStream)) && spStream )
    {
        // Save the TextInk through IPersistStream Interface to the IStream
        hr = spIPersistStream->Save(spStream, FALSE);
    }
}

Następnie kod tworzy obiekt InkCollector, tworzy obiekt InkDisp dla InkCollector, dołącza InkCollector do okna aplikacji oraz włącza zbieranie pisma ręcznego w InkCollector.

// Now create an InkCollector object along with InkDisp Object
if( SUCCEEDED(hr) && spStream)
{
    CComPtr<IInkCollector *> spIInkCollector;
    CComPtr<IInkDisp *> spIInkDisp = NULL;

    // Create the InkCollector object.
    hr = CoCreateInstance(CLSID_InkCollector, 
        NULL, CLSCTX_INPROC_SERVER, 
        IID_IInkCollector, 
        (void **) &spIInkCollector);
    if (FAILED(hr)) 
        return -1;

    // Get a pointer to the Ink object
    hr = spIInkCollector->get_Ink(&spIInkDisp);
    if (FAILED(hr)) 
        return -1;

    // Tell InkCollector the window to collect ink in
    hr = spIInkCollector->put_hWnd((long)hwnd);
    if (FAILED(hr)) 
        return -1;

    // Enable ink input in the window
    hr = spIInkCollector->put_Enabled(VARIANT_TRUE);
    if (FAILED(hr)) 
        return -1;

Następnie kod pobiera rozmiar strumienia i tworzy bezpieczną tablicę do przechowywania zawartości strumienia.

    // Now create a variant data type based on the IStream data
    const LARGE_INTEGER li0 = {0, 0};
    ULARGE_INTEGER uli = {0,0};

    // Find the size of the stream
    hr = spStream->Seek(li0, STREAM_SEEK_END, &uli);
    ASSERT(0 == uli.HighPart);
    DWORD dwSize = uli.LowPart;

    // Set uli to point to the beginning of the stream.
    hr=spStream->Seek(li0, STREAM_SEEK_SET, &uli);
    ASSERT(SUCCEEDED(hr));

    // Create a safe array to hold the stream contents
    if( SUCCEEDED(hr) )
    {
        VARIANT vtData;
        VariantInit(&vtData);
        vtData.vt = VT_ARRAY | VT_UI1;

        vtData.parray = ::SafeArrayCreateVector(VT_UI1, 0, dwSize);
        if (vtData.parray)
        {

Na koniec kod uzyskuje dostęp do bezpiecznej tablicy i używa metody InkDisp obiektu Load w celu załadowania atramentu z tablicy.

            DWORD dwRead = 0;
            LPBYTE pbData = NULL; 

            if (SUCCEEDED(::SafeArrayAccessData(vtData.parray, (void**)&pbData)))
            {
                // Read the data from the stream to the varian data and load that into an InkDisp object
                if (TRUE == spStream->Read(pbData, uli.LowPart, &dwRead)
                    && SUCCEEDED(spIInkDisp->Load(vtData)))
                {
                    hr = S_OK;
                }
                ::SafeArrayUnaccessData(vtData.parray);
            }
            ::SafeArrayDestroy(vtData.parray);
        }
    }
}