2025-11-27 16:46:48 +09:00

498 lines
18 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ==========================================================================
// 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 views 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__