Visual c++ 获取列顺序(MFC)

Visual 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

我试图获取MFC
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)。我不喜欢它,因为它不是在自动调用的函数(如消息通知)中完成的,但它可以工作:/感谢您的时间!我很高兴输入很有用[我们通常在视图即将关闭时在应用程序中保存视图设置,而不是在实际更改期间(如拖放)保存视图设置),这样您就可以对列进行任意次数的重新排序,并且设置只保存一次,当您关闭]可爱的,我只是没有足够仔细地阅读文档--