📄 cooltabctrls.h
字号:
GetClientRect(&rc); InvalidateRect(&rc);
// Send notification
nmh.code = TCN_SELCHANGE;
m_wndNotify.SendMessage(WM_NOTIFY, nmh.idFrom, (LPARAM) &nmh);
return iOldSel;
}
int GetCurSel() const
{
ATLASSERT(::IsWindow(m_hWnd));
return m_iCurSel;
}
int GetItemCount() const
{
ATLASSERT(::IsWindow(m_hWnd));
return m_Items.GetSize();
}
void SetImageList(HIMAGELIST hImageList)
{
m_ImageList = hImageList;
}
CImageList GetImageList() const
{
return m_ImageList;
}
int HitTest(POINT pt) const
{
TCHITTESTINFO tchti = { 0 };
tchti.pt = pt;
return HitTest(&tchti);
}
int HitTest(LPTCHITTESTINFO pinfo) const
{
ATLASSERT(!::IsBadWritePtr(pinfo,sizeof(TCHITTESTINFO)));
for( int i = 0; i < m_Items.GetSize(); i++ ) {
if( ::PtInRect(&m_Items[i]->rcItem, pinfo->pt) ) {
pinfo->flags = TCHT_ONITEM;
return i;
}
}
return -1;
}
DWORD GetExtendedStyle() const
{
ATLASSERT(::IsWindow(m_hWnd));
return m_dwExtStyle;
}
DWORD SetExtendedStyle(DWORD dwExMask, DWORD dwExStyle)
{
ATLASSERT(::IsWindow(m_hWnd));
DWORD dwOldStyle = m_dwExtStyle;
m_dwExtStyle = (m_dwExtStyle & ~dwExMask) | dwExStyle;
_Repaint();
return dwOldStyle;
}
int GetRowCount() const
{
return 1;
}
CToolTipCtrl GetToolTips() const
{
return m_Tip;
}
int GetScrollPos() const
{
return m_iScrollPos;
}
void SetScrollPos(int iPos)
{
ATLASSERT(::IsWindow(m_hWnd));
if( m_Items.GetSize() == 0 ) {
m_iScrollPos = 0;
return;
}
RECT rcClient;
GetClientRect(&rcClient);
int iMax = m_Items[m_Items.GetSize() - 1]->rcItem.right - m_Items[0]->rcItem.left;
if( iMax - rcClient.right > 0 && iPos > iMax - rcClient.right ) iPos = iMax - rcClient.right;
if( iPos < 0 ) iPos = 0;
m_iScrollPos = iPos;
_Repaint();
}
void SetScrollStep(int iStep)
{
m_iScrollStep = iStep;
}
BOOL IsScrollVisible(int Side) const
{
ATLASSERT(::IsWindow(m_hWnd));
if( (m_dwExtStyle & TCS_EX_SCROLLBUTTONS) == 0 ) return _IsScrollBarNeeded(Side);
if( Side == HTLEFT ) return m_ctrlLeft.IsWindowVisible();
if( Side == HTRIGHT ) return m_ctrlRight.IsWindowVisible();
return FALSE;
}
void SetNotify(HWND hWnd)
{
ATLASSERT(::IsWindow(hWnd));
m_wndNotify = hWnd;
}
void SetMinTabWidth(int nWidth = -1)
{
m_nMinWidth = nWidth;
}
DWORD SetItemSize(int iItem, int cx, int cy)
{
ATLASSERT(::IsWindow(m_hWnd));
if( !_ValidateItem(iItem) ) return 0;
RECT rcOld = m_Items[iItem]->rcItem;
m_Items[iItem].cx = cx;
m_Items[iItem].mask |= TCIF_WIDTH;
_Repaint();
return MAKELONG(rcOld.right - rcOld.left, rcOld.bottom - rcOld.top);
}
BOOL GetItemRect(int iItem, LPRECT prcItem) const
{
ATLASSERT(::IsWindow(m_hWnd));
ATLASSERT(prcItem);
if( prcItem == NULL ) return FALSE;
::SetRectEmpty(prcItem);
if( iItem < 0 || iItem >= m_Items.GetSize() ) return FALSE;
*prcItem = m_Items[iItem]->rcItem;
return TRUE;
}
void GetMetrics(TCMETRICS *pMetrics) const
{
ATLASSERT(!::IsBadWritePtr(pMetrics,sizeof(TCMETRICS)));
*pMetrics = m_metrics;
}
void SetMetrics(const TCMETRICS *pMetrics)
{
ATLASSERT(::IsWindow(m_hWnd));
ATLASSERT(!::IsBadReadPtr(pMetrics,sizeof(TCMETRICS)));
m_metrics = *pMetrics;
_Repaint();
}
void SetSelFont(HFONT hFont)
{
m_hSelFont = hFont;
}
HFONT GetSelFont() const
{
return (m_dwExtStyle & TCS_EX_SELHIGHLIGHT) != 0 ? m_hSelFont : m_hFont;
}
int FindItem(LPTCITEM pFindInfo, int nStart = -1) const
{
ATLASSERT(::IsWindow(m_hWnd));
if( nStart < 0 ) nStart = -1;
// Find the next item matching the criteria specified
const UINT maskFind = pFindInfo->mask;
int nCount = m_Items.GetSize();
for( int i = nStart + 1; i < nCount; i++ ) {
LPTCITEM pItem = m_Items[i];
UINT mask = pItem->mask;
if( (maskFind & mask) != maskFind ) continue;
if( (maskFind & TCIF_PARAM) != 0 && pItem->lParam != pFindInfo->lParam ) continue;
if( (maskFind & TCIF_TEXT) != 0 && pItem->pszText != NULL && pFindInfo->pszText != NULL && ::lstrcmp(pItem->pszText, pFindInfo->pszText) != 0 ) continue;
if( (maskFind & TCIF_IMAGE) != 0 && pItem->iImage != pFindInfo->iImage ) continue;
if( (maskFind & TCIF_STATE) != 0 && pItem->dwState != pFindInfo->dwState ) continue;
return i;
}
return -1;
}
// Implementation
void _Init()
{
ATLASSERT(::IsWindow(m_hWnd));
ATLASSERT(GetStyle() & WS_CHILD);
m_idDlgCtrl = GetDlgCtrlID();
m_wndNotify = GetParent();
m_ctrlLeft.Create(m_hWnd, rcDefault, _T("<"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 0, IDC_CB_SCROLLLEFT);
m_ctrlLeft.SetFont( AtlGetDefaultGuiFont() );
m_ctrlRight.Create(m_hWnd, rcDefault, _T(">"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 0, IDC_CB_SCROLLRIGHT);
m_ctrlRight.SetFont( AtlGetDefaultGuiFont() );
SendMessage(WM_SETTINGCHANGE);
// This is a little WTL subclass helper notification
NMHDR nmh = { m_hWnd, m_idDlgCtrl, TCN_INITIALIZE };
m_wndNotify.SendMessage(WM_NOTIFY, nmh.idFrom, (LPARAM) &nmh);
}
BOOL _IsScrollBarNeeded(int Side) const
{
ATLASSERT(Side==HTLEFT || Side==HTRIGHT || Side==HTHSCROLL);
if( m_Items.GetSize() == 0 ) return FALSE;
// Left button is easy
if( Side == HTLEFT ) return m_iScrollPos > 0;
// Right button need to have side calc'ed
RECT rcClient;
GetClientRect(&rcClient);
int iMax = m_Items[m_Items.GetSize() - 1]->rcItem.right - m_Items[0]->rcItem.left;
if( Side == HTRIGHT ) return m_iScrollPos + rcClient.right < iMax;
if( Side == HTHSCROLL ) return rcClient.right < iMax;
return FALSE;
}
ATLINLINE bool _ValidateItem(int iItem) const
{
ATLASSERT(iItem>=0 && iItem<m_Items.GetSize());
if( iItem < 0 || iItem >= m_Items.GetSize() ) return false;
return true;
}
ATLINLINE void _Repaint()
{
T* pT = static_cast<T*>(this);
pT->UpdateLayout();
if( (pT->GetStyle() & WS_VISIBLE) != 0 ) Invalidate();
}
// Message map and handlers
BEGIN_MSG_MAP(CCustomTabCtrl)
CHAIN_MSG_MAP(COffscreenDrawRect< T >)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
MESSAGE_HANDLER(WM_SIZE, OnSize)
MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTest)
MESSAGE_HANDLER(WM_GETFONT, OnGetFont)
MESSAGE_HANDLER(WM_SETFONT, OnSetFont)
MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
MESSAGE_HANDLER(WM_GETDLGCODE, OnGetDlgCode)
MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonClick)
MESSAGE_HANDLER(WM_RBUTTONDOWN, OnRButtonClick)
MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseMessage)
COMMAND_ID_HANDLER(IDC_CB_SCROLLLEFT, OnScrollLeft)
COMMAND_ID_HANDLER(IDC_CB_SCROLLRIGHT, OnScrollRight)
END_MSG_MAP()
LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
LRESULT lRes = DefWindowProc();
_Init();
return lRes;
}
LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
ShowWindow(SW_HIDE); // Repaint checks WS_VISIBLE; so we won't need repaints.
DeleteAllItems(); // Make sure to clean up memory
bHandled = FALSE;
return 0;
}
LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
T* pT = static_cast<T*>(this);
pT->UpdateLayout();
bHandled = FALSE;
return 0;
}
LRESULT OnNcHitTest(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
ScreenToClient(&pt);
T* pT = static_cast<T*>(this);
int iItem = pT->HitTest(pt);
if( iItem == -1 ) return HTTRANSPARENT;
return HTCLIENT;
}
LRESULT OnGetFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
return (LRESULT) (HFONT)( m_hFont != NULL ? m_hFont : AtlGetDefaultGuiFont() );
}
LRESULT OnSetFont(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
m_hFont = (HFONT) wParam;
if( lParam != 0 ) _Repaint();
return 0;
}
LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
_Repaint();
return 0;
}
LRESULT OnGetDlgCode(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
return DefWindowProc(uMsg, wParam, lParam) | DLGC_WANTARROWS;
}
LRESULT OnLButtonClick(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
// Send click notification
NMHDR nmh = { m_hWnd, m_idDlgCtrl, NM_CLICK };
m_wndNotify.SendMessage(WM_NOTIFY, nmh.idFrom, (LPARAM) &nmh);
// Select tab below
T* pT = static_cast<T*>(this);
int iItem = pT->HitTest(pt);
if( iItem != -1 ) {
SetFocus();
SetCurSel(iItem);
}
return 0;
}
LRESULT OnRButtonClick(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
SendMessage(WM_LBUTTONDOWN, wParam, lParam); // BUG: Triggers NM_CLICK as well!
NMHDR nmh = { m_hWnd, m_idDlgCtrl, NM_RCLICK };
m_wndNotify.SendMessage(WM_NOTIFY, nmh.idFrom, (LPARAM) &nmh);
return 0;
}
LRESULT OnScrollLeft(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
SetScrollPos(GetScrollPos() - m_iScrollStep);
m_ctrlLeft.SetButtonStyle(BS_PUSHBUTTON);
return 0;
}
LRESULT OnScrollRight(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
SetScrollPos(GetScrollPos() + m_iScrollStep);
m_ctrlRight.SetButtonStyle(BS_PUSHBUTTON);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -