mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
608 lines
15 KiB
608 lines
15 KiB
#include "stdafx.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
CComToolBar::CComToolBar()
|
|
{
|
|
}
|
|
|
|
CToolBar::~CToolBar()
|
|
{
|
|
}
|
|
|
|
BOOL CToolBar::Create(CWnd* pParentWnd, DWORD dwStyle, UINT nID)
|
|
{
|
|
m_dwStyle = dwStyle;
|
|
if (nID == AFX_IDW_TOOLBAR)
|
|
m_dwStyle |= CBRS_HIDE_INPLACE;
|
|
|
|
// create the HWND
|
|
CRect rect;
|
|
rect.SetRectEmpty();
|
|
if (!CWnd::Create(_afxWndControlBar, NULL, dwStyle, rect, pParentWnd, nID))
|
|
return FALSE;
|
|
|
|
// Note: Parent must resize itself for control bar to be resized
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CToolBar::SetSizes(SIZE sizeButton, SIZE sizeImage)
|
|
{
|
|
ASSERT_VALID(this);
|
|
// set height
|
|
Invalidate(); // just to be nice if called when toolbar is visible
|
|
}
|
|
|
|
void CToolBar::SetHeight(int cyHeight)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
int nHeight = cyHeight;
|
|
if (m_dwStyle & CBRS_BORDER_TOP)
|
|
cyHeight -= afxData.cyBorder2;
|
|
if (m_dwStyle & CBRS_BORDER_BOTTOM)
|
|
cyHeight -= afxData.cyBorder2;
|
|
m_cyBottomBorder = (cyHeight - m_sizeButton.cy) / 2;
|
|
// if there is an extra pixel, m_cyTopBorder will get it
|
|
m_cyTopBorder = cyHeight - m_sizeButton.cy - m_cyBottomBorder;
|
|
if (m_cyTopBorder < 0)
|
|
{
|
|
TRACE1("Warning: CToolBar::SetHeight(%d) is smaller than button.\n",
|
|
nHeight);
|
|
m_cyBottomBorder += m_cyTopBorder;
|
|
m_cyTopBorder = 0; // will clip at bottom
|
|
}
|
|
// bottom border will be ignored (truncate as needed)
|
|
Invalidate(); // just to be nice if called when toolbar is visible
|
|
}
|
|
|
|
BOOL CToolBar::LoadBitmap(LPCTSTR lpszResourceName)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(lpszResourceName != NULL);
|
|
|
|
return (m_hbmImageWell != NULL);
|
|
}
|
|
|
|
BOOL CToolBar::SetButtons(const UINT* lpIDArray, int nIDCount)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(nIDCount >= 1); // must be at least one of them
|
|
ASSERT(lpIDArray == NULL ||
|
|
AfxIsValidAddress(lpIDArray, sizeof(UINT) * nIDCount, FALSE));
|
|
|
|
// first allocate array for panes and copy initial data
|
|
if (!AllocElements(nIDCount, sizeof(AFX_TBBUTTON)))
|
|
return FALSE;
|
|
ASSERT(nIDCount == m_nCount);
|
|
|
|
if (lpIDArray != NULL)
|
|
{
|
|
int iImage = 0;
|
|
// go through them adding buttons
|
|
AFX_TBBUTTON* pTBB = (AFX_TBBUTTON*)m_pData;
|
|
for (int i = 0; i < nIDCount; i++, pTBB++)
|
|
{
|
|
ASSERT(pTBB != NULL);
|
|
if ((pTBB->nID = *lpIDArray++) == 0)
|
|
{
|
|
// separator
|
|
pTBB->nStyle = TBBS_SEPARATOR;
|
|
// width of separator includes 2 pixel overlap
|
|
pTBB->iImage = m_cxDefaultGap + m_cxSharedBorder * 2;
|
|
}
|
|
else
|
|
{
|
|
// a command button with image
|
|
pTBB->nStyle = TBBS_BUTTON;
|
|
pTBB->iImage = iImage++;
|
|
}
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CToolBar attribute access
|
|
|
|
int CToolBar::CommandToIndex(UINT nIDFind) const
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
AFX_TBBUTTON* pTBB = _GetButtonPtr(0);
|
|
for (int i = 0; i < m_nCount; i++, pTBB++)
|
|
if (pTBB->nID == nIDFind)
|
|
return i;
|
|
return -1;
|
|
}
|
|
|
|
UINT CToolBar::GetItemID(int nIndex) const
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
return _GetButtonPtr(nIndex)->nID;
|
|
}
|
|
|
|
inline UINT CToolBar::_GetButtonStyle(int nIndex) const
|
|
{
|
|
return _GetButtonPtr(nIndex)->nStyle;
|
|
}
|
|
|
|
void CToolBar::_SetButtonStyle(int nIndex, UINT nStyle)
|
|
{
|
|
AFX_TBBUTTON* pTBB = _GetButtonPtr(nIndex);
|
|
UINT nOldStyle = pTBB->nStyle;
|
|
if (nOldStyle != nStyle)
|
|
{
|
|
// update the style and invalidate
|
|
pTBB->nStyle = nStyle;
|
|
|
|
// invalidate the button only if both styles not "pressed"
|
|
if (!(nOldStyle & nStyle & TBBS_PRESSED))
|
|
InvalidateButton(nIndex);
|
|
}
|
|
}
|
|
|
|
CSize CToolBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
CSize size = CControlBar::CalcFixedLayout(bStretch, bHorz);
|
|
|
|
CRect rect;
|
|
rect.SetRectEmpty(); // only need top and left
|
|
CalcInsideRect(rect, bHorz);
|
|
AFX_TBBUTTON* pTBB = (AFX_TBBUTTON*)m_pData;
|
|
int nButtonDist = 0;
|
|
|
|
if (!bStretch)
|
|
{
|
|
for (int iButton = 0; iButton < m_nCount; iButton++, pTBB++)
|
|
{
|
|
ASSERT(pTBB != NULL);
|
|
// skip this button or separator
|
|
nButtonDist += (pTBB->nStyle & TBBS_SEPARATOR) ?
|
|
pTBB->iImage : (bHorz ? m_sizeButton.cx : m_sizeButton.cy);
|
|
// go back one for overlap
|
|
nButtonDist -= bHorz ? m_cxSharedBorder : m_cySharedBorder;
|
|
}
|
|
if (bHorz)
|
|
size.cx = nButtonDist - rect.Width() + m_cxSharedBorder;
|
|
else
|
|
size.cy = nButtonDist - rect.Height() + m_cySharedBorder;
|
|
}
|
|
|
|
if (bHorz)
|
|
size.cy = m_sizeButton.cy - rect.Height(); // rect.Height() < 0
|
|
else
|
|
size.cx = m_sizeButton.cx - rect.Width(); // rect.Width() < 0
|
|
|
|
return size;
|
|
}
|
|
|
|
void CToolBar::GetButtonInfo(int nIndex, UINT& nID, UINT& nStyle, int& iImage) const
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
AFX_TBBUTTON* pTBB = _GetButtonPtr(nIndex);
|
|
nID = pTBB->nID;
|
|
nStyle = pTBB->nStyle;
|
|
iImage = pTBB->iImage;
|
|
}
|
|
|
|
void CToolBar::SetButtonInfo(int nIndex, UINT nID, UINT nStyle, int iImage)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
AFX_TBBUTTON* pTBB = _GetButtonPtr(nIndex);
|
|
pTBB->nID = nID;
|
|
pTBB->iImage = iImage;
|
|
pTBB->nStyle = nStyle;
|
|
InvalidateButton(nIndex);
|
|
}
|
|
|
|
void CToolBar::DoPaint(CDC* pDC)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT_VALID(pDC);
|
|
|
|
#ifdef _MAC
|
|
#ifdef _DEBUG
|
|
// turn off validation to speed up button drawing
|
|
int wdSav = WlmDebug(WD_NOVALIDATE | WD_ASSERT);
|
|
#endif
|
|
#endif
|
|
|
|
CControlBar::DoPaint(pDC); // draw border
|
|
|
|
BOOL bHorz = m_dwStyle & CBRS_ORIENT_HORZ ? TRUE : FALSE;
|
|
CRect rect;
|
|
GetClientRect(rect);
|
|
CalcInsideRect(rect, bHorz);
|
|
|
|
// force the full size of the button
|
|
if (bHorz)
|
|
rect.bottom = rect.top + m_sizeButton.cy;
|
|
else
|
|
rect.right = rect.left + m_sizeButton.cx;
|
|
|
|
DrawState ds;
|
|
if (!PrepareDrawButton(ds))
|
|
return; // something went wrong
|
|
|
|
AFX_TBBUTTON* pTBB = (AFX_TBBUTTON*)m_pData;
|
|
for (int iButton = 0; iButton < m_nCount; iButton++, pTBB++)
|
|
{
|
|
ASSERT(pTBB != NULL);
|
|
if (pTBB->nStyle & TBBS_SEPARATOR)
|
|
{
|
|
// separator
|
|
if (bHorz)
|
|
rect.right = rect.left + pTBB->iImage;
|
|
else
|
|
rect.bottom = rect.top + pTBB->iImage;
|
|
}
|
|
else
|
|
{
|
|
if (bHorz)
|
|
rect.right = rect.left + m_sizeButton.cx;
|
|
else
|
|
rect.bottom = rect.top + m_sizeButton.cy;
|
|
if (!afxData.bWin32s || pDC->RectVisible(&rect))
|
|
{
|
|
DrawButton(pDC, rect.left, rect.top,
|
|
pTBB->iImage, pTBB->nStyle);
|
|
}
|
|
}
|
|
// adjust for overlap
|
|
if (bHorz)
|
|
rect.left = rect.right - m_cxSharedBorder;
|
|
else
|
|
rect.top = rect.bottom - m_cySharedBorder;
|
|
}
|
|
EndDrawButton(ds);
|
|
|
|
}
|
|
|
|
UINT CToolBar::OnCmdHitTest(CPoint point, CPoint* pCenter)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
// check child windows first by calling CControlBar
|
|
UINT nHit = CControlBar::OnCmdHitTest(point, pCenter);
|
|
if (nHit != (UINT)-1)
|
|
return nHit;
|
|
|
|
// now hit test against CToolBar buttons
|
|
nHit = (UINT)HitTest(point);
|
|
if (nHit != (UINT)-1)
|
|
{
|
|
AFX_TBBUTTON* pTBB = _GetButtonPtr(nHit);
|
|
nHit = pTBB->nID;
|
|
}
|
|
return nHit;
|
|
}
|
|
|
|
int CToolBar::HitTest(CPoint point) // in window relative coords
|
|
{
|
|
BOOL bHorz = (m_dwStyle & CBRS_ORIENT_HORZ) ? TRUE : FALSE;
|
|
CRect rect;
|
|
rect.SetRectEmpty(); // only need top and left
|
|
CalcInsideRect(rect, bHorz);
|
|
AFX_TBBUTTON* pTBB = (AFX_TBBUTTON*)m_pData;
|
|
ASSERT(pTBB != NULL);
|
|
if (bHorz)
|
|
{
|
|
if (point.y < rect.top || point.y >= rect.top + m_sizeButton.cy)
|
|
return -1; // no Y hit
|
|
for (int iButton = 0; iButton < m_nCount; iButton++, pTBB++)
|
|
{
|
|
if (point.x < rect.left)
|
|
break; // missed it
|
|
rect.left += (pTBB->nStyle & TBBS_SEPARATOR) ?
|
|
pTBB->iImage : m_sizeButton.cx;
|
|
if (point.x < rect.left && !(pTBB->nStyle & TBBS_SEPARATOR))
|
|
return iButton; // hit !
|
|
rect.left -= m_cxSharedBorder; // go back for overlap
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (point.x < rect.left || point.x >= rect.left + m_sizeButton.cx)
|
|
return -1; // no X hit
|
|
for (int iButton = 0; iButton < m_nCount; iButton++, pTBB++)
|
|
{
|
|
if (point.y < rect.top)
|
|
break; // missed it
|
|
rect.top += (pTBB->nStyle & TBBS_SEPARATOR) ?
|
|
pTBB->iImage : m_sizeButton.cy;
|
|
if (point.y < rect.top && !(pTBB->nStyle & TBBS_SEPARATOR))
|
|
return iButton; // hit !
|
|
rect.top -= m_cySharedBorder; // go back for overlap
|
|
}
|
|
}
|
|
|
|
return -1; // nothing hit
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CToolBar message handlers
|
|
|
|
BEGIN_MESSAGE_MAP(CToolBar, CControlBar)
|
|
//{{AFX_MSG_MAP(CToolBar)
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_MOUSEMOVE()
|
|
ON_WM_LBUTTONUP()
|
|
ON_WM_CANCELMODE()
|
|
ON_WM_SYSCOLORCHANGE()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
void CToolBar::OnLButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
m_pointLastMove = point;
|
|
if ((m_iButtonCapture = HitTest(point)) < 0) // nothing hit
|
|
{
|
|
CControlBar::OnLButtonDown(nFlags, point);
|
|
return;
|
|
}
|
|
|
|
AFX_TBBUTTON* pTBB = _GetButtonPtr(m_iButtonCapture);
|
|
ASSERT(!(pTBB->nStyle & TBBS_SEPARATOR));
|
|
|
|
// update the button before checking for disabled status
|
|
UpdateButton(m_iButtonCapture);
|
|
if (pTBB->nStyle & TBBS_DISABLED)
|
|
{
|
|
m_iButtonCapture = -1;
|
|
return; // don't press it
|
|
}
|
|
|
|
pTBB->nStyle |= TBBS_PRESSED;
|
|
InvalidateButton(m_iButtonCapture);
|
|
UpdateWindow(); // immediate feedback
|
|
SetCapture();
|
|
GetOwner()->SendMessage(WM_SETMESSAGESTRING, (WPARAM)pTBB->nID);
|
|
}
|
|
|
|
void CToolBar::OnMouseMove(UINT /*nFlags*/, CPoint point)
|
|
{
|
|
if (m_iButtonCapture >= 0)
|
|
{
|
|
AFX_TBBUTTON* pTBB = _GetButtonPtr(m_iButtonCapture);
|
|
ASSERT(!(pTBB->nStyle & TBBS_SEPARATOR));
|
|
|
|
UINT nNewStyle = (pTBB->nStyle & ~TBBS_PRESSED);
|
|
int iButtonCapture = m_iButtonCapture;
|
|
if (GetCapture() != this)
|
|
{
|
|
m_iButtonCapture = -1; // lost capture
|
|
GetOwner()->SendMessage(WM_SETMESSAGESTRING, AFX_IDS_IDLEMESSAGE);
|
|
}
|
|
else
|
|
{
|
|
// should be pressed if still hitting the captured button
|
|
if (HitTest(point) == m_iButtonCapture)
|
|
nNewStyle |= TBBS_PRESSED;
|
|
}
|
|
_SetButtonStyle(iButtonCapture, nNewStyle);
|
|
UpdateWindow(); // immediate feedback
|
|
}
|
|
}
|
|
|
|
void CToolBar::OnLButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
if (m_iButtonCapture < 0)
|
|
{
|
|
CControlBar::OnLButtonUp(nFlags, point);
|
|
return; // not captured
|
|
}
|
|
|
|
AFX_TBBUTTON* pTBB = _GetButtonPtr(m_iButtonCapture);
|
|
ASSERT(!(pTBB->nStyle & TBBS_SEPARATOR));
|
|
UINT nIDCmd = 0;
|
|
|
|
UINT nNewStyle = (pTBB->nStyle & ~TBBS_PRESSED);
|
|
if (GetCapture() == this)
|
|
{
|
|
// we did not lose the capture
|
|
ReleaseCapture();
|
|
if (HitTest(point) == m_iButtonCapture)
|
|
{
|
|
// give button a chance to update
|
|
UpdateButton(m_iButtonCapture);
|
|
|
|
// then check for disabled state
|
|
if (!(pTBB->nStyle & TBBS_DISABLED))
|
|
{
|
|
// pressed, will send command notification
|
|
nIDCmd = pTBB->nID;
|
|
|
|
if (pTBB->nStyle & TBBS_CHECKBOX)
|
|
{
|
|
// auto check: three state => down
|
|
if (nNewStyle & TBBS_INDETERMINATE)
|
|
nNewStyle &= ~TBBS_INDETERMINATE;
|
|
|
|
nNewStyle ^= TBBS_CHECKED;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GetOwner()->SendMessage(WM_SETMESSAGESTRING, AFX_IDS_IDLEMESSAGE);
|
|
|
|
int iButtonCapture = m_iButtonCapture;
|
|
m_iButtonCapture = -1;
|
|
if (nIDCmd != 0)
|
|
GetOwner()->SendMessage(WM_COMMAND, nIDCmd); // send command
|
|
|
|
_SetButtonStyle(iButtonCapture, nNewStyle);
|
|
UpdateButton(iButtonCapture);
|
|
|
|
UpdateWindow(); // immediate feedback
|
|
}
|
|
|
|
void CToolBar::OnCancelMode()
|
|
{
|
|
CControlBar::OnCancelMode();
|
|
|
|
if (m_iButtonCapture >= 0)
|
|
{
|
|
AFX_TBBUTTON* pTBB = _GetButtonPtr(m_iButtonCapture);
|
|
ASSERT(!(pTBB->nStyle & TBBS_SEPARATOR));
|
|
UINT nNewStyle = (pTBB->nStyle & ~TBBS_PRESSED);
|
|
if (GetCapture() == this)
|
|
ReleaseCapture();
|
|
_SetButtonStyle(m_iButtonCapture, nNewStyle);
|
|
m_iButtonCapture = -1;
|
|
UpdateWindow();
|
|
}
|
|
}
|
|
|
|
void CToolBar::OnSysColorChange()
|
|
{
|
|
#ifdef _MAC
|
|
CControlBar::OnSysColorChange();
|
|
|
|
ASSERT(hDCGlyphs != NULL);
|
|
VERIFY(::DeleteDC(hDCGlyphs));
|
|
hDCGlyphs = ::CreateCompatibleDC(NULL);
|
|
|
|
ASSERT(hDCMono != NULL);
|
|
VERIFY(::DeleteDC(hDCMono));
|
|
hDCMono = ::CreateCompatibleDC(NULL);
|
|
#endif
|
|
|
|
// re-initialize global dither brush
|
|
#ifndef _MAC
|
|
HBITMAP hbmGray = ::CreateDitherBitmap();
|
|
#else
|
|
HBITMAP hbmGray = ::CreateDitherBitmap(m_bMonochrome);
|
|
#endif
|
|
if (hbmGray != NULL)
|
|
{
|
|
HBRUSH hbrNew = ::CreatePatternBrush(hbmGray);
|
|
if (hbrNew != NULL)
|
|
{
|
|
AfxDeleteObject((HGDIOBJ*)&hbrDither); // free old one
|
|
hbrDither = hbrNew;
|
|
}
|
|
::DeleteObject(hbmGray);
|
|
}
|
|
|
|
// re-color bitmap for toolbar
|
|
if (m_hbmImageWell != NULL)
|
|
{
|
|
HBITMAP hbmNew;
|
|
#ifndef _MAC
|
|
hbmNew = AfxLoadSysColorBitmap(m_hInstImageWell, m_hRsrcImageWell);
|
|
#else
|
|
hbmNew = AfxLoadSysColorBitmap(m_hInstImageWell, m_hRsrcImageWell,
|
|
m_hDCGlyphs, m_bMonochrome);
|
|
#endif
|
|
if (hbmNew != NULL)
|
|
{
|
|
::DeleteObject(m_hbmImageWell); // free old one
|
|
m_hbmImageWell = 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(pToolBar->IsKindOf(RUNTIME_CLASS(CToolBar)));
|
|
ASSERT(m_nIndex < m_nIndexMax);
|
|
|
|
UINT nNewStyle = pToolBar->_GetButtonStyle(m_nIndex) & ~TBBS_DISABLED;
|
|
if (!bOn)
|
|
nNewStyle |= TBBS_DISABLED;
|
|
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(pToolBar->IsKindOf(RUNTIME_CLASS(CToolBar)));
|
|
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)m_nCount;
|
|
for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
|
|
state.m_nIndex++)
|
|
{
|
|
AFX_TBBUTTON* pTBB = _GetButtonPtr(state.m_nIndex);
|
|
state.m_nID = pTBB->nID;
|
|
|
|
// ignore separators
|
|
if (!(pTBB->nStyle & TBBS_SEPARATOR))
|
|
state.DoUpdate(pTarget, bDisableIfNoHndler);
|
|
}
|
|
|
|
// update the dialog controls added to the toolbar
|
|
UpdateDialogControls(pTarget, bDisableIfNoHndler);
|
|
}
|
|
|
|
void CToolBar::UpdateButton(int nIndex)
|
|
{
|
|
// determine target of command update
|
|
CFrameWnd* pTarget = (CFrameWnd*)GetOwner();
|
|
if (pTarget == NULL || !pTarget->IsFrameWnd())
|
|
pTarget = GetParentFrame();
|
|
|
|
// send the update notification
|
|
if (pTarget != NULL)
|
|
{
|
|
CToolCmdUI state;
|
|
state.m_pOther = this;
|
|
state.m_nIndex = nIndex;
|
|
state.m_nIndexMax = (UINT)m_nCount;
|
|
AFX_TBBUTTON* pTBB = _GetButtonPtr(nIndex);
|
|
state.m_nID = pTBB->nID;
|
|
state.DoUpdate(pTarget, pTarget->m_bAutoMenuEnable);
|
|
}
|
|
}
|
|
|
|
IMPLEMENT_DYNAMIC(CToolBar, CControlBar)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|