2013-08-22 5 views
1

Я пытаюсь получить порядок столбцов в MFC CListCtrl. Первоначально я пробовал звонить GetColumnOrderArray() в обработчике сообщений для уведомления HDN_ENDDRAG, но всегда возвращал старый порядок (пре-перетаскивание и падение). Итак, основываясь на рекомендации в комментарии this SO post, я пробовал обрабатывать как HDN_BEGINDRAG, так и HDN_ENDDRAG и захватывать старые и новые порядки столбцов с phdr->pitem->iOrder. Но pitem всегда имеет значение NULL для меня в обоих обработчиках. Не знаю, почему.Получить столбец (MFC)

SOOO Я попытался с помощью индекса столбца, хранящегося в сообщении (phdr->iItem) поговорить непосредственно с CHeaderCtrl и захватить порядок столбцов себя, но поля в структуре, населенной моим контролем заголовка были недействительными; Я все еще не мог получить порядок столбцов.

Есть ли какая-то более глубокая проблема с моим контролем списка? Или я неправильно обрабатываю сообщения?

HDN_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; 
} 

HDN_ENDDRAG сообщение:

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; 
} 

ответ

0

В то время как это старый вопрос, я наткнулся на него только сейчас, рассматривая перетаскивание столбца CListCtrl и думал, что немного обновлю его, если он будет полезен кому-то другому.

ОП отметил, что,

HDITEM columnStruct; 

List->GetHeaderCtrl()->GetItem(phdr->iItem, &columnStruct); // but this call just fills columnStruct with junk values 

Это будет, потому что вы не инициализирован columnStruct достаточно, чтобы сказать GetItem, какие данные вы заинтересованы в получении. Вам нужно инициализировать columnStruct.mask различными флагами, такими как HDI_WIDTH | HDI_ORDER, и если вы используете HDI_TEXT, дайте столбцуStruct.pszText буфер и columnStruct.cchTextMax размер буфера.

Это, например, documented in the CHeaderCtrl::GetItem documentation on MSDN.

Любые флаги, установленные в элементе маски, гарантируют, что значения в соответствующих элементах должным образом заполнены после возврата. Если элемент маски установлен на ноль, значения в других элементах структуры равны бессмысленным.

+0

Прекрасный, я просто недостаточно читал документацию -.- – aguazales

0

Это может быть немного упрощенным решения, почему бы не назвать GetColumnOrderArray(), когда родительский контроль список должен быть закрыт ?

Если вам нужно порядок столбцов для других целей сразу и от SO опубликовать вы процитировали, это выглядит как HDN_ENDDRAG слишком рано называть GetColumnOrderArray(), попробуйте PostMessage к (родитель) управления списком в конец OnHdnEnddrag() с номером сообщения в диапазоне WM_USER through 0x7FFF и вызовите GetColumnOrderArray() в обработчике этого сообщения.

+0

Я уже пробовал ваше первое решение, вызывая 'GetColumnOrderArray()' из деструктора 'CListView', который содержал мой элемент управления списком, но элемент управления списком уже недействителен этой точкой; программа потерпела крах :(Я посмотрю, смогу ли я заставить ваше второе решение работать, но 'PostMessage()' не дает вам четкого представления о том, когда сообщение будет обработано, верно? Я не могу гарантировать, что родительский обработает сообщение ПОСЛЕ завершения обработчика 'HDN_ENDDRAG' и' GetColumnArray() 'вернет правильный ответ? – aguazales

+0

Я уверен, что деструктор слишком поздно, поэтому я упомянул «когда родительский элемент управления списком должен быть закрыт», так что это произойдет до начала закрытого процесса; какой родительский класс вы используете для размещения ListControl? 'PostMessage' обработает сообщение только после того, как оно закончит обработку всех других сообщений очереди, стоит попробовать –

+0

Хорошо, я попробую. И родитель - это 'CListView'. Я пытался вызвать 'GetColumnOrderArray()' из деструктора 'CListView', а не' CListCtrl() '. – aguazales