// Swap the selected item in the Quick Access list with the previous item
void MyQuickAccessPage::OnButtonMoveUp()
{
if (!GetDlgItem(IDC_RIBBONBUTTON_MOVE_UP)->IsWindowEnabled())
return;
int nSel = m_lstQuickAccess.GetCurSel();
if (nSel < 1)
return;
CXTPControl* pControlInList = (CXTPControl*)m_lstQuickAccess.GetItemDataPtr(nSel);
if (!pControlInList)
return;
CXTPRibbonQuickAccessControls* pQuickAccessControls = GetRibbonBar()->GetQuickAccessControls();
if (!pQuickAccessControls)
return;
CXTPControl* pControlInQAT = pQuickAccessControls->FindControl(pControlInList->GetID());
if (!pControlInQAT)
return;
// I'm not convinced that GetIndex is the same as the position in the array,
// so this may not be correct. Is GetIndex 1-based rather than 0-based?
long nPrev = pControlInQAT->GetIndex() - 1 - 1;
if (nPrev < 0)
return;
// This was my first try. It asserts and crashes in CXTPControls::MoveBefore
// because pQuickAccessControls != pControlInQAT->GetControls()
//pQuickAccessControls->MoveBefore(pControlInQAT, (int)nPrev);
// This seems like it would work. It does result in the objects in the list
// control swapping, but no corresponding change happens on the QAT.
pQuickAccessControls->AddClone(pControlInList, nPrev);
pQuickAccessControls->Remove(pControlInQAT);
GetRibbonBar()->OnRecalcLayout();
RefreshQuickAccessList();
}
I wrote some code to dump the QAT try to track what is going on and called it from the debugger at strategic points. Here's that function:
void DumpQAT()
{
. . . get the ribbon bar . . .
if (CXTPRibbonQuickAccessControls* pQuickAccessControls = pRibbonBar->GetQuickAccessControls())
{
int nCount = pQuickAccessControls->GetCount();
TRACE("Count: %d\n", nCount);
for (int n = 0; n < nCount; ++n)
{
if (CXTPControl* pControl = pQuickAccessControls->GetAt(n))
{
int nID = pControl->GetID();
long nIndex = pControl->GetIndex();
CString strName = pControl->GetCaption();
TRACE("%d: %#010x %5d %4d %s\n", n, pControl, nID, nIndex, (LPCSTR)strName);
}
}
}
}
}
}
Before the call to AddClone, I had this:
Count: 6
0: 0x0a2b9548 57600 1 &New
1: 0x0a2b9820 57601 2 &Open
2: 0x0a0c4630 57603 3 &Save
3: 0x0a2b9270 57607 4 &Print
4: 0x1f01c6b8 40002 5 Send To Mail Recipient
5: 0x1f334bf8 40003 6 Send To Routing Recipient
After that call, I had what I expected in terms of overall order, although the index column seems odd:
Count: 7
0: 0x0a2b9548 57600 1 &New
1: 0x0a2b9820 57601 2 &Open
2: 0x0a0c4630 57603 3 &Save
3: 0x0a2b9270 57607 4 &Print
4: 0x1f334da0 40003 7 Send To Routing Recipient
5: 0x1f01c6b8 40002 5 Send To Mail Recipient
6: 0x1f334bf8 40003 6 Send To Routing Recipient
After the call to Remove, I got this:
Count: 6
0: 0x0a2b9548 57600 1 &New
1: 0x0a2b9820 57601 2 &Open
2: 0x0a0c4630 57603 3 &Save
3: 0x0a2b9270 57607 4 &Print
4: 0x1f334da0 40003 6 Send To Routing Recipient
5: 0x1f01c6b8 40002 5 Send To Mail Recipient
The part that throws me is the index, which I believe is contributing to me not seeing the results I expect. Notice that "Send to Routing Recipient" has an index of 6, when I would expect it to have 5 and "Send to Mail Recipient" to have 6. I stepped all the way through Remove into CXTPControls::RefreshIndexes and saw the indices recomputed sequentially, but I'm not positive that the correct thing is getting recomputed. There are controls visited in that loop that I didn't expect to see (eg CXTPRibbonScrollableBar::CControlGroupsScroll, CXTPRibbonBarControlQuickAccessPopup).
Can someone enlighten me? I went into this thinking it shouldn't be too difficult.