ON_WM_PAINT()
ON_NOTIFY_REFLECT_EX(TCN_SELCHANGE, OnSelchange)
ON_WM_DRAWITEM_REFLECT()
+ ON_WM_MOUSEMOVE()
+ ON_WM_MOUSELEAVE()
+ ON_WM_LBUTTONDOWN()
+ ON_WM_LBUTTONUP()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
*/
void CMDITabBar::OnContextMenu(CWnd *pWnd, CPoint point)
{
- TCHITTESTINFO hit;
- hit.pt = point;
- ScreenToClient(&hit.pt);
- int index = HitTest(&hit);
+ CPoint ptClient = point;
+ ScreenToClient(&ptClient);
+ int index = GetItemIndexFromPoint(ptClient);
if (index < 0) return;
TCITEM tci;
*/
void CMDITabBar::OnMButtonDown(UINT nFlags, CPoint point)
{
- TCHITTESTINFO hit;
- hit.pt = point;
- int index = HitTest(&hit);
+ int index = GetItemIndexFromPoint(point);
if (index < 0)
return;
void CMDITabBar::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
- TCHAR szBuf[256];
- TCITEM item;
- LPDRAWITEMSTRUCT lpDraw = (LPDRAWITEMSTRUCT)lpDrawItemStruct;
+ TCHAR szBuf[256];
+ TCITEM item;
+ LPDRAWITEMSTRUCT lpDraw = (LPDRAWITEMSTRUCT)lpDrawItemStruct;
- item.mask = TCIF_TEXT | TCIF_PARAM;
- item.pszText = szBuf;
- item.cchTextMax = sizeof(szBuf) / sizeof(TCHAR);
- TabCtrl_GetItem(this->m_hWnd, lpDraw->itemID, &item);
+ item.mask = TCIF_TEXT | TCIF_PARAM;
+ item.pszText = szBuf;
+ item.cchTextMax = sizeof(szBuf) / sizeof(TCHAR);
+ TabCtrl_GetItem(this->m_hWnd, lpDraw->itemID, &item);
- RECT rc = lpDraw->rcItem;
- if (lpDraw->itemState & ODS_SELECTED)
- {
- rc.left += 9;
- rc.top += 2;
- FillRect(lpDraw->hDC, &lpDraw->rcItem, (HBRUSH)GetStockObject(WHITE_BRUSH));
- }
- else
- {
- rc.left += 5;
- rc.top += 3;
- }
- rc.left += 16;
- SetTextColor(lpDraw->hDC, RGB(0, 0, 0));
- SetBkMode(lpDraw->hDC, TRANSPARENT);
- HICON hIcon = CWnd::FromHandle((HWND)item.lParam)->GetIcon(TRUE);
- if (!hIcon)
- hIcon = (HICON)GetClassLongPtr((HWND)item.lParam, GCLP_HICONSM);
- if (hIcon)
- DrawIconEx(lpDraw->hDC, rc.left - 16 - 2, 5, hIcon, 16, 16, 0, NULL, DI_NORMAL);
- DrawText(lpDraw->hDC, szBuf, -1, &rc, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ RECT rc = lpDraw->rcItem;
+ if (lpDraw->itemState & ODS_SELECTED)
+ {
+ rc.left += 9;
+ rc.top += 2;
+ FillRect(lpDraw->hDC, &lpDraw->rcItem, (HBRUSH)GetStockObject(WHITE_BRUSH));
+ }
+ else
+ {
+ rc.left += 5;
+ rc.top += 3;
+ }
+ rc.left += 16;
+ SetTextColor(lpDraw->hDC, RGB(0, 0, 0));
+ SetBkMode(lpDraw->hDC, TRANSPARENT);
+ HICON hIcon = CWnd::FromHandle((HWND)item.lParam)->GetIcon(TRUE);
+ if (!hIcon)
+ hIcon = (HICON)GetClassLongPtr((HWND)item.lParam, GCLP_HICONSM);
+ if (hIcon)
+ DrawIconEx(lpDraw->hDC, rc.left - 16 - 2, 5, hIcon, 16, 16, 0, NULL, DI_NORMAL);
+ DrawText(lpDraw->hDC, szBuf, -1, &rc, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+
+ int nItem = GetItemIndexFromPoint(m_rcCurrentCloseButtom.CenterPoint());
+ if (nItem == lpDraw->itemID)
+ {
+ CPoint pt;
+ GetCursorPos(&pt);
+ ScreenToClient(&pt);
+ CRect rc = GetCloseButtonRect(nItem);
+ DrawFrameControl(lpDraw->hDC, &rc, DFC_CAPTION,
+ DFCS_CAPTIONCLOSE | DFCS_FLAT | (rc.PtInRect(pt) ? DFCS_HOT : 0) |
+ ((m_bCloseButtonDown && rc.PtInRect(pt)) ? DFCS_PUSHED : 0));
+ }
+}
+
+void CMDITabBar::OnMouseMove(UINT nFlags, CPoint point)
+{
+ CRect rc = GetCloseButtonRect(GetItemIndexFromPoint(point));
+ InvalidateRect(&rc);
+ if (rc != m_rcCurrentCloseButtom)
+ InvalidateRect(&m_rcCurrentCloseButtom);
+ m_rcCurrentCloseButtom = rc;
+ if (!m_bMouseTracking)
+ {
+ TRACKMOUSEEVENT tme = {0};
+ tme.cbSize = sizeof(TRACKMOUSEEVENT);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = m_hWnd;
+ TrackMouseEvent(&tme);
+ m_bMouseTracking = true;
+ }
+}
+
+void CMDITabBar::OnMouseLeave()
+{
+ TRACKMOUSEEVENT tme = {0};
+ tme.cbSize = sizeof(TRACKMOUSEEVENT);
+ tme.dwFlags = TME_LEAVE | TME_CANCEL;
+ tme.hwndTrack = m_hWnd;
+ TrackMouseEvent(&tme);
+ m_bMouseTracking = false;
+ InvalidateRect(&m_rcCurrentCloseButtom);
+ m_rcCurrentCloseButtom = CRect();
+ m_bCloseButtonDown = false;
+}
+
+void CMDITabBar::OnLButtonDown(UINT nFlags, CPoint point)
+{
+ m_bCloseButtonDown = !!m_rcCurrentCloseButtom.PtInRect(point);
+ InvalidateRect(m_rcCurrentCloseButtom);
+ CWnd::OnLButtonDown(nFlags, point);
+}
+
+void CMDITabBar::OnLButtonUp(UINT nFlags, CPoint point)
+{
+ if (m_bCloseButtonDown && m_rcCurrentCloseButtom.PtInRect(point))
+ OnMButtonDown(nFlags, point);
+ InvalidateRect(m_rcCurrentCloseButtom);
+ m_bCloseButtonDown = false;
+ CWnd::OnLButtonUp(nFlags, point);
+}
+
+CRect CMDITabBar::GetCloseButtonRect(int nItem)
+{
+ CRect rc;
+ GetItemRect(nItem, &rc);
+ rc.left = rc.right - 20;
+ rc.right = rc.left + 16;
+ int y = (rc.top + rc.bottom) / 2;
+ rc.top = y - 16 / 2 + 1;
+ rc.bottom = rc.top + 16;
+ return rc;
+}
+
+int CMDITabBar::GetItemIndexFromPoint(CPoint point)
+{
+ TCHITTESTINFO hit;
+ hit.pt = point;
+ return HitTest(&hit);
}
BOOL m_bInSelchange;
CMDIFrameWnd *m_pMainFrame;
+ bool m_bMouseTracking;
+ bool m_bCloseButtonDown;
+ CRect m_rcCurrentCloseButtom;
public:
- CMDITabBar() : m_bInSelchange(FALSE), m_pMainFrame(NULL) {}
+ CMDITabBar() : m_bInSelchange(FALSE), m_pMainFrame(NULL), m_bMouseTracking(false), m_bCloseButtonDown(false) {}
virtual ~CMDITabBar() {}
BOOL Create(CMDIFrameWnd* pParentWnd);
void UpdateTabs();
{ ASSERT(::IsWindow(m_hWnd)); return (int)::SendMessage(m_hWnd, TCM_SETCURSEL, nItem, 0L); }
int HitTest(TCHITTESTINFO* pHitTestInfo) const
{ ASSERT(::IsWindow(m_hWnd)); return (int)::SendMessage(m_hWnd, TCM_HITTEST, 0, (LPARAM) pHitTestInfo); }
+ BOOL GetItemRect(int nItem, LPRECT lpRect) const
+ { ASSERT(::IsWindow(m_hWnd)); return (BOOL)::SendMessage(m_hWnd, TCM_GETITEMRECT, (WPARAM)nItem, (LPARAM)lpRect); }
protected:
//{{AFX_MSG(CMDITabBar)
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
afx_msg void OnMButtonDown(UINT nFlags, CPoint point);
afx_msg void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
+ afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+ afx_msg void OnMouseLeave();
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
+
+private:
+ CRect GetCloseButtonRect(int nItem);
+ int GetItemIndexFromPoint(CPoint pt);
};
#endif // MDITABBAR_H