Macros PROVIDER_COLUMN_ENTRY normalmente identificador chamar IColumnsInfo:: GetColumnsInfo . Uma vez que um consumidor pode ou não pode optar por usar marcadores, no entanto, o provedor deve ser capaz de alterar as colunas retornadas dependendo ou não o consumidor pede um indicador.
Para lidar com a chamada de IColumnsInfo:: GetColumnsInfo , excluir the PROVIDER_COLUMN_MAP (que define uma função _GetColumnInfo ) do CAgentMan usuário gravar em MyProviderRS. H e substituí-lo com a definição para o seu próprio _GetColumnInfo função
////////////////////////////////////////////////////////////////////////
/ / MyProviderRS. H
Classe C&AgentMan
{
público:
DWORD dwBookmark;
TCHAR szCommand [256];
TCHAR szText [256];
TCHAR szCommand2 [256];
TCHAR szText2 [256];
estático ATLCOLUMNINFO * _GetColumnInfo (void * pThis, ULONG * pcCols);
bool operador = = (const CAgentManamp; am)
{
retornar (lstrcmpi (szCommand, am.szCommand) = = 0);
}
}
Em seguida, implementar o _GetColumnInfo função em MyProviderRS.cpp, conforme mostrado no código a seguir.
_GetColumnInfoverifica primeiro se a propriedade OOLE DB DBPROP_IRowsetLocate é definida. Para obter a propriedade, _GetColumnInfo usa um ponteiro ( pRowset ) para o objeto de conjunto de linhas. O pThis ponteiro representa a classe que criou o conjunto de linhas (que é a classe onde está armazenado o mapa de propriedade). _GetColumnInfo typecasts a pThis ponteiro para um RMyProviderRowset ponteiro.
Para verificar a propriedade DBPROP_IRowsetLocate , _GetColumnInfo usa a interface de IRowsetInfo , que pode ser obtido por chamado Falha de QueryInterface sobre o pRowset interface. (Como alternativa, você pode usar um ATL CComQIPtr .)
////////////////////////////////////////////////////////////////////
/ / MyProviderRS.cpp
ATLCOLUMNINFO * CAgentMan::_GetColumnInfo(void* pThis, ULONG* pcCols)
{
estático ATLCOLUMNINFO _rgColumns [5];
ULONG ulCols = 0;
/ / Verificar o sinalizador de propriedade de marcadores, se for definido, defina o zero ordinal
/ / entrada na coluna mapa com as informações de marcador.
CAgentRowset * pRowset = (CAgentRowset *) pThis;
CComQIPtrlt; IRowsetInfo, & IID_IRowsetInfo > spRowsetProps = pRowset;
CDBPropIDSet set(DBPROPSET_ROWSET);
Defina.AddPropertyID(DBPROP_BOOKMARKS);
DBPROPSET * pPropSet = NULL;
ULONG ulPropSet = 0;
HRESULT hr;
se (spRowsetProps)
hr = spRowsetProps - > GetProperties (1, conjunto, & ulPropSet, & pPropSet);
se (pPropSet)
{
CComVariant var = pPropSet - > .vvalue rgProperties [0];
CoTaskMemFree (pPropSet - > rgProperties);
CoTaskMemFree(pPropSet);
se (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 + +;
}
}
/ / Em seguida configure as outras colunas.
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 + +;
se (pcCols! = NULL)
* pcCols = ulCols;
retornar _rgColumns;
}
Este exemplo usa uma matriz estática para conter as informações de coluna. Se o consumidor não quer a coluna de indicador, uma entrada na matriz é não utilizada. Para lidar com as informações, você cria duas macros de matriz, ADD_COLUMN_ENTRY e ADD_COLUMN_ENTRY_EX. ADD_COLUMN_ENTRY_EX tem um parâmetro extra, flags , isto é necessário se você designar uma coluna de indicador.
////////////////////////////////////////////////////////////////////////
/ / MyProviderRS. H
# define &ADD_COLUMN_ENTRY (ulCols, nome, ordinal, colSize, tipo, precisão, escala, guid, dataClass, membro) \
.pwszName _rgColumns [ulCols] = nome (LPOLESTR); \
.pTypeInfo _rgColumns [ulCols] = (ITypeInfo *) NULL; \
.iOrdinal _rgColumns [ulCols] = ordinal (ULONG); \
.dwFlags _rgColumns [ulCols] = 0; \
_rgColumns [ulCols] .ulcolumnsize = colSize (ULONG); \
.wType _rgColumns [ulCols] = tipo (DBTYPE); \
.bPrecision _rgColumns [ulCols] = precisão (BYTE); \
.bScale _rgColumns [ulCols] = (BYTE) escala; \
.cbOffset _rgColumns [ulCols] = offsetof (dataClass, membro);
# define ADD_COLUMN_ENTRY_EX (ulCols, nome, ordinal, colSize, tipo, precisão, escala, guid, dataClass, membro, flags) \
.pwszName _rgColumns [ulCols] = nome (LPOLESTR); \
.pTypeInfo _rgColumns [ulCols] = (ITypeInfo *) NULL; \
.iOrdinal _rgColumns [ulCols] = ordinal (ULONG); \
.dwFlags _rgColumns [ulCols] = sinalizadores; \
_rgColumns [ulCols] .ulcolumnsize = colSize (ULONG); \
.wType _rgColumns [ulCols] = tipo (DBTYPE); \
.bPrecision _rgColumns [ulCols] = precisão (BYTE); \
.bScale _rgColumns [ulCols] = (BYTE) escala; \
.cbOffset _rgColumns [ulCols] = offsetof (dataClass, membro); \
memset(amp;(_rgColumns[ulCols].columnid), 0, sizeof(DBID)); \
.columnid.uName.pwszName _rgColumns [ulCols] = nome (LPOLESTR)
No _GetColumnInfo função, a macro de indicador é usada como este:
ADD_COLUMN_ENTRY_EX (ulCols, OLESTR("Bookmark"), 0, sizeof(DWORD),
DBTYPE_BYTES, 0, 0, GUID_NULL, CAgentMan, dwBookmark, DBCOLUMNFLAGS_ISBOOKMARK)
Agora você pode compilar e executar o provedor avançado. Para testar o provedor, modifique o consumidor de teste, conforme descrito em modificar o consumidor para uso com o provedor avançado. Execute teste de consumidor com o provedor. Verifique se que o consumidor teste recupera as seqüências de caracteres apropriadas do provedor ao clicar no botão executar na caixa de diálogo teste consumidor.