📄 atlscrl.h
字号:
// Windows Template Library - WTL version 7.0
// Copyright (C) 1997-2002 Microsoft Corporation
// All rights reserved.
//
// This file is a part of the Windows Template Library.
// The code and information is provided "as-is" without
// warranty of any kind, either expressed or implied.
#ifndef __ATLSCRL_H__
#define __ATLSCRL_H__
#pragma once
#ifndef __cplusplus
#error ATL requires C++ compilation (use a .cpp suffix)
#endif
#ifndef __ATLAPP_H__
#error atlscrl.h requires atlapp.h to be included first
#endif
#ifndef __ATLWIN_H__
#error atlscrl.h requires atlwin.h to be included first
#endif
#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
#include <zmouse.h>
#endif //!((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
/////////////////////////////////////////////////////////////////////////////
// Classes in this file
//
// CScrollImpl<T>
// CScrollWindowImpl<T, TBase, TWinTraits>
// CMapScrollImpl<T>
// CMapScrollWindowImpl<T, TBase, TWinTraits>
// CFSBWindowT<TBase>
namespace WTL
{
/////////////////////////////////////////////////////////////////////////////
// CScrollImpl - Provides scrolling support to any window
// Scroll extended styles
#define SCRL_SCROLLCHILDREN 0x00000001
#define SCRL_ERASEBACKGROUND 0x00000002
#define SCRL_NOTHUMBTRACKING 0x00000004
#if (WINVER >= 0x0500)
#define SCRL_SMOOTHSCROLL 0x00000008
#endif //(WINVER >= 0x0500)
template <class T>
class CScrollImpl
{
public:
enum { uSCROLL_FLAGS = SW_INVALIDATE };
POINT m_ptOffset;
SIZE m_sizeAll;
SIZE m_sizeLine;
SIZE m_sizePage;
SIZE m_sizeClient;
int m_zDelta; // current wheel value
int m_nWheelLines; // number of lines to scroll on wheel
#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
UINT m_uMsgMouseWheel; // MSH_MOUSEWHEEL
// Note that this message must be forwarded from a top level window
#endif //!((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
UINT m_uScrollFlags;
DWORD m_dwExtendedStyle; // scroll specific extended styles
// Constructor
CScrollImpl() : m_zDelta(0), m_nWheelLines(3), m_uScrollFlags(0U), m_dwExtendedStyle(0)
{
m_ptOffset.x = 0;
m_ptOffset.y = 0;
m_sizeAll.cx = 0;
m_sizeAll.cy = 0;
m_sizePage.cx = 0;
m_sizePage.cy = 0;
m_sizeLine.cx = 0;
m_sizeLine.cy = 0;
m_sizeClient.cx = 0;
m_sizeClient.cy = 0;
SetScrollExtendedStyle(SCRL_SCROLLCHILDREN | SCRL_ERASEBACKGROUND);
}
// Attributes & Operations
DWORD GetScrollExtendedStyle() const
{
return m_dwExtendedStyle;
}
DWORD SetScrollExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0)
{
DWORD dwPrevStyle = m_dwExtendedStyle;
if(dwMask == 0)
m_dwExtendedStyle = dwExtendedStyle;
else
m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask);
// cache scroll flags
T* pT = static_cast<T*>(this);
pT; // avoid level 4 warning
m_uScrollFlags = pT->uSCROLL_FLAGS | (IsScrollingChildren() ? SW_SCROLLCHILDREN : 0) | (IsErasingBackground() ? SW_ERASE : 0);
#if (WINVER >= 0x0500)
m_uScrollFlags |= (IsSmoothScroll() ? SW_SMOOTHSCROLL : 0);
#endif //(WINVER >= 0x0500)
return dwPrevStyle;
}
// offset operations
void SetScrollOffset(int x, int y, BOOL bRedraw = TRUE)
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
m_ptOffset.x = x;
m_ptOffset.y = y;
SCROLLINFO si;
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = m_ptOffset.x;
pT->SetScrollInfo(SB_HORZ, &si, bRedraw);
si.nPos = m_ptOffset.y;
pT->SetScrollInfo(SB_VERT, &si, bRedraw);
if(bRedraw)
pT->Invalidate();
}
void SetScrollOffset(POINT ptOffset, BOOL bRedraw = TRUE)
{
SetScrollOffset(ptOffset.x, ptOffset.y, bRedraw);
}
void GetScrollOffset(POINT& ptOffset) const
{
ptOffset = m_ptOffset;
}
// size operations
void SetScrollSize(int cx, int cy, BOOL bRedraw = TRUE)
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
m_sizeAll.cx = cx;
m_sizeAll.cy = cy;
m_ptOffset.x = 0;
m_ptOffset.y = 0;
SCROLLINFO si;
si.cbSize = sizeof(si);
si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
si.nMin = 0;
si.nMax = m_sizeAll.cx - 1;
si.nPage = m_sizeClient.cx;
si.nPos = m_ptOffset.x;
pT->SetScrollInfo(SB_HORZ, &si, bRedraw);
si.nMax = m_sizeAll.cy - 1;
si.nPage = m_sizeClient.cy;
si.nPos = m_ptOffset.y;
pT->SetScrollInfo(SB_VERT, &si, bRedraw);
SetScrollLine(0, 0);
SetScrollPage(0, 0);
if(bRedraw)
pT->Invalidate();
}
void SetScrollSize(SIZE size, BOOL bRedraw = TRUE)
{
SetScrollSize(size.cx, size.cy, bRedraw);
}
void GetScrollSize(SIZE& sizeWnd) const
{
sizeWnd = m_sizeAll;
}
// line operations
void SetScrollLine(int cxLine, int cyLine)
{
ATLASSERT(cxLine >= 0 && cyLine >= 0);
ATLASSERT(m_sizeAll.cx != 0 && m_sizeAll.cy != 0);
m_sizeLine.cx = CalcLineOrPage(cxLine, m_sizeAll.cx, 100);
m_sizeLine.cy = CalcLineOrPage(cyLine, m_sizeAll.cy, 100);
}
void SetScrollLine(SIZE sizeLine)
{
SetScrollLine(sizeLine.cx, sizeLine.cy);
}
void GetScrollLine(SIZE& sizeLine) const
{
sizeLine = m_sizeLine;
}
// page operations
void SetScrollPage(int cxPage, int cyPage)
{
ATLASSERT(cxPage >= 0 && cyPage >= 0);
ATLASSERT(m_sizeAll.cx != 0 && m_sizeAll.cy != 0);
m_sizePage.cx = CalcLineOrPage(cxPage, m_sizeAll.cx, 10);
m_sizePage.cy = CalcLineOrPage(cyPage, m_sizeAll.cy, 10);
}
void SetScrollPage(SIZE sizePage)
{
SetScrollPage(sizePage.cx, sizePage.cy);
}
void GetScrollPage(SIZE& sizePage) const
{
sizePage = m_sizePage;
}
// commands
void ScrollLineDown()
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
pT->DoScroll(SB_VERT, SB_LINEDOWN, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
}
void ScrollLineUp()
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
pT->DoScroll(SB_VERT, SB_LINEUP, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
}
void ScrollPageDown()
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
pT->DoScroll(SB_VERT, SB_PAGEDOWN, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
}
void ScrollPageUp()
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
pT->DoScroll(SB_VERT, SB_PAGEUP, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
}
void ScrollTop()
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
pT->DoScroll(SB_VERT, SB_TOP, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
}
void ScrollBottom()
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
pT->DoScroll(SB_VERT, SB_BOTTOM, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
}
void ScrollLineRight()
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
pT->DoScroll(SB_HORZ, SB_LINEDOWN, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
}
void ScrollLineLeft()
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
pT->DoScroll(SB_HORZ, SB_LINEUP, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
}
void ScrollPageRight()
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
pT->DoScroll(SB_HORZ, SB_PAGEDOWN, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
}
void ScrollPageLeft()
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
pT->DoScroll(SB_HORZ, SB_PAGEUP, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
}
void ScrollAllLeft()
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
pT->DoScroll(SB_HORZ, SB_TOP, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
}
void ScrollAllRight()
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
pT->DoScroll(SB_HORZ, SB_BOTTOM, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
}
BEGIN_MSG_MAP(CScrollImpl< T >)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_VSCROLL, OnVScroll)
MESSAGE_HANDLER(WM_HSCROLL, OnHScroll)
MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel)
#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
MESSAGE_HANDLER(m_uMsgMouseWheel, OnMouseWheel)
#endif //(_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
MESSAGE_HANDLER(WM_SIZE, OnSize)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
// standard scroll commands
ALT_MSG_MAP(1)
COMMAND_ID_HANDLER(ID_SCROLL_UP, OnScrollUp)
COMMAND_ID_HANDLER(ID_SCROLL_DOWN, OnScrollDown)
COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, OnScrollPageUp)
COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, OnScrollPageDown)
COMMAND_ID_HANDLER(ID_SCROLL_TOP, OnScrollTop)
COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, OnScrollBottom)
COMMAND_ID_HANDLER(ID_SCROLL_LEFT, OnScrollLeft)
COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, OnScrollRight)
COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, OnScrollPageLeft)
COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, OnScrollPageRight)
COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, OnScrollAllLeft)
COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, OnScrollAllRight)
END_MSG_MAP()
LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
GetSystemSettings();
bHandled = FALSE;
return 1;
}
LRESULT OnVScroll(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
pT->DoScroll(SB_VERT, (int)(short)LOWORD(wParam), (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
return 0;
}
LRESULT OnHScroll(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
pT->DoScroll(SB_HORZ, (int)(short)LOWORD(wParam), (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
return 0;
}
LRESULT OnMouseWheel(UINT uMsg, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
#if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
uMsg;
int zDelta = (int)(short)HIWORD(wParam);
#else
int zDelta = (uMsg == WM_MOUSEWHEEL) ? (int)(short)HIWORD(wParam) : (int)wParam;
#endif //!((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
int nScrollCode = (m_nWheelLines == WHEEL_PAGESCROLL) ? ((zDelta > 0) ? SB_PAGEUP : SB_PAGEDOWN) : ((zDelta > 0) ? SB_LINEUP : SB_LINEDOWN);
m_zDelta += zDelta; // cumulative
int zTotal = (m_nWheelLines == WHEEL_PAGESCROLL) ? abs(m_zDelta) : abs(m_zDelta) * m_nWheelLines;
if((pT->GetStyle() & WS_VSCROLL) != 0)
{
for(short i = 0; i < zTotal; i += WHEEL_DELTA)
{
pT->DoScroll(SB_VERT, nScrollCode, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
pT->UpdateWindow();
}
}
else // can't scroll vertically, scroll horizontally
{
for(short i = 0; i < zTotal; i += WHEEL_DELTA)
{
pT->DoScroll(SB_HORZ, nScrollCode, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
pT->UpdateWindow();
}
}
int nSteps = m_zDelta / WHEEL_DELTA;
m_zDelta -= nSteps * WHEEL_DELTA;
return 0;
}
LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
GetSystemSettings();
return 0;
}
LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
m_sizeClient.cx = GET_X_LPARAM(lParam);
m_sizeClient.cy = GET_Y_LPARAM(lParam);
SCROLLINFO si;
si.cbSize = sizeof(si);
si.fMask = SIF_PAGE | SIF_POS;
si.nPage = m_sizeClient.cx;
si.nPos = m_ptOffset.x;
pT->SetScrollInfo(SB_HORZ, &si, FALSE);
si.nPage = m_sizeClient.cy;
si.nPos = m_ptOffset.y;
pT->SetScrollInfo(SB_VERT, &si, FALSE);
bool bUpdate = false;
int cxMax = m_sizeAll.cx - m_sizeClient.cx;
int cyMax = m_sizeAll.cy - m_sizeClient.cy;
int x = m_ptOffset.x;
int y = m_ptOffset.y;
if(m_ptOffset.x > cxMax)
{
bUpdate = true;
x = (cxMax >= 0) ? cxMax : 0;
}
if(m_ptOffset.y > cyMax)
{
bUpdate = true;
y = (cyMax >= 0) ? cyMax : 0;
}
if(bUpdate)
{
pT->ScrollWindowEx(m_ptOffset.x - x, m_ptOffset.y - y, m_uScrollFlags);
SetScrollOffset(x, y, FALSE);
}
bHandled = FALSE;
return 1;
}
LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
if(wParam != NULL)
{
CDCHandle dc = (HDC)wParam;
dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y);
pT->DoPaint(dc);
}
else
{
CPaintDC dc(pT->m_hWnd);
dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y);
pT->DoPaint(dc.m_hDC);
}
return 0;
}
// scrolling handlers
LRESULT OnScrollUp(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
ScrollLineUp();
return 0;
}
LRESULT OnScrollDown(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
ScrollLineDown();
return 0;
}
LRESULT OnScrollPageUp(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
ScrollPageUp();
return 0;
}
LRESULT OnScrollPageDown(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
ScrollPageDown();
return 0;
}
LRESULT OnScrollTop(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
ScrollTop();
return 0;
}
LRESULT OnScrollBottom(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
ScrollBottom();
return 0;
}
LRESULT OnScrollLeft(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
ScrollLineLeft();
return 0;
}
LRESULT OnScrollRight(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
ScrollLineRight();
return 0;
}
LRESULT OnScrollPageLeft(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
ScrollPageLeft();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -