Le macro PROVIDER_COLUMN_ENTRY normalmente gestiscono il GetColumnsInfo . Dal momento che il consumatore può o non può scegliere di usare i segnalibri, tuttavia, il provider deve essere in grado di modificare le colonne restituite a seconda se non il consumatore chiede un segnalibro.
Per gestire il GetColumnsInfo , eliminare PROVIDER_COLUMN_MAP (che definisce una funzione _GetColumnInfo ) dal CAgentMan utente registrare in MyProviderRS. H e sostituirla con la definizione per il proprio _GetColumnInfo funzione
////////////////////////////////////////////////////////////////////////
/ / MyProviderRS. H
classe C&AgentMan
{
pubblica:
DWORD dwBookmark;
TCHAR szCommand [256];
TCHAR szText [256];
Mentre szCommand2 TCHAR [256];
TCHAR szText2 [256];
statico ATLCOLUMNINFO * _GetColumnInfo (void * pThis, ULONG * pcCols);
bool operator = = (const CAgentManamp; am)
{
ritorno (lstrcmpi (szCommand, am.szCommand) = = 0);
}
}
Successivamente, implementare la _GetColumnInfo funzionare in MyProviderRS.cpp, come mostrato nel codice seguente.
_GetColumnInfocontrolla il primo a vedere se la proprietà OLE DB DBPROP_IRowsetLocate è impostata. Per ottenere la proprietà _GetColumnInfo utilizza un puntatore ( pRowset ) per l'oggetto rowset. Il pThis puntatore rappresenta la classe che ha creato il set di righe (che è la classe in cui è memorizzata la mappa delle proprietà). _GetColumnInfo esegue il pThis puntatore a un RMyProviderRowset puntatore.
Per controllare la proprietà DBPROP_IRowsetLocate , _GetColumnInfo utilizza l'interfaccia IRowsetInfo , che può ottenere dal chiamante QueryInterface sul pRowset interfaccia. (In alternativa, si può utilizzare un ATL CComQIPtr .)
////////////////////////////////////////////////////////////////////
/ / MyProviderRS.cpp
ATLCOLUMNINFO * CAgentMan::_GetColumnInfo(void* pThis, ULONG* pcCols)
{
statico ATLCOLUMNINFO _rgColumns [5];
ULONG ulCols = 0;
/ / Controlla il flag di proprietà per i segnalibri, se è impostato, il numero ordinale di zero
/ / voce nella colonna map con informazioni del segnalibro.
CAgentRowset * pRowset = (CAgentRowset *) pThis;
CComQIPtrlt; IRowsetInfo, & IID_IRowsetInfo > spRowsetProps = pRowset;
CDBPropIDSet set(DBPROPSET_ROWSET);
impostare.AddPropertyID(DBPROP_BOOKMARKS);
DBPROPSET * pPropSet = NULL;
ULONG ulPropSet = 0;
HRESULT hr;
Se (spRowsetProps)
HR = spRowsetProps - > GetProperties (1, insieme, ulPropSet & pPropSet);
Se (pPropSet)
{
Var CComVariant = 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 + +;
}
}
/ / Next istituire le altre colonne.
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, mentre szCommand2)
ulCols + +;
ADD_COLUMN_ENTRY (ulCols, OLESTR("Text2"), 4, 256, DBTYPE_STR, 0xFF, 0xFF, GUID_NULL, CAgentMan, szText2)
ulCols + +;
Se (pcCols! = NULL)
* pcCols = ulCols;
return _rgColumns;
}
Questo esempio utilizza una matrice statica per contenere le informazioni di colonna. Se il consumatore non vuole la colonna segnalibro, una voce nella matrice è inutilizzata. Per gestire le informazioni, creare due macro di matrice, ADD_COLUMN_ENTRY e ADD_COLUMN_ENTRY_EX. ADD_COLUMN_ENTRY_EX accetta un parametro aggiuntivo, flags , che è necessario se si designa una colonna segnalibro.
////////////////////////////////////////////////////////////////////////
/ / MyProviderRS. H
# define &ADD_COLUMN_ENTRY (ulCols, nome, numero ordinale, colSize, type, precisione, scala, guid, dataClass, membro) \
.pwszName _rgColumns [ulCols] = nome (LPOLESTR); \
.pTypeInfo _rgColumns [ulCols] = (ITypeInfo *) NULL; \
.iOrdinal _rgColumns [ulCols] = ordinale (ULONG); \
.dwFlags _rgColumns [ulCols] = 0; \
.ulColumnSize _rgColumns [ulCols] = colSize (ULONG); \
.wType _rgColumns [ulCols] = tipo (DBTYPE); \
.bPrecision _rgColumns [ulCols] = precisione (BYTE); \
.bScale _rgColumns [ulCols] = scala (BYTE); \
.cbOffset _rgColumns [ulCols] = offsetof (dataClass, membro);
# define ADD_COLUMN_ENTRY_EX (ulCols, nome, numero ordinale, colSize, type, precisione, scala, guid, dataClass, membro, bandiere) \
.pwszName _rgColumns [ulCols] = nome (LPOLESTR); \
.pTypeInfo _rgColumns [ulCols] = (ITypeInfo *) NULL; \
.iOrdinal _rgColumns [ulCols] = ordinale (ULONG); \
.dwFlags _rgColumns [ulCols] = bandiere; \
.ulColumnSize _rgColumns [ulCols] = colSize (ULONG); \
.wType _rgColumns [ulCols] = tipo (DBTYPE); \
.bPrecision _rgColumns [ulCols] = precisione (BYTE); \
.bScale _rgColumns [ulCols] = scala (BYTE); \
.cbOffset _rgColumns [ulCols] = offsetof (dataClass, membro); \
memset(amp;(_rgColumns[ulCols].ColumnID), 0, sizeof(DBID)); \
.columnid.uName.pwszName _rgColumns [ulCols] = nome (LPOLESTR)
Nella _GetColumnInfo come questo viene utilizzata la funzione, la macro segnalibro:
ADD_COLUMN_ENTRY_EX (ulCols, OLESTR("Bookmark"), 0, sizeof(DWORD),
DBTYPE_BYTES, 0, 0, GUID_NULL, CAgentMan, dwBookmark, DBCOLUMNFLAGS_ISBOOKMARK)
Ora potete compilare ed eseguire il maggiore fornitore. Per testare il provider, modificare il consumatore di prova, come descritto nel modificare il consumatore per l'utilizzo con Enhanced Provider. Eseguire il test di consumatore con il provider. Verificare che il consumatore prova recupera le stringhe corretta dal provider quando clicchi il pulsante Esegui nella finestra di dialogo prova dei consumatori.