Type | Description | |||
Boolean | A boolean expression that indicates whether the control runs in the virtual mode. |
Displaying a table, using the Virtual Mode
When you need to display large number of records, you need to provide an object that implements the IUnboundHandler interface. The object provides the number of records that need to be displayed, and data for each record. The VirtualMode property needs to be set on true, and the object you have written needs to be passed to the UnboundHandler property.
The following sample adds a column, and 100 records. The index of each item in the list is displayed.
The control calls the IUnboundHandler_ItemsCount property when the UnboundHandler property is set, to update the vertical scroll range.Private Property Get IUnboundHandler_ItemsCount(ByVal Source As Object) As Long IUnboundHandler_ItemsCount = 100 End Property
The control calls the IUnboundHandler_ReadItem method each time when a virtual item becomes visible. Important to notice is that the Items.VirtualToItem property is used to convert the index of the virtual item to the index of the item in the list.Private Sub IUnboundHandler_ReadItem(ByVal Index As Long, ByVal Source As Object) With Source.Items .Caption(.VirtualToItem(Index), 0) = Index + 1 End With End Sub
Private Sub Form_Load() With List1 .BeginUpdate .Columns.Add "Column 1" .VirtualMode = True Set .UnboundHandler = New Class1 .EndUpdate End With End Sub
The sample runs the control in the virtual mode. The control calls the IUnboundHandler_ItemsCount property when UnboundHandler property is set. The IUnboundHandler_ReadItem method is invoked when a record needs to be displayed.
Now, that you got the idea of the virtual mode, let's start to complicate the things. Let's suppose that we have a table and we need to display its records in the control.
Public Sub AttachTable(ByVal strTable As String, ByVal strPath As String, ByVal g As EXLISTLibCtl.List) Set rs = CreateObject("ADODB.Recordset") rs.Open strTable, "Provider=Microsoft.Jet.OLEDB.4.0;Data Source= " & strPath, 3, 3 With g .BeginUpdate With .Columns Dim f As Variant For Each f In rs.Fields .Add f.Name Next End With .EndUpdate End With End Sub
The AttachTable subroutine opens a table using ADO, and insert in the control's Columns collection a new column for each field found in the table.
Private Property Get IUnboundHandler_ItemsCount(ByVal Source As Object) As Long IUnboundHandler_ItemsCount = rs.RecordCount End Property
In this case the IUnboundHandler_ItemsCount property the number of records in the table.
Private Sub IUnboundHandler_ReadItem(ByVal Index As Long, ByVal Source As Object) rs.Move Index, 1 Dim i As Long, l As Long With Source.Items i = 0 l = .VirtualToItem(Index) Dim f As Variant For Each f In rs.Fields .Caption(l, i) = f.Value i = i + 1 Next End With End SubThe IUnboundHandler_ReadItem method moves the current record using the rs.Move method, at the record with the specified index, and loads values for each cell in the item. If you need to apply colors, font attributes, ... to the items in the control, your handler may change the CellBold, CellForeColor, ... properties.
Private Sub Form_Load() With List1 .BeginUpdate n.AttachTable "Select * from Orders", "D:\Exontrol\ExList\sample\sample.mdb", List1 .VirtualMode = True Set .UnboundHandler = n .EndUpdate End With End SubThe AttachTable method opens the table, and fills the control's Columns collection. The AttachTable method needs to be called before putting the control on virtual mode, because properties of the rs object are called in the ItemsCount and ReadItem methods.
Adding a custom column, when the control is running in the virtual mode.
Let's suppose that we want to display a column with the current position for each record in the table. In this case, we need to add a new column, and we need to change the ReadItem method like follows:
Private Sub Form_Load() With List1 .BeginUpdate n.AttachTable "Select * from Orders", "D:\Exontrol\ExList\sample\sample.mdb", List1 .VirtualMode = True Set .UnboundHandler = n With .Columns.Add("Position") .Position = 0 End With .EndUpdate End With End Sub
Private Sub IUnboundHandler_ReadItem(ByVal Index As Long, ByVal Source As Object) rs.Move Index, 1 Dim i As Long, l As Long With Source.Items i = 0 l = .VirtualToItem(Index) Dim f As Variant For Each f In rs.Fields .Caption(l, i) = f.Value i = i + 1 Next .Caption(l, "Position") = Index + 1 End With End Sub
For instance, if you need to have a column that computes its value based on the other columns, it can be done like this:
.Caption(l, "Column") = .Caption(l, "Quantity") * .Caption(l, "UnitPrice")
Editing a table using the Virtual Mode
Private Sub Form_Load() With List1 .BeginUpdate .AllowEdit = True n.AttachTable "Select * from Orders", "D:\Exontrol\ExList\sample\sample.mdb", List1 .VirtualMode = True Set .UnboundHandler = n With .Columns.Add("Position") .Position = 0 End With .EndUpdate End With End Sub
Private Sub List1_AfterCellEdit(ByVal Index As Long, ByVal ColIndex As Long, ByVal newCaption As String) With List1.Items n.Change newCaption, .ItemToVirtual(Index), ColIndex End With End SubImportant to notice is that the Items.ItemToVirtual property is called to convert the index of item in the list to the index of the virtual item being changed. The Change method in the Class1 changes the value in the recordset.
Public Sub Change(ByVal newCaption As Variant, ByVal Index As Long, ByVal ColIndex As Long) rs.Move Index, 1 rs(ColIndex) = newCaption rs.Update End SubThe Change method moves the current position to the Index position in the recordset, and updates the recordset.
Loading a table using the Virtual Mode in C++
The following tutorial will show how to run the control in virtual mode. The sample is a simple MFC dialog based application. Anyway, if your application is different than a MFC dialog based, the base things you need are here, so please find that the following information is useful.
#import "c:\winnt\system32\exlist.dll" rename( "GetItems", "exGetItems" )The #import directive is used to incorporate information from a type library. The content of the type library is converted into C++ classes, mostly describing the COM interfaces. The path to the file need to be changed if the dll is somewhere else. After building the project, the environment generates a namespace EXLISTLib. The generated namespace includes definition for IUnboundHandler interface. It can be accessed using the declaration EXLISTLib::IUnboundHandler
DECLARE_INTERFACE_MAP() public: BEGIN_INTERFACE_PART(Handler, EXLISTLib::IUnboundHandler) STDMETHOD(get_ItemsCount)(IDispatch * Source,long* pVal); STDMETHOD(raw_ReadItem)(long Index, IDispatch * Source); END_INTERFACE_PART(Handler)The CUnboundHandler class definition should look like follows ( we have removed the comments added by the wizard ):
#import "c:\winnt\system32\exlist.dll" rename( "GetItems", "exGetItems" ) class CUnboundHandler : public CCmdTarget { DECLARE_DYNCREATE(CUnboundHandler) CUnboundHandler(); // protected constructor used by dynamic creation DECLARE_INTERFACE_MAP() public: BEGIN_INTERFACE_PART(Handler, EXLISTLib::IUnboundHandler) STDMETHOD(get_ItemsCount)(IDispatch * Source, long* pVal); STDMETHOD(raw_ReadItem)(long Index, IDispatch * Source); END_INTERFACE_PART(Handler) // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CUnboundHandler) //}}AFX_VIRTUAL // Implementation virtual ~CUnboundHandler(); // Generated message map functions //{{AFX_MSG(CUnboundHandler) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG DECLARE_MESSAGE_MAP() };
BEGIN_INTERFACE_MAP(CUnboundHandler, CCmdTarget) INTERFACE_PART(CUnboundHandler, __uuidof(EXLISTLib::IUnboundHandler), Handler) END_INTERFACE_MAP()
STDMETHODIMP CUnboundHandler::XHandler::get_ItemsCount(IDispatch * Source, long* pVal) { METHOD_PROLOGUE(CUnboundHandler, Handler); if ( pVal ) { *pVal = 25000; return S_OK;; } return E_POINTER; }
STDMETHODIMP CUnboundHandler::XHandler::raw_ReadItem(long Index, IDispatch * Source) { METHOD_PROLOGUE(CUnboundHandler, Handler); // gets the source control EXLISTLib::IList* pList = NULL; if ( SUCCEEDED( Source->QueryInterface( __uuidof(EXLISTLib::IList), (LPVOID*)&pList ) ) ) { // assigns the value for each cell. pList->Items->Caption[ pList->Items->VirtualToItem[Index] ][ _variant_t((long)0) ] = _variant_t( Index ); pList->Release(); } return S_OK; }
STDMETHODIMP CUnboundHandler::XHandler::QueryInterface( REFIID riid, void** ppvObject) { METHOD_PROLOGUE(CUnboundHandler, Handler); if ( ppvObject ) { if ( IsEqualIID( __uuidof(IUnknown), riid ) ) { *ppvObject = static_cast<IUnknown*>( this ); AddRef(); return S_OK; } if ( IsEqualIID( __uuidof( EXLISTLib::IUnboundHandler), riid ) ) { *ppvObject = static_cast<EXLISTLib::IUnboundHandler*>( this ); AddRef(); return S_OK; } return E_NOINTERFACE; } return E_POINTER; } STDMETHODIMP_(ULONG) CUnboundHandler::XHandler::AddRef() { METHOD_PROLOGUE(CUnboundHandler, Handler); return 1; } STDMETHODIMP_(ULONG) CUnboundHandler::XHandler::Release() { METHOD_PROLOGUE(CUnboundHandler, Handler); return 0; }
IMPLEMENT_DYNCREATE(CUnboundHandler, CCmdTarget) BEGIN_INTERFACE_MAP(CUnboundHandler, CCmdTarget) INTERFACE_PART(CUnboundHandler, __uuidof(EXLISTLib::IUnboundHandler), Handler) END_INTERFACE_MAP() CUnboundHandler::CUnboundHandler() { } CUnboundHandler::~CUnboundHandler() { } STDMETHODIMP CUnboundHandler::XHandler::get_ItemsCount(IDispatch * Source, long* pVal) { METHOD_PROLOGUE(CUnboundHandler, Handler); if ( pVal ) { *pVal = 25000; return S_OK;; } return E_POINTER; } STDMETHODIMP CUnboundHandler::XHandler::raw_ReadItem(long Index, IDispatch * Source) { METHOD_PROLOGUE(CUnboundHandler, Handler); // gets the source control EXLISTLib::IList* pList = NULL; if ( SUCCEEDED( Source->QueryInterface( __uuidof(EXLISTLib::IList), (LPVOID*)&pList ) ) ) { // assigns the value for each cell. pList->Items->Caption[ pList->Items->VirtualToItem[Index] ][ _variant_t((long)0) ] = _variant_t( Index ); pList->Release(); } return S_OK; } STDMETHODIMP CUnboundHandler::XHandler::QueryInterface( REFIID riid, void** ppvObject) { METHOD_PROLOGUE(CUnboundHandler, Handler); if ( ppvObject ) { if ( IsEqualIID( __uuidof(IUnknown), riid ) ) { *ppvObject = static_cast<IUnknown*>( this ); AddRef(); return S_OK; } if ( IsEqualIID( __uuidof( EXLISTLib::IUnboundHandler), riid ) ) { *ppvObject = static_cast<EXLISTLib::IUnboundHandler*>( this ); AddRef(); return S_OK; } return E_NOINTERFACE; } return E_POINTER; } STDMETHODIMP_(ULONG) CUnboundHandler::XHandler::AddRef() { METHOD_PROLOGUE(CUnboundHandler, Handler); return 1; } STDMETHODIMP_(ULONG) CUnboundHandler::XHandler::Release() { METHOD_PROLOGUE(CUnboundHandler, Handler); return 0; } BEGIN_MESSAGE_MAP(CUnboundHandler, CCmdTarget) //{{AFX_MSG_MAP(CUnboundHandler) // NOTE - the ClassWizard will add and remove mapping macros here. //}}AFX_MSG_MAP END_MESSAGE_MAP()After all these steps we have defined the class CUnboundHandler that implements the IUnboundHandler interface. All that we need to do from now, is to add a column to the control, and to set the VirtualMode and UnboundHanlder properties like follows:
#include "UnboundHandler.h"
CUnboundHandler m_unboundHandler;
#include "Columns.h"
m_list.BeginUpdate(); m_list.GetColumns().Add( _T("Column 1") ); m_list.SetVirtualMode( TRUE ); m_list.SetUnboundHandler( &m_unboundHandler.m_xHandler ); m_list.EndUpdate();
The tutorial shows how to put the control on virtual mode. The sample loads the numbers from 0 to 24999.
Now, that we got the idea how to implement the IUnboundHandler let's say that we want to change the sample to load an edit an ADO recordset. The following tutorials shows how to display a table and how to add code in order to let user edits the data.
#import <msado15.dll> rename ( "EOF", "adoEOF" )The #import directive generates the ADODB namspace. The ADODB namspace includes all definitions in the Microsoft ADO Type Library.
ADODB::_RecordsetPtr m_spRecordset;
virtual void AttachTable( EXLISTLib::IList* pList, LPCTSTR szTable, LPCTSTR szDatabase );Now, the CUnboundHandler class definition should look like follows:
#import "c:\winnt\system32\exlist.dll" rename( "GetItems", "exGetItems" ) #import <msado15.dll> rename ( "EOF", "adoEOF" ) class CUnboundHandler : public CCmdTarget { DECLARE_DYNCREATE(CUnboundHandler) CUnboundHandler(); // protected constructor used by dynamic creation DECLARE_INTERFACE_MAP() public: BEGIN_INTERFACE_PART(Handler, EXLISTLib::IUnboundHandler) STDMETHOD(get_ItemsCount)(IDispatch * Source, long* pVal); STDMETHOD(raw_ReadItem)(long Index, IDispatch * Source); END_INTERFACE_PART(Handler) virtual void AttachTable( EXLISTLib::IList* pList, LPCTSTR szTable, LPCTSTR szDatabase ); // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CUnboundHandler) //}}AFX_VIRTUAL // Implementation virtual ~CUnboundHandler(); // Generated message map functions //{{AFX_MSG(CUnboundHandler) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG DECLARE_MESSAGE_MAP() ADODB::_RecordsetPtr m_spRecordset; };
void CUnboundHandler::AttachTable( EXLISTLib::IList* pList, LPCTSTR szTable, LPCTSTR szDatabase ) { if ( SUCCEEDED( m_spRecordset.CreateInstance( "ADODB.Recordset") ) ) { try { CString strConnection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="; strConnection += szDatabase; if ( SUCCEEDED( m_spRecordset->Open(_variant_t( szTable ), _variant_t(strConnection), ADODB::adOpenStatic, ADODB::adLockPessimistic, NULL ) ) ) { pList->BeginUpdate(); for ( long i = 0; i < m_spRecordset->Fields->GetCount(); i++ ) pList->GetColumns()->Add( m_spRecordset->Fields->GetItem( _variant_t( i ) )->Name ); pList->EndUpdate(); } } catch ( _com_error& e ) { AfxMessageBox( e.Description() ); } } }The AttachTable function opens a recordset, and adds a new column to the control's Columns collection for each field found in the recordset.
STDMETHODIMP CUnboundHandler::XHandler::get_ItemsCount(IDispatch * Source, long* pVal) { METHOD_PROLOGUE(CUnboundHandler, Handler); if ( pVal ) { *pVal = pThis->m_spRecordset->RecordCount; return S_OK;; } return E_POINTER; }The ItemsCount property specifies that the control displays all records in the recordset
STDMETHODIMP CUnboundHandler::XHandler::raw_ReadItem(long Index, IDispatch * Source) { METHOD_PROLOGUE(CUnboundHandler, Handler); pThis->m_spRecordset->Move( Index, _variant_t( (long)ADODB::adBookmarkFirst ) ); // gets the source control EXLISTLib::IList* pList = NULL; if ( SUCCEEDED( Source->QueryInterface( __uuidof(EXLISTLib::IList), (LPVOID*)&pList ) ) ) { // assigns the value for each cell. long l = pList->Items->VirtualToItem[ Index ]; for ( long i = 0; i < pThis->m_spRecordset->Fields->GetCount(); i++ ) pList->Items->Caption[ pList->Items->VirtualToItem[ Index ] ][ _variant_t( i )] = pThis->m_spRecordset->Fields->GetItem( _variant_t( i ) )->Value; pList->Release(); } return S_OK; }The ReadItem method moves the position of the current record in the recordset, and sets the value for each cell in the item.
The implementation for CUnbundHandler class should look like:
IMPLEMENT_DYNCREATE(CUnboundHandler, CCmdTarget) BEGIN_INTERFACE_MAP(CUnboundHandler, CCmdTarget) INTERFACE_PART(CUnboundHandler, __uuidof(EXLISTLib::IUnboundHandler), Handler) END_INTERFACE_MAP() CUnboundHandler::CUnboundHandler() { } CUnboundHandler::~CUnboundHandler() { } STDMETHODIMP CUnboundHandler::XHandler::get_ItemsCount(IDispatch * Source, long* pVal) { METHOD_PROLOGUE(CUnboundHandler, Handler); if ( pVal ) { *pVal = pThis->m_spRecordset->RecordCount; return S_OK;; } return E_POINTER; } STDMETHODIMP CUnboundHandler::XHandler::raw_ReadItem(long Index, IDispatch * Source) { METHOD_PROLOGUE(CUnboundHandler, Handler); pThis->m_spRecordset->Move( Index, _variant_t( (long)ADODB::adBookmarkFirst ) ); // gets the source control EXLISTLib::IList* pList = NULL; if ( SUCCEEDED( Source->QueryInterface( __uuidof(EXLISTLib::IList), (LPVOID*)&pList ) ) ) { // assigns the value for each cell. long l = pList->Items->VirtualToItem[ Index ]; for ( long i = 0; i < pThis->m_spRecordset->Fields->GetCount(); i++ ) pList->Items->Caption[ l ][ _variant_t( i )] = pThis->m_spRecordset->Fields->GetItem( _variant_t( i ) )->Value; pList->Release(); } return S_OK; } void CUnboundHandler::AttachTable( EXLISTLib::IList* pList, LPCTSTR szTable, LPCTSTR szDatabase ) { if ( SUCCEEDED( m_spRecordset.CreateInstance( "ADODB.Recordset") ) ) { try { CString strConnection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="; strConnection += szDatabase; if ( SUCCEEDED( m_spRecordset->Open(_variant_t( szTable ), _variant_t(strConnection), ADODB::adOpenStatic, ADODB::adLockPessimistic, NULL ) ) ) { pList->BeginUpdate(); for ( long i = 0; i < m_spRecordset->Fields->GetCount(); i++ ) pList->GetColumns()->Add( m_spRecordset->Fields->GetItem( _variant_t( i ) )->Name ); pList->EndUpdate(); } } catch ( _com_error& e ) { AfxMessageBox( e.Description() ); } } } STDMETHODIMP CUnboundHandler::XHandler::QueryInterface( REFIID riid, void** ppvObject) { METHOD_PROLOGUE(CUnboundHandler, Handler); if ( ppvObject ) { if ( IsEqualIID( __uuidof(IUnknown), riid ) ) { *ppvObject = static_cast<IUnknown*>( this ); AddRef(); return S_OK; } if ( IsEqualIID( __uuidof( EXLISTLib::IUnboundHandler), riid ) ) { *ppvObject = static_cast<EXLISTLib::IUnboundHandler*>( this ); AddRef(); return S_OK; } return E_NOINTERFACE; } return E_POINTER; } STDMETHODIMP_(ULONG) CUnboundHandler::XHandler::AddRef() { METHOD_PROLOGUE(CUnboundHandler, Handler); return 1; } STDMETHODIMP_(ULONG) CUnboundHandler::XHandler::Release() { METHOD_PROLOGUE(CUnboundHandler, Handler); return 0; } BEGIN_MESSAGE_MAP(CUnboundHandler, CCmdTarget) //{{AFX_MSG_MAP(CUnboundHandler) // NOTE - the ClassWizard will add and remove mapping macros here. //}}AFX_MSG_MAP END_MESSAGE_MAP()
EXLISTLib::IListPtr spList = NULL; m_list.GetControlUnknown()->QueryInterface( &spList ); m_list.BeginUpdate(); m_unboundHandler.AttachTable( spList, _T("Orders"), _T("D:\\Exontrol\\ExList\\sample\\sample.mdb") ); m_list.SetVirtualMode( TRUE ); m_list.SetUnboundHandler( &m_unboundHandler.m_xHandler ); m_list.EndUpdate();The AttachTable function is called before setting the UnboundHandler property. The AttachTable function opens a recordset giving the SQL phrase and the database. The AttachTable function loads also the control's Columns collection from the Fields collection of the recordset.
After all these your control will be able to display a table using the virtual mode. Now, we need to add some changes in order to let user edits the data in the control.
m_list.SetAllowEdit( TRUE );The OnInitDialog looks like:
EXLISTLib::IListPtr spList = NULL; m_list.GetControlUnknown()->QueryInterface( &spList ); m_list.BeginUpdate(); m_unboundHandler.AttachTable( spList, _T("Orders"), _T("D:\\Exontrol\\ExList\\sample\\sample.mdb") ); m_list.SetAllowEdit( TRUE ); m_list.SetVirtualMode( TRUE ); m_list.SetUnboundHandler( &m_unboundHandler.m_xHandler ); m_list.EndUpdate();
#include "Items.h"
void CADOVirtualDlg::OnAfterCellEditList1(long Index, long ColIndex, LPCTSTR NewCaption) { m_unboundHandler.Change( NewCaption, m_list.GetItems().GetItemToVirtual( Index ), ColIndex ); }
virtual void Change( LPCTSTR szCaption, long Index, long ColIndex );The CUnboundHandler class definition should look like:
#import "c:\winnt\system32\exlist.dll" rename( "GetItems", "exGetItems" ) #import <msado15.dll> rename ( "EOF", "adoEOF" ) class CUnboundHandler : public CCmdTarget { DECLARE_DYNCREATE(CUnboundHandler) CUnboundHandler(); // protected constructor used by dynamic creation DECLARE_INTERFACE_MAP() public: BEGIN_INTERFACE_PART(Handler, EXLISTLib::IUnboundHandler) STDMETHOD(get_ItemsCount)(IDispatch * Source, long* pVal); STDMETHOD(raw_ReadItem)(long Index, IDispatch * Source); END_INTERFACE_PART(Handler) virtual void AttachTable( EXLISTLib::IList* pList, LPCTSTR szTable, LPCTSTR szDatabase ); virtual void Change( LPCTSTR szCaption, long Index, long ColIndex ); // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CUnboundHandler) //}}AFX_VIRTUAL // Implementation virtual ~CUnboundHandler(); // Generated message map functions //{{AFX_MSG(CUnboundHandler) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG DECLARE_MESSAGE_MAP() ADODB::_RecordsetPtr m_spRecordset; };
void CUnboundHandler::Change( LPCTSTR szCaption, long Index, long ColIndex ) { m_spRecordset->Move( Index, _variant_t( (long)ADODB::adBookmarkFirst ) ); m_spRecordset->Fields->GetItem( _variant_t( ColIndex ) )->Value = szCaption; m_spRecordset->Update(); }
If you need to apply colors, font attributes, ... for items or cells while the control is running in the virtual mode, the changes should be done in the raw_ReadItem method like follows:
STDMETHODIMP CUnboundHandler::XHandler::raw_ReadItem(long Index, IDispatch * Source) { METHOD_PROLOGUE(CUnboundHandler, Handler); pThis->m_spRecordset->Move( Index, _variant_t( (long)ADODB::adBookmarkFirst ) ); // gets the source control EXLISTLib::IList* pList = NULL; if ( SUCCEEDED( Source->QueryInterface( __uuidof(EXLISTLib::IList), (LPVOID*)&pList ) ) ) { long l = pList->Items->VirtualToItem[ Index ]; // assigns the value for each cell. for ( long i = 0; i < pThis->m_spRecordset->Fields->GetCount(); i++ ) pList->Items->Caption[ l ][ _variant_t( i )] = pThis->m_spRecordset->Fields->GetItem( _variant_t( i ) )->Value; if ( pList->Items->Caption[ _variant_t( l ) ][ _variant_t( _T("ShipRegion") )] == _variant_t( _T("RJ") ) ) pList->Items->put_ItemForeColor( l , RGB(0,0,255 ) ); if ( pList->Items->Caption[ _variant_t( l ) ][ _variant_t( _T("ShipRegion") )] == _variant_t( _T("SP") ) ) pList->Items->put_ItemBold( l , TRUE ); pList->Release(); } return S_OK; }
While compiling the project the compiler displays warnings like: "warning C4146: unary minus operator applied to unsigned type, result still unsigned". You have to include the :
#pragma warning( disable : 4146 )
before importing the type libraries.
#pragma warning( disable : 4146 ) #import "c:\winnt\system32\exlist.dll" rename( "GetItems", "exGetItems" ) #import <msado15.dll> rename ( "EOF", "adoEOF" )