tbar95.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,707 行 · 第 1/4 页
CPP
1,707 行
// Realize() later
tool->Attach(this);
InvalidateBestSize();
return true;
}
bool wxToolBar::DoDeleteTool(size_t pos, wxToolBarToolBase *tool)
{
// the main difficulty we have here is with the controls in the toolbars:
// as we (sometimes) use several separators to cover up the space used by
// them, the indices are not the same for us and the toolbar
// first determine the position of the first button to delete: it may be
// different from pos if we use several separators to cover the space used
// by a control
wxToolBarToolsList::compatibility_iterator node;
for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
{
wxToolBarToolBase *tool2 = node->GetData();
if ( tool2 == tool )
{
// let node point to the next node in the list
node = node->GetNext();
break;
}
if ( tool2->IsControl() )
{
pos += ((wxToolBarTool *)tool2)->GetSeparatorsCount() - 1;
}
}
// now determine the number of buttons to delete and the area taken by them
size_t nButtonsToDelete = 1;
// get the size of the button we're going to delete
RECT r;
if ( !::SendMessage(GetHwnd(), TB_GETITEMRECT, pos, (LPARAM)&r) )
{
wxLogLastError(_T("TB_GETITEMRECT"));
}
int width = r.right - r.left;
if ( tool->IsControl() )
{
nButtonsToDelete = ((wxToolBarTool *)tool)->GetSeparatorsCount();
width *= nButtonsToDelete;
tool->GetControl()->Destroy();
}
// do delete all buttons
m_nButtons -= nButtonsToDelete;
while ( nButtonsToDelete-- > 0 )
{
if ( !::SendMessage(GetHwnd(), TB_DELETEBUTTON, pos, 0) )
{
wxLogLastError(wxT("TB_DELETEBUTTON"));
return false;
}
}
tool->Detach();
// and finally reposition all the controls after this button (the toolbar
// takes care of all normal items)
for ( /* node -> first after deleted */ ; node; node = node->GetNext() )
{
wxToolBarToolBase *tool2 = node->GetData();
if ( tool2->IsControl() )
{
int x;
wxControl *control = tool2->GetControl();
control->GetPosition(&x, NULL);
control->Move(x - width, wxDefaultCoord);
}
}
InvalidateBestSize();
return true;
}
void wxToolBar::CreateDisabledImageList()
{
// as we can't use disabled image list with older versions of comctl32.dll,
// don't even bother creating it
if ( wxTheApp->GetComCtl32Version() >= 470 )
{
// search for the first disabled button img in the toolbar, if any
for ( wxToolBarToolsList::compatibility_iterator
node = m_tools.GetFirst(); node; node = node->GetNext() )
{
wxToolBarToolBase *tool = node->GetData();
wxBitmap bmpDisabled = tool->GetDisabledBitmap();
if ( bmpDisabled.Ok() )
{
m_disabledImgList = new wxImageList
(
m_defaultWidth,
m_defaultHeight,
bmpDisabled.GetMask() != NULL,
GetToolsCount()
);
return;
}
}
// we don't have any disabled bitmaps
}
m_disabledImgList = NULL;
}
bool wxToolBar::Realize()
{
const size_t nTools = GetToolsCount();
if ( nTools == 0 )
{
// nothing to do
return true;
}
const bool isVertical = HasFlag(wxTB_VERTICAL);
bool doRemap, doRemapBg, doTransparent;
#ifdef __WXWINCE__
doRemapBg = false;
doRemap = false;
doTransparent = false;
#else
if (wxSystemOptions::GetOptionInt(wxT("msw.remap")) == 2)
{
doRemapBg = doRemap = false;
doTransparent = true;
}
else
{ doRemap = !wxSystemOptions::HasOption(wxT("msw.remap"))
|| wxSystemOptions::GetOptionInt(wxT("msw.remap")) == 1;
doRemapBg = !doRemap;
doTransparent = false;
}
#endif
// delete all old buttons, if any
for ( size_t pos = 0; pos < m_nButtons; pos++ )
{
if ( !::SendMessage(GetHwnd(), TB_DELETEBUTTON, 0, 0) )
{
wxLogDebug(wxT("TB_DELETEBUTTON failed"));
}
}
// First, add the bitmap: we use one bitmap for all toolbar buttons
// ----------------------------------------------------------------
wxToolBarToolsList::compatibility_iterator node;
int bitmapId = 0;
wxSize sizeBmp;
if ( HasFlag(wxTB_NOICONS) )
{
// no icons, don't leave space for them
sizeBmp.x =
sizeBmp.y = 0;
}
else // do show icons
{
// if we already have a bitmap, we'll replace the existing one --
// otherwise we'll install a new one
HBITMAP oldToolBarBitmap = (HBITMAP)m_hBitmap;
sizeBmp.x = m_defaultWidth;
sizeBmp.y = m_defaultHeight;
const wxCoord totalBitmapWidth = m_defaultWidth *
wx_truncate_cast(wxCoord, nTools),
totalBitmapHeight = m_defaultHeight;
// Create a bitmap and copy all the tool bitmaps to it
wxMemoryDC dcAllButtons;
wxBitmap bitmap(totalBitmapWidth, totalBitmapHeight);
dcAllButtons.SelectObject(bitmap);
#ifdef __WXWINCE__
dcAllButtons.SetBackground(wxBrush(wxColour(192,192,192)));
#else
if (doTransparent)
dcAllButtons.SetBackground(*wxTRANSPARENT_BRUSH);
else
dcAllButtons.SetBackground(wxBrush(GetBackgroundColour()));
#endif
dcAllButtons.Clear();
m_hBitmap = bitmap.GetHBITMAP();
HBITMAP hBitmap = (HBITMAP)m_hBitmap;
#ifndef __WXWINCE__
if (doRemapBg)
{
dcAllButtons.SelectObject(wxNullBitmap);
// Even if we're not remapping the bitmap
// content, we still have to remap the background.
hBitmap = (HBITMAP)MapBitmap((WXHBITMAP) hBitmap,
totalBitmapWidth, totalBitmapHeight);
dcAllButtons.SelectObject(bitmap);
}
#endif // !__WXWINCE__
// the button position
wxCoord x = 0;
// the number of buttons (not separators)
int nButtons = 0;
CreateDisabledImageList();
for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
{
wxToolBarToolBase *tool = node->GetData();
if ( tool->IsButton() )
{
const wxBitmap& bmp = tool->GetNormalBitmap();
const int w = bmp.GetWidth();
const int h = bmp.GetHeight();
if ( bmp.Ok() )
{
int xOffset = wxMax(0, (m_defaultWidth - w)/2);
int yOffset = wxMax(0, (m_defaultHeight - h)/2);
// notice the last parameter: do use mask
dcAllButtons.DrawBitmap(bmp, x + xOffset, yOffset, true);
}
else
{
wxFAIL_MSG( _T("invalid tool button bitmap") );
}
// also deal with disabled bitmap if we want to use them
if ( m_disabledImgList )
{
wxBitmap bmpDisabled = tool->GetDisabledBitmap();
#if wxUSE_IMAGE && wxUSE_WXDIB
if ( !bmpDisabled.Ok() )
{
// no disabled bitmap specified but we still need to
// fill the space in the image list with something, so
// we grey out the normal bitmap
wxImage imgGreyed;
wxCreateGreyedImage(bmp.ConvertToImage(), imgGreyed);
// we need to have light grey background colour for
// MapBitmap() to work correctly
for ( int y = 0; y < h; y++ )
{
for ( int x = 0; x < w; x++ )
{
if ( imgGreyed.IsTransparent(x, y) )
imgGreyed.SetRGB(x, y,
wxLIGHT_GREY->Red(),
wxLIGHT_GREY->Green(),
wxLIGHT_GREY->Blue());
}
}
bmpDisabled = wxBitmap(imgGreyed);
}
#endif // wxUSE_IMAGE
MapBitmap(bmpDisabled.GetHBITMAP(), w, h);
m_disabledImgList->Add(bmpDisabled);
}
// still inc width and number of buttons because otherwise the
// subsequent buttons will all be shifted which is rather confusing
// (and like this you'd see immediately which bitmap was bad)
x += m_defaultWidth;
nButtons++;
}
}
dcAllButtons.SelectObject(wxNullBitmap);
// don't delete this HBITMAP!
bitmap.SetHBITMAP(0);
if (doRemap)
{
// Map to system colours
hBitmap = (HBITMAP)MapBitmap((WXHBITMAP) hBitmap,
totalBitmapWidth, totalBitmapHeight);
}
bool addBitmap = true;
if ( oldToolBarBitmap )
{
#ifdef TB_REPLACEBITMAP
if ( wxApp::GetComCtl32Version() >= 400 )
{
TBREPLACEBITMAP replaceBitmap;
replaceBitmap.hInstOld = NULL;
replaceBitmap.hInstNew = NULL;
replaceBitmap.nIDOld = (UINT) oldToolBarBitmap;
replaceBitmap.nIDNew = (UINT) hBitmap;
replaceBitmap.nButtons = nButtons;
if ( !::SendMessage(GetHwnd(), TB_REPLACEBITMAP,
0, (LPARAM) &replaceBitmap) )
{
wxFAIL_MSG(wxT("Could not replace the old bitmap"));
}
::DeleteObject(oldToolBarBitmap);
// already done
addBitmap = false;
}
else
#endif // TB_REPLACEBITMAP
{
// we can't replace the old bitmap, so we will add another one
// (awfully inefficient, but what else to do?) and shift the bitmap
// indices accordingly
addBitmap = true;
bitmapId = m_nButtons;
}
}
if ( addBitmap ) // no old bitmap or we can't replace it
{
TBADDBITMAP addBitmap;
addBitmap.hInst = 0;
addBitmap.nID = (UINT) hBitmap;
if ( ::SendMessage(GetHwnd(), TB_ADDBITMAP,
(WPARAM) nButtons, (LPARAM)&addBitmap) == -1 )
{
wxFAIL_MSG(wxT("Could not add bitmap to toolbar"));
}
}
if ( m_disabledImgList )
{
HIMAGELIST oldImageList = (HIMAGELIST)
::SendMessage(GetHwnd(),
TB_SETDISABLEDIMAGELIST,
0,
(LPARAM)GetHimagelistOf(m_disabledImgList));
// delete previous image list if any
if ( oldImageList )
::DeleteObject( oldImageList );
}
}
// don't call SetToolBitmapSize() as we don't want to change the values of
// m_defaultWidth/Height
if ( !::SendMessage(GetHwnd(), TB_SETBITMAPSIZE, 0,
MAKELONG(sizeBmp.x, sizeBmp.y)) )
{
wxLogLastError(_T("TB_SETBITMAPSIZE"));
}
// Next add the buttons and separators
// -----------------------------------
TBBUTTON *buttons = new TBBUTTON[nTools];
// this array will hold the indices of all controls in the toolbar
wxArrayInt controlIds;
bool lastWasRadio = false;
int i = 0;
for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
{
wxToolBarToolBase *tool = node->GetData();
// don't add separators to the vertical toolbar with old comctl32.dll
// versions as they didn't handle this properly
if ( isVertical && tool->IsSeparator() &&
wxApp::GetComCtl32Version() <= 472 )
{
continue;
}
TBBUTTON& button = buttons[i];
wxZeroMemory(button);
bool isRadio = false;
switch ( tool->GetStyle() )
{
case wxTOOL_STYLE_CONTROL:
button.idCommand = tool->GetId();
// fall through: create just a separator too
case wxTOOL_STYLE_SEPARATOR:
button.fsState = TBSTATE_ENABLED;
button.fsStyle = TBSTYLE_SEP;
break;
case wxTOOL_STYLE_BUTTON:
if ( !HasFlag(wxTB_NOICONS) )
button.iBitmap = bitmapId;
if ( HasFlag(wxTB_TEXT) )
{
const wxString& label = tool->GetLabel();
if ( !label.empty() )
{
button.iString = (int)label.c_str();
}
}
button.idCommand = tool->GetId();
if ( tool->IsEnabled() )
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?