Convertendo um objeto text ink em tinta
Implementação da conversão de um objeto de tinta de texto (tInk) em tinta.
Para converter de um objeto de tinta de texto em tinta
- Use a interface IPersistStream para gravar o conteúdo do objeto de tinta de texto em um fluxo. O objeto de tinta de texto usa formato serializado à tinta para gravar no vapor.
- Leia o conteúdo do fluxo em uma matriz BYTE.
- Use o método Load do objeto InkDisp para carregar o conteúdo do fluxo no objeto InkDisp.
Exemplo do objeto Text Ink para Ink
O fragmento de código a seguir converte um objeto de tinta de texto em tinta.
Primeiro, o código obtém um objeto de tinta de texto.
/* Create a variable to hold the text ink object */
CComPtr<IInkObject *> spITextInk;
/* Obtain the text ink object */
Em seguida, o código cria um ponteiro para o fluxo que contém o conteúdo do objeto de tinta de texto.
// Create a Stream pointer to hold the saved object
CComPtr<IStream *> spStream = NULL;
Em seguida, o código obtém a interface IPersistStream do objeto de tinta de texto.
// 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);
Em seguida, o código usa a interface IPersistStream para salvar o conteúdo do objeto de tinta de texto no fluxo.
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);
}
}
Em seguida, o código cria um objeto InkCollector , cria um objeto InkDisp para o InkCollector, anexa o InkCollector à janela do aplicativo e habilita a coleção de tinta no 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;
Em seguida, o código recupera o tamanho do fluxo e cria uma matriz segura para manter o conteúdo do fluxo.
// 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)
{
Por fim, o código acessa a matriz segura e usa o método Load do objeto InkDisp para carregar a tinta da matriz.
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);
}
}
}