⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atlscrl.h

📁 一个与传统电子字典不同的字典
💻 H
📖 第 1 页 / 共 4 页
字号:
	// 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__

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -