📄 tabctrl.h
字号:
m_bLockRefreshBandInfo = false;
RefreshBandInfo();
return true;
}
// bool SetItem(int nIndex, const CTabCtrlItem& item)
// {
// if (!_IsValidIndex(nIndex))
// return false;
// m_items[nIndex] = item;
// _UpdateItems(nIndex);
// }
bool SetItemText(int nIndex, const CString& str)
{
if (!_IsValidIndex(nIndex))
return false;
if (m_items[nIndex].m_strItem == str)
return true;
m_items[nIndex].m_strItem = str;
if (m_dwTabCtrl2ExtendedStyle & TAB2_EX_FIXEDSIZE) {
InvalidateRect(m_items[nIndex].m_rcItem);
UpdateWindow();
}
else {
InvalidateRect(m_items[nIndex].m_rcItem);// even if layout will not be changed
_UpdateLayout();//_UpdateItems(nIndex);
}
return true;
}
bool SetItemImageIndex(int nIndex, int nImgIndex)
{
if (!_IsValidIndex(nIndex))
return false;
if (m_items[nIndex].m_nImgIndex == nImgIndex)
return true;
m_items[nIndex].m_nImgIndex = nImgIndex;
// imagelist does'nt change item rect
// if (m_dwTabCtrl2ExtendedStyle & TAB2_EX_FIXEDSIZE) {
InvalidateRect(m_items[nIndex].m_rcItem);
UpdateWindow();
// }
// else {
// InvalidateRect(m_items[nIndex].m_rcItem);// even if layout will not be changed
// _UpdateLayout();//_UpdateItems(nIndex);
// }
return true;
}
bool SetItemInactive(int nIndex)
{
if (!_IsValidIndex(nIndex))
return false;
if (m_items[nIndex].ModifyState(0, TCISTATE_INACTIVE)) {
InvalidateRect(m_items[nIndex].m_rcItem, FALSE);
return true;
}
return false;
}
bool SetItemActive(int nIndex)
{
if (!_IsValidIndex(nIndex))
return false;
if (m_items[nIndex].ModifyState(TCISTATE_INACTIVE, 0)) {
InvalidateRect(m_items[nIndex].m_rcItem, FALSE);
return true;
}
return false;
}
bool SetItemDisabled(int nIndex)
{
if (!_IsValidIndex(nIndex))
return false;
if (m_items[nIndex].ModifyState(TCISTATE_ENABLED, 0)) {
InvalidateRect(m_items[nIndex].m_rcItem);
return true;
}
return false;
}
bool SetItemEnabled(int nIndex)
{
if (!_IsValidIndex(nIndex))
return false;
if (m_items[nIndex].ModifyState(0, TCISTATE_ENABLED)) {
InvalidateRect(m_items[nIndex].m_rcItem);
return true;
}
return false;
}
bool SetItemUserData(int nIndex, DWORD dwUser)
{
if (!_IsValidIndex(nIndex))
return false;
m_items[nIndex].m_dwUser = m_dwUser;
return true;
}
bool GetItem(int nIndex, CTabCtrlItem& item)
{
if (!_IsValidIndex(nIndex))
return false;
item = m_items[nIndex];
return true;
}
bool GetItemText(int nIndex, CString& str)
{
if (!_IsValidIndex(nIndex))
return false;
str = m_items[nIndex].m_strItem;
return true;
}
bool GetItemImageIndex(int nIndex, int& nImgIndex)
{
if (!_IsValidIndex(nIndex))
return false;
nImgIndex = m_items[nIndex].m_nImgIndex;
return true;
}
bool GetItemUserData(int nIndex, DWORD& dwData)
{
if (!_IsValidIndex(nIndex))
return false;
dwData = m_items[nIndex].m_dwUser;
return true;
}
bool GetItemRect(int nIndex, CRect& rc)
{
if (!_IsValidIndex(nIndex))
return false;
if (!(m_dwTabCtrl2ExtendedStyle & TAB2_EX_MULTILINE) && nIndex < m_nFirstIndexOnSingleLine)
return false;
rc = m_items[nIndex].m_rcItem;
return true;
}
bool AddItem(const CTabCtrlItem& item)
{
_HotItem();
m_items.push_back(item);
_UpdateLayout();// _UpdateItems(m_items.size() - 1);
return true;
}
bool DeleteItem(int nIndex)
{
if (!_IsValidIndex(nIndex))
return false;
_HotItem();
// first, post it
InvalidateRect(_InflateGapWidth(m_items[nIndex].m_rcItem));
// _InvalidateItemsRect(nIndex, m_items.size());
if (nIndex < m_nFirstIndexOnSingleLine || nIndex + 1 == GetItemCount()) {
--m_nFirstIndexOnSingleLine;
if (m_nFirstIndexOnSingleLine < 0)
m_nFirstIndexOnSingleLine = 0;
}
m_items.erase(m_items.begin() + nIndex);
_UpdateLayout();
return true;
}
void GetCurMultiSel(CSimpleArray<int>& arrDest, bool bIncludeCurSel = true)
{// have to be sorted!
arrDest.RemoveAll();
for (int i = 0; i < m_items.size(); ++i) {
if (bIncludeCurSel) {
if (m_items[i].m_fsState & TCISTATE_SELECTED) {
arrDest.Add(i);
continue;
}
}
if (m_items[i].m_fsState & TCISTATE_MSELECTED)
arrDest.Add(i);
}
}
bool SetCurSel(int nIndex, bool bClicked = false)
{
TCTRACE(_T("SetCurSel\n"));
if (!_IsValidIndex(nIndex)) {
TCTRACE(_T(" invalid index\n"));
return false;
}
_ResetMultiSelectedItems();
int nCurSel = GetCurSel();
if (nCurSel != -1 && nCurSel == nIndex) {
TCTRACE(_T(" no need\n"));
return true;
}
// clean up
if (_IsValidIndex(nCurSel)) {
if (m_items[nCurSel].ModifyState(TCISTATE_SELECTED | TCISTATE_HOT | TCISTATE_PRESSED | TCISTATE_MSELECTED, 0))
InvalidateRect(m_items[nCurSel].m_rcItem);
}
// new selected item
if (m_items[nIndex].ModifyState(TCISTATE_HOT | TCISTATE_PRESSED | TCISTATE_MSELECTED, TCISTATE_SELECTED))
InvalidateRect(m_items[nIndex].m_rcItem);
_ScrollOpposite(nIndex, bClicked);
T* pT = static_cast<T*>(this);
pT->OnSetCurSel(nIndex);
UpdateWindow();
return true;
}
void _ScrollOpposite(int nNewSel, bool bClicked)
{
ATLASSERT(_IsValidIndex(nNewSel));
if (GetItemCount() < 2)
return;
if (!(m_dwTabCtrl2ExtendedStyle & TAB2_EX_SCROLLOPPOSITE))
return;
if (m_dwTabCtrl2ExtendedStyle & TAB2_EX_MULTILINE)
return;
if (!m_wndUpDown.IsWindowVisible())
return;
const CRect& rcItem = m_items[nNewSel].m_rcItem;
CRect rcClient; GetClientRect(rcClient);
if (bClicked) {
if (m_nFirstIndexOnSingleLine != nNewSel) {
CRect rcUpDown; m_wndUpDown.GetWindowRect(rcUpDown);
ScreenToClient(rcUpDown);
if (MtlIsCrossRect(rcItem, rcUpDown))
ScrollItem();
}
}
else if (rcItem.IsRectEmpty() || (rcClient & rcItem) != rcItem) {// outside or crossed
m_nFirstIndexOnSingleLine = MtlMax(0, nNewSel - 1);//nNewSel;
_UpdateSingleLineLayout(m_nFirstIndexOnSingleLine);
Invalidate();
_ShowOrHideUpDownCtrl(rcClient);
}
}
void RefreshBandInfo()
{
ATLASSERT(m_dwTabCtrl2ExtendedStyle & TAB2_EX_SUPPORTREBAR);
if (m_bLockRefreshBandInfo)
return;
HWND hWndReBar = GetParent();
CReBarCtrl rebar(hWndReBar);
REBARBANDINFO rbBand;
rbBand.cbSize = sizeof(REBARBANDINFO);
rbBand.fMask = RBBIM_CHILDSIZE;
int nIndex = rebar.IdToIndex(GetDlgCtrlID());
rebar.GetBandInfo(nIndex, &rbBand);
if (rbBand.cyMinChild != _GetRequiredHeight()) {
// Calculate the size of the band
rbBand.cxMinChild = 0;
rbBand.cyMinChild = _GetRequiredHeight();
rebar.SetBandInfo(nIndex, &rbBand);
}
}
int GetItemHeight()
{
if (m_dwTabCtrl2ExtendedStyle & TAB2_EX_FIXEDSIZE) {
return m_sizeItem.cy;
}
else {
int cxIcon = 0, cyIcon = 0;
if (m_imgs.m_hImageList != NULL)
m_imgs.GetIconSize(cxIcon, cyIcon);
LOGFONT lf;
m_font.GetLogFont(lf);
int cy = lf.lfHeight;
if(cy < 0)
cy = -cy;
cy += 2 * s_kcyTextMargin;
return MtlMax(cy, cxIcon);
}
}
bool CanScrollItem(bool bRight = true)
{
if (m_dwTabCtrl2ExtendedStyle & TAB2_EX_MULTILINE)
return false;// can't
if (bRight) {
if (m_nFirstIndexOnSingleLine + 1 < GetItemCount()) {
return true;
}
else {
return false;
}
}
else {
if (m_nFirstIndexOnSingleLine - 1 >= 0) {
return true;
}
else {
return false;
}
}
}
bool ScrollItem(bool bRight = true)
{
if (m_dwTabCtrl2ExtendedStyle & TAB2_EX_MULTILINE)
return false;// do nothing
if (bRight) {
if (m_nFirstIndexOnSingleLine + 1 < GetItemCount()) {
++m_nFirstIndexOnSingleLine;
_UpdateSingleLineLayout(m_nFirstIndexOnSingleLine);
Invalidate();
}
else {
return false;
}
}
else {
if (m_nFirstIndexOnSingleLine - 1 >= 0) {
--m_nFirstIndexOnSingleLine;
_UpdateSingleLineLayout(m_nFirstIndexOnSingleLine);
Invalidate();
}
else {
return false;
}
}
CRect rcClient; GetClientRect(&rcClient);
_ShowOrHideUpDownCtrl(rcClient);
return true;
}
// Overrides
void OnTrackMouseMove(UINT nFlags, CPoint pt)
{
int nIndex = HitTest(pt);
if (_IsValidIndex(nIndex)) {
if (m_nHotIndex == -1 || m_nHotIndex != nIndex) { // if other button made hot or first hot
m_tip.Activate(FALSE);
m_tip.Activate(TRUE);
PostMessage(WM_MOUSEMOVE, (WPARAM)nFlags, MAKELPARAM(pt.x, pt.y));// make sure
_HotItem(nIndex);// button made hot with mouse
}
}
else {
m_tip.Activate(FALSE);
_HotItem();
}
}
void OnTrackMouseLeave()
{
m_tip.SetDelayTime(TTDT_INITIAL, 500);
_HotItem();
}
// Message map and handlers
BEGIN_MSG_MAP(CTabCtrl2Impl)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
MESSAGE_HANDLER(WM_WINDOWPOSCHANGING, OnWindowPosChanging)
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
NOTIFY_CODE_HANDLER(UDN_DELTAPOS, OnDeltaPos)
NOTIFY_CODE_HANDLER(TTN_GETDISPINFO, OnGetDispInfo)
CHAIN_MSG_MAP(CTrackMouseLeave<CTabCtrl2Impl>)
END_MSG_MAP()
LRESULT OnDeltaPos(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
{
LPNMUPDOWN lpnmud = (LPNMUPDOWN)pnmh;
TCTRACE(_T("OnDeltaPos iPos(%d), iDelta(%d)\n"), lpnmud->iPos, lpnmud->iDelta);
ScrollItem(lpnmud->iDelta > 0);
return 0;
}
LRESULT OnGetDispInfo(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
{
LPNMTTDISPINFO pDispInfo = (LPNMTTDISPINFO)pnmh;
TCTRACE(_T("OnGetDispInfo\n"));
CPoint ptCursor; ::GetCursorPos(&ptCursor);
ScreenToClient(&ptCursor);
int nIndex = HitTest(ptCursor);
if (_IsValidIndex(nIndex)) {
T* pT = static_cast<T*>(this);
CString strToolTip = pT->OnGetToolTipText(nIndex);
strToolTip = MtlCompactString(strToolTip, _countof(pDispInfo->szText));
::lstrcpyn(pDispInfo->szText, strToolTip, _countof(pDispInfo->szText));
}
else {
pDispInfo->szText[0] = _T('\0');
}
m_tip.SetDelayTime(TTDT_INITIAL, m_tip.GetDelayTime(TTDT_RESHOW));
return 0;
}
LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
// maybe nothing done
LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);
// get and use system settings
GetSystemSettings();
m_wndUpDown.Create(m_hWnd, CRect(0, 0, s_kcxUpDown, s_kcyUpDown), NULL, WS_CHILD|WS_OVERLAPPED|UDS_HORZ);
_InitToolTip();
// default size
MoveWindow(0, 0, 200, _GetRequiredHeight(), FALSE);
return lRet;
}
LRESULT OnWindowPosChanging(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
bHandled = FALSE;
LPWINDOWPOS lpwndpos = (LPWINDOWPOS)lParam;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -