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
- Użyj interfejsu IPersistStream, aby zapisać zawartość obiektu pisma oddyskowego do strumienia. Obiekt tekstu atramentu używa zserializowanego formatu atramentu do zapisu w strumieniu.
- Odczytaj zawartość strumienia do tablicy BYTE.
- 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);
}
}
}