使用 COM 库
现在可以在常规的 Windows Vista SDK 类库参考部分找到平板电脑托管库参考。 它为Microsoft Visual C++提供对象模型。 COM 库中的大多数对象与 Tablet PC 托管 API 中的对象相同。
但是,由于标准 Microsoft Win32 环境和 Microsoft .NET Framework 软件开发工具包 (SDK) 环境之间的差异,COM API 还包含托管 API 中的成员。 例如,InkRectangle 和 InkTransform 对象在 COM 中使用,但 FrameworkSDK 为 InkRectangle 类 和 InkTransform 类 提供了本机实现,无需在平板电脑平台托管 API 中使用这些对象。
注意
COM API 中的对象和墨迹控件不设计用于 Active Server Pages (ASP) 。
使用集合
如果将 NULL 值作为索引传入 COM 库中的任何集合对象,则会收到集合中的第一项,因为这些参数值在调用时被强制转换为 0。
_NewEnum 属性在集合接口的接口定义语言 (IDL) 定义中被标记为受限。
在 C++ 中,使用 For...
循环通过首先获取集合的长度来循环访问集合。 下面的示例演示如何循环访问 InkDisp 对象的笔划。 pInk
IInkStrokes* pStrokes;
HRESULT result = pInk->get_Strokes(&pStrokes);
if (SUCCEEDED(result))
{
// Loop over strokes
long nStrokes;
result = pStrokes->get_Count(&nStrokes);
if (SUCCEEDED(result))
{
for (int i =0; i < nStrokes; i++)
{
IInkStrokeDisp* pStroke;
result = pStrokes->Item(i, &pStroke);
if (SUCCEEDED(result))
{
// Code that uses pStroke
// ...
}
}
}
}
parameters
如果将VT_EMPTY或VT_NULL作为索引传入 COM 库中的任何集合对象,则会收到集合中的第一项,因为在进行调用时,这些参数值被强制设置为 0。
使用 IDispatch
为了提高性能,平板电脑平台 COM 应用程序编程接口 (API) 不支持使用带命名参数的 DISPPARAMS 结构调用 IDispatchImpl::Invoke
。
IDispatchImpl::GetIDsOfNames
也不支持 。 而是使用 SDK 标头中提供的 DISPID 调用 Invoke
。
正在等待事件
平板电脑环境是多线程的。 有关多线程处理,请参阅 COM 文档。
对聚合的支持
仅针对 InkEdit 控件、 InkPicture 控件、 InkDisp 对象和 InkOverlay 对象测试了聚合。 尚未针对库中的其他控件和对象测试聚合。
C++
在 C++ 中使用 Tablet PC SDK 需要使用一些 COM 概念,例如 VARIANT、SAFEARRAY 和 BSTR。 本部分介绍如何使用它们。
VARIANT 和 SAFEARRAY
VARIANT 结构用于 COM 对象之间的通信。 从本质上讲,VARIANT 结构是承载多种类型的数据的大型联合的容器。
结构的第一个成员 vt 中的值描述哪个联合成员有效。 在 VARIANT 结构中收到信息时,检查 vt 成员,找出哪个成员包含有效数据。 同样,在使用 VARIANT 结构发送信息时,始终设置 vt 以反映包含该信息的联合成员。
在使用 结构之前,请通过调用 VariantInit COM 函数对其进行初始化。 完成结构后,在通过调用 VariantClear 释放包含 VARIANT 的内存之前清除它。
有关 VARIANT 结构的详细信息,请参阅 VARIANT 和 VARIANTARG 数据类型。
SAFEARRAY 结构是作为在 COM 中安全地处理数组的一种方式提供的。 VARIANT 的 parray 字段是指向 SAFEARRAY 的指针。 使用 SafeArrayCreateVector、SafeArrayAccessData 和 SafeArrayUnaccessData 等函数在 VARIANT 中创建和填充 SAFEARRAY。
有关 SAFEARRAY 数据类型的详细信息,请参阅 SafeArray 数据类型。
此 C++ 示例从点数据数组在 InkDisp 对象 中创建 IInkStrokeDisppInkStrokeDisp
、 pInk
。
VARIANT var, varPK;
LONG* plongArray=NULL;
POINT ptArray[2]={0};
long lSize=0;
IInkStrokeDisp* pInkStrokeDisp;
IInkDisp* pInk; // the object should be created correctly
// elsewhere and assigned here.
HRESULT hr=E_FAIL;
ptArray[0].x = 20;
ptArray[0].y = 100;
ptArray[1].x = 30;
ptArray[1].y = 110;
lSize = 2; // two points
VariantInit( &var );
VariantInit( &varPK );
SAFEARRAY* psa = SafeArrayCreateVector( VT_I4, 0, lSize*2 );
if( psa )
{
if( SUCCEEDED( hr = SafeArrayAccessData( psa, (void**)&plongArray) ))
{
for( long i = 0; i < lSize; i++ )
{
plongArray[2*i] = ptArray[i].x;
plongArray[2*i+1] = ptArray[i].y;
}
hr = SafeArrayUnaccessData( psa );
if ( SUCCEEDED( hr ) )
{
var.vt = VT_ARRAY | VT_I4;
var.parray = psa;
// varPK (packet description) is currently reserved, so it is
// just empty variant for now.
pInk->CreateStroke( var, varPK, &pInkStrokeDisp );
}
}
}
VariantClear( &var );
VariantClear( &varPK );
BSTR
COM 支持的字符串格式为 BSTR。 BSTR 具有指向以零结尾的字符串的指针,但它还包含字符串 (的长度(以字节为单位),不包括终止符) ,该终止符存储在紧邻字符串第一个字符之前的 4 个字节中。
有关 BSTR 的详细信息,请参阅 BSTR 数据类型。
此 C++ 示例演示如何使用 BSTR 在 InkRecognizerContext 上设置 factoid。
IInkRecognizerContext* pRecognizerContext = NULL;
result = CoCreateInstance(CLSID_InkRecognizerContext,
NULL, CLSCTX_INPROC_SERVER,
IID_IInkRecognizerContext,
(void **) &pRecognizerContext);
if SUCCEEDED(result)
{
BSTR bstrFactoid = SysAllocString(FACTOID_DATE);
result = pRecognizerContext->put_Factoid(bstrFactoid);
if SUCCEEDED(result)
{
// Use recognizer context...
// ...
}
SysFreeString(bstrFactoid);
}