📄 toolbarex.cpp
字号:
CRect rect;
GetItemRect( nIndex, &rect );
CRect rt;
pWnd->GetWindowRect(&rt);
rect.top+=max((rect.Height()-rt.Height())/2,0);
pWnd->SetWindowPos(0, rect.left, rect.top, 0, 0,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOCOPYBITS );
//pWnd->SetFont( GetFont( ));
if (bVert && m_bHideChildWndOnVertical)
{
ASSERT(GetToolBarCtrl().IsButtonHidden(id));
pWnd->ShowWindow( SW_HIDE );
}
else
{
ASSERT(!GetToolBarCtrl().IsButtonHidden(id));
pWnd->ShowWindow( SW_SHOW );
}
}
else
{
pWnd->ShowWindow( SW_HIDE);
}
//////////////////////////
pWnd=pWnd->GetNextWindow();
}
}
m_bDelayedButtonLayout = bIsDelayed;
}
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 CToolBarEx::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
{
DWORD dwMode = bStretch ? LM_STRETCH : 0;
dwMode |= bHorz ? LM_HORZ : 0;
return CalcLayout(dwMode);
}
CSize CToolBarEx::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);
}
/////////////////////////////////////////////////////////////////////////////
// CToolBarEx attribute access
void CToolBarEx::_GetButton(int nIndex, TBBUTTON* pButton) const
{
CToolBarEx* pBar = (CToolBarEx*)this;
VERIFY(pBar->DefWindowProc(TB_GETBUTTON, nIndex, (LPARAM)pButton));
// TBSTATE_ENABLED == TBBS_DISABLED so invert it
pButton->fsState ^= TBSTATE_ENABLED;
}
void CToolBarEx::_SetButton(int nIndex, TBBUTTON* pButton)
{
// get original button state
TBBUTTON button;
VERIFY(DefWindowProc(TB_GETBUTTON, nIndex, (LPARAM)&button));
// prepare for old/new button comparsion
button.bReserved[0] = 0;
button.bReserved[1] = 0;
// TBSTATE_ENABLED == TBBS_DISABLED so invert it
pButton->fsState ^= TBSTATE_ENABLED;
pButton->bReserved[0] = 0;
pButton->bReserved[1] = 0;
// nothing to do if they are the same
if (memcmp(pButton, &button, sizeof(TBBUTTON)) != 0)
{
// don't redraw everything while setting the button
DWORD dwStyle = GetStyle();
ModifyStyle(WS_VISIBLE, 0);
VERIFY(DefWindowProc(TB_DELETEBUTTON, nIndex, 0));
// Force a recalc of the toolbar's layout to work around a comctl bug
int iTextRows = (int)::SendMessage(m_hWnd, TB_GETTEXTROWS, 0, 0);
::SendMessage(m_hWnd, WM_SETREDRAW, FALSE, 0);
::SendMessage(m_hWnd, TB_SETMAXTEXTROWS, iTextRows+1, 0);
::SendMessage(m_hWnd, TB_SETMAXTEXTROWS, iTextRows, 0);
::SendMessage(m_hWnd, WM_SETREDRAW, TRUE, 0);
VERIFY(DefWindowProc(TB_INSERTBUTTON, nIndex, (LPARAM)pButton));
ModifyStyle(0, dwStyle & WS_VISIBLE);
// invalidate appropriate parts
if (((pButton->fsStyle ^ button.fsStyle) & TBSTYLE_SEP) ||
((pButton->fsStyle & TBSTYLE_SEP) && pButton->iBitmap != button.iBitmap))
{
// changing a separator
Invalidate();
}
else
{
// invalidate just the button
CRect rect;
if (DefWindowProc(TB_GETITEMRECT, nIndex, (LPARAM)&rect))
InvalidateRect(rect);
}
}
}
BOOL CToolBarEx::SetDropDownButton(UINT nID, BOOL bArrow)
{
int iButton = CommandToIndex(nID);
DWORD dwStyle = GetButtonStyle(iButton);
dwStyle |= TBSTYLE_DROPDOWN|( (!bArrow) ?BTNS_WHOLEDROPDOWN :0);
SetButtonStyle(iButton, dwStyle);
GetToolBarCtrl().SetExtendedStyle(GetToolBarCtrl().GetExtendedStyle() |TBSTYLE_EX_DRAWDDARROWS);
return TRUE;
}
BOOL CToolBarEx::IsVertDocked()
{
UINT nID =GetParent()->GetDlgCtrlID();
return ( (nID ==AFX_IDW_DOCKBAR_LEFT) || (nID== AFX_IDW_DOCKBAR_RIGHT));
}
void CToolBarEx::OnPaint()
{
CToolBar::OnPaint();
//I have to use this, as there is not customdraw mesasges for seperators
// draw the controls seperator again to hide it
for (int i=0;i<GetToolBarCtrl().GetButtonCount();i++)
{
TBBUTTON tb;
GetToolBarCtrl().GetButton(i,&tb);
//only for seperators
if ( ((tb.fsStyle & TBSTYLE_SEP) == TBSTYLE_SEP) &&
(tb.idCommand!=0) )
{
CRect rc;
GetItemRect(i,rc);
CClientDC dc(this);
// draw the separator bar in the middle
int x = (rc.left + rc.right) / 2;
rc.left = x-1; rc.right = x+1;
dc.FillSolidRect(rc, m_clrBtnFace);
}
}
}
void CToolBarEx::SetTextOptions(TextOptions eTextOptions, BOOL bUpdate)
{
ASSERT( ::IsWindow( m_hWnd ) );
ASSERT( eTextOptions != toNone );
m_eTextOptions = eTextOptions;
// Modify toolbar style according to new text options
ModifyStyle(
( eTextOptions == toTextOnRight ) ? 0 : TBSTYLE_LIST,
( eTextOptions == toTextOnRight ) ? TBSTYLE_LIST : 0 );
CToolBarCtrl& tbCtrl = GetToolBarCtrl();
DWORD dwStyleEx = tbCtrl.GetExtendedStyle();
tbCtrl.SetExtendedStyle(
( eTextOptions == toTextOnRight ) ?
( dwStyleEx | TBSTYLE_EX_MIXEDBUTTONS ) :
( dwStyleEx & ~TBSTYLE_EX_MIXEDBUTTONS ) );
for(int i=0;i<m_ToolBarInfo.GetSize();i++)
{
// if ((m_ToolBarInfo[i].tbButton.fsStyle & TBSTYLE_SEP) != TBSTYLE_SEP)
{
int nIndex= CommandToIndex(m_ToolBarInfo[i].tbButton.idCommand);
if (nIndex>-1) // buton is there on bar
{
TBBUTTON tbinfo;
_GetButton(nIndex,&tbinfo);
if ( !( tbinfo.fsStyle & TBSTYLE_SEP ) ) //check again
{
// attempt to lookup string index in map
int nString = -1;
if ((eTextOptions==toTextLabels) || ((eTextOptions==toTextOnRight)))
{
void* p=NULL;
CString strTemp(m_ToolBarInfo[i].btnText);
if (m_pStringMap != NULL && m_pStringMap->Lookup(strTemp, 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;
ASSERT(m_pStringMap);
}
// add new string to toolbar list
nString = (int)DefWindowProc(TB_ADDSTRING, 0, (LPARAM)(LPCTSTR)strTemp);
if (nString != -1)
{
// cache string away in string map
m_pStringMap->SetAt(strTemp, (void*)nString);
ASSERT(m_pStringMap->Lookup(strTemp, p));
}
}
}
switch ( eTextOptions )
{
case toTextLabels:
{
tbinfo.iString =nString;
tbinfo.fsStyle &= ~BTNS_SHOWTEXT;
tbinfo.fsStyle |= TBSTYLE_AUTOSIZE;
}
break;
case toTextOnRight:
{
if ((nString!=-1) &&
(HasButtonText(m_ToolBarInfo[i].tbButton.idCommand)))
{
tbinfo.iString =nString;
tbinfo.fsStyle |= ( TBSTYLE_AUTOSIZE |BTNS_SHOWTEXT );
}
else
{
tbinfo.fsStyle &= ~BTNS_SHOWTEXT;
tbinfo.fsStyle |= TBSTYLE_AUTOSIZE;
}
}
break;
case toNoTextLabels:
{
tbinfo.iString= -1; //Set string to zero
tbinfo.fsStyle &= ~BTNS_SHOWTEXT;
tbinfo.fsStyle |= TBSTYLE_AUTOSIZE;
}
break;
default:
ASSERT(FALSE); // anew type added
}
//Delete & add the button
{
tbinfo.fsState ^= TBSTATE_ENABLED;
m_ToolBarInfo[i].tbButton=tbinfo;
tbinfo.fsState ^= TBSTATE_ENABLED;
_SetButton(nIndex,&tbinfo);
}
}
}
}
}
int iTextRows = 0;
// now total setting
switch ( eTextOptions )
{
case toTextLabels:
{
iTextRows=1;
}
break;
case toTextOnRight:
{
iTextRows=1;
}
break;
case toNoTextLabels:
{
iTextRows=0;
}
break;
default:
ASSERT(FALSE); // anew type added
}
::SendMessage(m_hWnd, TB_SETMAXTEXTROWS, iTextRows, 0);
// If requested, reflect changes immediately
if ( bUpdate )
{
PositionControls();
GetParentFrame()->RecalcLayout();
OnIdleUpdateCmdUI(TRUE, 0L);
}
}
void CToolBarEx::SetIconOptions(IconOptions eIconOptions, BOOL bUpdate)
{
ASSERT( ::IsWindow( m_hWnd ) );
ASSERT( eIconOptions != ioNone );
m_eIconOptions = eIconOptions;
switch(eIconOptions)
{
case ioSmallIcons:
m_sizeImage= m_szImageSmall ;
SetIconOptionBitmap(ioSmallIcons);
GetToolBarCtrl().SetBitmapSize(m_szImageSmall);
break;
case ioLargeIcons:
m_sizeImage= m_szImageLarge ;
SetIconOptionBitmap(ioLargeIcons);
GetToolBarCtrl().SetBitmapSize(m_szImageLarge);
break;
}
// Force a recalc of the toolbar's layout to work around a comctl bug
int iTextRows = (int)::SendMessage(m_hWnd, TB_GETTEXTROWS, 0, 0);
::SendMessage(m_hWnd, WM_SETREDRAW, FALSE, 0);
::SendMessage(m_hWnd, TB_SETMAXTEXTROWS, iTextRows+1, 0);
::SendMessage(m_hWnd, TB_SETMAXTEXTROWS, iTextRows, 0);
::SendMessage(m_hWnd, WM_SETREDRAW, TRUE, 0);
// If requested, reflect changes immediately
if ( bUpdate )
{
PositionControls();
GetParentFrame()->RecalcLayout();
OnIdleUpdateCmdUI(TRUE, 0L);
}
}
//static ftn for Hook
LRESULT CALLBACK CToolBarEx::CBTProc( int nCode, WPARAM wParam, LPARAM lParam )
{
ASSERT( m_pCustomizeDlg != NULL );
try
{
if ( ( nCode == HCBT_CREATEWND ) && (m_pCustomizeDlg) && ( m_pCustomizeDlg->m_hWnd == 0 ) )
{
// This is where we have a good chance to subclass standard
// "Customize toolbar" dialog in order to add to it some of
// our new features (ie. text and icon options selectors)
HWND hWnd = ( HWND )wParam;
VERIFY( m_pCustomizeDlg->SubclassWindow( hWnd ) );
}
}
catch(...) // if exception is not caught then we can get in infinite loop as assert window is opened.
{
TRACE0(_T("Exception thrown while Hooking-Extra Custom features unavaialble.\n"));
//Call next
LRESULT lResult=::CallNextHookEx( m_hCBTHook, nCode, wParam, lParam );
VERIFY( ::UnhookWindowsHookEx( m_hCBTHook ) );
m_hCBTHook = 0;
if (m_pCustomizeDlg) delete m_pCustomizeDlg;
m_pCustomizeDlg = NULL;
return lResult;
}
return ::CallNextHookEx( m_hCBTHook, nCode, wParam, lParam );
}
// has to override this
BOOL CToolBarEx::HasButtonText(int nID)
{
nID;
return TRUE;
}
/*
DIBs use RGBQUAD format:
0xbb 0xgg 0xrr 0x00
Reasonably efficient code to convert a COLORREF into an
RGBQUAD is byte-order-dependent, so we need different
code depending on the byte order we're targeting.
*/
#define RGB_TO_RGBQUAD(r,g,b) (RGB(b,g,r))
#define CLR_TO_RGBQUAD(clr) (RGB(GetBValue(clr), GetGValue(clr), GetRValue(clr)))
struct AFX_COLORMAP
{
// use DWORD instead of RGBQUAD so we can compare two RGBQUADs easily
DWORD rgbqFrom;
int iSysColorTo;
};
const AFX_COLORMAP _afxSysColorMap[] =
{
// mapping from color in DIB to system color
{ RGB_TO_RGBQUAD(0x00, 0x00, 0x00), COLOR_BTNTEXT }, // black
{ RGB_TO_RGBQUAD(0x80, 0x80, 0x80), COLOR_BTNSHADOW }, // dark gray
{ RGB_TO_RGBQUAD(0xC0, 0xC0, 0xC0), COLOR_BTNFACE }, // bright gray
{ RGB_TO_RGBQUAD(0xFF, 0xFF, 0xFF), COLOR_BTNHIGHLIGHT } // white
};
static HBITMAP AfxLoadSysColorBitmapSize(HINSTANCE hInst, HRSRC hRsrc,CSize sz)
{
HGLOBAL hglb;
if ((hglb = LoadResource(hInst, hRsrc)) == NULL)
return NULL;
LPBITMAPINFOHEADER lpBitmap = (LPBITMAPINFOHEADER)LockResource(hglb);
if (lpBitmap == NULL)
return NULL;
// make copy of BITMAPINFOHEADER so we can modify the color table
const int nColorTableSize = 16;
UINT nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
LPBITMAPINFOHEADER lpBitmapInfo = (LPBITMAPINFOHEADER)::malloc(nSize);
if (lpBitmapInfo == NULL) return NULL;
memcpy(lpBitmapInfo, lpBitmap, nSize);
// color table is in RGBQUAD DIB format
DWORD* pColorTable =
(DWORD*)(((LPBYTE)lpBitmapInfo) + (UINT)lpBitmapInfo->biSize);
for (int iColor = 0; iColor < nColorTableSize; iColor++)
{
// look for matching RGBQUAD color in original
for (int i = 0; i < sizeof(_afxSysColorMap)/sizeof(_afxSysColorMap[0]); i++)
{
if (pColorTable[iColor] == _afxSysColorMap[i].rgbqFrom)
{
pColorTable[iColor] =
CLR_TO_RGBQUAD(::GetSysColor(_afxSysColorMap[i].iSysColorTo));
break;
}
}
}
int nWidth = (int)lpBitmapInfo->biWidth;
int nHeight = (int)lpBitmapInfo->biHeight;
HDC hDCScreen = ::GetDC(NULL);
HBITMAP hbm = ::CreateCompatibleBitmap(hDCScreen, sz.cx, sz.cy);
if (hbm != NULL)
{
HDC hDCGlyphs = ::CreateCompatibleDC(hDCScreen);
HBITMAP hbmOld = (HBITMAP)::SelectObject(hDCGlyphs, hbm);
LPBYTE lpBits;
lpBits = (LPBYTE)(lpBitmap + 1);
lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);
StretchDIBits(hDCGlyphs, 0, 0, sz.cx, sz.cy, 0, 0, nWidth, nHeight,
lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS, SRCCOPY);
SelectObject(hDCGlyphs, hbmOld);
::DeleteDC(hDCGlyphs);
}
::ReleaseDC(NULL, hDCScreen);
// free copy of bitmap info struct and resource itself
::free(lpBitmapInfo);
::FreeResource(hglb);
return hbm;
}
BOOL CToolBarEx::SetIconOptionBitmap(IconOptions eIconOptions)
{
if ((m_hInstImageWell != NULL) && (m_hRsrcImageWell != NULL))
{
HBITMAP hBitmap=NULL;
HINSTANCE hInstImageWell= m_hInstImageWell ;
HRSRC hRsrcImageWell = m_hRsrcImageWell ;
int nCount = 0;
for(UINT i=0;i<m_nResButtons;i++)
{
if ((m_ToolBarInfo[i].tbButton.idCommand !=0))
nCount++;
}
if (eIconOptions==ioSmallIcons)
{
CSize sizeSmallImage(nCount *m_szImageSmall.cx,m_szImageSmall.cy);
hBitmap= AfxLoadSysColorBitmapSize(m_hInstImageWell, m_hRsrcImageWell,sizeSmallImage);
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -