I'm trying to get the order of the columns in an MFC CListCtrl
. Initially I tried calling GetColumnOrderArray()
in a message handler for the HDN_ENDDRAG
notification, but that always returned the old (pre-drag and drop) column order. So, based on the advice in this SO post's comment, I tried handling both the HDN_BEGINDRAG
and the HDN_ENDDRAG
and grabbing the old and new column orders with phdr->pitem->iOrder
. But pitem
is always NULL for me in the both handlers. No idea why.
SOOO I tried using the column index stored in the message (phdr->iItem
) to talk directly to the CHeaderCtrl
and grab the column order myself, but the fields in the structure populated by my header control were all invalid; I still couldn't get the column order.
Is there some sort of deeper problem with my list control? Or am I just handling messages incorrectly?
HDN_BEGINDRAG
message handler:
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;
}
HDN_ENDDRAG
message handler:
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;
}
While this is an old question, I came across it just now while looking into CListCtrl column dragging and thought I'd update it a bit in case it's of use to somebody else.
The OP mentioned that,
This will because you haven't initialised columnStruct enough to tell GetItem what data you're interested in retrieving. You need to initialise columnStruct.mask with various flags such as HDI_WIDTH | HDI_ORDER, and if you use HDI_TEXT then give columnStruct.pszText a buffer and columnStruct.cchTextMax the size of the buffer.
This is documented in the CHeaderCtrl::GetItem documentation on MSDN for example.
This may be a bit of simplistic solution, why not call
GetColumnOrderArray()
when the parent of the list control needs to be closed?If you do need the column order for some other purpose right away and from the SO post you quoted, it looks like
HDN_ENDDRAG
is too early to callGetColumnOrderArray()
, try aPostMessage
to the (parent of) the list control at the end ofOnHdnEnddrag()
with the message number in the rangeWM_USER through 0x7FFF
and callGetColumnOrderArray()
in the handler of that message.