CListCtrl--NM_CLICK
void CCListCtrlDlg::OnNMClickList4(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
//NM_CLICK 这个是鼠标左键点击CListCtrl控件客户区时激发的消息
int han = pNMItemActivate->iItem; //获取单击的行号
/*
【最好设置:LVS_EX_FULLROWSELECT //选择整行;否则只有单击项头才有效】
*/
str.Format(_T("行号han=%d\r\n"), han);
OutputDebugString(str);
int lie = pNMItemActivate->iSubItem;//获取单击的列号
str.Format(_T("列号lie=%d\r\n"), lie);
OutputDebugString(str);
UINT ns=pNMItemActivate->uNewState;
str.Format(_T("新状态ns=%d\r\n"), ns);
OutputDebugString(str);
UINT olds = pNMItemActivate->uOldState;
str.Format(_T("老状态olds=%d\r\n"), olds);
OutputDebugString(str);
*pResult = 0;
}
我的问题:新状态和老状态返回值都是0 ??
单击后 应该被选中了 起码有个选中状态,我认为新状态的返回值不应该是0 ??
回答:可能是因为你的列表控件设置了不可选中,导致新状态和老状态都是0。你可以在初始化列表控件的代码中添加以下语句,开启整行选择功能:
m_listCtrl.SetExtendedStyle(m_listCtrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT);
这样就可以正常获取新状态和老状态了。 根据您提供的代码,可以看到NM_CLICK消息中的NMITEMACTIVATE结构体中包含了两个状态变量uOldState和uNewState,它们分别表示单击(或右键单击)前和单击(或右键单击)后子项的状态。如果在调试中发现这两个变量都为0,可能是由于CListCtrl控件的样式设置不正确而导致的。
默认情况下,CListCtrl控件只在单击行头时才选择整行。如果要使用户单击列表中任意位置都可以选择整行并激活NM_CLICK消息,您需要设置以下样式:
m_listCtrl.SetExtendedStyle(m_listCtrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT);
此外,还有一种情况会导致uOldState和uNewState都为0,就是当用户试图多选时,即同时按下shift或ctrl键单击两个或多个项目时。
如果问题仍然存在,请尝试在代码中加入一些断点,并检查计算过程中是否有漏掉的细节。 NMITEMACTIVATE 结构体的 uNewState 和 uOldState 成员表示鼠标点击事件后的新状态和旧状态,它们是可以组合多个位标志来表示多种状态的。
在你的代码中,uNewState 和 uOldState 都具有0的值,这意味着没有状态被设置。这很可能是因为列表控件没有配置以报告项目状态更改。你可以调用 CListCtrl::SetExtendedStyle 方法,并指定 LVS_EX_FULLROWSELECT 标志来启用此功能,就像你代码中的注释所示。
启用此标志后,列表控件将突出显示所选项目,当项目被点击时,NMITEMACTIVATE 结构体的 uNewState 成员应该具有 LVIS_SELECTED(0x0002)的值。同样地,如果项目之前已经被选择,则 uOldState 成员将具有相同的值。 mylist4.SetExtendedStyle(mylist4.GetExtendedStyle() |LVS_REPORT | LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT);//指定报表显示格式
但是新老状态 还是都返回 0 根据您提供的代码和问题,我可以看出您正在处理 `CListCtrl` 控件的单击事件,并尝试使用以下代码行来获取有关被点击项的信息:
UINT ns=pNMItemActivate->uNewState;
str.Format(_T("新状态ns=%d\r\n"), ns);
OutputDebugString(str);
UINT olds = pNMItemActivate->uOldState;
str.Format(_T("老状态olds=%d\r\n"), olds);
OutputDebugString(str);
但是,您注意到即使您单击了某个项,这些状态值都为0。这可能是因为没有设置需要选中项的样式属性。
您可以在对话框初始化期间使用以下代码行启用选择项:
m_listControl.SetExtendedStyle(m_listControl.GetExtendedStyle() | LVS_EX_FULLROWSELECT);
这将通过启用 `LVS_EX_FULLROWSELECT` 样式属性,指定每次用户单击Listctrl时选择整行而不是仅选择项目,来激活选择。
此后,您应该能够正确地获取有关选定行的新和旧状态信息。 根据您的代码,您已经正确地设置了选择模式,应该能够获取到新老状态的值,因此问题可能出在其他地方。以下是一些可能的原因:
1、是否已经正确地配置了CListCtrl控件的通知消息?
您需要确保您已经为控件分配了ID,并在响应它时注册相应的WM_NOTIFY消息。
2、是否正确地创建了CImageList对象?
LVS_EX_CHECKBOXES要求将图像列表分配给控件以显示复选框。如果未给控件分配图片列表,则可能导致控件无法显示复选框或返回错误的状态信息。
3、其他原因
如果您尝试从OnNMCustomDraw()消息处理程序中获取状态,那么您可能必须调用DefWindowProc()来接收默认的类处理,否则您的消息很可能被忽略。
您也可以使用其他方法(如GetItemState()) 来获取选定项的状态。
请检查这些原因,并尝试修复您的代码以获得正确的状态。
还有,以后要回复请点击下面的“回复”,不然收不到你的消息 您的代码是一个处理CListCtrl控件单击事件的函数。从您的描述中,我了解到您遇到的问题是新状态(new state)和旧状态(old state)的返回值都是0,而您期望当单击后,新状态应该有一个选中状态。
首先,请确保您的CListCtrl控件已经设置了单选模式和整行选择模式。您可以在对话框的OnInitDialog()方法中添加以下代码来设置这些模式:
m_listCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_ONECLICKACTIVATE);
其中,m_listCtrl是CListCtrl控件的对象。这样设置后,当您单击某一行时,整行都将被选中。
然后,在处理单击事件的函数中,您需要使用GetItemState方法来获取新状态(new state)和旧状态(old state)。NMITEMACTIVATE结构体中的uNewState和uOldState成员主要用于响应其他类型的通知消息,如LVN_ITEMCHANGED。在处理NM_CLICK消息时,您可以使用以下代码来获取新状态和旧状态:
UINT ns = m_listCtrl.GetItemState(han, LVIS_SELECTED);
str.Format(_T("新状态ns=%d\r\n"), ns);
OutputDebugString(str);
UINT olds = m_listCtrl.GetItemState(han, LVIS_SELECTED) ? 0 : LVIS_SELECTED;
str.Format(_T("老状态olds=%d\r\n"), olds);
OutputDebugString(str);
这里,m_listCtrl是CListCtrl控件的对象。GetItemState方法需要两个参数:项的索引(index)和状态掩码(state mask)。在这个例子中,我们使用LVIS_SELECTED作为状态掩码,表示我们只关心选中状态。
上面的代码将获取新状态和旧状态,并将它们的值分别输出到调试窗口。请尝试使用这些修改后的代码,看看是否能解决您遇到的问题。
页:
[1]