// Windows Template Library - WTL version 8.0
// Copyright (C) Microsoft Corporation. All rights reserved.
//
// This file is a part of the Windows Template Library.
// The use and distribution terms for this software are covered by the
// Microsoft Permissive License (Ms-PL) which can be found in the file
// Ms-PL.txt at the root of this distribution.

#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)) && !defined(_WIN32_WCE)
  #include <zmouse.h>
#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE)

#ifndef GET_WHEEL_DELTA_WPARAM
  #define GET_WHEEL_DELTA_WPARAM(wParam)  ((short)HIWORD(wParam))
#endif

#ifndef WM_MOUSEHWHEEL
  #define WM_MOUSEHWHEEL                  0x020E
#endif


///////////////////////////////////////////////////////////////////////////////
// Classes in this file:
//
// CScrollImpl<T>
// CScrollWindowImpl<T, TBase, TWinTraits>
// CMapScrollImpl<T>
// CMapScrollWindowImpl<T, TBase, TWinTraits>
// CFSBWindowT<TBase>
// CZoomScrollImpl<T>
// CZoomScrollWindowImpl<T, TBase, TWinTraits>
// CScrollContainerImpl<T, TBase, TWinTraits>
// CScrollContainer

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)
#define SCRL_DISABLENOSCROLLV	0x00000010
#define SCRL_DISABLENOSCROLLH	0x00000020
#define SCRL_DISABLENOSCROLL	(SCRL_DISABLENOSCROLLV | SCRL_DISABLENOSCROLLH)


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)) && !defined(_WIN32_WCE)
	// Note that this message must be forwarded from a top level window
	UINT m_uMsgMouseWheel;     // MSH_MOUSEWHEEL
#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE)
	int m_zHDelta;              // current horizontal wheel value
	int m_nHWheelChars;         // number of chars to scroll on horizontal wheel
	UINT m_uScrollFlags;
	DWORD m_dwExtendedStyle;   // scroll specific extended styles

// Constructor
	CScrollImpl() : m_zDelta(0), m_nWheelLines(3), 
#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE)
			m_uMsgMouseWheel(0U), 
#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE)
			m_zHDelta(0), m_nHWheelChars(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) && !defined(_WIN32_WCE)
		m_uScrollFlags |= (IsSmoothScroll() ? SW_SMOOTHSCROLL : 0);
#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE)
		return dwPrevStyle;
	}

	// offset operations
	void SetScrollOffset(int x, int y, BOOL bRedraw = TRUE)
	{
		T* pT = static_cast<T*>(this);
		ATLASSERT(::IsWindow(pT->m_hWnd));

		pT->AdjustScrollOffset(x, y);

		int dx = m_ptOffset.x - x;
		int dy = m_ptOffset.y - y;
		m_ptOffset.x = x;
		m_ptOffset.y = y;

		// block: set horizontal scroll bar
		{
			SCROLLINFO si = { sizeof(SCROLLINFO) };
			si.fMask = SIF_POS;
			if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLH) != 0)
				si.fMask |= SIF_DISABLENOSCROLL;
			si.nPos = m_ptOffset.x;
			pT->SetScrollInfo(SB_HORZ, &si, bRedraw);
		}

		// block: set vertical scroll bar
		{
			SCROLLINFO si = { sizeof(SCROLLINFO) };
			si.fMask = SIF_POS;
			if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLV) != 0)
				si.fMask |= SIF_DISABLENOSCROLL;
			si.nPos = m_ptOffset.y;
			pT->SetScrollInfo(SB_VERT, &si, bRedraw);
		}

		// Move all children if needed
		if(IsScrollingChildren() && (dx != 0 || dy != 0))
		{
			for(HWND hWndChild = ::GetWindow(pT->m_hWnd, GW_CHILD); hWndChild != NULL; hWndChild = ::GetWindow(hWndChild, GW_HWNDNEXT))
			{
				RECT rect = { 0 };
				::GetWindowRect(hWndChild, &rect);
				::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rect, 1);
				::SetWindowPos(hWndChild, NULL, rect.left + dx, rect.top + dy, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
			}
		}

		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, bool bResetOffset = true)
	{
		T* pT = static_cast<T*>(this);
		ATLASSERT(::IsWindow(pT->m_hWnd));

		m_sizeAll.cx = cx;
		m_sizeAll.cy = cy;

		int x = 0;
		int y = 0;
		if(!bResetOffset)
		{
			x = m_ptOffset.x;
			y = m_ptOffset.y;
			pT->AdjustScrollOffset(x, y);
		}

		int dx = m_ptOffset.x - x;
		int dy = m_ptOffset.y - y;
		m_ptOffset.x = x;
		m_ptOffset.y = y;

		// block: set horizontal scroll bar
		{
			SCROLLINFO si = { sizeof(SCROLLINFO) };
			si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
			if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLH) != 0)
				si.fMask |= SIF_DISABLENOSCROLL;
			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);
		}

		// block: set vertical scroll bar
		{
			SCROLLINFO si = { sizeof(SCROLLINFO) };
			si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
			if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLV) != 0)
				si.fMask |= SIF_DISABLENOSCROLL;
			si.nMin = 0;
			si.nMax = m_sizeAll.cy - 1;
			si.nPage = m_sizeClient.cy;
			si.nPos = m_ptOffset.y;
			pT->SetScrollInfo(SB_VERT, &si, bRedraw);
		}

		// Move all children if needed
		if(IsScrollingChildren() && (dx != 0 || dy != 0))
		{
			for(HWND hWndChild = ::GetWindow(pT->m_hWnd, GW_CHILD); hWndChild != NULL; hWndChild = ::GetWindow(hWndChild, GW_HWNDNEXT))
			{
				RECT rect = { 0 };
				::GetWindowRect(hWndChild, &rect);
				::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rect, 1);
				::SetWindowPos(hWndChild, NULL, rect.left + dx, rect.top + dy, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
			}
		}

		SetScrollLine(0, 0);
		SetScrollPage(0, 0);

		if(bRedraw)
			pT->Invalidate();
	}

	void SetScrollSize(SIZE size, BOOL bRedraw = TRUE, bool bResetOffset = true)
	{
		SetScrollSize(size.cx, size.cy, bRedraw, bResetOffset);
	}

	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 = T::CalcLineOrPage(cxLine, m_sizeAll.cx, 100);
		m_sizeLine.cy = T::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 = T::CalcLineOrPage(cxPage, m_sizeAll.cx, 10);
		m_sizePage.cy = T::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);
	}

	// scroll to make point/view/window visible
	void ScrollToView(POINT pt)
	{
		T* pT = static_cast<T*>(this);
		ATLASSERT(::IsWindow(pT->m_hWnd));
		RECT rect = { pt.x, pt.y, pt.x, pt.y };
		pT->ScrollToView(rect);
	}

	void ScrollToView(RECT& rect)
	{
		T* pT = static_cast<T*>(this);
		ATLASSERT(::IsWindow(pT->m_hWnd));

		RECT rcClient = { 0 };
		pT->GetClientRect(&rcClient);

		int x = m_ptOffset.x;
		if(rect.left < m_ptOffset.x)
			x = rect.left;
		else if(rect.right > (m_ptOffset.x + rcClient.right))
			x = rect.right - rcClient.right;

		int y = m_ptOffset.y;
		if(rect.top < m_ptOffset.y)
			y = rect.top;
		else if(rect.bottom > (m_ptOffset.y + rcClient.bottom))
			y = rect.bottom - rcClient.bottom;

		SetScrollOffset(x, y);
	}

	void ScrollToView(HWND hWnd)
	{
		T* pT = static_cast<T*>(this);
		ATLASSERT(::IsWindow(pT->m_hWnd));

		RECT rect = { 0 };
		::GetWindowRect(hWnd, &rect);
		::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rect, 2);
		ScrollToView(rect);
	}

	BEGIN_MSG_MAP(CScrollImpl)
		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)) && !defined(_WIN32_WCE)
		MESSAGE_HANDLER(m_uMsgMouseWheel, OnMouseWheel)
#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE)
		MESSAGE_HANDLER(WM_MOUSEHWHEEL, OnMouseHWheel)
		MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
		MESSAGE_HANDLER(WM_SIZE, OnSize)
		MESSAGE_HANDLER(WM_PAINT, OnPaint)
#ifndef _WIN32_WCE
		MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
#endif // !_WIN32_WCE
	// 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) || defined(_WIN32_WCE)
		uMsg;
		int zDelta = (int)GET_WHEEL_DELTA_WPARAM(wParam);
#else
		int zDelta = (uMsg == WM_MOUSEWHEEL) ? (int)GET_WHEEL_DELTA_WPARAM(wParam) : (int)wParam;
#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400) || defined(_WIN32_WCE))
		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(m_sizeAll.cy > m_sizeClient.cy)
		{
			for(int 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(int 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();
			}
		}
		m_zDelta %= WHEEL_DELTA;

		return 0;
	}

	LRESULT OnMouseHWheel(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		T* pT = static_cast<T*>(this);
		ATLASSERT(::IsWindow(pT->m_hWnd));

		int zDelta = (int)GET_WHEEL_DELTA_WPARAM(wParam);
		int nScrollCode = (m_nHWheelChars == WHEEL_PAGESCROLL) ? ((zDelta > 0) ? SB_PAGERIGHT : SB_PAGELEFT) : ((zDelta > 0) ? SB_LINERIGHT : SB_LINELEFT);
		m_zHDelta += zDelta;   // cumulative
		int zTotal = (m_nHWheelChars == WHEEL_PAGESCROLL) ? abs(m_zHDelta) : abs(m_zHDelta) * m_nHWheelChars;
		if(m_sizeAll.cx > m_sizeClient.cx)
		{
			for(int 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();
			}
		}
		m_zHDelta %= 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);

		// block: set horizontal scroll bar
		{
			SCROLLINFO si = { sizeof(SCROLLINFO) };
			si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
			si.nMin = 0;
			si.nMax = m_sizeAll.cx - 1;
			if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLH) != 0)
				si.fMask |= SIF_DISABLENOSCROLL;
			si.nPage = m_sizeClient.cx;
			si.nPos = m_ptOffset.x;
			pT->SetScrollInfo(SB_HORZ, &si, TRUE);
		}

		// block: set vertical scroll bar
		{
			SCROLLINFO si = { sizeof(SCROLLINFO) };
			si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
			si.nMin = 0;
			si.nMax = m_sizeAll.cy - 1;
			if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLV) != 0)
				si.fMask |= SIF_DISABLENOSCROLL;
			si.nPage = m_sizeClient.cy;
			si.nPos = m_ptOffset.y;
			pT->SetScrollInfo(SB_VERT, &si, TRUE);
		}

		int x = m_ptOffset.x;
		int y = m_ptOffset.y;
		if(pT->AdjustScrollOffset(x, y))
		{
			// Children will be moved in SetScrollOffset, if needed
			pT->ScrollWindowEx(m_ptOffset.x - x, m_ptOffset.y - y, (m_uScrollFlags & ~SCRL_SCROLLCHILDREN));
			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;
			POINT ptViewportOrg = { 0, 0 };
			dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y, &ptViewportOrg);
			pT->DoPaint(dc);
			dc.SetViewportOrg(ptViewportOrg);
		}
		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;
	}

	LRESULT OnScrollPageRight(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		ScrollPageRight();
		return 0;
	}

	LRESULT OnScrollAllLeft(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		ScrollAllLeft();
		return 0;
	}

	LRESULT OnScrollAllRight(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		ScrollAllRight();
		return 0;
	}

// Overrideables
	void DoPaint(CDCHandle /*dc*/)
	{
		// must be implemented in a derived class
		ATLASSERT(FALSE);
	}

// Implementation
	void DoScroll(int nType, int nScrollCode, int& cxyOffset, int cxySizeAll, int cxySizePage, int cxySizeLine)
	{
		T* pT = static_cast<T*>(this);
		RECT rect = { 0 };
		pT->GetClientRect(&rect);
		int cxyClient = (nType == SB_VERT) ? rect.bottom : rect.right;
		int cxyMax = cxySizeAll - cxyClient;

		if(cxyMax < 0)   // can't scroll, client area is bigger
			return;

		bool bUpdate = true;
		int cxyScroll = 0;

		switch(nScrollCode)
		{
		case SB_TOP:		// top or all left
			cxyScroll = cxyOffset;
			cxyOffset = 0;
			break;
		case SB_BOTTOM:		// bottom or all right
			cxyScroll = cxyOffset - cxyMax;
			cxyOffset = cxyMax;
			break;
		case SB_LINEUP:		// line up or line left
			if(cxyOffset >= cxySizeLine)
			{
				cxyScroll = cxySizeLine;
				cxyOffset -= cxySizeLine;
			}
			else
			{
				cxyScroll = cxyOffset;
				cxyOffset = 0;
			}
			break;
		case SB_LINEDOWN:	// line down or line right
			if(cxyOffset < cxyMax - cxySizeLine)
			{
				cxyScroll = -cxySizeLine;
				cxyOffset += cxySizeLine;
			}
			else
			{
				cxyScroll = cxyOffset - cxyMax;
				cxyOffset = cxyMax;
			}
			break;
		case SB_PAGEUP:		// page up or page left
			if(cxyOffset >= cxySizePage)
			{
				cxyScroll = cxySizePage;
				cxyOffset -= cxySizePage;
			}
			else
			{
				cxyScroll = cxyOffset;
				cxyOffset = 0;
			}
			break;
		case SB_PAGEDOWN:	// page down or page right
			if(cxyOffset < cxyMax - cxySizePage)
			{
				cxyScroll = -cxySizePage;
				cxyOffset += cxySizePage;
			}
			else
			{
				cxyScroll = cxyOffset - cxyMax;
				cxyOffset = cxyMax;
			}
			break;
		case SB_THUMBTRACK:
			if(IsNoThumbTracking())
				break;
			// else fall through
		case SB_THUMBPOSITION:
			{
				SCROLLINFO si = { sizeof(SCROLLINFO), SIF_TRACKPOS };
				if(pT->GetScrollInfo(nType, &si))
				{
					cxyScroll = cxyOffset - si.nTrackPos;
					cxyOffset = si.nTrackPos;
				}
			}
			break;
		case SB_ENDSCROLL:
		default:
			bUpdate = false;
			break;
		}

		if(bUpdate && cxyScroll != 0)
		{
			pT->SetScrollPos(nType, cxyOffset, TRUE);
			if(nType == SB_VERT)
				pT->ScrollWindowEx(0, cxyScroll, m_uScrollFlags);
			else
				pT->ScrollWindowEx(cxyScroll, 0, m_uScrollFlags);
		}
	}

	static int CalcLineOrPage(int nVal, int nMax, int nDiv)
	{
		if(nVal == 0)
		{
			nVal = nMax / nDiv;
			if(nVal < 1)
				nVal = 1;
		}
		else if(nVal > nMax)
		{
			nVal = nMax;
		}

		return nVal;
	}

	bool AdjustScrollOffset(int& x, int& y)
	{
		int xOld = x;
		int yOld = y;

		int cxMax = m_sizeAll.cx - m_sizeClient.cx;
		if(x > cxMax)
			x = (cxMax >= 0) ? cxMax : 0;
		else if(x < 0)
			x = 0;

		int cyMax = m_sizeAll.cy - m_sizeClient.cy;
		if(y > cyMax)
			y = (cyMax >= 0) ? cyMax : 0;
		else if(y < 0)
			y = 0;

		return (x != xOld || y != yOld);
	}

	void GetSystemSettings()
	{
#ifndef _WIN32_WCE
#ifndef SPI_GETWHEELSCROLLLINES
		const UINT SPI_GETWHEELSCROLLLINES = 104;
#endif // !SPI_GETWHEELSCROLLLINES
		::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &m_nWheelLines, 0);

#ifndef SPI_GETWHEELSCROLLCHARS
		const UINT SPI_GETWHEELSCROLLCHARS = 0x006C;
#endif // !SPI_GETWHEELSCROLLCHARS
		::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &m_nHWheelChars, 0);

#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
		if(m_uMsgMouseWheel != 0)
			m_uMsgMouseWheel = ::RegisterWindowMessage(MSH_MOUSEWHEEL);

		HWND hWndWheel = FindWindow(MSH_WHEELMODULE_CLASS, MSH_WHEELMODULE_TITLE);
		if(::IsWindow(hWndWheel))
		{
			UINT uMsgScrollLines = ::RegisterWindowMessage(MSH_SCROLL_LINES);
			if(uMsgScrollLines != 0)
				m_nWheelLines = (int)::SendMessage(hWndWheel, uMsgScrollLines, 0, 0L);
		}
#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
#endif // !_WIN32_WCE
	}

	bool IsScrollingChildren() const
	{
		return (m_dwExtendedStyle & SCRL_SCROLLCHILDREN) != 0;
	}

	bool IsErasingBackground() const
	{
		return (m_dwExtendedStyle & SCRL_ERASEBACKGROUND) != 0;
	}

	bool IsNoThumbTracking() const
	{
		return (m_dwExtendedStyle & SCRL_NOTHUMBTRACKING) != 0;
	}

#if (WINVER >= 0x0500)
	bool IsSmoothScroll() const
	{
		return (m_dwExtendedStyle & SCRL_SMOOTHSCROLL) != 0;
	}
#endif // (WINVER >= 0x0500)
};


///////////////////////////////////////////////////////////////////////////////
// CScrollWindowImpl - Implements a scrollable window

template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
class ATL_NO_VTABLE CScrollWindowImpl : public ATL::CWindowImpl<T, TBase, TWinTraits>, public CScrollImpl< T >
{
public:
	BEGIN_MSG_MAP(CScrollWindowImpl)
		MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll)
		MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll)
		MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel)
#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE)
		MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel)
#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE)
		MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel)
		MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange)
		MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize)
		MESSAGE_HANDLER(WM_PAINT, CScrollImpl< T >::OnPaint)
#ifndef _WIN32_WCE
		MESSAGE_HANDLER(WM_PRINTCLIENT, CScrollImpl< T >::OnPaint)
#endif // !_WIN32_WCE
	ALT_MSG_MAP(1)
		COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp)
		COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown)
		COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp)
		COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown)
		COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop)
		COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom)
		COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft)
		COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight)
		COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft)
		COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight)
		COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft)
		COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight)
	END_MSG_MAP()
};


///////////////////////////////////////////////////////////////////////////////
// CMapScrollImpl - Provides mapping and scrolling support to any window

#ifndef _WIN32_WCE

template <class T>
class CMapScrollImpl : public CScrollImpl< T >
{
public:
	int m_nMapMode;
	RECT m_rectLogAll;
	SIZE m_sizeLogLine;
	SIZE m_sizeLogPage;

// Constructor
	CMapScrollImpl() : m_nMapMode(MM_TEXT)
	{
		::SetRectEmpty(&m_rectLogAll);
		m_sizeLogPage.cx = 0;
		m_sizeLogPage.cy = 0;
		m_sizeLogLine.cx = 0;
		m_sizeLogLine.cy = 0;
	}

// Attributes & Operations
	// mapping mode operations
	void SetScrollMapMode(int nMapMode)
	{
		ATLASSERT(nMapMode >= MM_MIN && nMapMode <= MM_MAX_FIXEDSCALE);
		m_nMapMode = nMapMode;
	}

	int GetScrollMapMode() const
	{
		ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
		return m_nMapMode;
	}

	// offset operations
	void SetScrollOffset(int x, int y, BOOL bRedraw = TRUE)
	{
		ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
		POINT ptOff = { x, y };
		// block: convert logical to device units
		{
			CWindowDC dc(NULL);
			dc.SetMapMode(m_nMapMode);
			dc.LPtoDP(&ptOff);
		}
		CScrollImpl< T >::SetScrollOffset(ptOff, bRedraw);
	}

	void SetScrollOffset(POINT ptOffset, BOOL bRedraw = TRUE)
	{
		SetScrollOffset(ptOffset.x, ptOffset.y, bRedraw);
	}

	void GetScrollOffset(POINT& ptOffset) const
	{
		ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
		ptOffset = m_ptOffset;
		// block: convert device to logical units
		{
			CWindowDC dc(NULL);
			dc.SetMapMode(m_nMapMode);
			dc.DPtoLP(&ptOffset);
		}
	}

	// size operations
	void SetScrollSize(int xMin, int yMin, int xMax, int yMax, BOOL bRedraw = TRUE, bool bResetOffset = true)
	{
		ATLASSERT(xMax > xMin && yMax > yMin);
		ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);

		::SetRect(&m_rectLogAll, xMin, yMin, xMax, yMax);

		SIZE sizeAll = { 0 };
		sizeAll.cx = xMax - xMin + 1;
		sizeAll.cy = yMax - yMin + 1;
		// block: convert logical to device units
		{
			CWindowDC dc(NULL);
			dc.SetMapMode(m_nMapMode);
			dc.LPtoDP(&sizeAll);
		}
		CScrollImpl< T >::SetScrollSize(sizeAll, bRedraw, bResetOffset);
		SetScrollLine(0, 0);
		SetScrollPage(0, 0);
	}

	void SetScrollSize(RECT& rcScroll, BOOL bRedraw = TRUE, bool bResetOffset = true)
	{
		SetScrollSize(rcScroll.left, rcScroll.top, rcScroll.right, rcScroll.bottom, bRedraw, bResetOffset);
	}

	void SetScrollSize(int cx, int cy, BOOL bRedraw = TRUE, bool bResetOffset = true)
	{
		SetScrollSize(0, 0, cx, cy, bRedraw, bResetOffset);
	}

	void SetScrollSize(SIZE size, BOOL bRedraw = TRUE, bool bResetOffset = true)
	{
		SetScrollSize(0, 0, size.cx, size.cy, bRedraw, bResetOffset);
	}

	void GetScrollSize(RECT& rcScroll) const
	{
		ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
		rcScroll = m_rectLogAll;
	}

	// line operations
	void SetScrollLine(int cxLine, int cyLine)
	{
		ATLASSERT(cxLine >= 0 && cyLine >= 0);
		ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);

		m_sizeLogLine.cx = cxLine;
		m_sizeLogLine.cy = cyLine;
		SIZE sizeLine = m_sizeLogLine;
		// block: convert logical to device units
		{
			CWindowDC dc(NULL);
			dc.SetMapMode(m_nMapMode);
			dc.LPtoDP(&sizeLine);
		}
		CScrollImpl< T >::SetScrollLine(sizeLine);
	}

	void SetScrollLine(SIZE sizeLine)
	{
		SetScrollLine(sizeLine.cx, sizeLine.cy);
	}

	void GetScrollLine(SIZE& sizeLine) const
	{
		ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
		sizeLine = m_sizeLogLine;
	}

	// page operations
	void SetScrollPage(int cxPage, int cyPage)
	{
		ATLASSERT(cxPage >= 0 && cyPage >= 0);
		ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);

		m_sizeLogPage.cx = cxPage;
		m_sizeLogPage.cy = cyPage;
		SIZE sizePage = m_sizeLogPage;
		// block: convert logical to device units
		{
			CWindowDC dc(NULL);
			dc.SetMapMode(m_nMapMode);
			dc.LPtoDP(&sizePage);
		}
		CScrollImpl< T >::SetScrollPage(sizePage);
	}

	void SetScrollPage(SIZE sizePage)
	{
		SetScrollPage(sizePage.cx, sizePage.cy);
	}

	void GetScrollPage(SIZE& sizePage) const
	{
		ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
		sizePage = m_sizeLogPage;
	}

	BEGIN_MSG_MAP(CMapScrollImpl)
		MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll)
		MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll)
		MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel)
#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
		MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel)
#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
		MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel)
		MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange)
		MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize)
		MESSAGE_HANDLER(WM_PAINT, OnPaint)
		MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
	ALT_MSG_MAP(1)
		COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp)
		COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown)
		COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp)
		COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown)
		COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop)
		COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom)
		COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft)
		COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight)
		COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft)
		COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight)
		COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft)
		COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight)
	END_MSG_MAP()

	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;
			int nMapModeSav = dc.GetMapMode();
			dc.SetMapMode(m_nMapMode);
			POINT ptViewportOrg = { 0, 0 };
			if(m_nMapMode == MM_TEXT)
				dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y, &ptViewportOrg);
			else
				dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y + m_sizeAll.cy, &ptViewportOrg);
			POINT ptWindowOrg = { 0, 0 };
			dc.SetWindowOrg(m_rectLogAll.left, m_rectLogAll.top, &ptWindowOrg);

			pT->DoPaint(dc);

			dc.SetMapMode(nMapModeSav);
			dc.SetViewportOrg(ptViewportOrg);
			dc.SetWindowOrg(ptWindowOrg);
		}
		else
		{
			CPaintDC dc(pT->m_hWnd);
			dc.SetMapMode(m_nMapMode);
			if(m_nMapMode == MM_TEXT)
				dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y);
			else
				dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y + m_sizeAll.cy);
			dc.SetWindowOrg(m_rectLogAll.left, m_rectLogAll.top);
			pT->DoPaint(dc.m_hDC);
		}
		return 0;
	}
};

#endif // !_WIN32_WCE


///////////////////////////////////////////////////////////////////////////////
// CMapScrollWindowImpl - Implements scrolling window with mapping

#ifndef _WIN32_WCE

template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
class ATL_NO_VTABLE CMapScrollWindowImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >, public CMapScrollImpl< T >
{
public:
	BEGIN_MSG_MAP(CMapScrollWindowImpl)
		MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll)
		MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll)
		MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel)
#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
		MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel)
#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
		MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel)
		MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange)
		MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize)
		MESSAGE_HANDLER(WM_PAINT, CMapScrollImpl< T >::OnPaint)
		MESSAGE_HANDLER(WM_PRINTCLIENT, CMapScrollImpl< T >::OnPaint)
	ALT_MSG_MAP(1)
		COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp)
		COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown)
		COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp)
		COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown)
		COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop)
		COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom)
		COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft)
		COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight)
		COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft)
		COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight)
		COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft)
		COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight)
	END_MSG_MAP()
};

#endif // !_WIN32_WCE


///////////////////////////////////////////////////////////////////////////////
// CFSBWindow - Use as a base instead of CWindow to get flat scroll bar support

#if defined(__ATLCTRLS_H__) && (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)

template <class TBase = ATL::CWindow>
class CFSBWindowT : public TBase, public CFlatScrollBarImpl<CFSBWindowT< TBase > >
{
public:
// Constructors
	CFSBWindowT(HWND hWnd = NULL) : TBase(hWnd)
	{ }

	CFSBWindowT< TBase >& operator =(HWND hWnd)
	{
		m_hWnd = hWnd;
		return *this;
	}

// CWindow overrides that use flat scroll bar API
// (only those methods that are used by scroll window classes)
	int SetScrollPos(int nBar, int nPos, BOOL bRedraw = TRUE)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return FlatSB_SetScrollPos(nBar, nPos, bRedraw);
	}

	BOOL GetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return FlatSB_GetScrollInfo(nBar, lpScrollInfo);
	}

	BOOL SetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return FlatSB_SetScrollInfo(nBar, lpScrollInfo, bRedraw);
	}
};

typedef CFSBWindowT<ATL::CWindow>   CFSBWindow;

#endif // defined(__ATLCTRLS_H__) && (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)


///////////////////////////////////////////////////////////////////////////////
// CZoomScrollImpl - Provides zooming and scrolling support to any window

#ifndef _WIN32_WCE

// The zoom modes that can be set with the SetZoomMode method
enum
{
	ZOOMMODE_OFF, 
	ZOOMMODE_IN,   // If left mouse button is clicked or dragged, zoom in on point clicked or rectangle dragged.
	ZOOMMODE_OUT   // If left mouse button clicked, zoom out on point clicked.
};

// Notification to parent that zoom scale changed as a result of user mouse action.
#define ZSN_ZOOMCHANGED	(NM_FIRST - 50) 

template <class T>
class CZoomScrollImpl : public CScrollImpl< T >
{
public:
	enum { m_cxyMinZoomRect = 12 };   // min rect size to zoom in on rect.

// Data members
	SIZE m_sizeLogAll;		
	SIZE m_sizeLogLine;	
	SIZE m_sizeLogPage;
	float m_fZoomScale;
	float m_fZoomScaleMin;
	float m_fZoomDelta;   // Used in ZOOMMODE_IN and ZOOMMODE_OUT on left-button click.
	int m_nZoomMode;		
	RECT m_rcTrack;
	bool m_bTracking;

// Constructor
	CZoomScrollImpl():
			m_fZoomScale(1.0),
			m_fZoomScaleMin(0.5),
			m_fZoomDelta(0.5),
			m_nZoomMode(ZOOMMODE_OFF),
			m_bTracking(false)
	{
		m_sizeLogAll.cx = 0;
		m_sizeLogAll.cy = 0;
		m_sizeLogPage.cx = 0;
		m_sizeLogPage.cy = 0;
		m_sizeLogLine.cx = 0;
		m_sizeLogLine.cy = 0;
		::SetRectEmpty(&m_rcTrack);
	}

// Attributes & Operations

	// size operations
	void SetScrollSize(int cxLog, int cyLog, BOOL bRedraw = TRUE, bool bResetOffset = true)
	{
		ATLASSERT(cxLog >= 0 && cyLog >= 0);

		// Set up the defaults
		if (cxLog == 0 && cyLog == 0)
		{
			cxLog = 1;
			cyLog = 1;
		}

		m_sizeLogAll.cx = cxLog;
		m_sizeLogAll.cy = cyLog;
		SIZE sizeAll = { 0 };
		sizeAll.cx = (int)((float)m_sizeLogAll.cx * m_fZoomScale);
		sizeAll.cy = (int)((float)m_sizeLogAll.cy * m_fZoomScale);

		CScrollImpl< T >::SetScrollSize(sizeAll, bRedraw, bResetOffset);
	}

	void SetScrollSize(SIZE sizeLog, BOOL bRedraw = TRUE, bool bResetOffset = true)
	{
		SetScrollSize(sizeLog.cx, sizeLog.cy, bRedraw, bResetOffset);
	}

	void GetScrollSize(SIZE& sizeLog) const
	{
		sizeLog = m_sizeLogAll;
	}

	// line operations
	void SetScrollLine(int cxLogLine, int cyLogLine)
	{
		ATLASSERT(cxLogLine >= 0 && cyLogLine >= 0);

		m_sizeLogLine.cx = cxLogLine;
		m_sizeLogLine.cy = cyLogLine;

		SIZE sizeLine = { 0 };
		sizeLine.cx = (int)((float)m_sizeLogLine.cx * m_fZoomScale);
		sizeLine.cy = (int)((float)m_sizeLogLine.cy * m_fZoomScale);
		CScrollImpl< T >::SetScrollLine(sizeLine);
	}

	void SetScrollLine(SIZE sizeLogLine)
	{
		SetScrollLine(sizeLogLine.cx, sizeLogLine.cy);
	}

	void GetScrollLine(SIZE& sizeLogLine) const
	{
		sizeLogLine = m_sizeLogLine;
	}

	// page operations
	void SetScrollPage(int cxLogPage, int cyLogPage)
	{
		ATLASSERT(cxLogPage >= 0 && cyLogPage >= 0);

		m_sizeLogPage.cx = cxLogPage;
		m_sizeLogPage.cy = cyLogPage;

		SIZE sizePage = { 0 };
		sizePage.cx = (int)((float)m_sizeLogPage.cx * m_fZoomScale);
		sizePage.cy = (int)((float)m_sizeLogPage.cy * m_fZoomScale);

		CScrollImpl< T >::SetScrollPage(sizePage);
	}

	void SetScrollPage(SIZE sizeLogPage)
	{
		SetScrollPage(sizeLogPage.cx, sizeLogPage.cy);
	}

	void GetScrollPage(SIZE& sizeLogPage) const
	{
		sizeLogPage = m_sizeLogPage;
	}

	void SetZoomScale(float fZoomScale)
	{
		ATLASSERT(fZoomScale > 0);

		if(fZoomScale > 0 && fZoomScale >= m_fZoomScaleMin)
			m_fZoomScale = fZoomScale;
	}

	float GetZoomScale() const
	{
		return m_fZoomScale;
	}

	void SetZoomScaleMin(float fZoomScaleMin)
	{
		m_fZoomScaleMin = fZoomScaleMin;
	}

	float GetZoomScaleMin() const
	{
		return m_fZoomScaleMin;
	}

	void SetZoomDelta(float fZoomDelta)
	{
		ATLASSERT(fZoomDelta >= 0);

		if(fZoomDelta >= 0)
			m_fZoomDelta = fZoomDelta;
	}

	float GetZoomDelta() const
	{
		return m_fZoomDelta;
	}

	void SetZoomMode(int nZoomMode)
	{
		m_nZoomMode = nZoomMode;
	}

	int GetZoomMode() const
	{
		return m_nZoomMode;
	}

	void Zoom(int x, int y, float fZoomScale)
	{
		if(fZoomScale <= 0)
			return;

		fZoomScale = __max(fZoomScale, m_fZoomScaleMin);

		T* pT = static_cast<T*>(this);
		POINT pt = { x, y };
		if(!pT->PtInDevRect(pt))
			return;

		pT->ViewDPtoLP(&pt);
		pT->Zoom(fZoomScale, false);
		pT->CenterOnLogicalPoint(pt);
	}

	void Zoom(POINT pt, float fZoomScale)
	{
		T* pT = static_cast<T*>(this);
		pT->Zoom(pt.x, pt.y, fZoomScale);
	}

	void Zoom(RECT& rc)
	{
		T* pT = static_cast<T*>(this);
		RECT rcZoom = rc;
		pT->NormalizeRect(rcZoom);
		SIZE size = { rcZoom.right - rcZoom.left, rcZoom.bottom - rcZoom.top };
		POINT pt = { rcZoom.left + size.cx / 2, rcZoom.top + size.cy / 2 };
		if(size.cx < m_cxyMinZoomRect || size.cy < m_cxyMinZoomRect)
		{
			pT->Zoom(pt, m_fZoomScale + m_fZoomDelta);
			return;
		}

		ATLASSERT(size.cx > 0 && size.cy > 0);
		
		float fScaleH = (float)(m_sizeClient.cx  + 1) / (float)size.cx;
		float fScaleV = (float)(m_sizeClient.cy + 1) / (float)size.cy;
		float fZoomScale = __min(fScaleH, fScaleV) * m_fZoomScale;
		pT->Zoom(pt, fZoomScale);		
	}

	void Zoom(float fZoomScale, bool bCenter = true)
	{
		if(fZoomScale <= 0)
			return;

		fZoomScale = __max(fZoomScale, m_fZoomScaleMin);


		T* pT = static_cast<T*>(this);
		POINT pt = { 0 };
		if(bCenter)
		{
			RECT rc;
			::GetClientRect(pT->m_hWnd, &rc);
			pt.x = rc.right / 2;
			pt.y = rc.bottom / 2;
			pT->ViewDPtoLP(&pt);
		}

		// Modify the Viewport extent
		m_fZoomScale = fZoomScale;
		SIZE sizeAll = { 0 };
		sizeAll.cx = (int)((float)m_sizeLogAll.cx * fZoomScale);
		sizeAll.cy = (int)((float)m_sizeLogAll.cy * fZoomScale);
		
		// Update scroll bars and window
		CScrollImpl< T >::SetScrollSize(sizeAll);

		if(bCenter)
			pT->CenterOnLogicalPoint(pt);
	}

	// Helper functions
	void PrepareDC(CDCHandle dc)
	{
		ATLASSERT(m_sizeAll.cx >= 0 && m_sizeAll.cy >= 0);
		dc.SetMapMode(MM_ANISOTROPIC);
		dc.SetWindowExt(m_sizeLogAll);
		dc.SetViewportExt(m_sizeAll);
		dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y);
	}

	void ViewDPtoLP(LPPOINT lpPoints, int nCount = 1)
	{
		ATLASSERT(lpPoints);
		T* pT = static_cast<T*>(this);
		ATLASSERT(::IsWindow(pT->m_hWnd));

		CWindowDC dc(pT->m_hWnd);
		pT->PrepareDC(dc.m_hDC);
		dc.DPtoLP(lpPoints, nCount);
	}

	void ViewLPtoDP(LPPOINT lpPoints, int nCount = 1)
	{
		ATLASSERT(lpPoints);
		T* pT = static_cast<T*>(this);
		ATLASSERT(::IsWindow(pT->m_hWnd));
	
		CWindowDC dc(pT->m_hWnd);
		pT->PrepareDC(dc.m_hDC);
		dc.LPtoDP(lpPoints, nCount);
	}

	void ClientToDevice(POINT &pt)
	{
		pt.x += m_ptOffset.x;
		pt.y += m_ptOffset.y;
	}	 

	void DeviceToClient(POINT &pt)
	{
		pt.x -= m_ptOffset.x;
		pt.y -= m_ptOffset.y;
	}

	void CenterOnPoint(POINT pt)
	{
		T* pT = static_cast<T*>(this);
		RECT rect;
		pT->GetClientRect(&rect);

		int xOfs = pt.x - (rect.right / 2) + m_ptOffset.x;
		if(xOfs < 0)
		{
			xOfs = 0;
		}
		else 
		{
			int xMax = __max((int)(m_sizeAll.cx - rect.right), 0);
			if(xOfs > xMax)
				xOfs = xMax;
		}
		
		int yOfs = pt.y - (rect.bottom / 2) + m_ptOffset.y;
		if(yOfs < 0)
		{
			yOfs = 0;
		}
		else 
		{
			int yMax = __max((int)(m_sizeAll.cy - rect.bottom), 0);
			if(yOfs > yMax)
				yOfs = yMax;
		}

		CScrollImpl< T >::SetScrollOffset(xOfs, yOfs);
	}

	void CenterOnLogicalPoint(POINT ptLog)
	{
		T* pT = static_cast<T*>(this);
		pT->ViewLPtoDP(&ptLog);
		pT->DeviceToClient(ptLog);
		pT->CenterOnPoint(ptLog);
	}

	BOOL PtInDevRect(POINT pt)
	{
		RECT rc = { 0, 0, m_sizeAll.cx, m_sizeAll.cy };
		::OffsetRect(&rc, -m_ptOffset.x, -m_ptOffset.y);
		return ::PtInRect(&rc, pt);
	}

	void NormalizeRect(RECT& rc)
	{
		if(rc.left > rc.right) 
		{
			int r = rc.right;
			rc.right = rc.left;
			rc.left = r;
		}
		if(rc.top > rc.bottom)
		{
			int b = rc.bottom;
			rc.bottom = rc.top;
			rc.top = b;
		}
	}

	void DrawTrackRect()
	{
		T* pT = static_cast<T*>(this);
		const SIZE sizeLines = { 2, 2 };
		RECT rc = m_rcTrack;
		pT->NormalizeRect(rc);
		if(!::IsRectEmpty(&rc))
		{
			::MapWindowPoints(pT->m_hWnd, NULL, (LPPOINT)&rc, 2);
			CWindowDC dc(NULL);
			dc.DrawDragRect(&rc, sizeLines, NULL, sizeLines);
		}
	}

	void NotifyParentZoomChanged()
	{
		T* pT = static_cast<T*>(this);
		int nId = pT->GetDlgCtrlID();
		NMHDR nmhdr = { pT->m_hWnd, nId, ZSN_ZOOMCHANGED };
		::SendMessage(pT->GetParent(), WM_NOTIFY, (WPARAM)nId, (LPARAM)&nmhdr);
	}

	BEGIN_MSG_MAP(CZoomScrollImpl)
		MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor)
		MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll)
		MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll)
		MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel)
#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
		MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel)
#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
		MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel)
		MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange)
		MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize)
		MESSAGE_HANDLER(WM_PAINT, OnPaint)
		MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
		MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
		MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
		MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
		MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged)
	ALT_MSG_MAP(1)
		COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp)
		COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown)
		COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp)
		COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown)
		COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop)
		COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom)
		COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft)
		COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight)
		COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft)
		COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight)
		COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft)
		COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight)
	END_MSG_MAP()

	LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		T* pT = static_cast<T*>(this);
		ATLASSERT(::IsWindow(pT->m_hWnd));
		ATLASSERT(m_sizeLogAll.cx >= 0 && m_sizeLogAll.cy >= 0);
		ATLASSERT(m_sizeAll.cx >= 0 && m_sizeAll.cy >= 0);

		if(wParam != NULL)
		{
			CDCHandle dc = (HDC)wParam;
			int nMapModeSav = dc.GetMapMode();
			dc.SetMapMode(MM_ANISOTROPIC);
			SIZE szWindowExt = { 0, 0 };
			dc.SetWindowExt(m_sizeLogAll, &szWindowExt);
			SIZE szViewportExt = { 0, 0 };
			dc.SetViewportExt(m_sizeAll, &szViewportExt);
			POINT ptViewportOrg = { 0, 0 };
			dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y, &ptViewportOrg);

			pT->DoPaint(dc);

			dc.SetMapMode(nMapModeSav);
			dc.SetWindowExt(szWindowExt);
			dc.SetViewportExt(szViewportExt);
			dc.SetViewportOrg(ptViewportOrg);
		}
		else
		{
			CPaintDC dc(pT->m_hWnd);
			pT->PrepareDC(dc.m_hDC);
			pT->DoPaint(dc.m_hDC);
		}
		return 0;
	}

	LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
	{
		if(m_nZoomMode == ZOOMMODE_IN && !m_bTracking)
		{
			T* pT = static_cast<T*>(this);
			POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
			if(pT->PtInDevRect(pt))
			{
				pT->SetCapture();
				m_bTracking = true;
				::SetRect(&m_rcTrack, pt.x, pt.y, pt.x, pt.y);
			}	
		}
		bHandled = FALSE;
		return 0;
	}

	LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
	{
		if(m_bTracking)
		{
			T* pT = static_cast<T*>(this);
			POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
			if(pT->PtInDevRect(pt))
			{
				pT->DrawTrackRect();
				m_rcTrack.right = pt.x;
				m_rcTrack.bottom = pt.y;
				pT->DrawTrackRect();
			}
		}
		bHandled = FALSE;
		return 0;
	}

	LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
	{
		::ReleaseCapture();
		if(m_nZoomMode == ZOOMMODE_OUT)
		{
			T* pT = static_cast<T*>(this);
			pT->Zoom(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), m_fZoomScale - m_fZoomDelta);
			pT->NotifyParentZoomChanged();
		}
		bHandled = FALSE;
		return 0;
	}

	LRESULT OnCaptureChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		if(m_bTracking)
		{
			m_bTracking = false;
			T* pT = static_cast<T*>(this);
			pT->DrawTrackRect();
			pT->Zoom(m_rcTrack);
			pT->NotifyParentZoomChanged();
			::SetRectEmpty(&m_rcTrack);
		}
		bHandled = FALSE;
		return 0;
	}	

	LRESULT OnSetCursor(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		if(LOWORD(lParam) == HTCLIENT && m_nZoomMode != ZOOMMODE_OFF)
		{
			T* pT = static_cast<T*>(this);
			if((HWND)wParam == pT->m_hWnd)
			{
				DWORD dwPos = ::GetMessagePos();
				POINT pt = { GET_X_LPARAM(dwPos), GET_Y_LPARAM(dwPos) };
				pT->ScreenToClient(&pt);
				if(pT->PtInDevRect(pt))
				{
					::SetCursor(::LoadCursor(NULL, IDC_CROSS));
					return 1;
				}
			}
		}
		bHandled = FALSE;
		return 0;
	}
};

///////////////////////////////////////////////////////////////////////////////
// CZoomScrollWindowImpl - Implements scrolling window with zooming

template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
class ATL_NO_VTABLE CZoomScrollWindowImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >, public CZoomScrollImpl< T >
{
public:
	BEGIN_MSG_MAP(CZoomScrollWindowImpl)
		MESSAGE_HANDLER(WM_SETCURSOR, CZoomScrollImpl< T >::OnSetCursor)
		MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll)
		MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll)
		MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel)
#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
		MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel)
#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
		MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel)
		MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange)
		MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize)
		MESSAGE_HANDLER(WM_PAINT, CZoomScrollImpl< T >::OnPaint)
		MESSAGE_HANDLER(WM_PRINTCLIENT, CZoomScrollImpl< T >::OnPaint)
		MESSAGE_HANDLER(WM_LBUTTONDOWN, CZoomScrollImpl< T >::OnLButtonDown)
		MESSAGE_HANDLER(WM_MOUSEMOVE, CZoomScrollImpl< T >::OnMouseMove)
		MESSAGE_HANDLER(WM_LBUTTONUP, CZoomScrollImpl< T >::OnLButtonUp)
		MESSAGE_HANDLER(WM_CAPTURECHANGED, CZoomScrollImpl< T >::OnCaptureChanged)
	ALT_MSG_MAP(1)
		COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp)
		COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown)
		COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp)
		COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown)
		COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop)
		COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom)
		COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft)
		COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight)
		COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft)
		COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight)
		COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft)
		COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight)
	END_MSG_MAP()
};

#endif // !_WIN32_WCE


///////////////////////////////////////////////////////////////////////////////
// CScrollContainer

template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
class ATL_NO_VTABLE CScrollContainerImpl : public CScrollWindowImpl< T, TBase, TWinTraits >
{
public:
	DECLARE_WND_CLASS_EX(NULL, 0, -1)

	typedef CScrollWindowImpl< T, TBase, TWinTraits >   _baseClass;

// Data members
	ATL::CWindow m_wndClient;
	bool m_bAutoSizeClient;
	bool m_bDrawEdgeIfEmpty;

// Constructor
	CScrollContainerImpl() : m_bAutoSizeClient(true), m_bDrawEdgeIfEmpty(false)
	{
		// Set CScrollWindowImpl extended style
		SetScrollExtendedStyle(SCRL_SCROLLCHILDREN);
	}

// Attributes
	HWND GetClient() const
	{
		return m_wndClient;
	}

	HWND SetClient(HWND hWndClient, bool bClientSizeAsMin = true)
	{
		ATLASSERT(::IsWindow(m_hWnd));

		HWND hWndOldClient = m_wndClient;
		m_wndClient = hWndClient;

		SetRedraw(FALSE);
		SetScrollSize(1, 1, FALSE);

		if(m_wndClient.m_hWnd != NULL)
		{
			m_wndClient.SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE);

			if(bClientSizeAsMin)
			{
				RECT rect = { 0 };
				m_wndClient.GetWindowRect(&rect);
				if((rect.right - rect.left) > 0 && (rect.bottom - rect.top) > 0)
					SetScrollSize(rect.right - rect.left, rect.bottom - rect.top, FALSE);
			}

			T* pT = static_cast<T*>(this);
			pT->UpdateLayout();
		}

		SetRedraw(TRUE);
		RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW | RDW_ALLCHILDREN);

		return hWndOldClient;
	}

// Message map and handlers
	BEGIN_MSG_MAP(CScrollContainerImpl)
		MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
		MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
		MESSAGE_HANDLER(WM_SIZE, OnSize)
		CHAIN_MSG_MAP(_baseClass)
		FORWARD_NOTIFICATIONS()
	ALT_MSG_MAP(1)
		CHAIN_MSG_MAP_ALT(_baseClass, 1)
	END_MSG_MAP()

	LRESULT OnSetFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		if(m_wndClient.m_hWnd != NULL)
			m_wndClient.SetFocus();

		return 0;
	}

	LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		return 1;   // no background needed
	}

	LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
	{
		BOOL bTmp = TRUE;
		LRESULT lRet = _baseClass::OnSize(uMsg, wParam, lParam, bTmp);

		T* pT = static_cast<T*>(this);
		pT->UpdateLayout();

		return lRet;
	}

// Overrides for CScrollWindowImpl
	void DoPaint(CDCHandle dc)
	{
		if(!m_bAutoSizeClient || m_wndClient.m_hWnd == NULL)
		{
			T* pT = static_cast<T*>(this);
			RECT rect = { 0 };
			pT->GetContainerRect(rect);

			if(m_bDrawEdgeIfEmpty && m_wndClient.m_hWnd == NULL)
				dc.DrawEdge(&rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);

			dc.FillRect(&rect, COLOR_APPWORKSPACE);
		}
	}

	void ScrollToView(POINT pt)
	{
		CScrollWindowImpl< T, TBase, TWinTraits >::ScrollToView(pt);
	}

	void ScrollToView(RECT& rect)
	{
		CScrollWindowImpl< T, TBase, TWinTraits >::ScrollToView(rect);
	}

	void ScrollToView(HWND hWnd)   // client window coordinates
	{
		T* pT = static_cast<T*>(this);
		pT;   // avoid level 4 warning
		ATLASSERT(::IsWindow(pT->m_hWnd));
		ATLASSERT(m_wndClient.IsWindow());

		RECT rect = { 0 };
		::GetWindowRect(hWnd, &rect);
		::MapWindowPoints(NULL, m_wndClient.m_hWnd, (LPPOINT)&rect, 2);
		ScrollToView(rect);
	}

// Implementation - overrideable methods
	void UpdateLayout()
	{
		ATLASSERT(::IsWindow(m_hWnd));

		if(m_bAutoSizeClient && m_wndClient.m_hWnd != NULL)
		{
			T* pT = static_cast<T*>(this);
			RECT rect = { 0 };
			pT->GetContainerRect(rect);

			m_wndClient.SetWindowPos(NULL, &rect, SWP_NOZORDER | SWP_NOMOVE);
		}
		else
		{
			Invalidate();
		}
	}

	void GetContainerRect(RECT& rect)
	{
		GetClientRect(&rect);

		if(rect.right < m_sizeAll.cx)
			rect.right = m_sizeAll.cx;

		if(rect.bottom < m_sizeAll.cy)
			rect.bottom = m_sizeAll.cy;
	}
};

class CScrollContainer : public CScrollContainerImpl<CScrollContainer>
{
public:
	DECLARE_WND_CLASS_EX(_T("WTL_ScrollContainer"), 0, -1)
};

}; // namespace WTL

#endif // __ATLSCRL_H__
