📄 toolbarex.cpp
字号:
if( nBefore < 0 || nBefore > wndToolBarCtrl.GetButtonCount() )
bAppend = TRUE;
int nWidth = rc.Width();
if( nWidth < 0 )
nWidth = -nWidth;
TBBUTTON tbButton;
tbButton.iBitmap = nWidth;
tbButton.idCommand = ID;
tbButton.fsState = TBSTATE_ENABLED;
tbButton.fsStyle = TBSTYLE_SEP;
tbButton.dwData = 0;
tbButton.iString = 0;
if( bAppend )
wndToolBarCtrl.AddButtons(1, &tbButton);
else
wndToolBarCtrl.InsertButton(nBefore, &tbButton);
CWnd * pCtrl = CreateControl(pClass, rc, ID, dwStyle);
return pCtrl;
}
CWnd * CToolBarEx :: CreateControl(
CRuntimeClass * pClass,
CRect & rc,
UINT ID,
DWORD dwStyle) {
if( ! pClass || ! pClass->IsDerivedFrom(RUNTIME_CLASS(CWnd)) ) {
TRACE0("CToolBarEx::CreateControl(): given class is NULL or not derived from CWnd.\n");
return 0;
}
CWnd * pCtrl = 0;
BOOL bSelfDeleting = TRUE;
CString strClass = pClass->m_lpszClassName;
if( strClass == TEXT("CComboBox") ) {
pCtrl = new CComboBox();
bSelfDeleting = FALSE;
} else if( strClass == TEXT("CEdit") ) {
pCtrl = new CEdit();
bSelfDeleting = FALSE;
} else {
pCtrl = (CWnd *)pClass->CreateObject();
if( pCtrl == 0 ) {
TRACE1("CToolBarEx::CreateControl(): dynamic create of control %hs failed.\n",
pClass->m_lpszClassName);
return 0;
}
}
// create the control itself
CRect rect = rc;
BOOL bCreate = FALSE;
if( pCtrl->IsKindOf(RUNTIME_CLASS(CComboBox)) )
bCreate = ((CComboBox*)pCtrl)->Create(WS_CHILD|WS_VISIBLE|dwStyle, rect, this, ID);
else if( pCtrl->IsKindOf(RUNTIME_CLASS(CEdit)) )
bCreate = ((CEdit*)pCtrl)->Create(WS_CHILD|WS_VISIBLE|dwStyle, rect, this, ID);
else
bCreate = pCtrl->Create(0, 0, WS_CHILD|WS_VISIBLE|dwStyle, rect, this, ID);
if( ! bCreate ) {
TRACE1("CToolBarEx::CreateControl(): could not Create() control.\n,", ID);
if( ! bSelfDeleting )
delete pCtrl;
return 0;
}
if( ! bSelfDeleting ) {
// we have to remember this control, so we can delete it later
if( ! m_pControls )
m_pControls = new CObList();
m_pControls->AddTail(pCtrl);
}
RepositionControls();
return pCtrl;
}
void CToolBarEx :: RepositionControls() {
// Walk all descendents.
for( CWnd * pWnd = GetWindow(GW_CHILD); pWnd; pWnd = pWnd->GetNextWindow() ) {
// If that window is a child of this
// toolbar, then reposition this control.
if( pWnd->GetParent() == this ) {
DWORD dwID = ::GetWindowLong(pWnd->GetSafeHwnd(), GWL_ID);
int idx = CommandToIndex(dwID);
ASSERT(idx >= 0);
CRect rc;
GetItemRect(idx, rc);
pWnd->SetWindowPos(0, rc.left, rc.top, 0, 0, SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOCOPYBITS);
pWnd->ShowWindow(SW_SHOW);
}
}
}
void CToolBarEx :: RecalcLayout() {
// Recalculate the size of the bar.
BOOL bHorz = (m_dwStyle & CBRS_ORIENT_HORZ) != 0;
if ((m_dwStyle & CBRS_FLOATING) && (m_dwStyle & CBRS_SIZE_DYNAMIC))
CalcDynamicLayout(0, LM_HORZ | LM_MRUWIDTH | LM_COMMIT);
else if (bHorz)
CalcDynamicLayout(0, LM_HORZ | LM_HORZDOCK | LM_COMMIT);
else
CalcDynamicLayout(0, LM_VERTDOCK | LM_COMMIT);
RepositionControls();
// recalculate the parent frame
if( m_dwStyle & CBRS_FLOATING ) {
ASSERT(m_pDockBar != 0);
((CMiniDockFrameWnd *)m_pDockBar->GetParent())->RecalcLayout();
} else {
((CFrameWnd*)GetParentFrame())->RecalcLayout();
}
}
HBITMAP CToolBarEx :: GetBitmap(int nBtnID) {
int nBitmap = SendMessage(TB_GETBITMAP, WPARAM(nBtnID));
return GetBitmap(nBitmap, m_sizeImage);
}
HBITMAP CToolBarEx :: GetBitmap(int nIndex, const CSize & sizeBitmap) {
HIMAGELIST hImgList = GetImageList();
if( ! hImgList )
return 0;
CImageList imglist;
imglist.Attach(hImgList);
HICON hIcon = imglist.ExtractIcon(nIndex);
CBitmap bmp;
if( hIcon ) {
CClientDC cdc(this) ;
CDC dc;
dc.CreateCompatibleDC(&cdc);
VERIFY(bmp.CreateCompatibleBitmap(&cdc, sizeBitmap.cx, sizeBitmap.cy));
CBitmap* pOldBmp = dc.SelectObject(&bmp);
CBrush brush ;
VERIFY(brush.CreateSolidBrush(m_clrBtnFace));
::DrawIconEx(
dc.GetSafeHdc(),
0,
0,
hIcon,
sizeBitmap.cx,
sizeBitmap.cy,
0,
(HBRUSH)brush,
DI_NORMAL
);
dc.SelectObject( pOldBmp );
dc.DeleteDC();
// the icon is not longer needed
DestroyIcon(hIcon);
} else
TRACE1("CToolBarEx::GetBitmap(): unable to extract bitmap with index %d\n", nIndex);
if( ! m_bDeleteImgList )
imglist.Detach();
return hIcon ? HBITMAP(bmp.Detach()) : 0;
}
LRESULT CToolBarEx::OnAddBitmap(WPARAM wParam, LPARAM lParam) {
// work around a bug in CToolBar:
// if one calls CToolBar::GetToolBarCtrl().AddBitmap(...),
// then CToolBar does not realize this. This can lead to
// confusing button images ...
int nButtons = int(wParam);
LPTBADDBITMAP pAddBmp = LPTBADDBITMAP(lParam);
if( pAddBmp->hInst != HINST_COMMCTRL ) {
// This workaround does not work, if one
// specifies "HINST_COMMCTRL" to the "hInst"
// member of pAddBmp, because we cannot access
// the internals of commctl32.dll ...
TRACE0("Adding a bitmap\n");
HBITMAP hBitmap;
if( pAddBmp->hInst != 0 )
// Have to load the bitmap "pAddBmp->nID"
// contains the resource-ID of the bitmap.
hBitmap = ::LoadBitmap(pAddBmp->hInst, MAKEINTRESOURCE(pAddBmp->nID));
else
// "pAddBmp->nID" is the handle of the bitmap.
hBitmap = HBITMAP(pAddBmp->nID);
if(hBitmap == 0)
return HRESULT(-1);
// You really should use CToolBarEx as a replacement for
// CToolBar. So make sure you have set up a toolbar
// properly before you begin to customize it.
ASSERT(m_hbmImageWell);
// retrieve number of images currently stored in CToolBar
BITMAP bitmap;
VERIFY(::GetObject(m_hbmImageWell, sizeof(BITMAP), &bitmap));
int nImageCount = bitmap.bmWidth / m_sizeImage.cx;
CClientDC cdc(this);
CDC dcOld, dcNew;
dcOld.CreateCompatibleDC(&cdc);
dcNew.CreateCompatibleDC(&cdc);
HGDIOBJ hOldBmp = ::SelectObject(dcOld.GetSafeHdc(), m_hbmImageWell);
// create the new bitmap and make it big enough to
// hold all images (old+new)
CBitmap bmpNew;
bmpNew.CreateCompatibleBitmap(
&cdc,
bitmap.bmWidth + nButtons * m_sizeImage.cx,
m_sizeImage.cy);
CBitmap * pbmpNew = dcNew.SelectObject(&bmpNew);
dcNew.BitBlt(0,0,bitmap.bmWidth,bitmap.bmHeight,&dcOld,0,0,SRCCOPY);
::SelectObject(dcOld.GetSafeHdc(), hBitmap);
dcNew.BitBlt(bitmap.bmWidth,0,m_sizeImage.cx*nButtons,bitmap.bmHeight,&dcOld,0,0,SRCCOPY);
::SelectObject(dcOld.GetSafeHdc(), hOldBmp);
dcNew.SelectObject(pbmpNew);
dcOld.DeleteDC();
dcNew.DeleteDC();
VERIFY(bmpNew.GetObject(sizeof(BITMAP), &bitmap));
HRESULT hRes = DefWindowProc(TB_ADDBITMAP, wParam, lParam);
// syncronize toolbarcontrol's bitmap with our's
AddReplaceBitmap(HBITMAP(bmpNew.Detach()));
return HRESULT(nImageCount);
}
return DefWindowProc(TB_ADDBITMAP, wParam, lParam);
}
// intercept TB_DELETEBUTTON, so we can delete controls too.
LRESULT CToolBarEx::OnDeleteButton(WPARAM wParam, LPARAM lParam) {
CWnd * pControl = GetControl(int(wParam));
if( pControl ) {
// this is the control associated with the button to delete
BOOL bMustDelete = FALSE;
if( m_pControls ) {
// It is really a good idea to add a control via the
// CToolBarEx own members. This will guarantee that
// all resources are freed.
POSITION pos = m_pControls->Find(pControl);
if( pos ) {
m_pControls->RemoveAt(pos);
bMustDelete = TRUE;
}
}
pControl->DestroyWindow();
if( bMustDelete )
delete pControl;
}
return DefWindowProc(TB_DELETEBUTTON, wParam, lParam);
}
#ifdef _MEMDC_H_
BOOL CToolBarEx::OnEraseBkgnd(CDC* pDC)
{
return IsFlatLook() ? FALSE : CToolBar::OnEraseBkgnd(pDC);
}
#endif
/////////////////////////////////////////////////////////////////////////////
// ALT-drag
// To prevent the users of CToolBarEx from inserting cursor-resources, we
// create the cursors on the fly. This makes usage of CToolBarEx as easy as
// possible:
static const BYTE ANDmaskDrop[] = {
0xFF, 0xFF, 0xFF, 0xFF, // line 1
0xFF, 0xFF, 0xFF, 0xFF, // line 2
0xF3, 0xFF, 0xFF, 0xFF, // line 3
0xF1, 0xFF, 0xFF, 0xFF, // line 4
0xF0, 0xFF, 0xFF, 0xFF, // line 5
0xF0, 0x7F, 0xFF, 0xFF, // line 6
0xF0, 0x3F, 0xFF, 0xFF, // line 7
0xF0, 0x1F, 0xFF, 0xFF, // line 8
0xF0, 0x0F, 0xFF, 0xFF, // line 9
0xF0, 0x07, 0xFF, 0xFF, // line 10
0xF0, 0x03, 0xFF, 0xFF, // line 11
0xF0, 0x01, 0xFF, 0xFF, // line 12
0xF0, 0x00, 0xFF, 0xFF, // line 13
0xF0, 0x0F, 0xFF, 0xFF, // line 14
0xF0, 0x0F, 0xFF, 0xFF, // line 15
0xF1, 0x07, 0xFF, 0xFF, // line 16
0xF3, 0x07, 0xFF, 0xFF, // line 17
0xF6, 0x00, 0x00, 0x3F, // line 18
0xFE, 0x00, 0x00, 0x3F, // line 19
0xFE, 0x00, 0x00, 0x3F, // line 20
0xFE, 0x00, 0x00, 0x3F, // line 21
0xFE, 0x00, 0x00, 0x3F, // line 22
0xFE, 0x00, 0x00, 0x3F, // line 23
0xFE, 0x00, 0x00, 0x3F, // line 24
0xFE, 0x00, 0x00, 0x3F, // line 25
0xFE, 0x00, 0x00, 0x3F, // line 26
0xFF, 0xFF, 0xFF, 0xFF, // line 27
0xFF, 0xFF, 0xFF, 0xFF, // line 28
0xFF, 0xFF, 0xFF, 0xFF, // line 29
0xFF, 0xFF, 0xFF, 0xFF, // line 30
0xFF, 0xFF, 0xFF, 0xFF, // line 31
0xFF, 0xFF, 0xFF, 0xFF // line 32
};
static const BYTE XORmaskDrop[] = {
0x00, 0x00, 0x00, 0x00, // line 1
0x00, 0x00, 0x00, 0x00, // line 2
0x00, 0x00, 0x00, 0x00, // line 3
0x04, 0x00, 0x00, 0x00, // line 4
0x06, 0x00, 0x00, 0x00, // line 5
0x07, 0x00, 0x00, 0x00, // line 6
0x07, 0x80, 0x00, 0x00, // line 7
0x07, 0xC0, 0x00, 0x00, // line 8
0x07, 0xE0, 0x00, 0x00, // line 9
0x07, 0xF0, 0x00, 0x00, // line 10
0x07, 0xF8, 0x00, 0x00, // line 11
0x07, 0xFC, 0x00, 0x00, // line 12
0x07, 0xE0, 0x00, 0x00, // line 13
0x07, 0x60, 0x00, 0x00, // line 14
0x06, 0x60, 0x00, 0x00, // line 15
0x04, 0x30, 0x00, 0x00, // line 16
0x00, 0x30, 0x00, 0x00, // line 17
0x00, 0x18, 0x00, 0x00, // line 18
0x00, 0xDD, 0xFF, 0x00, // line 19
0x00, 0xAC, 0xAA, 0x00, // line 20
0x00, 0xCD, 0x55, 0x00, // line 21
0x00, 0xA0, 0xAA, 0x00, // line 22
0x00, 0xD5, 0x55, 0x00, // line 23
0x00, 0xAA, 0xAA, 0x00, // line 24
0x00, 0x00, 0x00, 0x00, // line 25
0x00, 0x00, 0x00, 0x00, // line 26
0x00, 0x00, 0x00, 0x00, // line 27
0x00, 0x00, 0x00, 0x00, // line 28
0x00, 0x00, 0x00, 0x00, // line 29
0x00, 0x00, 0x00, 0x00, // line 30
0x00, 0x00, 0x00, 0x00, // line 31
0x00, 0x00, 0x00, 0x00 // line 32
};
static const BYTE ANDmaskNoDrop[] = {
0xFF, 0xFF, 0xFF, 0xFF, // line 1
0xFF, 0xFF, 0xFF, 0xFF, // line 2
0xF3, 0xFF, 0xFF, 0xFF, // line 3
0xF1, 0xFF, 0xFF, 0xFF, // line 4
0xF0, 0xFF, 0xFF, 0xFF, // line 5
0xF0, 0x7F, 0xFF, 0xFF, // line 6
0xF0, 0x3F, 0xFF, 0xFF, // line 7
0xF0, 0x1F, 0xFF, 0xFF, // line 8
0xF0, 0x0F, 0xFF, 0xFF, // line 9
0xF0, 0x07, 0xFF, 0xFF, // line 10
0xF0, 0x03, 0xFF, 0xFF, // line 11
0xF0, 0x01, 0xFF, 0xFF, // line 12
0xF0, 0x00, 0xFF, 0xFF, // line 13
0xF0, 0x0F, 0xFF, 0xFF, // line 14
0xF0, 0x0F, 0xFF, 0xFF, // line 15
0xF1, 0x07, 0xFF, 0xFF, // line 16
0xF3, 0x07, 0xFF, 0xFF, // line 17
0xF6, 0x00, 0x00, 0x3F, // line 18
0xFE, 0x00, 0x00, 0x3F, // line 19
0xFE, 0x00, 0x00, 0x3F, // line 20
0xFE, 0x00, 0x00, 0x3F, // line 21
0xFE, 0x00, 0x00, 0x0F, // line 22
0xFE, 0x00, 0x00, 0x0F, // line 23
0xFE, 0x00, 0x00, 0x0F, // line 24
0xFE, 0x00, 0x00, 0x0F, // line 25
0xFE, 0x00, 0x00, 0x0F, // line 26
0xFF, 0xFF, 0x80, 0x0F, // line 27
0xFF, 0xFF, 0x80, 0x0F, // line 28
0xFF, 0xFF, 0x80, 0x0F, // line 29
0xFF, 0xFF, 0x80, 0x0F, // line 30
0xFF, 0xFF, 0x80, 0x0F, // line 31
0xFF, 0xFF, 0x80, 0x0F // line 32
};
static const BYTE XORmaskNoDrop[] = {
0x00, 0x00, 0x00, 0x00, // line 1
0x00, 0x00, 0x00, 0x00, // line 2
0x00, 0x00, 0x00, 0x00, // line 3
0x04, 0x00, 0x00, 0x00, // line 4
0x06, 0x00, 0x00, 0x00, // line 5
0x07, 0x00, 0x00, 0x00, // line 6
0x07, 0x80, 0x00, 0x00, // line 7
0x07, 0xC0, 0x00, 0x00, // line 8
0x07, 0xE0, 0x00, 0x00, // line 9
0x07, 0xF0, 0x00, 0x00, // line 10
0x07, 0xF8, 0x00, 0x00, // line 11
0x07, 0xFC, 0x00, 0x00, // line 12
0x07, 0xE0, 0x00, 0x00, // line 13
0x07, 0x60, 0x00, 0x00, // line 14
0x06, 0x60, 0x00, 0x00, // line 15
0x04, 0x30, 0x00, 0x00, // line 16
0x00, 0x30, 0x00, 0x00, // line 17
0x00, 0x18, 0x00, 0x00, // line 18
0x00, 0xDD, 0xFF, 0x00, // line 19
0x00, 0xAC, 0xAA, 0x00, // line 20
0x00, 0xCD, 0x55, 0x00, // line 21
0x00, 0xA0, 0x80, 0x00, // line 22
0x00, 0xD5, 0x3F, 0xE0, // line 23
0x00, 0xAA, 0xA7, 0x20, // line 24
0x00, 0x00, 0x22, 0x20, // line 25
0x00, 0x00, 0x30, 0x60, // line 26
0x00, 0x00, 0x38, 0xE0, // line 27
0x00, 0x00, 0x30, 0x60, // line 28
0x00, 0x00, 0x22, 0x20, // line 29
0x00, 0x00, 0x27, 0x20, // line 30
0x00, 0x00, 0x3F, 0xE0, // line 31
0x00, 0x00, 0x00, 0x00 // line 32
};
void CToolBarEx::OnLButtonDown(UINT nFlags, CPoint point)
{
if( ::GetAsyncKeyState(VK_MENU) & (1<<15) )
// one of the ALT keys is pressed too - begin drag operation
if( BeginDrag() )
return;
if( ::GetAsyncKeyState(VK_SHIFT) & (1<<15) )
// disable the old-style drag
return;
CToolBar::OnLButtonDown(nFlags, point);
}
void CToolBarEx::OnLButtonUp(UINT nFlags, CPoint point)
{
if( m_bDragging )
EndDrag();
else
CToolBar::OnLButtonUp(nFlags, point);
}
BOOL CToolBarEx :: BeginDrag() {
TRACE0("beginning drag operation\n");
VERIFY(!m_hDragCursor);
VERIFY(!m_hNoDragCursor);
if( !(::GetWindowLong(GetToolBarCtrl().GetSafeHwnd(),GWL_STYLE) & CCS_ADJUSTABLE) )
return FALSE; // Bar is not adjustable
register const int nBtn = GetToolBarCtrl().GetButtonCount();
const int nLastBtn = m_nLastBtn;
m_nLastBtn = -1;
CPoint pt;
::GetCursorPos(&pt);
ScreenToClient(&pt);
m_nDragButton = -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -