?? scrollerctrl.cpp
字號:
if ( m_pbmpPattern->GetBitmap(&bitmap) && bitmap.bmWidth > 0 && bitmap.bmHeight > 0 )
{
if ( m_bTilePattern )
{
for (int y=0; y<rectClient.bottom+bitmap.bmHeight; y += bitmap.bmHeight)
{
for (int x=0; x<rectClient.right+bitmap.bmWidth; x += bitmap.bmWidth)
{
pDC->BitBlt(x,y, bitmap.bmWidth, bitmap.bmHeight, &dcPat, 0,0, SRCCOPY);
}
}
}
else
{
pDC->FillSolidRect(rectClient, m_crBackground);
pDC->BitBlt((m_sizeBuffer.cx-bitmap.bmWidth)/2,(m_sizeBuffer.cy-bitmap.bmHeight)/2, bitmap.bmWidth, bitmap.bmHeight, &dcPat, 0,0, SRCCOPY);
}
}
dcPat.SelectObject(pbmpOld);
}
}
// Draws the logo (if specified) at the given offset.
// If bDraw is false, calculates height, but does not draw.
// Returns height of logo.
int CScrollerCtrl::DrawLogo(CDC* pDC, int nOffset, BOOL bDraw)
{
if ( NULL == m_pbmpLogo )
return 0;
BITMAP bitmap;
memset(&bitmap,0,sizeof(bitmap));
if ( m_pbmpLogo->GetBitmap(&bitmap) && bDraw && bitmap.bmWidth > 0 && bitmap.bmHeight > 0 )
{
CDC dcLogo;
dcLogo.CreateCompatibleDC(pDC);
CBitmap* pbmpOld = dcLogo.SelectObject(m_pbmpLogo);
pDC->BitBlt((m_sizeBuffer.cx-bitmap.bmWidth)/2,nOffset, bitmap.bmWidth, bitmap.bmHeight, &dcLogo, 0,0, SRCCOPY);
dcLogo.SelectObject(pbmpOld);
}
return bitmap.bmHeight;
}
// Draws the text at the specified offset.
// If bDraw is false, will calculate text height, but not draw.
// Returns height of text.
int CScrollerCtrl::DrawBodyText(CDC* pDC, int nOffset, BOOL bDraw)
{
CRect rect(nMARGIN,nOffset,m_sizeBuffer.cx-nMARGIN,m_sizeBuffer.cy);
UINT uFlags = bDraw ? DT_EXPANDTABS|DT_NOPREFIX|DT_WORDBREAK : DT_EXPANDTABS|DT_NOCLIP|DT_CALCRECT|DT_NOPREFIX|DT_WORDBREAK;
CFont* pOldFont = pDC->SelectObject(&m_font);
pDC->SetBkMode(TRANSPARENT);
// draw shadow if displayed over pattern
if ( bDraw && NULL != m_pbmpPattern )
{
// offset 1/10 of font size
LOGFONT logFont;
m_font.GetLogFont(&logFont);
int nShadowOffset = MulDiv(-logFont.lfHeight, 72, pDC->GetDeviceCaps(LOGPIXELSY)*10);
// get color between forground and background for shadow (not correct i'm sure) int red = (GetRValue(m_crForeground) + GetRValue(m_crBackground)*2)/3; int green = (GetGValue(m_crForeground) + GetGValue(m_crBackground)*2)/3; int blue = (GetBValue(m_crForeground) + GetBValue(m_crBackground)*2)/3; COLORREF crDarker = RGB(red, green, blue);
pDC->SetTextColor(crDarker);
rect.OffsetRect(nShadowOffset,nShadowOffset);
pDC->DrawText(m_strText, &rect, uFlags);
rect.OffsetRect(-nShadowOffset,-nShadowOffset);
}
if(m_eState == PAUSED)
pDC->SetTextColor(m_crForeground);
else
{
pDC->SetTextColor(RGB((int)160,0,0));
}
int nHeight = pDC->DrawText(m_strText, &rect, uFlags);
pDC->SelectObject(pOldFont);
return nHeight;
}
// indicate that this control will process arrow keystrokes.
UINT CScrollerCtrl::OnGetDlgCode()
{
if ( GetStyle()&WS_TABSTOP )
return DLGC_WANTARROWS;
return 0;
}
// Grab focus if required.
void CScrollerCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
if ( GetStyle()&WS_TABSTOP )
SetFocus();
}
// Handle keyboard scrolling.
void CScrollerCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
switch ( nChar )
{
case VK_UP:
PostMessage(WM_VSCROLL, SB_LINEUP);
break;
case VK_DOWN:
PostMessage(WM_VSCROLL, SB_LINEDOWN);
break;
case VK_PRIOR: // why not VK_PAGEUP?
PostMessage(WM_VSCROLL, SB_PAGEUP);
break;
case VK_NEXT: // why not VK_PAGEDOWN?
PostMessage(WM_VSCROLL, SB_PAGEDOWN);
break;
}
}
// Handle scrolling.
// This can be triggered by mouse wheel and keyboard,
// as well as the scrollbar.
void CScrollerCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if ( !(GetStyle()&WS_TABSTOP) )
return;
// delay autoscroll after manual scroll
if ( m_nScrollPause > m_nScrollDelay )
{
m_eState = PAUSED;
m_unTimerPause = SetTimer(m_unTimerPause, m_nScrollPause, NULL);
}
switch (nSBCode)
{
case SB_BOTTOM: // Scroll to bottom.
m_nScrollOffset = m_sizeBuffer.cy-m_nContentHeight;
break;
case SB_TOP: // Scroll to top.
m_nScrollOffset = 0;
break;
case SB_LINEDOWN: // Scroll one line down.
m_nScrollOffset -= 8;
break;
case SB_LINEUP: // Scroll one line up.
m_nScrollOffset += 8;
break;
case SB_PAGEDOWN: // Scroll one page down.
m_nScrollOffset -= m_sizeBuffer.cy;
break;
case SB_PAGEUP: // Scroll one page up.
m_nScrollOffset += m_sizeBuffer.cy;
break;
case SB_THUMBPOSITION:
case SB_THUMBTRACK:
m_nScrollOffset = -((int)nPos);
break;
default:
return;
}
// constrain
if ( m_nScrollOffset < m_sizeBuffer.cy-m_nContentHeight )
m_nScrollOffset = m_sizeBuffer.cy-m_nContentHeight;
else if ( m_nScrollOffset > 0 )
m_nScrollOffset = 0;
// scroll
SetScrollPos(SB_VERT, -m_nScrollOffset);
Invalidate(FALSE);
}
// Handle mouse wheel scrolling.
// I'll put actual effort into handling non-WHEEL_DELTA increments
// when i actually get a mouse that sends them. ;~)
BOOL CScrollerCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
int nDist = abs(zDelta)/WHEEL_DELTA+1;
while ( nDist-- )
{
PostMessage(WM_VSCROLL, zDelta > 0 ? SB_LINEUP : SB_LINEDOWN);
}
return TRUE;
}
// Timers are used for three purposes:
// + Periodic checking to show/hide the scrollbar
// + Automatic scrolling (when m_eState == SCROLLING)
// + Ending automatic scrolling pauses (when m_eState == PAUSED)
// This is accomplished via two timers:
// The first does double duty, handling both the scrollbar and
// automatic scrolling; it is active for the life of the window.
// The second is used for ending autoscroll pauses.
void CScrollerCtrl::OnTimer(UINT nIDEvent)
{
// don't autoscroll or hide scrollbar when user is dragging the scroll button.
if ( this == GetCapture() )
return;
// the scrollbar can be shown if the following are true:
// + The content size is larger than the window
// + The mouse cursor is over the window
// + The top-level parent containing this control is active
if ( m_bShowScroll )
{
CRect rectWindow;
GetWindowRect(&rectWindow);
CPoint pntCursor;
::GetCursorPos(&pntCursor);
if ( m_sizeBuffer.cy < m_nContentHeight && GetTopLevelParent() == GetActiveWindow() && rectWindow.PtInRect(pntCursor) )
{
SetScrollRange(SB_VERT, 0, m_nContentHeight-m_sizeBuffer.cy, FALSE);
SetScrollPos(SB_VERT, -m_nScrollOffset, TRUE);
ShowScrollBar(SB_VERT, TRUE);
}
else if ( this != GetCapture() )
{
ShowScrollBar(SB_VERT, FALSE);
}
}
if ( nIDEvent == m_unTimerPause )
{
m_eState = SCROLLING;
KillTimer(m_unTimerPause);
}
if ( m_eState == SCROLLING )
{
--m_nScrollOffset;
if ( m_nContentHeight+m_nScrollOffset < 0 )
{
// scrolling is complete; restart
m_nScrollOffset = m_bWrap ? 0 : m_sizeBuffer.cy;
CWnd* pwndParent = GetParent();
if ( NULL != pwndParent )
pwndParent->SendMessage(WM_COMMAND, MAKELPARAM(GetDlgCtrlID(), SC_SCROLL_COMPLETE), (LPARAM)GetSafeHwnd());
}
// pause at top and bottom
if ( 0 == m_nScrollOffset || (m_nScrollOffset+m_nContentHeight == m_sizeBuffer.cy && m_sizeBuffer.cy < m_nContentHeight) )
{
if ( m_nScrollPause > m_nScrollDelay )
{
m_eState = PAUSED;
m_unTimerPause = SetTimer(m_unTimerPause, m_nScrollPause, NULL);
}
}
Invalidate(FALSE);
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -