I've created a List Control that displays in the following attached image. The checkboxes come from an ImageList, also attached and shown below.
What I'd like to do now is provide the functionality to do something like an OnItemSelected(). Then see what item and subitem is clicked and if it is the second sub item, isn't one of the disabled images, check or uncheck respectively.
I've provided all the project code zipped up and the main Dialog and List Item Changed code below
Code:
**************** Dialog Init Code ***************
BOOL CCheckLCDemoDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
CRect rect;
m_listCtrl.GetClientRect(rect);
m_listCtrl.InsertColumn(0, _T(""), LVCFMT_CENTER, 30);
m_listCtrl.InsertColumn(1, _T("Layer"), LVCFMT_LEFT, 150);
m_listCtrl.InsertColumn(2, _T("Zoom"), LVCFMT_LEFT, 100);
m_listCtrl.InsertColumn(3, _T("Labels"), LVCFMT_LEFT, rect.Width() - 280);
VERIFY( m_checkLCImgList.Create(IDB_CHECKBOXES, 16, 4, RGB(255,0,255)) );
int j = m_checkLCImgList.GetImageCount();
m_listCtrl.SetImageList(&m_checkLCImgList, LVSIL_SMALL);
//Add items
int nPos = 0;
LV_ITEM lvi;
ZeroMemory(&lvi, sizeof(lvi));
lvi.mask = LVIF_TEXT | LVIF_IMAGE;
lvi.pszText = "";
lvi.cchTextMax = lstrlen(lvi.pszText);
lvi.iImage = 4; // First image from image list
nPos = m_listCtrl.InsertItem(&lvi);
ZeroMemory(&lvi, sizeof(lvi));
lvi.mask = LVIF_TEXT;
lvi.pszText = "Item 1";
lvi.cchTextMax = lstrlen(lvi.pszText);
lvi.iItem = nPos;
lvi.iSubItem = 1;
m_listCtrl.SetItem(&lvi);
ZeroMemory(&lvi, sizeof(lvi));
lvi.mask = LVIF_TEXT | LVIF_IMAGE;
lvi.pszText = "";
lvi.cchTextMax = lstrlen(lvi.pszText);
lvi.iImage = 3; // First image from image list
nPos = m_listCtrl.InsertItem(&lvi);
ZeroMemory(&lvi, sizeof(lvi));
lvi.mask = LVIF_TEXT;
lvi.pszText = "Item 1";
lvi.cchTextMax = lstrlen(lvi.pszText);
lvi.iItem = nPos;
lvi.iSubItem = 1;
m_listCtrl.SetItem(&lvi);
ZeroMemory(&lvi, sizeof(lvi));
lvi.mask = LVIF_TEXT | LVIF_IMAGE;
lvi.pszText = "";
lvi.cchTextMax = lstrlen(lvi.pszText);
lvi.iImage = 1; // First image from image list
nPos = m_listCtrl.InsertItem(&lvi);
ZeroMemory(&lvi, sizeof(lvi));
lvi.mask = LVIF_TEXT;
lvi.pszText = "Item 1";
lvi.cchTextMax = lstrlen(lvi.pszText);
lvi.iItem = nPos;
lvi.iSubItem = 1;
m_listCtrl.SetItem(&lvi);
ZeroMemory(&lvi, sizeof(lvi));
lvi.mask = LVIF_TEXT | LVIF_IMAGE;
lvi.pszText = "";
lvi.cchTextMax = lstrlen(lvi.pszText);
lvi.iImage = 1; // First image from image list
nPos = m_listCtrl.InsertItem(&lvi);
ZeroMemory(&lvi, sizeof(lvi));
lvi.mask = LVIF_TEXT;
lvi.pszText = "Item 1";
lvi.cchTextMax = lstrlen(lvi.pszText);
lvi.iItem = nPos;
lvi.iSubItem = 1;
m_listCtrl.SetItem(&lvi);
ZeroMemory(&lvi, sizeof(lvi));
lvi.mask = LVIF_TEXT | LVIF_IMAGE;
lvi.pszText = "";
lvi.cchTextMax = lstrlen(lvi.pszText);
lvi.iImage = 2; // First image from image list
nPos = m_listCtrl.InsertItem(&lvi);
ZeroMemory(&lvi, sizeof(lvi));
lvi.mask = LVIF_TEXT;
lvi.pszText = "Item 1";
lvi.cchTextMax = lstrlen(lvi.pszText);
lvi.iItem = nPos;
lvi.iSubItem = 1;
m_listCtrl.SetItem(&lvi);
int listOrder[4];
listOrder[0] = 1;
listOrder[1] = 0;
listOrder[2] = 2;
listOrder[3] = 3;
m_listCtrl.SetColumnOrderArray(4, listOrder);
m_listCtrl.SetExtendedStyle( m_listCtrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_SUBITEMIMAGES);
m_listCtrl.Init();
return TRUE; // return TRUE unless you set the focus to a control
}
void CCheckListCtrl::OnItemChanged(NMHDR* pNMHDR, LRESULT* pResult)
{
NMLISTVIEW* pNMLV = (NMLISTVIEW*)pNMHDR;
*pResult = 0;
if ( m_blInited && LVIF_STATE == pNMLV->uChanged)
{
//Not sure on how to continue from here
//See what item and sub item have been selected if the image is not
//disabled then the active check or uncheck box images get displayed
//respectively.
}
}
Last edited by ill_comms; March 22nd, 2009 at 09:21 PM.
Reason: Added code tags
Found the answer, decided to for the following code. If someone clicks on the sub item with the checkbox image inside it which happens to be zero (the first column) then it changes it's image accordingly, from the image list.
LVHITTESTINFO hti = {0};
hti.pt = point;
if (SubItemHitTest(&hti) == -1)
return;
int iItem = hti.iItem;
int iSubItem = hti.iSubItem;
if (iItem == -1 || iSubItem == -1)
return;
if (iSubItem == 0)
{
//Then see what state the sub item is if disabled or enabled, then checked or unchecked
LVITEM tempItem;
int theImage = 0;
CString theText = "";
ZeroMemory(&tempItem, sizeof(tempItem));
tempItem.mask = LVIF_IMAGE;
tempItem.iItem = iItem;
tempItem.iSubItem = iSubItem;
GetItem(&tempItem);
In my opinion, perhaps using events is better to achive. In event, you can judge if the check box in this line is pressed or not and do something. Anyway, this is just thinking of mine, it's up to you for this.
This looks interesting, a few questions. Is "CTest507Dlg" supposed to be the list class or the dialog? After that how would you create the declare the "OnNMClickList1"?
This looks interesting, a few questions. Is "CTest507Dlg" supposed to be the list class or the dialog? After that how would you create the declare the "OnNMClickList1"?
I think the name of the class is self explanatory, it's the class of the dialog. No list view derived class is supposed to be used.
How to add a handler for the OnClick event depends on what version of VS are you using.
In VS6 you use the class wizard (Ctrl + W), select the class of the dialog box, then select the identifier of the list view control and finally select the click event. Finally click the Add Handler (or Add Function ?) button.
In the other versions of the VS, make sure the dialog box is open and the list view control is selected. In the toolbar of the Properties window click the "Control Events" button (the one with a yellow flash on it), then scroll down the list to find the desired event.
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.