void CXTPTabCtrlButton::CheckForMouseOver (CWnd* pWnd, CPoint pt) { if (!PtInRect (pt) && DB_ISOVER(m_wStyle)) { m_wStyle &= ~DB_OVER; pWnd->InvalidateRect (m_Rect, FALSE); } if (!DB_ISOVER(m_wStyle) && PtInRect (pt) && DB_ISENABLED(m_wStyle)) { TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT), TME_LEAVE, *pWnd, 0 }; _TrackMouseEvent(&tme); m_wStyle |= DB_OVER; pWnd->InvalidateRect (m_Rect, FALSE); } }
DWORD CDrawButton::Click (CWnd* pWnd, CPoint pt, UINT nIDRepeat) const { // don't handle if capture already set if ( ::GetCapture() != NULL || !DB_ISENABLED(m_wStyle) ) { return DB_DEFAULT; } // set capture to the window which received this message pWnd->SetCapture(); ASSERT(pWnd == CWnd::GetCapture()); bool bDown = false, bClick = false; int nSpinType = DB_PRESSED; CRect rcBtn(m_Rect); if ( DB_GETTYPE(m_wStyle) == DB_UPDOWN ) { if ( pt.y >= (rcBtn.top+rcBtn.bottom)/2 ) { nSpinType = DB_PRESSED2; rcBtn.top = (rcBtn.top+rcBtn.bottom)/2; } else { rcBtn.bottom = (rcBtn.top+rcBtn.bottom)/2; } if ( nIDRepeat != 0 ) { s_wNotify = (nSpinType == DB_PRESSED) ? LOWORD(nIDRepeat) : HIWORD(nIDRepeat); if ( !pWnd->SetTimer (nIDRepeat, 100, &CDrawButton_TimerProcRepeat) ) { nIDRepeat = 0; } } } // get messages until capture lost or cancelled/accepted for(;;) //while ( true ) { bool bNewDown = ::PtInRect (rcBtn, pt) != 0; if ( bNewDown != bDown ) { bDown = bNewDown; if ( DB_ISWINDOWDC(m_wStyle) ) { CWindowDC cDC (pWnd); Draw (&cDC, m_wStyle|(bDown ? nSpinType : DB_DEFAULT)); } else { CClientDC cDC (pWnd); Draw (&cDC, m_wStyle|(bDown ? nSpinType : DB_DEFAULT)); } } MSG msg; VERIFY(::GetMessage(&msg, NULL, 0, 0)); if ( CWnd::GetCapture() != pWnd ) { DispatchMessage (&msg); goto ExitLoop; } switch ( msg.message ) { // handle movement messages case WM_MOUSEMOVE: pt.x = (short signed)LOWORD(msg.lParam); pt.y = (short signed)HIWORD(msg.lParam); if ( DB_ISWINDOWDC(m_wStyle) ) { pWnd->ClientToScreen (&pt); pt -= CWindowRect(pWnd).TopLeft(); } break; // handle accept messages case WM_LBUTTONUP: bClick = bDown; goto ExitLoop; // handle cancel messages case WM_KEYDOWN: if ( msg.wParam != VK_ESCAPE ) { break; } // continue... case WM_CANCELMODE: case WM_RBUTTONDOWN: goto ExitLoop; case WM_TIMER: if ( msg.wParam == nIDRepeat && !bDown ) { break; } // continue... default: // just dispatch rest of the messages DispatchMessage (&msg); break; } } ExitLoop: ReleaseCapture(); if ( DB_GETTYPE(m_wStyle) == DB_UPDOWN && nIDRepeat != 0 ) { pWnd->KillTimer (nIDRepeat); } if ( bDown ) { if ( DB_ISWINDOWDC(m_wStyle) ) { CWindowDC cDC (pWnd); Draw (&cDC); } else { CClientDC cDC (pWnd); Draw (&cDC); } } return bClick ? (DB_GETTYPE(m_wStyle)|nSpinType) : DB_DEFAULT; }
void CDrawButton::Draw (CDC* pDC, DWORD wStyle) const { if ( wStyle == DB_DEFAULT ) { wStyle = m_wStyle; } ASSERT (pDC != NULL); CRect rc (m_Rect); CPenDC pen (pDC->m_hDC, ::GetSysColor (COLOR_3DFACE)); CBrushDC brush (pDC->m_hDC, ::GetSysColor (COLOR_3DFACE)); if ( DB_ISBORDER(m_wStyle) && !DB_ISFLAT(wStyle) ) { pDC->MoveTo (rc.right-1, rc.top); pDC->LineTo (rc.left, rc.top); pDC->LineTo (rc.left, rc.bottom); pDC->SetPixel (rc.right-1, rc.top, ::GetSysColor (COLOR_3DDKSHADOW)); rc.left++; rc.top++; } COLORREF crBorder = 0, crPressed = 0, crOver = 0, crText = 0; if ( DB_ISFLAT(wStyle) ) { crBorder = ::GetSysColor (COLOR_HIGHLIGHT); crPressed = HLS_TRANSFORM (crBorder, +50, -50); crOver = HLS_TRANSFORM (crBorder, +70, -57); } if ( DB_GETTYPE(wStyle) == DB_UPDOWN ) { if ( !DB_ISPRESSED2(wStyle) ) { if ( DB_ISFLAT(wStyle) ) { CRect rcBtn (rc.left, rc.top, rc.right, (rc.top+rc.bottom)/2+1); if ( DB_ISENABLED(wStyle) && DB_ISOVER(wStyle) ) { pen.Color (crBorder); brush.Color (DB_ISPRESSED(wStyle) ? crPressed : crOver); pDC->Rectangle (rcBtn); } else if ( !DB_ISTRANSPARENT(wStyle) ) { pen.Color (::GetSysColor (DB_ISBORDER(m_wStyle) ? COLOR_3DSHADOW : COLOR_WINDOW)); pDC->Rectangle (rcBtn); } } else { CRect rcBtn (rc.left, rc.top, rc.right, (rc.top+rc.bottom)/2); pDC->DrawFrameControl (rcBtn, DFC_BUTTON, DFCS_BUTTONPUSH|(DB_ISPRESSED1(wStyle) ? DFCS_PUSHED : 0)); } } if ( !DB_ISPRESSED(wStyle) && !DB_ISFLAT(wStyle) ) { pDC->MoveTo (rc.left, (rc.top+rc.bottom)/2); pDC->LineTo (rc.right, (rc.top+rc.bottom)/2); } if ( !DB_ISPRESSED1(wStyle) ) { if ( DB_ISFLAT(wStyle) ) { CRect rcBtn (rc.left, (rc.top+rc.bottom)/2/*+rc.Height()%2*/, rc.right, rc.bottom); if ( DB_ISENABLED(wStyle) && DB_ISOVER(wStyle) ) { pen.Color (crBorder); brush.Color (DB_ISPRESSED(wStyle) ? crPressed : crOver); pDC->Rectangle (rcBtn); } else if ( !DB_ISTRANSPARENT(wStyle) ) { pen.Color (::GetSysColor (DB_ISBORDER(m_wStyle) ? COLOR_3DSHADOW : COLOR_WINDOW)); pDC->Rectangle (rcBtn); } } else { CRect rcBtn (rc.left, (rc.top+rc.bottom)/2+rc.Height()%2, rc.right, rc.bottom); pDC->DrawFrameControl (rcBtn, DFC_BUTTON, DFCS_BUTTONPUSH|(DB_ISPRESSED2(wStyle) ? DFCS_PUSHED : 0)); } } if ( DB_ISFLAT(wStyle) ) { crText = DB_ISENABLED(wStyle) && pDC->GetPixel (rc.left+1, rc.top+1) == crOver ? RGB(0,0,0) : ::GetSysColor (COLOR_BTNTEXT); pen.Color (DB_ISPRESSED(wStyle) ? RGB(240,240,240) : DB_ISENABLED(wStyle) ? crText : ::GetSysColor (COLOR_GRAYTEXT)); } else { pen.Color (::GetSysColor (DB_ISENABLED(wStyle) ? COLOR_BTNTEXT : COLOR_GRAYTEXT)); } if ( !DB_ISPRESSED2(wStyle) ) { _DrawTriangle (pDC, (rc.left+rc.right)/2 + ((DB_ISPRESSED1(wStyle)&&!DB_ISFLAT(wStyle)) ? 1 : 0), (rc.top*3+rc.bottom)/4 + ((DB_ISPRESSED1(wStyle)||DB_ISFLAT(wStyle)) ? 1 : 0) - 2, 3, false); } if ( !DB_ISPRESSED1(wStyle) ) { _DrawTriangle (pDC, (rc.left+rc.right)/2 + ((DB_ISPRESSED2(wStyle)&&!DB_ISFLAT(wStyle)) ? 1 : 0), (rc.top+rc.bottom*3)/4 + ((DB_ISPRESSED2(wStyle)&&!DB_ISFLAT(wStyle)) ? 1 : 0) + 1, 3, true); } } else { if ( DB_ISFLAT(wStyle) ) { if ( DB_ISENABLED(wStyle) && DB_ISOVER(wStyle) ) { pen.Color (crBorder); brush.Color (DB_ISPRESSED(wStyle) ? crPressed : crOver); pDC->Rectangle (rc); } else if ( !DB_ISTRANSPARENT(wStyle) ) { pen.Color (::GetSysColor (DB_ISBORDER(m_wStyle) ? COLOR_3DSHADOW : COLOR_WINDOW)); pDC->Rectangle (rc); } } else { pDC->DrawFrameControl (rc, DFC_BUTTON, DFCS_BUTTONPUSH|(DB_ISPRESSED(wStyle) ? DFCS_PUSHED : 0)); } switch ( DB_GETTYPE(wStyle) ) { case DB_3POINTS: if ( DB_ISFLAT(wStyle) ) { crText = DB_ISENABLED(wStyle) && pDC->GetPixel (rc.left+1, rc.top+1) == crOver ? RGB(0,0,0) : ::GetSysColor (COLOR_BTNTEXT); crText = DB_ISPRESSED(wStyle) ? RGB(240,240,240) : DB_ISENABLED(wStyle) ? crText : ::GetSysColor (COLOR_GRAYTEXT); } else { crText = ::GetSysColor (DB_ISENABLED(wStyle) ? COLOR_BTNTEXT : COLOR_GRAYTEXT); } crText = pDC->SetTextColor (crText); pDC->SetBkMode (TRANSPARENT); pDC->DrawText (_T("..."), 3, CRect(rc.left + ((DB_ISPRESSED(wStyle)||DB_ISFLAT(wStyle)) ? 2 : 1), rc.top, rc.right, rc.bottom + ((DB_ISPRESSED(wStyle)&&!DB_ISFLAT(wStyle)) ? 1 : 0)), DT_LEFT|DT_BOTTOM|DT_SINGLELINE); pDC->SetTextColor (crText); break; case DB_UP: case DB_DOWN: if ( DB_ISFLAT(wStyle) ) { crText = DB_ISENABLED(wStyle) && pDC->GetPixel (rc.left+1, rc.top+1) == crOver ? RGB(0,0,0) : ::GetSysColor (COLOR_BTNTEXT); pen.Color (DB_ISPRESSED(wStyle) ? RGB(240,240,240) : DB_ISENABLED(wStyle) ? crText : ::GetSysColor (COLOR_GRAYTEXT)); } else { pen.Color (::GetSysColor (DB_ISENABLED(wStyle) ? COLOR_BTNTEXT : COLOR_GRAYTEXT)); } _DrawTriangle (pDC, (rc.left+rc.right)/2 + ((DB_ISPRESSED(wStyle)&&!DB_ISFLAT(wStyle)) ? 1 : 0), (rc.top+rc.bottom)/2 + ((DB_ISPRESSED(wStyle)||DB_ISFLAT(wStyle)) ? 2 : 1) - ((DB_GETTYPE(wStyle) == DB_UP) ? 3 : 0), 4, DB_GETTYPE(wStyle) == DB_DOWN); break; case DB_CROSS: { int x1 = (rc.left*2+rc.right)/3-1; int x2 = (rc.left+rc.right*2)/3; int y1 = (rc.top*2+rc.bottom)/3-1; int y2 = (rc.top+rc.bottom*2)/3-1; if ( DB_ISFLAT(wStyle) ) { x2++; y2++; } else if ( DB_ISPRESSED(wStyle) ) { x1++; y1++; x2++; y2++; } if ( DB_ISFLAT(wStyle) ) { crText = DB_ISENABLED(wStyle) && pDC->GetPixel (x1, y1+1) == crOver ? RGB(0,0,0) : ::GetSysColor (COLOR_BTNTEXT); pen.Color (DB_ISPRESSED(wStyle) ? RGB(240,240,240) : DB_ISENABLED(wStyle) ? crText : ::GetSysColor (COLOR_GRAYTEXT)); } else { pen.Color (::GetSysColor (DB_ISENABLED(wStyle) ? COLOR_BTNTEXT : COLOR_GRAYTEXT)); } pDC->MoveTo (x1, y1); pDC->LineTo (x2, y2+1); pDC->MoveTo (x1+1, y1); pDC->LineTo (x2+1, y2+1); pDC->MoveTo (x2-1, y1); pDC->LineTo (x1-1, y2+1); pDC->MoveTo (x2, y1); pDC->LineTo (x1, y2+1); } break; } } }
DWORD CXTPTabCtrlButton::Click (CXTPTabCtrlButtons* pWnd, CPoint pt, BOOL bRepeat) { if ((::GetCapture() != NULL) || !DB_ISENABLED(m_wStyle)) { return FALSE; } pWnd->SetCapture(); ASSERT(pWnd == CWnd::GetCapture()); BOOL bDown = FALSE, bClick = FALSE; CRect rcBtn(m_Rect); UINT_PTR nTimer = (bRepeat == FALSE) ? 0 : SetTimer(pWnd->GetSafeHwnd(), 1, 150, NULL); for (;;) { if (bRepeat && DB_ISENABLED(m_wStyle)) { ASSERT(m_pTabCtrl); if (!m_pTabCtrl) return FALSE; int nCount = m_pTabCtrl->GetItemCount(); CRect rc; m_pTabCtrl->GetItemRect(-1, rc); TCHITTESTINFO hi = {{5, rc.CenterPoint().y}}; int nFirst = m_pTabCtrl->HitTest(&hi); if (m_wStyle & DB_LEFT) { if (nFirst > 0) m_pTabCtrl->SendMessage(WM_HSCROLL, MAKEWPARAM(SB_THUMBPOSITION, nFirst - 1), 0); } else if (nCount > 0) { m_pTabCtrl->SendMessage(WM_HSCROLL, MAKEWPARAM(SB_THUMBPOSITION, nFirst + 1), 0); } m_pTabCtrl->Invalidate(FALSE); pWnd->Invalidate(FALSE); } BOOL bNewDown = ::PtInRect (rcBtn, pt) != 0; if (bNewDown != bDown) { bDown = bNewDown; if (bDown) m_wStyle = m_wStyle | DB_PRESSED; else m_wStyle &= ~DB_PRESSED; pWnd->InvalidateRect (m_Rect, FALSE); } MSG msg; VERIFY(::GetMessage(&msg, NULL, 0, 0)); if (CWnd::GetCapture() != pWnd) { DispatchMessage (&msg); goto ExitLoop; } switch (msg.message) { case WM_MOUSEMOVE: pt = CPoint((short signed)LOWORD(msg.lParam), (short signed)HIWORD(msg.lParam)); break; case WM_LBUTTONUP: bClick = bDown; goto ExitLoop; case WM_KEYDOWN: if (msg.wParam != VK_ESCAPE) break; case WM_CANCELMODE: case WM_RBUTTONDOWN: goto ExitLoop; default: DispatchMessage (&msg); break; } } ExitLoop: ReleaseCapture(); if (nTimer) KillTimer(*pWnd, nTimer); m_wStyle &= ~DB_PRESSED; CheckForMouseOver (pWnd, pt); pWnd->InvalidateRect (m_Rect, FALSE); return bClick; }