Dynamicznie określanie kolumn zwracanych do konsumenta
Normalnie obsługi makr PROVIDER_COLUMN_ENTRY IColumnsInfo::GetColumnsInfo zadzwonić.Jednak ponieważ konsument może być przydatny program zakładek, dostawca musi być możliwa zmiana kolumny zwracane w zależności od tego, czy konsument zwraca się do zakładki.
Do obsługi IColumnsInfo::GetColumnsInfo zadzwonić, usuwanie PROVIDER_COLUMN_MAP, który definiuje funkcję GetColumnInfo, z CAgentMan użytkownika rejestrowane w MyProviderRS.h i zamień go na własną definicję GetColumnInfo funkcji:
////////////////////////////////////////////////////////////////////////
// MyProviderRS.H
class CAgentMan
{
public:
DWORD dwBookmark;
TCHAR szCommand[256];
TCHAR szText[256];
TCHAR szCommand2[256];
TCHAR szText2[256];
static ATLCOLUMNINFO* GetColumnInfo(void* pThis, ULONG* pcCols);
bool operator==(const CAgentMan& am)
{
return (lstrcmpi(szCommand, am.szCommand) == 0);
}
};
Następnie należy zaimplementować GetColumnInfo funkcjonować w MyProviderRS.cpp, jak pokazano w poniższym kodzie.
GetColumnInfokontrole po raz pierwszy, aby sprawdzić, czy właściwość OLE DB DBPROP_BOOKMARKS jest ustawiona.Aby uzyskać właściwości, GetColumnInfo używa wskaźnika (pRowset) do obiektu zestawu wierszy.pThis Wskaźnik reprezentuje klasę utworzony zestaw wierszy, która jest klasą przechowywania mapowania właściwości.GetColumnInfotypecasts pThis wskaźnik do RMyProviderRowset wskaźnik.
Aby sprawdzić DBPROP_BOOKMARKS właściwość, GetColumnInfo korzysta z IRowsetInfo interfejs, który można uzyskać, dzwoniąc QueryInterface na pRowset interfejsu.Alternatywnie, można użyć biblioteki ATL CComQIPtr metoda zamiast.
////////////////////////////////////////////////////////////////////
// MyProviderRS.cpp
ATLCOLUMNINFO* CAgentMan::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.
CAgentRowset* pRowset = (CAgentRowset*) 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, CAgentMan, dwBookmark,
DBCOLUMNFLAGS_ISBOOKMARK)
ulCols++;
}
}
// Next, set the other columns up.
ADD_COLUMN_ENTRY(ulCols, OLESTR("Command"), 1, 256, DBTYPE_STR, 0xFF, 0xFF,
GUID_NULL, CAgentMan, szCommand)
ulCols++;
ADD_COLUMN_ENTRY(ulCols, OLESTR("Text"), 2, 256, DBTYPE_STR, 0xFF, 0xFF,
GUID_NULL, CAgentMan, szText)
ulCols++;
ADD_COLUMN_ENTRY(ulCols, OLESTR("Command2"), 3, 256, DBTYPE_STR, 0xFF, 0xFF,
GUID_NULL, CAgentMan, szCommand2)
ulCols++;
ADD_COLUMN_ENTRY(ulCols, OLESTR("Text2"), 4, 256, DBTYPE_STR, 0xFF, 0xFF,
GUID_NULL, CAgentMan, szText2)
ulCols++;
if (pcCols != NULL)
*pcCols = ulCols;
return _rgColumns;
}
W tym przykładzie używa statycznej tablicy musi zawierać informacje kolumny.Jeśli konsument nie chce kolumnę zakładki, jeden wpis w tablicy jest nieużywany.Do obsługi informacji, tworzenia dwóch makr tablicy: ADD_COLUMN_ENTRY i ADD_COLUMN_ENTRY_EX.ADD_COLUMN_ENTRY_EX przyjmuje jako dodatkowy parametr flags, który jest potrzebny, jeśli można wyznaczyć kolumnę zakładki.
////////////////////////////////////////////////////////////////////////
// MyProviderRS.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;
W GetColumnInfo takiego służy funkcja makro zakładki:
ADD_COLUMN_ENTRY_EX(ulCols, OLESTR("Bookmark"), 0, sizeof(DWORD),
DBTYPE_BYTES, 0, 0, GUID_NULL, CAgentMan, dwBookmark,
DBCOLUMNFLAGS_ISBOOKMARK)
Można teraz skompilować i uruchomić dostawcę rozszerzonych.Aby przetestować dostawca, zmodyfikować konsumenta testu zgodnie z opisem w wykonania prostego konsumenta.Uruchom test konsumenta z dostawcą.Sprawdź, czy konsument badania pobiera odpowiednie ciągi od dostawcy, po kliknięciu przycisku uruchomić przycisk w Konsumentów Test okno dialogowe.