This is an extension to
CListViewCtrl for WTL (Windows Template Library). It supports exchange of most OLEDB datatypes (excluding blob types) between an OLEDB source and a virtual listview control placed in a view window or on a dialog. It was developed and tested with MS SQL Server but should work with any OLEDB accessible database.
This template is compatible with WTL 8.0 and the samples were created in Visual Studio 2008. However, earlier versions of WTL and VS should be supportable with minor modifications.
WTLVirtualList interfaces an OLEDB consumer to an owner-supplied data (
LVS_OWNERDATA) report-style listview control. A handler provides data in response to
LVN_GETDISPINFO messages. This control dynamically creates listview columns using the consumer-supplied column names and displays an in-place edit control in response to a double click on a subitem. It supports bookmarks for row identification and manipulation, and provides menu handlers for common operations such as move, add, and delete. Column data editing is accomplished with an in-place edit control.
Using the code
The starting point for using this class in your application is generating an OLEDB consumer class for your database table. See Introduction to WTL OLEDB Database Applications for details on how to create an OLEDB consumer class using the ATL Object Wizard. Make a few simple modifications to your consumer class as outlined below to support the bookmark function. Download the sample projects and consult the Titles.h or Customers.h fils if you need assistance.
CBookmark<4> m_Bookmark; and
DBSTATUS m_dwBookmarkStatus; as member variables
pPropSet->AddProperty(DBPROP_IRowsetLocate, true, DBPROPOPTIONS_OPTIONAL); to the
BOOKMARK_ENTRY_STATUS(m_Bookmark, m_dwBookmarkStatus) to the column map
Add a member variable to MainFrm or MainDlg
After your consumer is created and modified, you need to add the
WTLVirtualList header to your project and add the
CWTLVirtualList<Cxxxxx> m_view; member variable (replace xxxxx with your consumer class name) to your dialog or frame. Initialization for a view window is handled automatically but make sure you add
REFLECT_NOTIFICATIONS() to the main frame message map.
You need to add a listview control to your dialog using the resource editor and then place the following code in
OnInitDialog to initialize the virtual listview.
int col = 0;
if (!m_view.GetShowBookmarks()) col = 1;
Menu or button mapping
You'll also want to add command handlers to the message map and, if needed, overridden event handlers for the data commands. As noted above, the virtual list class contains a set of default menu identifiers and event handlers in
CLVMenuCommands that handle ordinary data functions. You would need to override the default handler if you need to set key and/or default values when inserting a new record. For example:
LRESULT OnDataNew(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
TCHAR* CustomerID = _T("ZZ997");
_tcsncpy_s(m_view.m_data.m_CustomerID, _tcslen(CustomerID) + 1, CustomerID, _TRUNCATE);
return m_view.OnDataNew(wNotifyCode, wID, hWndCtl, bHandled);
Get/SetBarColor - color of alternating data rows. Choices are
REDBAR, but you can add any color you want to the enum.
Get/SetReadOnly - data can be modified or not.
Get/SetShowBookmarks - a bookmark is an internal row ID. This ID is limited to the consumer presentation and is independent of any key values in the data.
Get/SetSingleSelect - one row or multiple rows can be selected.
Under the covers
WTLVirtualList uses a handler for the
LVN_GETDISPINFO notification to synchronize on-screen data display with fetches of data from the data source and a conversion function (
OledbToString) to format the data for display in the list view. Initial load and scrolling are common triggers for the data fetch.
LRESULT OnLVGetDispInfo(int, LPNMHDR pNMHDR, BOOL&)
if (pNMHDR->hwndFrom != m_hWnd) return 0;
if (!IsValidRow()) return SetRowCount();
LVITEM* pItem = &((NMLVDISPINFO*)pNMHDR)->item;
if (pItem->mask & LVIF_TEXT)
if (pItem->iSubItem == 0)
ULONG row = SetActiveRow(pItem->iItem);
_ltot_s(row, pItem->pszText, MAXOLEDBNUM, 10);
else OledbToString(m_prgBindings[pItem->iSubItem], pItem->pszText);
A handler for
NM_CUSTOMDRAW paints alternate row colors and could be extended to support other visual trinkets. Also, there are handlers for mouse clicks, edit control, and scroll bars to provide support for those functions.
About the samples
The dialog application uses the titles table from the Pubs database while the view application uses customers from Northwind. You will either need access to a database server with these databases to use the samples or generate a consumer class for your specific table and add it to the project. You may also need to modify the connection string in the consumer classes to point to your database. They are currently set to localhost with Integrated Security.