📄 bartool.cpp
字号:
}
delete[] pData;
}
//BLOCK: Adjust Margins
{
CRect rect; rect.SetRectEmpty();
CalcInsideRect(rect, (dwMode & LM_HORZ));
sizeResult.cy -= rect.Height();
sizeResult.cx -= rect.Width();
CSize size = CControlBar::CalcFixedLayout((dwMode & LM_STRETCH), (dwMode & LM_HORZ));
sizeResult.cx = max(sizeResult.cx, size.cx);
sizeResult.cy = max(sizeResult.cy, size.cy);
}
return sizeResult;
}
CSize CToolBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
{
DWORD dwMode = bStretch ? LM_STRETCH : 0;
dwMode |= bHorz ? LM_HORZ : 0;
return CalcLayout(dwMode);
}
CSize CToolBar::CalcDynamicLayout(int nLength, DWORD dwMode)
{
if ((nLength == -1) && !(dwMode & LM_MRUWIDTH) && !(dwMode & LM_COMMIT) &&
((dwMode & LM_HORZDOCK) || (dwMode & LM_VERTDOCK)))
{
return CalcFixedLayout(dwMode & LM_STRETCH, dwMode & LM_HORZDOCK);
}
return CalcLayout(dwMode, nLength);
}
void CToolBar::GetButtonInfo(int nIndex, UINT& nID, UINT& nStyle, int& iImage) const
{
ASSERT_VALID(this);
ASSERT(::IsWindow(m_hWnd));
TBBUTTON button;
_GetButton(nIndex, &button);
nID = button.idCommand;
nStyle = MAKELONG(button.fsStyle, button.fsState);
iImage = button.iBitmap;
}
void CToolBar::SetButtonInfo(int nIndex, UINT nID, UINT nStyle, int iImage)
{
ASSERT_VALID(this);
TBBUTTON button;
_GetButton(nIndex, &button);
TBBUTTON save;
memcpy(&save, &button, sizeof(save));
button.idCommand = nID;
button.iBitmap = iImage;
button.fsStyle = (BYTE)LOWORD(nStyle);
button.fsState = (BYTE)HIWORD(nStyle);
if (memcmp(&save, &button, sizeof(save)) != 0)
{
_SetButton(nIndex, &button);
m_bDelayedButtonLayout = TRUE;
}
}
int CToolBar::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
{
ASSERT_VALID(this);
ASSERT(::IsWindow(m_hWnd));
// check child windows first by calling CControlBar
int nHit = CControlBar::OnToolHitTest(point, pTI);
if (nHit != -1)
return nHit;
// now hit test against CToolBar buttons
CToolBar* pBar = (CToolBar*)this;
int nButtons = (int)pBar->DefWindowProc(TB_BUTTONCOUNT, 0, 0);
for (int i = 0; i < nButtons; i++)
{
CRect rect;
TBBUTTON button;
if (pBar->DefWindowProc(TB_GETITEMRECT, i, (LPARAM)&rect))
{
++rect.bottom;
++rect.right;
if (rect.PtInRect(point) &&
pBar->DefWindowProc(TB_GETBUTTON, i, (LPARAM)&button) &&
!(button.fsStyle & TBSTYLE_SEP))
{
int nHit = GetItemID(i);
if (pTI != NULL && pTI->cbSize >= sizeof(AFX_OLDTOOLINFO))
{
pTI->hwnd = m_hWnd;
pTI->rect = rect;
pTI->uId = nHit;
pTI->lpszText = LPSTR_TEXTCALLBACK;
}
// found matching rect, return the ID of the button
return nHit != 0 ? nHit : -1;
}
}
}
return -1;
}
BOOL CToolBar::SetButtonText(int nIndex, LPCTSTR lpszText)
{
// attempt to lookup string index in map
int nString = -1;
void* p;
if (m_pStringMap != NULL && m_pStringMap->Lookup(lpszText, p))
nString = (int)p;
// add new string if not already in map
if (nString == -1)
{
// initialize map if necessary
if (m_pStringMap == NULL)
m_pStringMap = new CMapStringToPtr;
// add new string to toolbar list
CString strTemp(lpszText, lstrlen(lpszText)+1);
nString = (int)DefWindowProc(TB_ADDSTRING, 0, (LPARAM)(LPCTSTR)strTemp);
if (nString == -1)
return FALSE;
// cache string away in string map
m_pStringMap->SetAt(lpszText, (void*)nString);
ASSERT(m_pStringMap->Lookup(lpszText, p));
}
// change the toolbar button description
TBBUTTON button;
_GetButton(nIndex, &button);
button.iString = nString;
_SetButton(nIndex, &button);
return TRUE;
}
CString CToolBar::GetButtonText(int nIndex) const
{
CString strResult;
GetButtonText(nIndex, strResult);
return strResult;
}
void CToolBar::GetButtonText(int nIndex, CString& rString) const
{
if (m_pStringMap != NULL)
{
// get button information (need button.iString)
TBBUTTON button;
_GetButton(nIndex, &button);
// look in map for matching iString
POSITION pos = m_pStringMap->GetStartPosition();
CString str; void* p;
while (pos)
{
m_pStringMap->GetNextAssoc(pos, str, p);
if ((int)p == button.iString)
{
rString = str;
return;
}
}
}
rString.Empty();
}
/////////////////////////////////////////////////////////////////////////////
// CToolBar message handlers
BEGIN_MESSAGE_MAP(CToolBar, CControlBar)
//{{AFX_MSG_MAP(CToolBar)
ON_WM_NCHITTEST()
ON_WM_NCPAINT()
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_NCCALCSIZE()
ON_WM_WINDOWPOSCHANGING()
ON_WM_NCCREATE()
ON_MESSAGE(TB_SETBITMAPSIZE, OnSetBitmapSize)
ON_MESSAGE(TB_SETBUTTONSIZE, OnSetButtonSize)
ON_MESSAGE(WM_SETTINGCHANGE, OnPreserveZeroBorderHelper)
ON_MESSAGE(WM_SETFONT, OnPreserveZeroBorderHelper)
ON_WM_SYSCOLORCHANGE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CToolBar::OnEraseBkgnd(CDC*)
{
return (BOOL)Default();
}
UINT CToolBar::OnNcHitTest(CPoint)
{
return HTCLIENT;
}
void CToolBar::OnNcCalcSize(BOOL /*bCalcValidRects*/, NCCALCSIZE_PARAMS* lpncsp)
{
// calculate border space (will add to top/bottom, subtract from right/bottom)
CRect rect; rect.SetRectEmpty();
BOOL bHorz = (m_dwStyle & CBRS_ORIENT_HORZ) != 0;
CControlBar::CalcInsideRect(rect, bHorz);
ASSERT(_afxComCtlVersion != -1);
ASSERT(_afxComCtlVersion >= VERSION_IE4 || rect.top >= 2);
// adjust non-client area for border space
lpncsp->rgrc[0].left += rect.left;
lpncsp->rgrc[0].top += rect.top;
// previous versions of COMCTL32.DLL had a built-in 2 pixel border
if (_afxComCtlVersion < VERSION_IE4)
lpncsp->rgrc[0].top -= 2;
lpncsp->rgrc[0].right += rect.right;
lpncsp->rgrc[0].bottom += rect.bottom;
}
void CToolBar::OnBarStyleChange(DWORD dwOldStyle, DWORD dwNewStyle)
{
// a dynamically resizeable toolbar can not have the CBRS_FLOAT_MULTI
ASSERT(!((dwNewStyle & CBRS_SIZE_DYNAMIC) &&
(m_dwDockStyle & CBRS_FLOAT_MULTI)));
// a toolbar can not be both dynamic and fixed in size
ASSERT (!((dwNewStyle & CBRS_SIZE_FIXED) &&
(dwNewStyle & CBRS_SIZE_DYNAMIC)));
// CBRS_SIZE_DYNAMIC can not be disabled once it has been enabled
ASSERT (((dwOldStyle & CBRS_SIZE_DYNAMIC) == 0) ||
((dwNewStyle & CBRS_SIZE_DYNAMIC) != 0));
if (m_hWnd != NULL &&
((dwOldStyle & CBRS_BORDER_ANY) != (dwNewStyle & CBRS_BORDER_ANY)))
{
// recalc non-client area when border styles change
SetWindowPos(NULL, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_DRAWFRAME);
}
m_bDelayedButtonLayout = TRUE;
}
void CToolBar::OnNcPaint()
{
EraseNonClient();
}
void CToolBar::OnWindowPosChanging(LPWINDOWPOS lpWndPos)
{
// not necessary to invalidate the borders
DWORD dwStyle = m_dwStyle;
m_dwStyle &= ~(CBRS_BORDER_ANY);
CControlBar::OnWindowPosChanging(lpWndPos);
m_dwStyle = dwStyle;
// If we can resize while floating
if (dwStyle & CBRS_SIZE_DYNAMIC)
{
// And we are resizing
if (lpWndPos->flags & SWP_NOSIZE)
return;
// Then redraw the buttons
Invalidate();
}
}
void CToolBar::OnPaint()
{
if (m_bDelayedButtonLayout)
Layout();
Default();
}
LRESULT CToolBar::OnSetButtonSize(WPARAM, LPARAM lParam)
{
return OnSetSizeHelper(m_sizeButton, lParam);
}
LRESULT CToolBar::OnSetBitmapSize(WPARAM, LPARAM lParam)
{
return OnSetSizeHelper(m_sizeImage, lParam);
}
LRESULT CToolBar::OnSetSizeHelper(CSize& size, LPARAM lParam)
{
//WINBUG: The IE4 version of COMCTL32.DLL supports a zero border, but
// only if TBSTYLE_TRANSPARENT is on during the the TB_SETBITMAPSIZE
// and/or TB_SETBUTTONSIZE messages. In order to enable this feature
// all the time (so we get consistent border behavior, dependent only
// on the version of COMCTL32.DLL) we turn on TBSTYLE_TRANSPARENT
// whenever these messages go through. It would be nice that in a
// future version, the system toolbar would just allow you to set
// the top and left borders to anything you please.
BOOL bModify = FALSE;
ASSERT(_afxComCtlVersion != -1);
DWORD dwStyle = 0;
if (_afxComCtlVersion >= VERSION_IE4)
{
dwStyle = GetStyle();
bModify = ModifyStyle(0, TBSTYLE_TRANSPARENT|TBSTYLE_FLAT);
}
LRESULT lResult = Default();
if (lResult)
size = lParam;
if (bModify)
SetWindowLong(m_hWnd, GWL_STYLE, dwStyle);
return lResult;
}
LRESULT CToolBar::OnPreserveZeroBorderHelper(WPARAM, LPARAM)
{
BOOL bModify = FALSE;
ASSERT(_afxComCtlVersion != -1);
DWORD dwStyle = 0;
if (_afxComCtlVersion >= VERSION_IE4)
{
dwStyle = GetStyle();
bModify = ModifyStyle(0, TBSTYLE_TRANSPARENT|TBSTYLE_FLAT);
}
LRESULT lResult = Default();
if (bModify)
SetWindowLong(m_hWnd, GWL_STYLE, dwStyle);
return lResult;
}
void CToolBar::OnSysColorChange()
{
// re-color bitmap for toolbar
if (m_hInstImageWell != NULL && m_hbmImageWell != NULL)
{
HBITMAP hbmNew;
hbmNew = AfxLoadSysColorBitmap(m_hInstImageWell, m_hRsrcImageWell);
if (hbmNew != NULL)
AddReplaceBitmap(hbmNew);
}
}
/////////////////////////////////////////////////////////////////////////////
// CToolBar idle update through CToolCmdUI class
class CToolCmdUI : public CCmdUI // class private to this file !
{
public: // re-implementations only
virtual void Enable(BOOL bOn);
virtual void SetCheck(int nCheck);
virtual void SetText(LPCTSTR lpszText);
};
void CToolCmdUI::Enable(BOOL bOn)
{
m_bEnableChanged = TRUE;
CToolBar* pToolBar = (CToolBar*)m_pOther;
ASSERT(pToolBar != NULL);
ASSERT_KINDOF(CToolBar, pToolBar);
ASSERT(m_nIndex < m_nIndexMax);
UINT nNewStyle = pToolBar->GetButtonStyle(m_nIndex) & ~TBBS_DISABLED;
if (!bOn)
{
nNewStyle |= TBBS_DISABLED;
// WINBUG: If a button is currently pressed and then is disabled
// COMCTL32.DLL does not unpress the button, even after the mouse
// button goes up! We work around this bug by forcing TBBS_PRESSED
// off when a button is disabled.
nNewStyle &= ~TBBS_PRESSED;
}
ASSERT(!(nNewStyle & TBBS_SEPARATOR));
pToolBar->SetButtonStyle(m_nIndex, nNewStyle);
}
void CToolCmdUI::SetCheck(int nCheck)
{
ASSERT(nCheck >= 0 && nCheck <= 2); // 0=>off, 1=>on, 2=>indeterminate
CToolBar* pToolBar = (CToolBar*)m_pOther;
ASSERT(pToolBar != NULL);
ASSERT_KINDOF(CToolBar, pToolBar);
ASSERT(m_nIndex < m_nIndexMax);
UINT nNewStyle = pToolBar->GetButtonStyle(m_nIndex) &
~(TBBS_CHECKED | TBBS_INDETERMINATE);
if (nCheck == 1)
nNewStyle |= TBBS_CHECKED;
else if (nCheck == 2)
nNewStyle |= TBBS_INDETERMINATE;
ASSERT(!(nNewStyle & TBBS_SEPARATOR));
pToolBar->SetButtonStyle(m_nIndex, nNewStyle | TBBS_CHECKBOX);
}
void CToolCmdUI::SetText(LPCTSTR)
{
// ignore it
}
void CToolBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
{
CToolCmdUI state;
state.m_pOther = this;
state.m_nIndexMax = (UINT)DefWindowProc(TB_BUTTONCOUNT, 0, 0);
for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax; state.m_nIndex++)
{
// get buttons state
TBBUTTON button;
_GetButton(state.m_nIndex, &button);
state.m_nID = button.idCommand;
// ignore separators
if (!(button.fsStyle & TBSTYLE_SEP))
{
// allow reflections
if (CWnd::OnCmdMsg(0,
MAKELONG((int)CN_UPDATE_COMMAND_UI, WM_COMMAND+WM_REFLECT_BASE),
&state, NULL))
continue;
// allow the toolbar itself to have update handlers
if (CWnd::OnCmdMsg(state.m_nID, CN_UPDATE_COMMAND_UI, &state, NULL))
continue;
// allow the owner to process the update
state.DoUpdate(pTarget, bDisableIfNoHndler);
}
}
// update the dialog controls added to the toolbar
UpdateDialogControls(pTarget, bDisableIfNoHndler);
}
/////////////////////////////////////////////////////////////////////////////
// CToolBar diagnostics
#ifdef _DEBUG
void CToolBar::AssertValid() const
{
// Note: CControlBar::AssertValid is not called because it checks for
// m_nCount and m_pData to be in sync, which they are not in CToolBar.
ASSERT(m_hbmImageWell == NULL ||
(afxData.bWin95 || ::GetObjectType(m_hbmImageWell) == OBJ_BITMAP));
if (m_hInstImageWell != NULL && m_hbmImageWell != NULL)
ASSERT(m_hRsrcImageWell != NULL);
}
void CToolBar::Dump(CDumpContext& dc) const
{
CControlBar::Dump(dc);
dc << "m_hbmImageWell = " << (UINT)m_hbmImageWell;
dc << "\nm_hInstImageWell = " << (UINT)m_hInstImageWell;
dc << "\nm_hRsrcImageWell = " << (UINT)m_hRsrcImageWell;
dc << "\nm_sizeButton = " << m_sizeButton;
dc << "\nm_sizeImage = " << m_sizeImage;
if (dc.GetDepth() > 0)
{
CToolBar* pBar = (CToolBar*)this;
int nCount = pBar->DefWindowProc(TB_BUTTONCOUNT, 0, 0);
for (int i = 0; i < nCount; i++)
{
TBBUTTON button;
_GetButton(i, &button);
dc << "\ntoolbar button[" << i << "] = {";
dc << "\n\tnID = " << button.idCommand;
dc << "\n\tnStyle = " << MAKELONG(button.fsStyle, button.fsState);
if (button.fsStyle & TBSTYLE_SEP)
dc << "\n\tiImage (separator width) = " << button.iBitmap;
else
dc <<"\n\tiImage (bitmap image index) = " << button.iBitmap;
dc << "\n}";
}
}
dc << "\n";
}
#endif
#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif
IMPLEMENT_DYNAMIC(CToolBar, CControlBar)
/////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -