?? dotnettabctrl.h
字號(hào):
DWORD dwStyle = this->GetStyle();
if (CTCS_BOTTOM == (dwStyle & CTCS_BOTTOM))
{
rcScroll.top += 3;
if(0 == (dwStyle & CTCS_CLOSEBUTTON))
{
rcScroll.right -= 3;
}
}
else
{
rcScroll.top += 1;
rcScroll.bottom -= 2;
if(0 == (dwStyle & CTCS_CLOSEBUTTON))
{
rcScroll.right -= 2;
}
}
rcScroll.top = (rcScroll.bottom + rcScroll.top - nButtonSizeY) / 2;
rcScroll.bottom = rcScroll.top + nButtonSizeY;
m_rcScrollRight = rcScroll;
m_rcScrollLeft = rcScroll;
m_rcScrollRight.left = m_rcScrollRight.right - nButtonSizeX;
m_rcScrollLeft.right = m_rcScrollRight.left;
m_rcScrollLeft.left = m_rcScrollLeft.right - nButtonSizeX;
if(m_tooltip.IsWindow())
{
m_tooltip.SetToolRect(m_hWnd, (UINT)ectcToolTip_ScrollRight, &m_rcScrollRight);
m_tooltip.SetToolRect(m_hWnd, (UINT)ectcToolTip_ScrollLeft, &m_rcScrollLeft);
}
// Adjust the tab area
prcTabItemArea->right = m_rcScrollLeft.left;
}
void UpdateLayout_Default(RECT rcTabItemArea)
{
long nMinInactiveWidth = 0x7FFFFFFF;
long nMaxInactiveWidth = 0;
//DWORD dwStyle = this->GetStyle();
CClientDC dc(m_hWnd);
//HFONT hOldFont = dc.SelectFont(lpNMCustomDraw->hFontInactive);
HFONT hOldFont = dc.SelectFont(m_font);
LONG nTabAreaWidth = (rcTabItemArea.right - rcTabItemArea.left);
RECT rcItem = rcTabItemArea;
// rcItem.top and rcItem.bottom aren't really going to change
// Recalculate tab positions and widths
// See DrawItem_ImageAndText for a discussion of how CDotNetTabCtrlImpl
// interprets margin, padding, etc.
size_t nCount = m_Items.GetCount();
int xpos = m_settings.iIndent;
HFONT hRestoreNormalFont = NULL;
for( size_t i=0; i<nCount; ++i )
{
bool bSelected = ((int)i == m_iCurSel);
if(bSelected)
{
//hRestoreNormalFont = dc.SelectFont(lpNMCustomDraw->hFontSelected);
hRestoreNormalFont = dc.SelectFont(m_fontSel);
}
TItem* pItem = m_Items[i];
ATLASSERT(pItem != NULL);
rcItem.left = rcItem.right = xpos;
//rcItem.right += ((bSelected ? m_settings.iSelMargin : m_settings.iMargin));
rcItem.right += m_settings.iMargin;
if(pItem->UsingImage() && !m_imageList.IsNull())
{
IMAGEINFO ii = {0};
int nImageIndex = pItem->GetImageIndex();
m_imageList.GetImageInfo(nImageIndex, &ii);
rcItem.right += (ii.rcImage.right - ii.rcImage.left);
}
if(pItem->UsingText())
{
RECT rcText = {0};
CString sText = pItem->GetText();
dc.DrawText(sText, sText.GetLength(), &rcText, DT_SINGLELINE | DT_CALCRECT);
rcItem.right += (rcText.right - rcText.left) + (m_settings.iPadding * 2);
}
rcItem.right += m_settings.iMargin;
pItem->SetRect(rcItem);
xpos += (rcItem.right - rcItem.left);
if(hRestoreNormalFont != NULL)
{
dc.SelectFont(hRestoreNormalFont);
hRestoreNormalFont = NULL;
}
if(!bSelected)
{
if((rcItem.right - rcItem.left) < nMinInactiveWidth)
{
nMinInactiveWidth = (rcItem.right - rcItem.left);
}
if((rcItem.right - rcItem.left) > nMaxInactiveWidth)
{
nMaxInactiveWidth = (rcItem.right - rcItem.left);
}
}
}
xpos += m_settings.iIndent;
if(xpos > nTabAreaWidth && nCount > 0 && m_iCurSel >= 0)
{
// Our desired widths are more than the width of the client area.
// We need to have some or all of the tabs give up some real estate
// We'll try to let the selected tab have its fully desired width.
// If it can't, we'll make all the tabs the same width.
RECT rcSelected = m_Items[m_iCurSel]->GetRect();
LONG nSelectedWidth = (rcSelected.right - rcSelected.left);
long cxClientInactiveTabs = nTabAreaWidth - (m_settings.iIndent * 2) - nSelectedWidth;
long cxDesiredInactiveTabs = xpos - (m_settings.iIndent * 2) - nSelectedWidth;
double nRatioWithSelectionFullSize = 0.0;
if(cxDesiredInactiveTabs != 0)
{
nRatioWithSelectionFullSize = (double) (cxClientInactiveTabs) / (double)(cxDesiredInactiveTabs);
}
long nInactiveSameSizeWidth = (m_nMinWidthToDisplayText + (m_settings.iMargin*2) + (m_settings.iPadding));
if(cxClientInactiveTabs > (nInactiveSameSizeWidth * (long)(nCount-1)))
{
// There should be enough room to display the entire contents of
// the selected tab plus something for the inactive tabs
bool bMakeInactiveSameSize = ((nMinInactiveWidth * nRatioWithSelectionFullSize) < nInactiveSameSizeWidth);
xpos = m_settings.iIndent;
for(size_t i=0; i<nCount; ++i )
{
TItem* pItem = m_Items[i];
ATLASSERT(pItem != NULL);
RECT rcItemDesired = pItem->GetRect();
rcItem.left = rcItem.right = xpos;
if((int)i == m_iCurSel)
{
rcItem.right += (rcItemDesired.right - rcItemDesired.left);
}
else
{
if(bMakeInactiveSameSize && (nCount != 1))
{
rcItem.right += (long)((cxClientInactiveTabs / (nCount-1)) + 0.5);
}
else
{
rcItem.right += (long)(((rcItemDesired.right - rcItemDesired.left) * nRatioWithSelectionFullSize) + 0.5);
}
}
pItem->SetRect(rcItem);
xpos += (rcItem.right-rcItem.left);
}
}
else
{
// We're down pretty small, so just make all the tabs the same width
int cxItem = (nTabAreaWidth - (m_settings.iIndent*2)) / (int)nCount;
xpos = m_settings.iIndent;
for(size_t i=0; i<nCount; ++i)
{
rcItem.left = rcItem.right = xpos;
rcItem.right += cxItem;
m_Items[i]->SetRect(rcItem);
xpos += (rcItem.right-rcItem.left);
}
}
}
dc.SelectFont(hOldFont);
}
void UpdateLayout_ScrollToFit(RECT rcTabItemArea)
{
//DWORD dwStyle = this->GetStyle();
// When we scroll to fit, we ignore what's passed in for the
// tab item area rect, and use the client rect instead
RECT rcClient;
this->GetClientRect(&rcClient);
CClientDC dc(m_hWnd);
//HFONT hOldFont = dc.SelectFont(lpNMCustomDraw->hFontInactive);
HFONT hOldFont = dc.SelectFont(m_font);
RECT rcItem = rcClient;
// rcItem.top and rcItem.bottom aren't really going to change
// Recalculate tab positions and widths
// See DrawItem_ImageAndText for a discussion of how CDotNetTabCtrlImpl
// interprets margin, padding, etc.
size_t nCount = m_Items.GetCount();
int xpos = m_settings.iIndent;
HFONT hRestoreNormalFont = NULL;
for( size_t i=0; i<nCount; ++i )
{
bool bSelected = ((int)i == m_iCurSel);
if(bSelected)
{
//hRestoreNormalFont = dc.SelectFont(lpNMCustomDraw->hFontSelected);
hRestoreNormalFont = dc.SelectFont(m_fontSel);
}
TItem* pItem = m_Items[i];
ATLASSERT(pItem != NULL);
rcItem.left = rcItem.right = xpos;
//rcItem.right += ((bSelected ? m_settings.iSelMargin : m_settings.iMargin));
rcItem.right += m_settings.iMargin;
if(pItem->UsingImage() && !m_imageList.IsNull())
{
IMAGEINFO ii = {0};
int nImageIndex = pItem->GetImageIndex();
m_imageList.GetImageInfo(nImageIndex, &ii);
rcItem.right += (ii.rcImage.right - ii.rcImage.left);
}
if(pItem->UsingText())
{
RECT rcText = {0};
CString sText = pItem->GetText();
dc.DrawText(sText, sText.GetLength(), &rcText, DT_SINGLELINE | DT_CALCRECT);
rcItem.right += (rcText.right - rcText.left) + (m_settings.iPadding * 2);
}
rcItem.right += m_settings.iMargin;
pItem->SetRect(rcItem);
xpos += (rcItem.right - rcItem.left);
if(hRestoreNormalFont != NULL)
{
dc.SelectFont(hRestoreNormalFont);
hRestoreNormalFont = NULL;
}
}
xpos += m_settings.iIndent;
// If we've been scrolled to the left, and resize so
// there's more client area to the right, adjust the
// scroll offset accordingly.
if((xpos + m_iScrollOffset) < rcTabItemArea.right)
{
m_iScrollOffset = (rcTabItemArea.right - xpos);
}
dc.SelectFont(hOldFont);
}
};
template <class TItem = CCustomTabItem>
class CDotNetTabCtrl :
public CDotNetTabCtrlImpl<CDotNetTabCtrl<TItem>, TItem>
{
protected:
typedef CDotNetTabCtrl thisClass;
typedef CDotNetTabCtrlImpl<CDotNetTabCtrl, TItem> baseClass;
// Constructors:
public:
CDotNetTabCtrl()
{
}
public:
DECLARE_WND_CLASS_EX(_T("WTL_DotNetTabCtrl"), CS_DBLCLKS, COLOR_WINDOW)
//We have nothing special to add.
//BEGIN_MSG_MAP(thisClass)
// CHAIN_MSG_MAP(baseClass)
//END_MSG_MAP()
};
template<typename T, typename TItem = CCustomTabItem, class TBase = CWindow, class TWinTraits = CCustomTabCtrlWinTraits>
class CDotNetButtonTabCtrlImpl :
public CDotNetTabCtrlImpl<T, TItem, TBase, TWinTraits>
{
protected:
typedef CDotNetButtonTabCtrlImpl<T, TItem, TBase, TWinTraits> thisClass;
typedef CDotNetTabCtrlImpl<T, TItem, TBase, TWinTraits> baseClass;
// Constructor
public:
CDotNetButtonTabCtrlImpl()
{
// We can't use a member initialization list to initialize
// members of our base class, so do it explictly by assignment here.
m_clrTextInactiveTab = ::GetSysColor(COLOR_BTNTEXT);
m_clrSelectedTab = ::GetSysColor(COLOR_WINDOW);
}
// Message Handling
public:
DECLARE_WND_CLASS_EX(_T("WTL_DotNetButtonTabCtrl"), CS_DBLCLKS, COLOR_WINDOW)
BEGIN_MSG_MAP(thisClass)
MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
MESSAGE_HANDLER(WM_SYSCOLORCHANGE, OnSettingChange)
CHAIN_MSG_MAP(baseClass)
END_MSG_MAP()
LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
DWORD dwStyle = this->GetStyle();
// Initialize/Reinitialize font
// Visual Studio.Net seems to use the "icon" font for the tabs
LOGFONT lfIcon = { 0 };
::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIcon), &lfIcon, 0);
bool bResetFont = true;
if(!m_font.IsNull())
{
LOGFONT lf = {0};
if(m_font.GetLogFont(&lf))
{
if(lstrcmpi(lf.lfFaceName, lfIcon.lfFaceName) == 0 &&
lf.lfHeight == lfIcon.lfHeight)
{
bResetFont = false;
}
}
}
if(bResetFont)
{
if(!m_font.IsNull()) m_font.DeleteObject();
if(!m_fontSel.IsNull()) m_fontSel.DeleteObject();
HFONT font = m_font.CreateFontIndirect(&lfIcon);
if(font==NULL)
{
m_font.Attach(AtlGetDefaultGuiFont());
}
if(CTCS_BOLDSELECTEDTAB == (dwStyle & CTCS_BOLDSELECTEDTAB))
{
lfIcon.lfWeight = FW_BOLD;
}
font = m_fontSel.CreateFontIndirect(&lfIcon);
if(font==NULL)
{
m_fontSel.Attach(AtlGetDefaultGuiFont());
}
}
// Background brush
if(!m_hbrBackground.IsNull() ) m_hbrBackground.DeleteObject();
m_hbrBackground.CreateSysColorBrush(COLOR_BTNFACE);
m_settings.iIndent = 5;
m_settings.iPadding = 4;
m_settings.iMargin = 3;
m_settings.iSelMargin = 3;
T* pT = static_cast<T*>(this);
pT->UpdateLayout();
pT->Invalidate();
return 0;
}
// Overrides for painting from CDotNetTabCtrlImpl
public:
void DrawBackground(RECT rcClient, LPNMCTCCUSTOMDRAW lpNMCustomDraw)
{
CDCHandle dc( lpNMCustomDraw->nmcd.hdc );
// Set up the text color and background mode
dc.SetTextColor(lpNMCustomDraw->clrBtnText);
dc.SetBkMode(TRANSPARENT);
// Erase Background
// (do it here instead of a handler for WM_ERASEBKGND
// so that we can do flicker-free drawing with the help
// of COffscreenDrawRect that's in the base class)
// Note: Because the "erase" part is very simple, and only coloring
// it with the background color, we can do a smarter erase.
// Instead of erasing the whole client area (which might be clipped),
// We'll just ask the HDC for the clip box.
RECT rc = {0};
//GetClientRect(&rc);
dc.GetClipBox(&rc);
HBRUSH hOldBrush = dc.SelectBrush(lpNMCustomDraw->hBrushBackground);
dc.PatBlt(rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, PATCOPY);
dc.SelectBrush(hOldBrush);
}
void DrawItem_InitBounds(DWORD dwStyle, RECT rcItem, RECT& rcTab, RECT& rcText, int& nIconVerticalCenter)
{
rcTab.top += 3;
rcTab.bottom -= 3;
nIconVerticalCenter = (rcTab.bottom + rcTab.top) / 2;
}
void DrawItem_TabSelected(DWORD dwStyle, LPNMCTCCUSTOMDRAW lpNMCustomDraw, RECT& rcTab)
{
// Tab is selected, so paint as select
bool bHighlighted = (CDIS_MARKED == (lpNMCustomDraw->nmcd.uItemState & CDIS_MARKED));
CDCHandle dc( lpNMCustomDraw->nmcd.hdc );
CPen penOutline;
CBrush brushSelected;
if(bHighlighted)
{
penOutline.CreatePen(PS_SOLID, 1, lpNMCustomDraw->clrBtnHighlight);
brushSelected.CreateSolidBrush(lpNMCustomDraw->clrHighlight);
}
else
{
penOutline.CreatePen(PS_SOLID, 1, lpNMCustomDraw->clrHighlight);
brushSelected.CreateSolidBrush(lpNMCustomDraw->clrSelectedTab);
}
HPEN hOldPen = dc.SelectPen(penOutline);
HBRUSH hOldBrush = dc.SelectBrush(brushSelected);
dc.Rectangle(&rcTab);
dc.SelectPen(hOldPen);
dc.SelectBrush(hOldBrush);
}
};
template <class TItem = CCustomTabItem>
class CDotNetButtonTabCtrl :
public CDotNetButtonTabCtrlImpl<CDotNetButtonTabCtrl<TItem>, TItem>
{
protected:
typedef CDotNetButtonTabCtrl<TItem> thisClass;
typedef CDotNetButtonTabCtrlImpl<CDotNetButtonTabCtrl<TItem>, TItem> baseClass;
// Constructors:
public:
CDotNetButtonTabCtrl()
{
}
public:
DECLARE_WND_CLASS_EX(_T("WTL_DotNetButtonTabCtrl"), CS_DBLCLKS, COLOR_WINDOW)
//We have nothing special to add.
//BEGIN_MSG_MAP(thisClass)
// CHAIN_MSG_MAP(baseClass)
//END_MSG_MAP()
};
#endif // __DOTNET_TABCTRL_H__
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -