Freigeben über


Dynamisches Festlegen der an den Consumer zurückgegebenen Spalten

Die PROVIDER_COLUMN_ENTRY Makros behandeln normalerweise den IColumnsInfo::GetColumnsInfo Aufruf. Da ein Verbraucher jedoch Lesezeichen verwenden kann, muss der Anbieter in der Lage sein, die zurückgegebenen Spalten zu ändern, je nachdem, ob der Verbraucher nach einer Textmarke fragt.

Um den Aufruf zu verarbeiten, löschen Sie den IColumnsInfo::GetColumnsInfo PROVIDER_COLUMN_MAP, der eine Funktion GetColumnInfodefiniert, aus dem CCustomWindowsFile Benutzerdatensatz in CustomRS.h, und ersetzen Sie ihn durch die Definition für Ihre eigene GetColumnInfo Funktion:

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

Implementieren Sie als Nächstes die GetColumnInfo Funktion in "CustomRS.cpp", wie im folgenden Code gezeigt.

GetColumnInfo überprüft zuerst, ob die OLE DB-Eigenschaft DBPROP_BOOKMARKS festgelegt ist. Zum Abrufen der Eigenschaft GetColumnInfo wird ein Zeiger (pRowset) auf das Rowset-Objekt verwendet. Der pThis Zeiger stellt die Klasse dar, die das Rowset erstellt hat. Dabei handelt es sich um die Klasse, in der die Eigenschaftszuordnung gespeichert ist. GetColumnInfo typecasts the pThis pointer to an RCustomRowset pointer.

Um nach der DBPROP_BOOKMARKS Eigenschaft zu suchen, GetColumnInfo verwendet die IRowsetInfo Schnittstelle, die Sie abrufen können, indem Sie die pRowset Schnittstelle aufrufenQueryInterface. Alternativ können Sie stattdessen eine ATL CComQIPtr-Methode verwenden.

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

In diesem Beispiel wird ein statisches Array verwendet, um die Spalteninformationen zu enthalten. Wenn der Consumer die Textmarkenspalte nicht verwenden möchte, wird ein Eintrag im Array nicht verwendet. Zum Behandeln der Informationen erstellen Sie zwei Arraymakros: ADD_COLUMN_ENTRY und ADD_COLUMN_ENTRY_EX. ADD_COLUMN_ENTRY_EX verwendet einen zusätzlichen Parameter, Flags, das erforderlich ist, wenn Sie eine Textmarkenspalte festlegen.

////////////////////////////////////////////////////////////////////////  
// 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;  

In der GetColumnInfo Funktion wird das Textmarkenmakro wie folgt verwendet:

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

Sie können jetzt den erweiterten Anbieter kompilieren und ausführen. Um den Anbieter zu testen, ändern Sie den Testanwender, wie in der Implementierung eines einfachen Verbrauchers beschrieben. Führen Sie den Testanwender mit dem Anbieter aus, und stellen Sie sicher, dass der Testanwender die richtigen Zeichenfolgen vom Anbieter abruft.

Siehe auch

Erweitern des einfachen schreibgeschützten Anbieters