Использование библиотеки COM

Справочник по библиотеке управляемых планшетных компьютеров теперь можно найти в обычном разделе Справочник по библиотеке классов пакета SDK для Windows Vista. Он предоставляет объектную модель для Microsoft Visual C++. Большинство объектов в библиотеке COM идентичны объектам, которые находятся в УПРАВЛЯЕМОМ API планшетного компьютера.

Однако COM API содержит некоторые элементы в дополнение к элементам, которые находятся в управляемом API из-за различий между стандартной средой Microsoft Win32 и средой пакета SDK microsoft .NET Framework. Например, объекты 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
              // ...
            }
        }
    }
}

Параметры

Если вы передаете VT_EMPTY или VT_NULL в качестве индекса любому из объектов коллекции в библиотеке COM, вы получите первый элемент в коллекции, так как эти значения аргументов принудаются к 0 при вызове.

Использование IDispatch

Чтобы повысить производительность, API платформы планшетного пк не поддерживает вызов IDispatchImpl::Invoke со структурой DISPPARAMS с именованными аргументами. Также IDispatchImpl::GetIDsOfNames не поддерживается. Вместо этого вызовите Invoke с идентификаторами DISPID, указанными в заголовках пакета SDK.

Ожидание событий

Среда планшетного компьютера является многопоточной. Сведения о многопотоковом использовании см. в документации по COM.

Поддержка агрегирования

Агрегирование было протестировано только для элемента управления InkEdit , элемента управления InkPicture , объекта InkDisp и Объекта InkOverlay . Агрегирование не проверялось для других элементов управления и объектов в библиотеке.

C++

Для использования пакета SDK для планшетного компьютера в C++ требуется использование некоторых концепций COM, таких как VARIANT, SAFEARRAY и BSTR. В этом разделе описывается их использование.

VARIANT и SAFEARRAY

Структура VARIANT используется для обмена данными между COM-объектами. По сути, структура VARIANT — это контейнер для большого объединения, который содержит множество типов данных.

Значение в первом элементе структуры , vt, описывает, какие из членов профсоюза являются допустимыми. При получении сведений в структуре VARIANT проверка член vt, чтобы узнать, какой элемент содержит допустимые данные. Аналогичным образом, при отправке данных с помощью структуры VARIANT всегда задается значение vt для отражения участника объединения, содержащего эти сведения.

Перед использованием структуры инициализируйте ее, вызвав com-функцию VariantInit. Завершив работу со структурой, очистите ее до освобождения памяти, содержащей VARIANT, путем вызова VariantClear.

Дополнительные сведения о структуре VARIANT см. в разделах Типы данных VARIANT и VARIANTARG.

Структура SAFEARRAY предоставляется для безопасной работы с массивами в COM. Поле parray variant является указателем на SAFEARRAY. Используйте такие функции, как SafeArrayCreateVector, SafeArrayAccessData и SafeArrayUnaccessData, чтобы создать и заполнить SAFEARRAY в VARIANT.

Дополнительные сведения о типе данных SAFEARRAY см. в разделе Тип данных SafeArray.

В этом примере C++ создается IInkStrokeDisp в pInkStrokeDispобъекте pInkInkDisp из массива точечных данных.

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++ показано, как задать фактоид в InkRecognizerContext с помощью BSTR.

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