498 lines
18 KiB
C++
498 lines
18 KiB
C++
// ==========================================================================
|
||
// Class Specification : COXZoomView
|
||
// ==========================================================================
|
||
|
||
// Header file : OXZoomView.h
|
||
|
||
// Version: 9.3
|
||
|
||
// This software along with its related components, documentation and files ("The Libraries")
|
||
// is © 1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is
|
||
// governed by a software license agreement ("Agreement"). Copies of the Agreement are
|
||
// available at The Code Project (www.codeproject.com), as part of the package you downloaded
|
||
// to obtain this file, or directly from our office. For a copy of the license governing
|
||
// this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900.
|
||
|
||
// //////////////////////////////////////////////////////////////////////////
|
||
//
|
||
// Properties:
|
||
// YES Abstract class (does not have any objects)
|
||
// YES Derived from CView
|
||
|
||
// YES Is a Cwnd.
|
||
// YES Two stage creation (constructor & Create())
|
||
// YES Has a message map
|
||
// NO Needs a resource (template)
|
||
|
||
// YES Persistent objects (saveable on disk)
|
||
// YES Uses exceptions
|
||
|
||
// //////////////////////////////////////////////////////////////////////////
|
||
|
||
// Desciption :
|
||
//
|
||
// COXZoomView - a virtual base class for views that need zooming and scrolling.
|
||
// It's based on CScrollView, but significantly modified and enhanced
|
||
// Additions/Alterations to CScrollView:
|
||
// - Handles MM_ANISOTROPIC.
|
||
// - Scrollsizes now definable in percent of the client area, updated on resizing.
|
||
// - ScrollToPosition allows the anchor to be the upper left corner, or additionally
|
||
// the lower left corner or the center of the window.
|
||
// - Accepts a CRect for the document size, so the origin can be located in the
|
||
// lower left corner or the center or any arbitrary point of the document. You don't
|
||
// need to handle negative y-coords any more !
|
||
// - Zoom level can vary between 10% and 1000%
|
||
// - When zooming, either keeps the upper left window corner, the lower left window
|
||
// corner or keeps the center.
|
||
// - Allows zooming up to a rectangle (in client coords).
|
||
// - After zooming, the rectangle can be justified to either the upper left or
|
||
// lower left corner or to the window center.
|
||
// - Allows zooming to the window size (so the scrollbars just disappear).
|
||
// - Output can be aligned to the bottom of the view, when the view's height is
|
||
// bigger than the document's.
|
||
//
|
||
|
||
|
||
// Remark:
|
||
// MM_SCALETOFIT not supported (no need, use CScrollView).
|
||
// Placement in splitter windows not supported (how to handle different zoom levels?).
|
||
// RESTRICTION: the users display shouldn't have more than 3200 pixels in either
|
||
// direction, iow. the viewport extents cannot exceed some 32000 units.
|
||
|
||
// Prerequisites (necessary conditions):
|
||
//
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
|
||
#ifndef __ZOOMVIEW_H__
|
||
#define __ZOOMVIEW_H__
|
||
|
||
#if _MSC_VER >= 1000
|
||
#pragma once
|
||
#endif // _MSC_VER >= 1000
|
||
|
||
#include "OXDllExt.h"
|
||
|
||
#ifdef OXZOOMVIEW_USE_RULER
|
||
#include "OXRulerOrganizer.h"
|
||
#endif // OXZOOMVIEW_USE_RULER
|
||
|
||
#define ID_MULTICOEF 10
|
||
|
||
class OX_CLASS_DECL COXZoomView : public CView
|
||
{
|
||
DECLARE_DYNAMIC(COXZoomView)
|
||
|
||
protected:
|
||
COXZoomView();
|
||
virtual ~COXZoomView();
|
||
|
||
// Data Members
|
||
public:
|
||
|
||
#ifdef WIN32
|
||
static AFX_DATA const SIZE sizeDefault;
|
||
#else
|
||
static const SIZE AFXAPI_DATA sizeDefault;
|
||
#endif
|
||
|
||
// used to specify default calculated page and line sizes
|
||
|
||
enum ZoomAlignment { ZV_DEFAULT, ZV_TOPLEFT, ZV_BOTTOMLEFT, ZV_CENTER };
|
||
enum { MINZOOM = 10, MAXZOOM = 1000 };
|
||
|
||
protected:
|
||
int m_nMapMode;
|
||
CSize m_totalLog;
|
||
CRect m_rectLog;
|
||
CSize m_totalDev;
|
||
CSize m_pageDev;
|
||
CSize m_lineDev;
|
||
CSize m_sizeDev;
|
||
BOOL m_bCenter;
|
||
BOOL m_bInsideUpdate;
|
||
int m_nZoomLevel;
|
||
BOOL m_bAlignToBottom;
|
||
int m_nPagePercent;
|
||
int m_nLinePercent;
|
||
BOOL m_bUseRelativeScrollSizes;
|
||
ZoomAlignment m_align;
|
||
|
||
#ifdef OXZOOMVIEW_USE_RULER
|
||
// ruller object
|
||
COXRulerOrganizer m_ruler;
|
||
#endif // OXZOOMVIEW_USE_RULER
|
||
|
||
// Member Functions
|
||
public:
|
||
|
||
// --- In: pDC: device context in which the filling is to be done
|
||
// pBrush: brush with which the area is to be filled
|
||
// --- Out: none
|
||
// --- Returns: none
|
||
// --- Effect: fills the area of the view that appears outside of the scrolling
|
||
// area. Use FillOutsideRect in your scroll view’s OnEraseBkgnd handler
|
||
// function to prevent excessive background repainting.
|
||
void FillOutsideRect(CDC* pDC, CBrush* pBrush);
|
||
|
||
|
||
// --- In: none
|
||
// --- Out: none
|
||
// --- Returns: whether alignment to bottom is active or not
|
||
// --- Effect: none
|
||
BOOL GetAlignToBottom() const;
|
||
|
||
// --- In:
|
||
// --- Out:
|
||
// --- Returns: whether centering of the contents is active or not
|
||
// --- Effect: none
|
||
BOOL IsCentered() const;
|
||
|
||
|
||
// --- In: none
|
||
// --- Out: none
|
||
// --- Returns: The horizontal and vertical positions (in device units) of the
|
||
// scroll boxes as a CPoint object. (in device units)
|
||
// --- Effect: Call GetDeviceScrollPosition when you need the current horizontal and
|
||
// vertical positions of the scroll boxes in the scroll bars. This coordinate pair
|
||
// corresponds to the location in the document to which the upper-left corner of
|
||
// the view has been scrolled. This is useful for offsetting mouse-device positions
|
||
// to scroll-view device positions.
|
||
CPoint GetDeviceScrollPosition() const;
|
||
|
||
|
||
// --- In: none
|
||
// --- Out: nMapMode: the current mapping mode for this view. For a list of possible values,
|
||
// see SetScrollSizes.
|
||
// sizeTotal: the current total size of the scroll view in device units.
|
||
// sizePage: the current horizontal and vertical amounts to scroll in each direction in response
|
||
// to a mouse click in a scroll-bar shaft.
|
||
// sizeLine: the current horizontal and vertical amounts to scroll in each direction in
|
||
// response to a mouse click in a scroll arrow.
|
||
// --- Returns: none
|
||
// --- Effect: Gets the current mapping mode, the total size, and the line and page sizes of the
|
||
// scrollable view. Sizes are in device units. This member function is rarely called.
|
||
void GetDeviceScrollSizes(int& nMapMode, SIZE& sizeTotal, SIZE& sizePage, SIZE& sizeLine) const;
|
||
|
||
|
||
// --- In : align: the alignement of
|
||
// --- Out : none
|
||
// --- Returns : The horizontal and vertical positions (in device units) of the
|
||
// scroll boxes as a CPoint object. (logical units)
|
||
// --- Effect : This call takes an alignment argument, in order to get back the
|
||
// position of one of the alignment reference points.
|
||
CPoint GetScrollPosition(ZoomAlignment Align = ZV_DEFAULT) const;
|
||
|
||
|
||
// --- In : none
|
||
// --- Out : none
|
||
// --- Returns : the logical size
|
||
// --- Effect :
|
||
CSize GetTotalSize() const;
|
||
|
||
|
||
// --- In: none
|
||
// --- Out: none
|
||
// --- Returns: the state of the zoom alignment
|
||
// --- Effect: none
|
||
ZoomAlignment GetZoomAlign();
|
||
|
||
|
||
// --- In : none
|
||
// --- Out : none
|
||
// --- Returns : the current zoom level in percent.
|
||
// --- Effect :
|
||
int GetZoomLevel() const;
|
||
|
||
// maintained for backward compatibility with CScrollView
|
||
|
||
// --- In : nMapMode: the mapping mode to set for this view
|
||
// sizeTotal: The total size of the zoom view. The cx member contains
|
||
// the horizontal extent. The cy member contains the vertical
|
||
// extent. Sizes are in logical units. Both cx and cy must be
|
||
// greater than or equal to 0.
|
||
// sizePage: The horizontal and vertical amounts to scroll in each
|
||
// direction in response to a mouse click in a scroll-bar shaft.
|
||
// sizeLine: The horizontal and vertical amounts to scroll in each
|
||
// direction in response to a mouse click in a scroll arrow.
|
||
// --- Out : none
|
||
// --- Returns : none
|
||
// --- Effect : Use this to set TEXT, ENGLISH or METRIC mapping modes. You have
|
||
// to specify the mode and the size of the document. If you are not
|
||
// using MM_TEXT make the rectangles top member bigger than the bottom
|
||
// member, because these modes assume that the y coords are getting
|
||
// bigger downside up. If you make top 0 and bottom negative you'll get
|
||
// normal CScrollView behaviour, having y always negative ore 0. If you
|
||
// make bottom 0 and top positive, you y coords are always positive.
|
||
// You can even shift the origin to the center of your doc by
|
||
// specifying the proper rectangle.
|
||
void SetScrollSizes(int nMapMode, SIZE sizeTotal,
|
||
const SIZE& sizePage = sizeDefault,
|
||
const SIZE& sizeLine = sizeDefault);
|
||
|
||
|
||
// three overloaded enhanced Versions to set the sizes
|
||
// allows control of logical origin
|
||
|
||
// --- In : nMapMode: the mapping mode to set for this view
|
||
// rectDoc: the total size of the document.
|
||
// nPagePercent: the amount to scroll in response to a mouse click in a
|
||
// scroll-bar shaft
|
||
// nLinePercent: the amount to scroll in response to a mouse click in a
|
||
// scroll arrow
|
||
// --- Out : none
|
||
// --- Returns : none
|
||
// --- Effect : Use this to set TEXT, ENGLISH or METRIC mapping modes. You have
|
||
// to specify the mode and the size of the document. If you are not
|
||
// using MM_TEXT make the rectangles top member bigger than the bottom
|
||
// member, because these modes assume that the y coords are getting
|
||
// bigger downside up. If you make top 0 and bottom negative you'll get
|
||
// normal CScrollView behaviour, having y always negative ore 0. If you
|
||
// make bottom 0 and top positive, you y coords are always positive.
|
||
// You can even shift the origin to the center of your doc by
|
||
// specifying the proper rectangle.
|
||
void SetDeviceScrollSizesRelative(int nMapMode, const CRect& rectDoc, int nPagePercent = 25, int nLinePercent = 5);
|
||
|
||
// --- In : sizeDevice: size of the view in pixels
|
||
// rectDoc: the total size of the document.
|
||
// nPagePercent: the amount to scroll in response to a mouse click in a
|
||
// scroll-bar shaft
|
||
// nLinePercent: the amount to scroll in response to a mouse click in a
|
||
// scroll arrow
|
||
// --- Out : none
|
||
// --- Returns : none
|
||
// --- Effect : Use this for MM_ANISOTROPIC. You specify the document rectangle
|
||
// as usual and the corresponding size of the view in pixels. cx and
|
||
// cy of the size have to be positive, COXZoomView will invert cy if
|
||
// necessary.
|
||
void SetDeviceScrollSizesRelative(SIZE sizeDevice, const CRect& rectDoc, int nPagePercent = 25, int nLinePercent = 5);
|
||
|
||
// --- In : nMapMode: the mapping mode to set for this view
|
||
// sizeTotal: The total size of the zoom view. The cx member contains
|
||
// the horizontal extent. The cy member contains the vertical
|
||
// extent. Sizes are in logical units. Both cx and cy must be
|
||
// greater than or equal to 0.
|
||
// nPagePercent: The amount to scroll in response to a mouse click in a
|
||
// scroll-bar shaft.
|
||
// nLinePercent: The amount to scroll in response to a mouse click in a
|
||
// scroll arrow.
|
||
// --- Out : none
|
||
// --- Returns : none
|
||
// --- Effect : this is the most compatible version to CScrollView. This Call will
|
||
// synthesize a rect based on the passed SIZE and the mapping mode.
|
||
void SetDeviceScrollSizesRelative(int nMapMode, SIZE sizeTotal, int nPagePercent, int nLinePercent);
|
||
|
||
|
||
// --- In : bAlignToBottom:
|
||
// --- Out : none
|
||
// --- Returns : none
|
||
// --- Effect : If you call this API with TRUE, COXZoomView will display your data
|
||
// aligned to the bottom, if the size of the view is bigger than it
|
||
// has to be to display the whole document.
|
||
void SetAlignToBottom(BOOL bAlignToBottom);
|
||
|
||
// --- In : bCenter:
|
||
// --- Out : none
|
||
// --- Returns : none
|
||
// --- Effect : If you call this API with TRUE, COXZoomView will display your data
|
||
// centered in the screen, if the size of the view is bigger than it
|
||
// has to be to display the whole document.
|
||
void Center( BOOL bCenter );
|
||
|
||
|
||
|
||
// --- In : align:
|
||
// --- Out : none
|
||
// --- Returns : none
|
||
// --- Effect : This sets the default ZoomAlignment for your view, you can specify
|
||
// one of the enumerated values: ZV_TOPLEFT, ZV_BOTTOMLEFT, ZV_CENTER.
|
||
void SetZoomAlign(ZoomAlignment align);
|
||
|
||
|
||
// --- In : nNewLevel: the new zoom level in percent.
|
||
// align: the new default ZoomAlignment for your view (ZV_TOPLEFT,
|
||
// ZV_BOTTOMLEFT, ZV_CENTER)
|
||
// --- Out : none
|
||
// --- Returns : the previous zoom level inpercent
|
||
// --- Effect : Sets the new zoom level and updates the window, using one of the alignment
|
||
// reference points.
|
||
int SetZoomLevel(int nNewLevel, ZoomAlignment Align = ZV_DEFAULT);
|
||
|
||
|
||
// --- In: pt: the point to scroll to, in logical units; the cx member must be
|
||
// a positive value (greater than or equal to 0, up to the total size
|
||
// of the view); the same is true for the cy member when the mapping
|
||
// mode is MM_TEXT;
|
||
// the cy member is negative in mapping modes other than MM_TEXT.
|
||
// align: the new default ZoomAlignment for your view (ZV_TOPLEFT,
|
||
// ZV_BOTTOMLEFT, ZV_CENTER)
|
||
// --- Out: none
|
||
// --- Returns: none
|
||
// --- Effect: Scrolls one of the alignment reference points to the desired POINT
|
||
// position. If you specify ZV_DEFAULT it uses the value set up with
|
||
// SetZoomAlignment.
|
||
void ScrollToPosition(POINT pt, ZoomAlignment Align = ZV_DEFAULT);
|
||
|
||
// --- In: none
|
||
// --- Out: none
|
||
// --- Returns: none
|
||
// --- Effect: Fits the view into the current window and updates the zoom
|
||
// level accordingly.
|
||
void ZoomToWindow();
|
||
|
||
|
||
// --- In: rectZoom: the rectangle you want to zoom out
|
||
// align: the new default ZoomAlignment for your view (ZV_TOPLEFT,
|
||
// ZV_BOTTOMLEFT, ZV_CENTER)
|
||
// --- Out: none
|
||
// --- Returns: none
|
||
// --- Effect: Zooms the view up, so that the passed rectangle in client coords fills
|
||
// the window as much as possible, using one of the reference points.
|
||
void ZoomToRectangle(CRect rectZoom, ZoomAlignment Align = ZV_DEFAULT);
|
||
|
||
|
||
// helper for mouse wheel support
|
||
BOOL DoMouseWheel(UINT fFlags, short zDelta, CPoint point);
|
||
|
||
|
||
#ifdef OXZOOMVIEW_USE_RULER
|
||
// --- In : bHorzRuler - horizontal ruler band will be displayed
|
||
// bVertRuler - vertical ruler band will be displayed
|
||
// --- Out :
|
||
// --- Returns: TRUE if COXRulerOrganizer object was successfully attached
|
||
// --- Effect: attaches to COXRulerOrganizer object which is responsible
|
||
// for displaying ruler bars
|
||
inline BOOL AttachRuler(BOOL bHorzRuler=TRUE, BOOL bVertRuler=TRUE) {
|
||
if(m_ruler.IsAttached())
|
||
{
|
||
SetShowHorzRulerBar(bHorzRuler);
|
||
SetShowVertRulerBar(bVertRuler);
|
||
return TRUE;
|
||
}
|
||
return m_ruler.Attach(this,bHorzRuler,bVertRuler);
|
||
}
|
||
|
||
// --- In :
|
||
// --- Out :
|
||
// --- Returns:
|
||
// --- Effect: detaches the attached COXRulerOrganizer object which is responsible
|
||
// for displaying ruler bars
|
||
inline void DetachRuler() { m_ruler.Detach(); }
|
||
|
||
|
||
// --- In :
|
||
// --- Out :
|
||
// --- Returns: pointer to the internal COXRulerOrganizer object that is used to
|
||
// draw ruler bars
|
||
// --- Effect: retrieves the pointer to the internal COXRulerOrganizer object
|
||
// that is used to draw ruler bars
|
||
inline COXRulerOrganizer* GetRulerOrganizer() { return &m_ruler; }
|
||
|
||
|
||
// --- In : bShowVertRulerBar - if TRUE then vertical ruler bar will
|
||
// be displayed
|
||
// --- Out :
|
||
// --- Returns:
|
||
// --- Effect: sets the flag that specifies whether to display the
|
||
// vertical ruler bar or not
|
||
inline void SetShowVertRulerBar(BOOL bShowVertRulerBar) {
|
||
m_ruler.SetShowVertRulerBar(bShowVertRulerBar);
|
||
}
|
||
|
||
// --- In :
|
||
// --- Out :
|
||
// --- Returns: TRUE if vertical ruler bar is displayed or FALSE otherwise
|
||
// --- Effect: retrieves the flag that specifies whether to display the
|
||
// vertical ruler bar or not
|
||
inline BOOL GetShowVertRulerBar() const { return m_ruler.GetShowVertRulerBar(); }
|
||
|
||
|
||
// --- In : bShowHorzRulerBar - if TRUE then horizontal ruler bar will
|
||
// be displayed
|
||
// --- Out :
|
||
// --- Returns:
|
||
// --- Effect: sets the flag that specifies whether to display the
|
||
// horizontal ruler bar or not
|
||
inline void SetShowHorzRulerBar(BOOL bShowHorzRulerBar) {
|
||
m_ruler.SetShowHorzRulerBar(bShowHorzRulerBar);
|
||
}
|
||
|
||
// --- In :
|
||
// --- Out :
|
||
// --- Returns: TRUE if horizontal ruler bar is displayed or FALSE otherwise
|
||
// --- Effect: retrieves the flag that specifies whether to display the
|
||
// horizontal ruler bar or not
|
||
inline BOOL GetShowHorzRulerBar() const { return m_ruler.GetShowHorzRulerBar(); }
|
||
|
||
#endif // OXZOOMVIEW_USE_RULER
|
||
|
||
|
||
#ifdef _DEBUG
|
||
virtual void Dump(CDumpContext&) const;
|
||
virtual void AssertValid() const;
|
||
#endif //_DEBUG
|
||
|
||
protected:
|
||
|
||
// virtual function, used to initialize the COXScrollWnd object after
|
||
// it was created or was used to subclass created window
|
||
virtual BOOL Initialize();
|
||
|
||
void ScrollToDevicePosition(POINT ptDev); // explicit scrolling no checking
|
||
|
||
// helper functions for zooming
|
||
void SetMapMode(CDC* pDC) const;
|
||
void ScaleViewport(CDC* pDC) const { pDC->ScaleViewportExt(m_nZoomLevel, 100, m_nZoomLevel, 100); }
|
||
|
||
virtual void OnDraw(CDC* pDC) = 0; // pass on pure virtual
|
||
|
||
void UpdateBars(BOOL bSendRecalc = TRUE); // adjust scrollbars etc
|
||
BOOL GetTrueClientSize(CSize& size, CSize& sizeSb);
|
||
// size with no bars
|
||
void GetScrollBarSizes(CSize& sizeSb);
|
||
void GetScrollBarState(CSize sizeClient, CSize& needSb,
|
||
CSize& sizeRange, CPoint& ptMove, BOOL bInsideClient);
|
||
|
||
virtual void CalcWindowRect(LPRECT lpClientRect, UINT nAdjustType = adjustBorder);
|
||
virtual void OnPrepareDC(CDC* pDC, CPrintInfo* pInfo = NULL);
|
||
|
||
// scrolling implementation support for OLE 2.0
|
||
virtual BOOL OnScroll(UINT nScrollCode, UINT nPos, BOOL bDoScroll = TRUE);
|
||
virtual BOOL OnScrollBy(CSize sizeScroll, BOOL bDoScroll = TRUE);
|
||
|
||
static UINT GetMouseScrollLines();
|
||
|
||
//{{AFX_MSG(COXZoomView)
|
||
afx_msg void OnSize(UINT nType, int cx, int cy);
|
||
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
|
||
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
|
||
afx_msg BOOL OnMouseWheel(UINT fFlags, short zDelta, CPoint point);
|
||
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
|
||
//}}AFX_MSG
|
||
DECLARE_MESSAGE_MAP()
|
||
|
||
private:
|
||
};
|
||
|
||
// little helper class for zooming to a rectangle
|
||
// DON'T comment on this !!
|
||
class OX_CLASS_DECL CZoomRect
|
||
{
|
||
public:
|
||
BOOL TrackTheMouse(UINT uMessageEnd, CWnd *pWnd, CRect& rectZoom, CPoint ptAnchor);
|
||
protected:
|
||
void RetrieveMsg(MSG* pmsg);
|
||
BOOL ProcessMsg(MSG* pmsg, CWnd* pWnd);
|
||
void UpdateRectangle(CWnd* pWnd, CPoint& pt);
|
||
void DrawZoomRect(CDC* pDC);
|
||
BOOL m_bFirstMove;
|
||
BOOL m_bSuccess;
|
||
UINT m_uMessageEnd;
|
||
CPoint m_ptOrig;
|
||
CPoint m_ptLast;
|
||
};
|
||
|
||
#include "OXZoomVw.inl"
|
||
|
||
#endif // __ZOOMVIEW_H__
|