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 GetColumnInfo
definiert, 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.