Inspired by the post on Yahoo’s WTL group (actually, I have been going to post on this topic for a couple of weeks already).
Standard Windows controls (including common controls) that have multiple items (list box, combo box, list view, tree view etc.) have an option to attach user defined value of type DWORD_PTR (LPARAM) to each item. This is quite sufficient when using controls, however type cast to and from DWORD_PTR is required with most control item data operations.
CAiComboBoxT and CAiListViewT classes templates redefine GetItemData/SetItemData methods to perform automatic type casts. An optional template class CAiListControlDataTraitsT does even more: it manages per-item definted item data class in contained CAtlList collection and attached a pointer to item data class to each control item.
The classes may be used as follows:
CAiComboBoxT < CComboBoxItemData* > m_ComboBox;
CAiListViewT < CListViewItemData, CAiListControlDataTraitsT > m_ListView;
m_ComboBox is a combo box window class (CComboBox descendant) with CComboBoxItemData pointer defined as control item data.
m_ListView is a list view class (CListViewCtrl descendant) with CListViewItemData defined as control item data. CListViewItemData instances are managed by control class using CAtlList collection (and a position in the collection is actually casted to DWORD_PTR and set as lower level control item data).
To access item class data, you need the following lines of code:
CComboBoxItemData* pComboBoxItemData = m_ComboBox.GetItemData(nItem); // INT nItem
CListViewItemData& ListViewItemData = m_ListView.GetItemData(nItem); // INT nItem
Sample project below illustrates basic usage of the classes:
BEGIN_MSG_MAP_EX(CMainDialog)
MSG_WM_INITDIALOG(OnInitDialog)
…
COMMAND_HANDLER_EX(IDC_COMBOBOX, CBN_SELENDOK, OnComboBoxSelEndOk)
MSG_LVN_GETDISPINFO(IDC_LISTVIEW, OnListGetDispInfo)
MSG_LVN_DBLCLK(IDC_LISTVIEW, OnListViewDblClk)
OnInitDialog initializes classes including control item data initialization, OnComboBoxSelEndOk obtains currently selected combo box item data class pointer (not managed by the window class), OnListGetDispInfo accesses managed control item data pointer, OnListViewDblClk retrieves first selected control item data class pointer to show message box.
Keywords: DWORD_PTR, CB_GETITEMDATA, CB_SETITEMDATA, LVM_GETITEM, LVM_SETITEM
Visual C++.NET 2005 source code can be downloaded here, compiled binary – here.
Update 2012-07-24:
Visual C++ 2010 .h file: /trac/public/browser/…/rowtlcrack.h
Code snippet:
https://www.alax.info/trac/public/browser/trunk/Utilities/LogProcessExceptions/MainWizard.h#L104
BEGIN_MSG_MAP_EX(CProcessPropertyPage) CHAIN_MSG_MAP(CWizardPropertyPageT<CProcessPropertyPage>) MSG_WM_INITDIALOG(OnInitDialog) MSG_LVN_GETDISPINFO(IDC_MAIN_PROCESSES, OnProcessListViewGetDispInfo) MSG_LVN_GETINFOTIP(IDC_MAIN_PROCESSES, OnProcessListViewGetInfoTip) MSG_LVN_ITEMCHANGED(IDC_MAIN_PROCESSES, OnProcessListItemChanged) MSG_LVN_DBLCLK(IDC_MAIN_PROCESSES, OnProcessListViewDblClk) COMMAND_ID_HANDLER_EX(IDC_MAIN_REFRESHPROCESSES, OnRefreshButtonClicked) REFLECT_NOTIFICATIONS() END_MSG_MAP()
https://www.alax.info/trac/public/browser/trunk/Utilities/LogProcessExceptions/MainWizard.h#L579
LRESULT OnProcessListViewGetInfoTip(NMLVGETINFOTIP* pHeader) { const CProcessData& ProcessData = m_ProcessDataList.GetAt(m_ProcessListView.GetItemData(pHeader->iItem)); CString& sTextBuffer = m_ProcessListView.GetTextBufferString(TRUE); sTextBuffer.AppendFormat(_T("File Name: %s\r\n"), ProcessData.GetFileName()); sTextBuffer.AppendFormat(_T("Identifier: %d (0x%x)\r\n"), ProcessData.m_nIdentifier, ProcessData.m_nIdentifier); BOOL bIs64Bit = FALSE; #if !defined(_WIN64) if(SafeIsWow64Process()) #endif // !defined(_WIN64) bIs64Bit = !ProcessData.m_bIsWow64; sTextBuffer.AppendFormat(_T("Type: %s\r\n"), !bIs64Bit ? _T("32-bit") : _T("64-bit")); if(!ProcessData.m_sAccount.IsEmpty()) sTextBuffer.AppendFormat(_T("Account: %s\r\n"), ProcessData.m_sAccount); sTextBuffer.AppendFormat(_T("Window Caption: %s\r\n"), ProcessData.m_sWindowCaption); //sTextBuffer.AppendFormat(_T("Image File Path: %s\r\n"), ProcessData.GetImageFilePath()); sTextBuffer.AppendFormat(_T("Working Set Size: %s MB\r\n"), _StringHelper::FormatNumber((LONG) ProcessData.GetMemoryCounters().WorkingSetSize >> 20)); sTextBuffer.AppendFormat(_T("Private Memory: %s MB\r\n"), _StringHelper::FormatNumber((LONG) ProcessData.GetMemoryCounters().PrivateUsage >> 20)); sTextBuffer.TrimRight(_T("\t\n\r .")); _tcsncpy_s(pHeader->pszText, pHeader->cchTextMax, m_ProcessListView.GetTextBuffer(), _TRUNCATE); return 0; }
[…] In continuation to recently posted “Smart ATL/WTL combo box and list view classes to cast and optionally manage typed control item data”, list box and tree view classes aware of typed item control data. […]
This code, along with some of your other WTL classes are still quite useful, but they don’t seem to be available in your SVN repositories and the old download links no longer work. Is there any chance you could put them back online? Thanks!
Yes this code is in good standing. It might need some updates to follow recent SDKs, but as far as I remember the file is a result of a sequence of regular expressions on the SDK commctrl.h file and I don’t want to go into trouble of doing them again just for minor updates.
Here is the file:
https://www.alax.info/trac/public/browser/trunk/Common/alax.info/rowtlcrack.h
I also re-uploaded the lost attachments, so the links above are valid.