Dynamique détermination de colonnes retournées au consommateur

Les macros PROVIDER_COLUMN_ENTRY gèrent normalement l'appel IColumnsInfo::GetColumnsInfo . Étant donné que le consommateur peut ou ne peut pas choisir utiliser des signets, toutefois, le fournisseur doit être capable de modifier les colonnes renvoyées selon si le consommateur demande un signet.

Pour gérer l'appel IColumnsInfo::GetColumnsInfo , supprimez la macro PROVIDER_COLUMN_MAP (qui définit une fonction _GetColumnInfo ) de la CAgentMan utilisateur enregistrer dans MyProviderRS.h et remplacez-la par la définition de votre propre _GetColumnInfo fonction

////////////////////////////////////////////////////////////////////////
/ / MyProviderRS.H
classe C&AgentMan
{
public :
   DWORD dwBookmark ;
   SzCommand TCHAR [256] ;
   SzText TCHAR [256] ;
   SzCommand2 TCHAR [256] ;
   SzText2 TCHAR [256] ;

statique ATLCOLUMNINFO * _GetColumnInfo (void * pThis, ULONG * pcCols) ;
   BOOL operator == (const CAgentManamp; am)
   {
      Return (lstrcmpi (szCommand, am.szCommand) == 0) ;
   }

}

Ensuite, mettre en œuvre la _GetColumnInfo fonction dans MyProviderRS.cpp, comme le montre le code suivant.

_GetColumnInfovérifie d'abord si la propriété OLE DB DBPROP_IRowsetLocate est définie. Pour obtenir la propriété _GetColumnInfo utilise un pointeur ( pRowset ) pour l'objet rowset. La pThis pointeur représente la classe ayant créé le jeu de lignes (qui est la classe où le mappage des propriétés est stocké). _GetColumnInfo des conversions de type les pThis pointeur vers un RMyProviderRowset pointeur.

Pour vérifier la propriété DBPROP_IRowsetLocate , _GetColumnInfo utilise l'interface IRowsetInfo , que vous pouvez obtenir en appelant QueryInterface sur le pRowset interface. (En guise d'alternative, vous pouvez utiliser un ATL CComQIPtr plutôt.)

////////////////////////////////////////////////////////////////////
/ / MyProviderRS.cpp
ATLCOLUMNINFO * CAgentMan::_GetColumnInfo(void* pThis, ULONG* pcCols)
{
   statique ATLCOLUMNINFO _rgColumns [5] ;
   ULONG ulCols = 0 ;
            
   / / Vérifier l'indicateur de la propriété pour les signets, si elle est définie, définir le zéro ordinal
   / / entrée dans la colonne de carte avec les informations de signet.
   CAgentRowset * pRowset = (CAgentRowset **) pThis ;
   CComQIPtrlt ; IRowsetInfo, & IID_IRowsetInfo > spRowsetProps = pRowset ;

CDBPropIDSet set(DBPROPSET_ROWSET) ;
   ensemble.AddPropertyID(DBPROP_BOOKMARKS) ;
   DBPROPSET * pPropSet = NULL ;
   ULONG ulPropSet = 0 ;
   HRESULT hr ;

Si (spRowsetProps)
      HR = spRowsetProps - > GetProperties (1, ensemble, ulPropSet, & pPropSet) ;

Si (pPropSet)
   {
      CComVariant var = pPropSet - > rgProperties [0] .vvalue ;
      CoTaskMemFree (pPropSet - > rgProperties) ;
      CoTaskMemFree(pPropSet) ;
      
      Si (SUCCEEDED(hr) & & (var.boolVal == valeur VARIANT_TRUE))
      {
         ADD_COLUMN_ENTRY_EX (ulCols, OLESTR("Bookmark"), 0, sizeof(DWORD), DBTYPE_BYTES, 0, 0, GUID_NULL, CAgentMan, dwBookmark, DBCOLUMNFLAGS_ISBOOKMARK)
         ulCols ++ ;
      }
   }

/ / Ensuite configurer les autres colonnes.
   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 ++ ;

Si (pcCols! = NULL)
      * pcCols = ulCols ;

Return _rgColumns ;
}

Cet exemple utilise un tableau statique pour contenir les informations de colonne. Si le consommateur ne veut pas la colonne des signets, une entrée du tableau est inutilisée. Pour gérer les informations, vous créez deux macros tableau, ADD_COLUMN_ENTRY et ADD_COLUMN_ENTRY_EX. ADD_COLUMN_ENTRY_EX prend un paramètre supplémentaire, flags , qui est nécessaire si vous désignez une colonne signet.

////////////////////////////////////////////////////////////////////////
/ / MyProviderRS.h

# define &ADD_COLUMN_ENTRY (ulCols, name, ordinal, colSize, type, précision, échelle, guid, dataClass, membre) \
   .pwszName _rgColumns [ulCols] = nom (LPOLESTR) ; \
   .pTypeInfo _rgColumns [ulCols] = (ITypeInfo **) NULL ; \
   _rgColumns [ulCols] .iordinal = ordinal (ULONG) ; \
   _rgColumns [ulCols] .dwflags = 0 ; \
   .ulColumnSize _rgColumns [ulCols] = colSize (ULONG) ; \
   .wType _rgColumns [ulCols] = type (DBTYPE) ; \
   _rgColumns [ulCols] .bprecision = précision (octet) ; \
   .bScale _rgColumns [ulCols] = échelle (octet) ; \
   _rgColumns [ulCols] .cboffset = offsetof (dataClass, membre) ;

# define ADD_COLUMN_ENTRY_EX (ulCols, name, ordinal, colSize, type, précision, échelle, guid, dataClass, membre, drapeaux) \
   .pwszName _rgColumns [ulCols] = nom (LPOLESTR) ; \
   .pTypeInfo _rgColumns [ulCols] = (ITypeInfo **) NULL ; \
   _rgColumns [ulCols] .iordinal = ordinal (ULONG) ; \
   _rgColumns [ulCols] .dwflags = drapeaux ; \
   .ulColumnSize _rgColumns [ulCols] = colSize (ULONG) ; \
   .wType _rgColumns [ulCols] = type (DBTYPE) ; \
   _rgColumns [ulCols] .bprecision = précision (octet) ; \
   .bScale _rgColumns [ulCols] = échelle (octet) ; \
   _rgColumns [ulCols] .cboffset = offsetof (dataClass, membre) ; \
   memset(amp;(_rgColumns[ulCols].columnID), 0, sizeof(DBID)) ; \
   .columnid.uName.pwszName _rgColumns [ulCols] = nom (LPOLESTR)

Dans la _GetColumnInfo fonction, la macro de signet est utilisée comme ceci:

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

Vous pouvez maintenant compiler et exécuter le fournisseur amélioré. Pour tester le fournisseur, modifiez le consommateur de test, comme décrit dans la modification de la consommation pour une utilisation avec le fournisseur amélioré. Exécutez le test consommateur avec le fournisseur. Vérifier que le test consommateur récupère les chaînes appropriées du fournisseur lorsque vous cliquez sur le bouton exécuter dans la boîte de dialogue de test consommateur.

Retour à la mise en œuvre d'un fournisseur d'OLE DB modèle

Index