void CMyTabCtrl::OnSelchange(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here int iNewTab = GetCurSel(); if (!IsTabEnabled(iNewTab)) { SetCurSel(m_iSelectedTab); } else { TCITEM item; CWnd* pWnd; item.mask = TCIF_PARAM; //** hide the current tab --------- GetItem(m_iSelectedTab, &item); pWnd = reinterpret_cast<CWnd*> (item.lParam); ASSERT_VALID(pWnd); pWnd->ShowWindow(SW_HIDE); //** show the selected tab -------- GetItem(iNewTab, &item); pWnd = reinterpret_cast<CWnd*> (item.lParam); ASSERT_VALID(pWnd); pWnd->ShowWindow(SW_SHOW); } *pResult = 0; }
BOOL CXTabCtrl::SelectNextTab(BOOL bForward) { int iSum = bForward ? 1 : -1; int iCurSel = GetCurSel(); int iCurSelSave(iCurSel); do { iCurSel += iSum; if (iCurSel < 0 || iCurSel == GetItemCount()) return FALSE; if (IsTabEnabled(iCurSel)) { if (iCurSel < GetItemCount()) { SelectTab(iCurSel); return TRUE; } return FALSE; } } while (iCurSel != iCurSelSave); return FALSE; }
////////////////// // Draw the tab: mimic SysTabControl32, except use gray if tab is disabled // void CMyTabCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { DRAWITEMSTRUCT& ds = *lpDrawItemStruct; int iItem = ds.itemID; // Get tab item info char text[128]; TCITEM tci; tci.mask = TCIF_TEXT; tci.pszText = text; tci.cchTextMax = sizeof(text); GetItem(iItem, &tci); // use draw item DC CDC dc; dc.Attach(ds.hDC); // calculate text rectangle and color CRect rc = ds.rcItem; rc += CPoint(1,4); // ?? by trial and error // draw the text OnDrawText(dc, rc, text, !IsTabEnabled(iItem)); dc.Detach(); }
///////////////// // Return the index of the previous enabled tab before a given index, or -1. // (0 = first tab). // If bWrap is TRUE, wrap from beginning to end; otherwise stop at zero. // int CMyTabCtrl::PrevEnabledTab(int iCurrentTab, BOOL bWrap) { for (int iTab = iCurrentTab-1; iTab != iCurrentTab; iTab--) { if (iTab < 0) { if (!bWrap) return -1; iTab = GetItemCount() - 1; } if (IsTabEnabled(iTab)) { return iTab; } } return -1; }
BOOL CMyTabCtrl::SubclassDlgItem(UINT nID, CWnd* pParent) { if (!CTabCtrl::SubclassDlgItem(nID, pParent)) return FALSE; ModifyStyle(0, TCS_OWNERDRAWFIXED); // If first tab is disabled, go to next enabled tab if (!IsTabEnabled(0)) { int iTab = NextEnabledTab(0, TRUE); SetActiveTab(iTab); } return TRUE; }
///////////////// // Return the index of the next enabled tab after a given index, or -1 if none // (0 = first tab). // If bWrap is TRUE, wrap from beginning to end; otherwise stop at zero. // int CMyTabCtrl::NextEnabledTab(int iCurrentTab, BOOL bWrap) { int nTabs = GetItemCount(); for (int iTab = iCurrentTab+1; iTab != iCurrentTab; iTab++) { if (iTab >= nTabs) { if (!bWrap) return -1; iTab = 0; } if (IsTabEnabled(iTab)) { return iTab; } } return -1; }
////////////////// // Selection is changing: disallow if tab is disabled // void CMyTabCtrl::OnSelChanging(NMHDR* pnmh, LRESULT* pRes) { TRACE("CMyTabCtrl::OnSelChanging\n"); // Figure out index of new tab we are about to go to, as opposed // to the current one we're at. Believe it or not, Windows doesn't // pass this info // TC_HITTESTINFO htinfo; GetCursorPos(&htinfo.pt); ScreenToClient(&htinfo.pt); int iNewTab = HitTest(&htinfo); if (iNewTab >= 0 && !IsTabEnabled(iNewTab)) *pRes = TRUE; // tab disabled: prevent selection }
void CXTabCtrl::OnSelchange(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here int iNewTab = GetCurSel(); if (!IsTabEnabled(iNewTab)) { SetCurSel(m_iSelectedTab); } else { TCITEM item; CWnd* pWnd; item.mask = TCIF_PARAM; //** hide the current tab --------- GetItem(m_iSelectedTab, &item); pWnd = reinterpret_cast<CWnd*> (item.lParam); ASSERT_VALID(pWnd); pWnd->ShowWindow(SW_HIDE); //** show the selected tab -------- GetItem(iNewTab, &item); pWnd = reinterpret_cast<CWnd*> (item.lParam); ASSERT_VALID(pWnd); // 改变属性页的大小位置 CRect rc; GetClientRect(rc); rc.top += 20; rc.bottom -= 3; rc.left += 2; rc.right -= 3; pWnd->MoveWindow(&rc); pWnd->ShowWindow(SW_SHOW); // 发送到父窗口Tab项改变 GetParent()->SendMessage(WM_TAB_SEL_CHANGED,0,iNewTab); } *pResult = 0; }
void CXTabCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { CRect rect = lpDrawItemStruct->rcItem; rect.bottom+=2; rect.top += ::GetSystemMetrics(SM_CYEDGE); int nTabIndex = lpDrawItemStruct->itemID; if (nTabIndex < 0) return; BOOL bSelected = (nTabIndex == GetCurSel()); COLORREF crSelected = m_bColorSelected ? m_crSelected : GetSysColor(COLOR_BTNTEXT); COLORREF crNormal = m_bColorNormal ? m_crNormal : GetSysColor(COLOR_BTNTEXT); COLORREF crDisabled = m_bColorDisabled ? m_crDisabled : GetSysColor(COLOR_GRAYTEXT); TCHAR label[64]; TC_ITEM item; item.mask = TCIF_TEXT|TCIF_IMAGE; item.pszText = label; item.cchTextMax = 63; if (!GetItem(nTabIndex, &item)) return; CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); if (!pDC) return; int nSavedDC = pDC->SaveDC(); CRect rectItem; POINT pt; GetItemRect(nTabIndex, &rectItem); GetCursorPos(&pt); ScreenToClient(&pt); if (rectItem.PtInRect(pt)) m_iIndexMouseOver = nTabIndex; pDC->SetBkMode(TRANSPARENT); pDC->FillSolidRect(rect, ::GetSysColor(COLOR_BTNFACE)); //** Draw the image CImageList* pImageList = GetImageList(); if (pImageList && item.iImage >= 0) { rect.left += pDC->GetTextExtent(_T(" ")).cx; IMAGEINFO info; pImageList->GetImageInfo(item.iImage, &info); CRect ImageRect(info.rcImage); int nYpos = rect.top; pImageList->Draw(pDC, item.iImage, CPoint(rect.left, nYpos), ILD_TRANSPARENT); rect.left += ImageRect.Width(); } if (!IsTabEnabled(nTabIndex)) { pDC->SetTextColor(crDisabled); rect.top -= ::GetSystemMetrics(SM_CYEDGE); pDC->DrawText(label, rect, DT_SINGLELINE|DT_VCENTER|DT_CENTER); } else { //** selected item ----- if (bSelected) pDC->SetTextColor(crSelected); else //** other item --- { if (m_bColorMouseOver && nTabIndex == m_iIndexMouseOver) { pDC->SetTextColor(m_crMouseOver); } else { pDC->SetTextColor(crNormal); } } rect.top -= ::GetSystemMetrics(SM_CYEDGE); pDC->DrawText(label, rect, DT_SINGLELINE|DT_VCENTER|DT_CENTER); } pDC->RestoreDC(nSavedDC); }