Conversione di un oggetto Input penna di testo in input penna
Implementazione della conversione da un oggetto input penna di testo (tInk) a input penna.
Per eseguire la conversione da un oggetto input penna di testo a input penna
- Usare l'interfaccia IPersistStream per scrivere il contenuto dell'oggetto input penna in un flusso. L'oggetto input penna di testo usa il formato serializzato dell'input penna per scrivere nel vapore.
- Leggere il contenuto del flusso in una matrice BYTE.
- Utilizzare il metodo Load dell'oggetto InkDisp per caricare il contenuto del flusso nell'oggetto InkDisp.
Esempio di oggetto Input penna testo in input penna
Il frammento di codice seguente converte un oggetto input penna di testo in input penna.
Innanzitutto, il codice ottiene un oggetto input penna di testo.
/* Create a variable to hold the text ink object */
CComPtr<IInkObject *> spITextInk;
/* Obtain the text ink object */
Il codice crea quindi un puntatore per il flusso che contiene il contenuto dell'oggetto input penna di testo.
// Create a Stream pointer to hold the saved object
CComPtr<IStream *> spStream = NULL;
Il codice ottiene quindi l'interfaccia IPersistStream dall'oggetto input penna di testo.
// 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);
Il codice usa quindi l'interfaccia IPersistStream per salvare il contenuto dell'oggetto input penna nel flusso.
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);
}
}
Il codice crea quindi un oggetto InkCollector, crea un oggetto InkDisp per InkCollector, associa InkCollector alla finestra dell'applicazione e abilita l'insieme input penna in 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;
Il codice recupera quindi le dimensioni del flusso e crea una matrice sicura per contenere il contenuto del flusso.
// 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)
{
Infine, il codice accede alla matrice sicura e usa il metodo Load dell'oggetto InkDisp per caricare l'input penna dalla matrice.
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);
}
}
}