다음을 통해 공유


소비자에게 반환되는 열을 동적으로 결정

PROVIDER_COLUMN_ENTRY 매크로는 일반적으로 호출을 처리합니다 IColumnsInfo::GetColumnsInfo . 그러나 소비자가 책갈피를 사용하도록 선택할 수 있으므로 공급자는 소비자가 책갈피를 요청하는지 여부에 따라 반환되는 열을 변경할 수 있어야 합니다.

호출을 IColumnsInfo::GetColumnsInfo 처리하려면 사용자 지정RS.h의 사용자 레코드에서 CCustomWindowsFile 함수GetColumnInfo를 정의하는 PROVIDER_COLUMN_MAP 삭제하고 사용자 고유 GetColumnInfo 의 함수에 대한 정의로 바꿉니다.

////////////////////////////////////////////////////////////////////////
// CustomRS.H
class CCustomWindowsFile
{
public:
   DWORD dwBookmark;
   static const int iSize = 256;
   TCHAR szCommand[iSize];
   TCHAR szText[iSize];
   TCHAR szCommand2[iSize];
   TCHAR szText2[iSize];
  
   static ATLCOLUMNINFO* GetColumnInfo(void* pThis, ULONG* pcCols);
   bool operator==(const CCustomWindowsFile& am)
   {
      return (lstrcmpi(szCommand, am.szCommand) == 0);
   }
};

다음으로, 다음 코드와 같이 사용자 지정RS.cpp 함수를 구현 GetColumnInfo 합니다.

GetColumnInfo 먼저 OLE DB 속성 DBPROP_BOOKMARKS 이 설정되어 있는지 확인합니다. 속성을 GetColumnInfo 얻으려면 행 집합 개체에 대한 포인터(pRowset)를 사용합니다. 포인터는 pThis 속성 맵이 저장되는 클래스인 행 집합을 만든 클래스를 나타냅니다. GetColumnInfo 포인터를 포인터로 pThis 변환합니다 RCustomRowset .

속성을 확인 DBPROP_BOOKMARKS 하려면 인터페이스를 IRowsetInfo 호출 QueryInterface 하여 가져올 수 있는 인터페이스를 pRowset GetColumnInfo 사용합니다. 대신 ATL CComQIPtr 메서드를 사용할 수 있습니다.

////////////////////////////////////////////////////////////////////
// CustomRS.cpp
ATLCOLUMNINFO* CCustomWindowsFile::GetColumnInfo(void* pThis, ULONG* pcCols)
{
   static ATLCOLUMNINFO _rgColumns[5];
   ULONG ulCols = 0;
  
   // Check the property flag for bookmarks; if it is set, set the zero
   // ordinal entry in the column map with the bookmark information.
   CCustomRowset* pRowset = (CCustomRowset*) pThis;
   CComQIPtr<IRowsetInfo, &IID_IRowsetInfo> spRowsetProps = pRowset;
  
   CDBPropIDSet set(DBPROPSET_ROWSET);
   set.AddPropertyID(DBPROP_BOOKMARKS);
   DBPROPSET* pPropSet = NULL;
   ULONG ulPropSet = 0;
   HRESULT hr;
  
   if (spRowsetProps)
      hr = spRowsetProps->GetProperties(1, &set, &ulPropSet, &pPropSet);
  
   if (pPropSet)
   {
      CComVariant var = pPropSet->rgProperties[0].vValue;
      CoTaskMemFree(pPropSet->rgProperties);
      CoTaskMemFree(pPropSet);
  
      if (SUCCEEDED(hr) && (var.boolVal == VARIANT_TRUE))
      {
         ADD_COLUMN_ENTRY_EX(ulCols, OLESTR("Bookmark"), 0, sizeof(DWORD),
         DBTYPE_BYTES, 0, 0, GUID_NULL, CCustomWindowsFile, dwBookmark,
         DBCOLUMNFLAGS_ISBOOKMARK)
         ulCols++;
      }
   }
  
   // Next, set the other columns up.
   ADD_COLUMN_ENTRY(ulCols, OLESTR("Command"), 1, 256, DBTYPE_STR, 0xFF, 0xFF,
      GUID_NULL, CCustomWindowsFile, szCommand)
   ulCols++;
   ADD_COLUMN_ENTRY(ulCols, OLESTR("Text"), 2, 256, DBTYPE_STR, 0xFF, 0xFF,
      GUID_NULL, CCustomWindowsFile, szText)
   ulCols++;
  
   ADD_COLUMN_ENTRY(ulCols, OLESTR("Command2"), 3, 256, DBTYPE_STR, 0xFF, 0xFF,
      GUID_NULL, CCustomWindowsFile, szCommand2)
   ulCols++;
   ADD_COLUMN_ENTRY(ulCols, OLESTR("Text2"), 4, 256, DBTYPE_STR, 0xFF, 0xFF,
      GUID_NULL, CCustomWindowsFile, szText2)
   ulCols++;
  
   if (pcCols != NULL)
      *pcCols = ulCols;
  
   return _rgColumns;
}

이 예제에서는 정적 배열을 사용하여 열 정보를 저장합니다. 소비자가 책갈피 열을 원하지 않는 경우 배열의 한 항목이 사용되지 않습니다. 정보를 처리하려면 ADD_COLUMN_ENTRY 및 ADD_COLUMN_ENTRY_EX 두 개의 배열 매크로를 만듭니다. ADD_COLUMN_ENTRY_EX 책갈피 열을 지정하는 경우 필요한 추가 매개 변수 인 플래그를 사용합니다.

////////////////////////////////////////////////////////////////////////  
// CustomRS.h  
  
#define ADD_COLUMN_ENTRY(ulCols, name, ordinal, colSize, type, precision, scale, guid, dataClass, member) \  
   _rgColumns[ulCols].pwszName = (LPOLESTR)name; \  
   _rgColumns[ulCols].pTypeInfo = (ITypeInfo*)NULL; \  
   _rgColumns[ulCols].iOrdinal = (ULONG)ordinal; \  
   _rgColumns[ulCols].dwFlags = 0; \  
   _rgColumns[ulCols].ulColumnSize = (ULONG)colSize; \  
   _rgColumns[ulCols].wType = (DBTYPE)type; \  
   _rgColumns[ulCols].bPrecision = (BYTE)precision; \  
   _rgColumns[ulCols].bScale = (BYTE)scale; \  
   _rgColumns[ulCols].cbOffset = offsetof(dataClass, member);  
  
#define ADD_COLUMN_ENTRY_EX(ulCols, name, ordinal, colSize, type, precision, scale, guid, dataClass, member, flags) \  
   _rgColumns[ulCols].pwszName = (LPOLESTR)name; \  
   _rgColumns[ulCols].pTypeInfo = (ITypeInfo*)NULL; \  
   _rgColumns[ulCols].iOrdinal = (ULONG)ordinal; \  
   _rgColumns[ulCols].dwFlags = flags; \  
   _rgColumns[ulCols].ulColumnSize = (ULONG)colSize; \  
   _rgColumns[ulCols].wType = (DBTYPE)type; \  
   _rgColumns[ulCols].bPrecision = (BYTE)precision; \  
   _rgColumns[ulCols].bScale = (BYTE)scale; \  
   _rgColumns[ulCols].cbOffset = offsetof(dataClass, member); \  
   memset(&(_rgColumns[ulCols].columnid), 0, sizeof(DBID)); \  
   _rgColumns[ulCols].columnid.uName.pwszName = (LPOLESTR)name;  

함수에서 GetColumnInfo 책갈피 매크로는 다음과 같이 사용됩니다.

ADD_COLUMN_ENTRY_EX(ulCols, OLESTR("Bookmark"), 0, sizeof(DWORD),
   DBTYPE_BYTES, 0, 0, GUID_NULL, CAgentMan, dwBookmark,
   DBCOLUMNFLAGS_ISBOOKMARK)

이제 향상된 공급자를 컴파일하고 실행할 수 있습니다. 공급자를 테스트하려면 단순 소비자 구현에 설명된 대로 테스트 소비자를 수정합니다. 공급자를 사용하여 테스트 소비자를 실행하고 테스트 소비자가 공급자로부터 적절한 문자열을 검색했는지 확인합니다.

참고 항목

단순한 읽기 전용 공급자의 기능 향상