COM 라이브러리 사용

태블릿 PC 관리형 라이브러리 참조는 이제 일반 Windows Vista SDK 클래스 라이브러리 참조 섹션에서 찾을 수 있습니다. Microsoft Visual C++ 개체 모델을 제공합니다. COM 라이브러리의 개체 대부분은 태블릿 PC 관리 API에 있는 개체와 동일합니다.

그러나 COM API에는 표준 Microsoft Win32 환경과 Microsoft .NET Frameworksoftware 개발 키트(SDK) 환경 간의 차이로 인해 관리되는 API에 있는 멤버 외에 일부 멤버가 포함되어 있습니다. 예를 들어 InkRectangle 및 InkTransform 개체는 COM에서 사용되지만 FrameworkSDK는 태블릿 PC 플랫폼 Managed API에서 이러한 개체가 필요하지 않도록 InkRectangle 클래스InkTransform 클래스 에 대한 네이티브 구현을 제공합니다.

참고

COM API 및 잉크 컨트롤의 개체는 ASP(Active Server Pages)에서 사용하도록 설계되지 않았습니다.

 

컬렉션 작업

COM 라이브러리의 컬렉션 개체에 인덱스로 NULL 값을 전달하면 호출 시 이러한 인수 값이 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
              // ...
            }
        }
    }
}

매개 변수

COM 라이브러리의 컬렉션 개체에 대한 인덱스로 VT_EMPTY 또는 VT_NULL 전달하는 경우 이러한 인수 값이 호출될 때 0으로 강제 변환되므로 컬렉션의 첫 번째 항목이 수신됩니다.

IDispatch 사용

성능을 높이기 위해 태블릿 PC 플랫폼 COM API(애플리케이션 프로그래밍 인터페이스)는 명명된 인수가 있는 DISPPARAMS 구조체를 사용한 호출 IDispatchImpl::Invoke 을 지원하지 않습니다. 도 IDispatchImpl::GetIDsOfNames 지원되지 않습니다. 대신 SDK 헤더에 제공된 DISPID를 사용하여 를 호출 Invoke 합니다.

이벤트 대기 중

태블릿 PC 환경은 다중 스레드됩니다. 다중 스레딩에 대한 COM 설명서를 참조하세요.

집계 지원

집계는 InkEdit 컨트롤, InkPicture 컨트롤, InkDisp 개체 및 InkOverlay 개체에 대해서만 테스트되었습니다. 라이브러리의 다른 컨트롤 및 개체에 대한 집계가 테스트되지 않았습니다.

C++

C++에서 태블릿 PC SDK를 사용하려면 VARIANT, SAFEARRAY 및 BSTR과 같은 일부 COM 개념을 사용해야 합니다. 이 섹션에서는 사용 방법을 설명합니다.

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 개체에 IInkStrokeDisp , pInkStrokeDisppInk를 만듭니다.

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에는 0으로 끝나는 문자열에 대한 포인터가 있지만 문자열의 첫 번째 문자 바로 앞에 있는 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);
}