I have a number of items with a number of associated
"properties" and they are represented using a single-selection
CListCtrl.
When the user makes a selection, these properties are checked
to see whether they are all valid. If any of these properties
are invalid, the user is given the option to validate them.
Should he/she wish not to validate, the selection is reverted
to the original.
The problem, I am getting is that, when the user decides not
to validate, Windows sends another notification message. This
causes problems as it performs the validation again and brings
up the message box asking the user for validation.
How do I stop this?
Also, I'm using the LVN_ITEMCHANGED message. I've tried using
the LVN_ITEMCHANGING message (with a few tweaks as item wouldn't
have been selected yet) but I still have the same problem.
TIA,
j.
example test code snippet...
ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, OnItemchangedList1)
BOOL CMfctestDlg::CheckValid(int idx)
{
//a dummy test, the fourth is invalid
if (idx == 3)
return FALSE;
return TRUE;
}
void CMfctestDlg::OnItemchangedList1(NMHDR * pNMHDR,
LRESULT * pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
int idx = m_listCtrl.GetNextItem(-1, LVNI_SELECTED);
BOOL bRevert = FALSE;
if (CheckValid(idx) == FALSE)
{
OutputDebugString("have properties invalid\n");
BOOL bRC = AfxMessageBox("have properties invalid.\n"\
"click ok to list properties.",
MB_OKCANCEL);
if (bRC == IDOK)
{
OutputDebugString("listing properties\n");
bRC = AfxMessageBox("list of properties...\n"\
"click ok to validate properties.",
MB_OKCANCEL);
if (bRC == IDOK)
{
OutputDebugString("properties validated\n");
//properties validated, nothing to do
}
else
{
OutputDebugString("properties not validated\n");
bRevert = TRUE;
}
}
else
{
OutputDebugString("not listing properties\n");
bRevert = TRUE;
}
}
if (bRevert == TRUE)
{
m_listCtrl.SetItem(0, 0, LVIF_STATE, NULL, 0,
LVIS_SELECTED | LVIS_FOCUSED,
LVIS_SELECTED | LVIS_FOCUSED, NULL);
}
*pResult = 0;
}
--
James Chow
>Hi all.
>
>I have a number of items with a number of associated
>"properties" and they are represented using a single-selection
>CListCtrl.
>
>When the user makes a selection, these properties are checked
>to see whether they are all valid. If any of these properties
>are invalid, the user is given the option to validate them.
>Should he/she wish not to validate, the selection is reverted
>to the original.
>
>The problem, I am getting is that, when the user decides not
>to validate, Windows sends another notification message. This
>causes problems as it performs the validation again and brings
>up the message box asking the user for validation.
The trick is to use the information passed to the message handler to
determine whether or not the item in question is being selected. See
below.
It is also important to realize that when a new item is selected, this
event will be generated twice: once for the item that was previously
selected (and is now deselected) and once for the newly selected item.
>How do I stop this?
>
>Also, I'm using the LVN_ITEMCHANGED message. I've tried using
>the LVN_ITEMCHANGING message (with a few tweaks as item wouldn't
>have been selected yet) but I still have the same problem.
>
>TIA,
>j.
>
>
>example test code snippet...
>
>ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, OnItemchangedList1)
>
>BOOL CMfctestDlg::CheckValid(int idx)
>{
> //a dummy test, the fourth is invalid
> if (idx == 3)
> return FALSE;
> return TRUE;
>}
>
>void CMfctestDlg::OnItemchangedList1(NMHDR * pNMHDR,
> LRESULT * pResult)
>{
> NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
>
> int idx = m_listCtrl.GetNextItem(-1, LVNI_SELECTED);
Don't do this. The NM_LISTVIEW struct contains all you need. From
the docs:
typedef struct tagNM_LISTVIEW {
NMHDR hdr;
int iItem;
int iSubItem;
UINT uNewState;
UINT uOldState;
UINT uChanged;
POINT ptAction;
LPARAM lParam;
} NM_LISTVIEW;
In this structure the items you care about are:
iItem: Identifies the list view item, or -1 if not used.
uNewState: Specifies the new item state. This member is zero for
notification messages that do not use it.
uOldState: Specifies the old item state. This member is zero for
notification messages that do not use it.
When you get the message, see if uNewState | LVS_SELECTED is true. If
so, the item is being selected and can be validated.
If not, check if uOldState | LVS_SELECTED is true. If so, then
pNMListView->iItem is the index of the item that is being deselected.
Store it so that you can change the selection back if necessary.
--
Chip
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
"Make it idiot-proof and someone will make a better idiot."
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
>When you get the message, see if uNewState | LVS_SELECTED is true.
That should be uNewState & LVS_SELECTED.
>If not, check if uOldState | LVS_SELECTED is true.
This should be uOldState & LVS_SELECTED.
Sorry!