Visual c++ 获取列顺序(MFC)
我试图获取MFCVisual c++ 获取列顺序(MFC),visual-c++,mfc,clistctrl,Visual C++,Mfc,Clistctrl,我试图获取MFCCListCtrl中列的顺序。最初,我尝试在HDN\u ENDDRAG通知的消息处理程序中调用GetColumnOrderArray(),但总是返回旧的(预拖放)列顺序。因此,根据So post评论中的建议,我尝试处理HDN_BEGINDRAG和HDN_ENDDRAG,并使用phdr->pitem->iOrder获取新旧列顺序。但是在这两个处理程序中,pitem对我来说总是空的。不知道为什么 因此,我尝试使用消息中存储的列索引(phdr->iItem)直接与CHeaderCtrl
CListCtrl
中列的顺序。最初,我尝试在HDN\u ENDDRAG
通知的消息处理程序中调用GetColumnOrderArray()
,但总是返回旧的(预拖放)列顺序。因此,根据So post评论中的建议,我尝试处理HDN_BEGINDRAG
和HDN_ENDDRAG
,并使用phdr->pitem->iOrder
获取新旧列顺序。但是在这两个处理程序中,pitem
对我来说总是空的。不知道为什么
因此,我尝试使用消息中存储的列索引(phdr->iItem
)直接与CHeaderCtrl
对话,并亲自获取列顺序,但由我的头控件填充的结构中的字段都无效;我仍然无法获得列顺序
我的列表控件是否存在某种更深层次的问题?还是我只是错误地处理了信息
HDN\u BEGINDRAG
消息处理程序:
BOOL CDFAManListView::OnHdnBegindrag(UINT, NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
phdr->iItem; // this contains a valid column index
HDITEM columnStruct;
List->GetHeaderCtrl()->GetItem(phdr->iItem, &columnStruct); // but this call just fills columnStruct with junk values
if (phdr->pitem) // pitem is always null
{
initialPosition = phdr->pitem->iOrder;
}
*pResult = 0;
return TRUE;
}
void CDFAManListView::OnHdnEnddrag(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
HDITEM columnStruct;
List->GetHeaderCtrl()->GetItem(phdr->iItem, &columnStruct); // still just fills columnStruct with junk
List->GetColumnOrderArray(signalColumnOrder); // gets **old** column order
*pResult = 0;
}
这可能是一种过于简单的解决方案,为什么不在需要关闭列表控件的父控件时调用
GetColumnOrderArray()
如果您确实需要立即将列顺序用于其他目的,并且从您引用的SO post来看,
HDN_ENDDRAG
调用GetColumnOrderArray()
,似乎太早了,请尝试将PostMessage
添加到OnHdnEnddrag()末尾的列表控件(父控件)中
消息编号在范围WM\u USER通过0x7FFF
并在该消息的处理程序中调用GetColumnOrderArray()
。虽然这是一个老问题,但我刚才在查看CListCtrl列拖动时遇到了它,并认为我应该对它进行一些更新,以防它对其他人有用
OP提到
HDITEM columnStruct;
List->GetHeaderCtrl()->GetItem(phdr->iItem, &columnStruct); // but this call just fills columnStruct with junk values
这是因为您尚未初始化columnStruct,无法告诉GetItem您感兴趣检索哪些数据。您需要使用各种标志(如HDI_宽度| HDI_顺序)初始化columnStruct.mask,如果使用HDI_文本,则为columnStruct.pszText提供缓冲区,并为columnStruct.cchTextMax提供缓冲区大小
这就是一个例子
掩码元素中设置的任何标志都确保
返回时正确填写相应的元素。如果面具
元素设置为零,其他结构元素中的值
毫无意义
我已经通过从包含我的列表控件的
CListView
的析构函数调用GetColumnOrderArray()
尝试了您的第一个解决方案,但是列表控件到那时已经无效;程序崩溃了:(我会看看是否能让你的第二个解决方案工作,但是PostMessage()
不能让你确切知道消息何时会被处理,对吗?我不能保证父进程会在HDN\u ENDDRAG
处理程序完成和GetColumnArray()后处理消息)
是否会返回有效答案?我确信析构函数太晚了,这就是为什么我提到“当列表控件的父控件需要关闭时”,这将在关闭进程开始之前;您使用什么样的父类来承载ListControl?PostMessage
仅在处理完所有其他队列消息后才会处理该消息,值得一试。父类是CListView
。我试图调用GetColumnOrderArray()
来自CListView
的析构函数,而不是CListCtrl()
。我最终只是创建了自己的SaveState()
函数,我在程序的其他地方调用了该函数(为了时间起见,您的解决方案可能工作得很好,idk)。我不喜欢它,因为它不是在自动调用的函数(如消息通知)中完成的,但它可以工作:/感谢您的时间!我很高兴输入很有用[我们通常在视图即将关闭时在应用程序中保存视图设置,而不是在实际更改期间(如拖放)保存视图设置),这样您就可以对列进行任意次数的重新排序,并且设置只保存一次,当您关闭]可爱的,我只是没有足够仔细地阅读文档--