使用 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::InvokeIDispatchImpl::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 对象 中创建 IInkStrokeDisppInkStrokeDisppInk

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);
}