Mit dem mitgelieferten Visual C++ Beispiel "Print and Design Reports (SQL data source)" finden Sie ein lauffähiges Beispiel für die Implementierung.
Am Pseudocode für Designeraufruf und Druckschleife lässt sich leicht erkennen, dass sich der Satz der benötigten API Funktionen nur unerheblich von der klassischen API Programmierung unterscheidet. Es werden aber einige Teile in die Implementierung des Datenproviders verlagert.
Im allgemeinen Initialisierungsteil nach LlJobOpen muss zunächst die Datenproviderinstanz bekannt gemacht werden und optional das verzögerte Laden aktiviert werden. Ebenso würde man an dieser Stelle z. B. die Callbacks für Vorschau und Drilldown anmelden.
auto pDP = (ILLDataProvider*) new MyDataProviderObject;
::LlSetOption(hJob,LL_OPTION_ILLDATAPROVIDER,(LPARAM)pDP);
::LlSetOption(hJob, LL_OPTION_SUPPORT_DELAYEDFIELDDEFINITION, 1);
Zur Erzeugung der Datenproviderinstanz wird mindestens eine Klasse benötigt, die die ILLDataProvider Schnittstelle implementiert. Zusätzlich müssen darin auch QueryInterface, AddRef und Release aus IUnknown implementiert sein. List & Label unterscheidet intern zwischen Wurzelobjekten und Knoten. Diese Unterscheidung kann nun entweder über mehrere Klassen verteilt abgebildet werden (siehe Beispiel unten) oder der Einfachheit halber auch innerhalb einer Klasse erfolgen.
Nicht implementierte Methoden geben jeweils E_NOTIMPL zurück.
#define SMI STDMETHODIMP
class DPBase : public ILLDataProvider
{
…
// From ILLDataProvider
SMI OpenTable(LPCWSTR pszTableName, IUnknown** ppUnkOfNewDP) = 0;
SMI OpenChildTable(LPCWSTR pszRelation, IUnknown** ppUnkOfNewDP) = 0;
SMI GetRowCount(INT* pnRows) = 0;
SMI DefineDelayedInfo(enDefineDelayedInfo nInfo) = 0;
SMI MoveNext() = 0;
SMI DefineRow(enDefineRowMode, const VARIANT* arvRelations) = 0;
SMI Dispose() = 0;
SMI SetUsedIdentifiers(const VARIANT* arvFieldRestriction) = 0;
SMI ApplySortOrder(LPCWSTR pszSortOrder) = 0;
SMI ApplyFilter(const VARIANT* arvFields, const VARIANT* arvValues) = 0;
SMI ApplyAdvancedFilter(LPCWSTR pszFilter, const VARIANT* arvValues) = 0;
SMI SetOption(enOptionIndex nIndex, const VARIANT * vValue) = 0;
SMI GetOption(enOptionIndex nIndex, VARIANT * vValue) = 0;
…
};
class DPRoot : public DPBase{ … };
class DPNode : public DPBase{ … };