Codejock Forums Homepage
Forum Home Forum Home > Codejock Products > Visual C++ MFC > Command Bars
  New Posts New Posts RSS Feed - Reordering the Quick Access Toolbar
  FAQ FAQ  Forum Search   Events   Register Register  Login Login

Reordering the Quick Access Toolbar

 Post Reply Post Reply
Author
Message
mrmathis View Drop Down
Senior Member
Senior Member
Avatar

Joined: 17 May 2007
Location: United States
Status: Offline
Points: 105
Post Options Post Options   Thanks (0) Thanks(0)   Quote mrmathis Quote  Post ReplyReply Direct Link To This Post Topic: Reordering the Quick Access Toolbar
    Posted: 19 February 2008 at 6:26pm
I am trying to extend the Quick Access customization page by adding "Move Up" and "Move Down" buttons a la MS Word's version of this dialog, but I'm not having much success.  Here is some sample code from my CustomizeQAT::OnMoveUp handler that can be used to replace the body of CXTPRibbonCustomizeQuickAccessPage::OnButtonReset to illustrate what I am trying to do.

// 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.
 
 
--Mike
Back to Top
Oleg View Drop Down
Admin Group
Admin Group


Joined: 21 May 2003
Location: United States
Status: Offline
Points: 11234
Post Options Post Options   Thanks (0) Thanks(0)   Quote Oleg Quote  Post ReplyReply Direct Link To This Post Posted: 04 March 2008 at 5:16am
Hi,
Yes, right :( problem in our sources that assumes that Quick Acccess controls always added in the end of list.
 
Here fix for source:
 
int CXTPRibbonQuickAccessControls::IndexOf(CXTPControl* pControl) const
{
 for (int nIndex = GetCount() - 1; nIndex >= 0; nIndex--)
 {
  if (GetAt(nIndex) == pControl)
  {
   return nIndex;
  }
 }
 return -1;
}
void CXTPRibbonQuickAccessControls::OnControlAdded(CXTPControl* pControl)
{
 int nIndex = IndexOf(pControl) + (((CXTPRibbonBar*)m_pParent)->GetSystemButton() ? 1 : 0);
 m_pParent->GetControls()->InsertAt(pControl, nIndex);
 pControl->InternalAddRef();
}
 
Here your method to move:
 
void CXTPRibbonCustomizeQuickAccessPage::OnButtonReset()
{
 int nSel = m_lstQuickAccess.GetCurSel();
    if (nSel < 1)
        return;
 
    CXTPControl* pControl = (CXTPControl*)m_lstQuickAccess.GetItemDataPtr(nSel);
    if (!pControl)
        return;
 
    CXTPRibbonQuickAccessControls* pQuickAccessControls = GetRibbonBar()->GetQuickAccessControls();
    if (!pQuickAccessControls)
        return;
 int nIndex = pQuickAccessControls->IndexOf(pControl);
 
    pQuickAccessControls->AddClone(pControl, nIndex - 1);
    pQuickAccessControls->Remove(pControl);
 
    GetRibbonBar()->OnRecalcLayout();
    RefreshQuickAccessList();
}
 
 
Thanks
Oleg, Support Team
CODEJOCK SOFTWARE SOLUTIONS
Back to Top
 Post Reply Post Reply
  Share Topic   

Forum Jump Forum Permissions View Drop Down

Forum Software by Web Wiz Forums® version 12.04
Copyright ©2001-2021 Web Wiz Ltd.

This page was generated in 0.047 seconds.