将文本墨迹对象转换为 Ink
实现从文本墨迹对象 (tInk) 转换为墨迹。
从文本墨迹对象转换为墨迹
- 使用 IPersistStream 接口将文本墨迹对象的内容写入流。 文本墨迹对象使用墨迹序列化格式写入 Steam。
- 将流的内容读取到 BYTE 数组中。
- 使用 InkDisp 对象的 Load 方法将流的内容加载到 InkDisp 对象中。
文本 Ink 对象到 Ink 对象示例
以下代码片段将文本墨迹对象转换为墨迹。
首先,代码获取文本墨迹对象。
/* Create a variable to hold the text ink object */
CComPtr<IInkObject *> spITextInk;
/* Obtain the text ink object */
然后,代码为保存文本墨迹对象内容的流创建指针。
// Create a Stream pointer to hold the saved object
CComPtr<IStream *> spStream = NULL;
然后,代码从文本墨迹对象获取 IPersistStream 接口。
// 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);
然后,代码使用 IPersistStream 接口将文本墨迹对象的内容保存到流中。
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);
}
}
然后,代码创建 InkCollector 对象,为 InkCollector 创建 InkDisp 对象,将 InkCollector 附加到应用程序窗口,并在 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;
然后,代码检索流的大小,并创建一个安全数组来保存流的内容。
// 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)
{
最后,代码访问安全数组并使用 InkDisp 对象的 Load 方法从数组加载墨迹。
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);
}
}
}