📄 toolbarex.cpp
字号:
if ((0 <= tbStruct->iItem) && (tbStruct->iItem < m_ToolBarInfo.GetSize()))
{
// copy the stored button structure
tbStruct->tbButton = m_ToolBarInfo[tbStruct->iItem].tbButton;
// copy the text for the button label in the dialog
_tcscpy(tbStruct->pszText, m_ToolBarInfo[tbStruct->iItem].btnText);
// indicate valid data was sent
*pResult = TRUE;
}
else // else there is no button for this index
{
*pResult = FALSE;
}
}
// This function is called when the user clicks on the reset button on the
// toolbar customization dialog box.
void CToolBarEx::OnToolBarReset(NMHDR *pNMHDR, LRESULT *pResult)
{
UNUSED_ALWAYS( pNMHDR );
UNUSED_ALWAYS( pResult );
int nCount, i;
CToolBarCtrl & tbCtrl =GetToolBarCtrl();
// Remove all of the existing buttons
nCount = tbCtrl.GetButtonCount();
for(i = nCount - 1; i >= 0; i--)
tbCtrl.DeleteButton(i);
// Restore the buttons that were saved.
for (i=0;i<m_ToolBarInfo.GetSize();i++)
{
if (m_ToolBarInfo[i].bInitiallyVisible)
tbCtrl.AddButtons(1,&m_ToolBarInfo[i].tbButton);
}
if (m_pCustomizeDlg)
{
ASSERT_VALID(m_pCustomizeDlg);
m_pCustomizeDlg->SetTextOptions(GetTextOptions());
m_pCustomizeDlg->SetIconOptions(GetIconOptions());
}
SetTextOptions(m_eInitialTextOptions,FALSE); //Default Values
SetIconOptions(m_eInitialIconOptions,FALSE); //Default Values
PositionControls();
// force the frame window to recalculate the size
GetParentFrame()->RecalcLayout();
OnIdleUpdateCmdUI(TRUE, 0L);
*pResult = TRUE;
}
void CToolBarEx::SetToolBarInfoForCustomization(const CToolBarEx::ToolBarInfoArray * pAdditional)
{
m_ToolBarInfo.RemoveAll();
const int nCount = GetToolBarCtrl().GetButtonCount();
m_ToolBarInfo.SetSize(nCount); //SetSize
CToolBarCtrl & tbCtrl = GetToolBarCtrl();
for (int i=0;i<nCount;i++)
{
CToolBarButtonInfo tbButtonInfo;
tbCtrl.GetButton(i,&tbButtonInfo.tbButton);
CString str;
str.LoadString(tbButtonInfo.tbButton.idCommand);
int nPos= str.ReverseFind(_T('\n'));
tbButtonInfo.btnText=str.Right(str.GetLength()-nPos-1);
tbButtonInfo.bInitiallyVisible=TRUE;
m_ToolBarInfo.SetAt(i,tbButtonInfo);
}
m_nResButtons =m_ToolBarInfo.GetSize();
// add the addiotnal buttons
if (pAdditional)
{
ASSERT_VALID(pAdditional);
m_ToolBarInfo.Append(*pAdditional);
}
m_ToolBarInfo.FreeExtra();
ModifyStyle(0, CCS_ADJUSTABLE);
SetTextOptions(m_eInitialTextOptions); //Default Values
SetIconOptions(m_eInitialIconOptions); //Default Values
}
/////////////////////////////////////////////////////////////////////////////////////////
// Overrides
int CToolBarEx::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CToolBar::OnCreate(lpCreateStruct) == -1)
return -1;
_GetComCtlVersion();
ASSERT(_ComCtlVersion>=VERSION_IE5);
//set version
int nVer=5;
DefWindowProc(CCM_SETVERSION,nVer,0);
ASSERT(nVer==DefWindowProc(CCM_GETVERSION,nVer,0));
return 0;
}
void CToolBarEx::PositionControls()
{
GetToolBarCtrl().AutoSize();
m_bDelayedButtonLayout=TRUE;
}
// the all important function
CSize CToolBarEx::GetButtonSize(TBBUTTON* pData, int iButton, DWORD dwMode)
{
ASSERT(_ComCtlVersion > 0);
// Get the actual size of the button, not what's in m_sizeButton.
// Make sure to do SendMessage instead of calling MFC's GetItemRect,
// which has all sorts of bad side-effects!
//
CRect rc;
SendMessage(TB_GETITEMRECT, iButton, (LPARAM)&rc);
CSize sz = rc.Size();
DWORD dwStyle = pData[iButton].fsStyle;
BOOL bVertDocked= (!(dwMode&LM_HORZ) && !(dwMode&LM_STRETCH) ) ;
// do not allow sepearot to be greater than Button height ( Have to check this)
if (dwStyle & TBSTYLE_SEP)
sz.cy = min(sz.cy ,HIWORD(GetToolBarCtrl().GetButtonSize()));
// special cas for custom controls
if (m_bHideChildWndOnVertical)
{
if ((dwStyle & TBSTYLE_SEP) &&
(pData[iButton].idCommand!=0))
{
if (bVertDocked)
{
sz.cx=sz.cy=0;
}
else
{
// we will get 0,0 on hidden things
if (GetToolBarCtrl().IsButtonHidden(pData[iButton].idCommand))
{
CWnd * pWnd =GetDlgItem(pData[iButton].idCommand);
ASSERT_VALID(pWnd);
CRect rt;
pWnd->GetWindowRect(rt);
sz=rt.Size();
}
}
}
}
////////////////
// Now must do special case for various versions of comctl32.dll,
//
if ((pData[iButton].fsState & TBSTATE_WRAP))
{
if (dwStyle & TBSTYLE_SEP)
{
CWnd *pWnd =GetDlgItem(pData[iButton].idCommand);
// Check seperator is child window
if (!pWnd)
{
// this is the last separator in the row (eg vertically docked)
// fudge the height, and ignore the width. TB_GETITEMRECT will return
// size = (8 x 22) even for a separator in vertical toolbar
//
if (_ComCtlVersion <= VERSION_IE3)
sz.cy -= 3; // empircally good fudge factor
else if (_ComCtlVersion != VERSION_IE4)
sz.cy = sz.cx;
sz.cx = 0; // separator takes no width if it's the last one
}
else
{
// Do not set value in case of the child window
//WE should never get here
ASSERT_VALID(pWnd);
ASSERT(FALSE);
}
}
}
// // drop down arrow check
// if ((dwStyle & TBSTYLE_DROPDOWN) &&
// (bVertDocked) &&
// !m_bShowDropdownArrowWhenVertical )
// {
// // ignore width of dropdown
// sz.cx = sz.cy;
// }
return sz;
}
////////////////////////////////////////////////////////////
#define CX_OVERLAP 0
CSize CToolBarEx::CalcSize(TBBUTTON* pData, int nCount,DWORD dwMode)
{
ASSERT(pData != NULL && nCount > 0);
CPoint cur(0,0);
CSize sizeResult(0,0);
int cyTallestOnRow = 0;
int nButtons=0;
for (int i = 0; i < nCount; i++)
{
// also calculate for hidden custom controls
if ( (pData[i].fsState & TBSTATE_HIDDEN) &&
!((pData[i].fsStyle & TBSTYLE_SEP) && (pData[i].idCommand!=0)))
continue;
// Load actual size of button into a local variable
//
CSize m_sizeButton = GetButtonSize(pData, i,dwMode);
// changed the logic below to be more correct.
cyTallestOnRow = max(cyTallestOnRow, m_sizeButton.cy);
sizeResult.cx = max(cur.x + m_sizeButton.cx, sizeResult.cx);
sizeResult.cy = max(cur.y + m_sizeButton.cy, sizeResult.cy);
cur.x += m_sizeButton.cx - CX_OVERLAP;
if (!(pData[i].fsState & TBSTATE_HIDDEN)) nButtons++;
if (pData[i].fsState & TBSTATE_WRAP)
{
//only seperator is present
if ((nButtons==1) && (pData[i].fsStyle & TBSTYLE_SEP))
{
cyTallestOnRow = HIWORD(GetToolBarCtrl().GetButtonSize());
}
cur.x = 0;
cur.y += cyTallestOnRow;
cyTallestOnRow = 0;
if (pData[i].fsStyle & TBSTYLE_SEP)
cur.y += m_sizeButton.cy;
nButtons=0;
}
}
return sizeResult;
}
int CToolBarEx::WrapToolBar(TBBUTTON* pData, int nCount, int nWidth, DWORD dwMode)
{
ASSERT(pData != NULL && nCount > 0);
int nResult = 0;
int x = 0;
for (int i = 0; i < nCount; i++)
{
pData[i].fsState &= ~TBSTATE_WRAP;
// also calculate for hidden custom controls
if ( (pData[i].fsState & TBSTATE_HIDDEN) &&
!((pData[i].fsStyle & TBSTYLE_SEP) && (pData[i].idCommand!=0)))
continue;
int dx, dxNext;
// Load actual size of button into a local variable
CSize m_sizeButton = GetButtonSize(pData, i,dwMode);
dx = m_sizeButton.cx;
dxNext = dx - CX_OVERLAP;
if (x + dx > nWidth)
{
BOOL bFound = FALSE;
for (int j = i; j >= 0 && !(pData[j].fsState & TBSTATE_WRAP); j--)
{
// Find last separator that isn't hidden
// a separator that has a command ID is not
// a separator, but a custom control.
if ((pData[j].fsStyle & TBSTYLE_SEP) &&
(pData[j].idCommand == 0)
&& !(pData[j].fsState & TBSTATE_HIDDEN))
{
bFound = TRUE; i = j; x = 0;
pData[j].fsState |= TBSTATE_WRAP;
nResult++;
break;
}
}
if (!bFound)
{
for (int j = i - 1; j >= 0 && !(pData[j].fsState & TBSTATE_WRAP); j--)
{
// Never wrap anything that is hidden,
// or any custom controls
if ((pData[j].fsState & TBSTATE_HIDDEN) ||
((pData[j].fsStyle & TBSTYLE_SEP) &&
(pData[j].idCommand != 0)))
continue;
bFound = TRUE; i = j; x = 0;
pData[j].fsState |= TBSTATE_WRAP;
nResult++;
break;
}
if (!bFound)
x += dxNext;
}
}
else
x += dxNext;
}
return nResult + 1;
}
/////////////////////////////////////////////////////////////////////////////////////////////
void CToolBarEx::SizeToolBar(TBBUTTON* pData, int nCount, int nLength, BOOL bVert, DWORD dwMode)
{
ASSERT(pData != NULL && nCount > 0);
if (!bVert)
{
int nMin, nMax, nTarget, nCurrent, nMid;
// Wrap ToolBar as specified
nMax = nLength;
nTarget = WrapToolBar(pData, nCount, nMax,dwMode);
// Wrap ToolBar vertically
nMin = 0;
nCurrent = WrapToolBar(pData, nCount, nMin,dwMode);
if (nCurrent != nTarget)
{
while (nMin < nMax)
{
nMid = (nMin + nMax) / 2;
nCurrent = WrapToolBar(pData, nCount, nMid,dwMode);
if (nCurrent == nTarget)
nMax = nMid;
else
{
if (nMin == nMid)
{
WrapToolBar(pData, nCount, nMax,dwMode);
break;
}
nMin = nMid;
}
}
}
CSize size = CalcSize(pData, nCount,dwMode);
WrapToolBar(pData, nCount, size.cx,dwMode);
}
else
{
CSize sizeMax, sizeMin, sizeMid;
// Wrap ToolBar vertically
WrapToolBar(pData, nCount, 0,dwMode);
sizeMin = CalcSize(pData, nCount,dwMode);
// Wrap ToolBar horizontally
WrapToolBar(pData, nCount, 32767,dwMode);
sizeMax = CalcSize(pData, nCount,dwMode);
while (sizeMin.cx < sizeMax.cx)
{
sizeMid.cx = (sizeMin.cx + sizeMax.cx) / 2;
WrapToolBar(pData, nCount, sizeMid.cx,dwMode);
sizeMid = CalcSize(pData, nCount,dwMode);
if (nLength < sizeMid.cy)
{
if (sizeMin == sizeMid)
{
WrapToolBar(pData, nCount, sizeMax.cx,dwMode);
return;
}
sizeMin = sizeMid;
}
else if (nLength > sizeMid.cy)
{
if (sizeMax == sizeMid)
{
WrapToolBar(pData, nCount, sizeMin.cx,dwMode);
return;
}
sizeMax = sizeMid;
}
else
return;
}
}
}
CSize CToolBarEx::CalcLayout(DWORD dwMode, int nLength)
{
ASSERT_VALID(this);
ASSERT(::IsWindow(m_hWnd));
if (dwMode & LM_HORZDOCK)
ASSERT(dwMode & LM_HORZ);
int nCount;
TBBUTTON* pData = NULL;
CSize sizeResult(0,0);
//BLOCK: Load Buttons
{
nCount = DefWindowProc(TB_BUTTONCOUNT, 0, 0);
if (nCount != 0)
{
int i;
pData = new TBBUTTON[nCount];
for (i = 0; i < nCount; i++)
_GetButton(i, &pData[i]);
}
}
if (nCount > 0)
{
if (!(m_dwStyle & CBRS_SIZE_FIXED))
{
BOOL bDynamic = m_dwStyle & CBRS_SIZE_DYNAMIC;
if (bDynamic && (dwMode & LM_MRUWIDTH))
SizeToolBar(pData, nCount, m_nMRUWidth,FALSE,dwMode);
else if (bDynamic && (dwMode & LM_HORZDOCK))
SizeToolBar(pData, nCount, 32767,FALSE,dwMode);
else if (bDynamic && (dwMode & LM_VERTDOCK))
SizeToolBar(pData, nCount, 0,FALSE,dwMode);
else if (bDynamic && (nLength != -1))
{
CRect rect; rect.SetRectEmpty();
CalcInsideRect(rect, (dwMode & LM_HORZ));
BOOL bVert = (dwMode & LM_LENGTHY);
int nLen = nLength + (bVert ? rect.Height() : rect.Width());
SizeToolBar(pData, nCount, nLen, bVert,dwMode);
}
else if (bDynamic && (m_dwStyle & CBRS_FLOATING))
SizeToolBar(pData, nCount, m_nMRUWidth,FALSE,dwMode);
else
SizeToolBar(pData, nCount, (dwMode & LM_HORZ) ? 32767 : 0,FALSE,dwMode);
}
sizeResult = CalcSize(pData, nCount,dwMode);
if (dwMode & LM_COMMIT)
{
int nControlCount = 0;
BOOL bIsDelayed = m_bDelayedButtonLayout;
m_bDelayedButtonLayout = FALSE;
BOOL bVert = (m_dwStyle & CBRS_ORIENT_VERT) != 0;
for (int i = 0; i < nCount; i++)
if ((pData[i].fsStyle & TBSTYLE_SEP) && (pData[i].idCommand != 0))
nControlCount++;
if (nControlCount > 0)
{
for(int i = 0; i < nCount; i++)
{
if ((pData[i].fsStyle & TBSTYLE_SEP) && (pData[i].idCommand != 0))
{
CRect rt;
CWnd* pWnd = GetDlgItem(pData[i].idCommand);
if (pWnd != NULL)
{
ASSERT_VALID(pWnd);
pWnd->GetWindowRect(rt);
pData[i].iBitmap=rt.Width(); //width
if (bVert && m_bHideChildWndOnVertical)
pData[i].fsState |= TBSTATE_HIDDEN;
else
pData[i].fsState &= ~TBSTATE_HIDDEN;
}
}
}
}
if ((m_dwStyle & CBRS_FLOATING) && (m_dwStyle & CBRS_SIZE_DYNAMIC))
m_nMRUWidth = sizeResult.cx;
for (i = 0; i < nCount; i++)
_SetButton(i, &pData[i]);
{
//Now place the windows
CWnd * pWnd = GetWindow(GW_CHILD);
while(pWnd)
{
ASSERT_VALID(pWnd);
int id =pWnd->GetDlgCtrlID();
///////////////////////////
// make sure the id is valid, and set the button
// style for a seperator.
int nIndex = CommandToIndex( id ) ;
if (nIndex>-1)
{
ASSERT( nIndex >= 0 );
// insert the control into the toolbar.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -