📄 diagrameditor.cpp
字号:
/* ==========================================================================
Class : CDiagramEditor
Author : Johan Rosengren, Abstrakt Mekanik AB
Date : 2004-03-29
Purpose : "CDiagramEditor" encapsulates a basic vector editor geared
towards diagrams rather than graphics. It supports
virtual screens both smaller and larger than the window,
snap to grid, copy/paste, unlimited undo, zoom etc. It
can be added to both dialogbox- and doc/view apps due to
the use of a separate container for data.
Normally, this class need only to be inherited from when
the drawing functionality is insufficient - many of the
settings can be modified through member accessors.
Description : The class derives from "CWnd", and handles Windows messages
relevant to the operations.
Usage :
========================================================================
Changes : 8/4 2004 SendMessageToObjects sets TRUE flag
sending message only to selected objects.
9/4 2004 Made some message mapping functions
virtual to allow enhancements in
derived classes.
9/4 2004 Added accessors for states to allow
access for derived classes
28/4 2004 Set interact mode to MODE_NONE after
ctrl+clicking item (to not move lines)
28/4 2004 Setting scrollbar positions to zero
in Clear
29/4 2004 Sending this window as a parent to the
property dialog. This is to be able to
redraw the editor properly after changes
to the dialog.
30/4 2004 Changed c-style casts to static_cast
30/4 2004 Remove ShowProperties-const-ness.
========================================================================
14/5 2004 Added access to m_subMode in
SetInteractMode
14/5 2004 Made OnObjectCommand virtual to allow
interception in derived classes.
15/5 2004 Made GetBackgroundColor const.
20/5 2004 Made SelectAll virtual.
24/5 2004 Added virtual size check against the client
rect in HScroll and VScroll (Graham).
========================================================================
24/6 2004 Corrected bug in SetZoom, where the minimum
zoom value was not honoured (pgrohs).
24/6 2004 Zeroing m_internalData after delete to
avoid crash. (pgrohs).
26/6 2004 Added group handling (Unruled Boy).
========================================================================
26/6 2004 Corrected bug in alignment handling - all
objects, not only selected, where modified.
Also made functions virtual.
29/6 2004 Added ZoomToFitScreen and
mousewheel-handling (John A. Johnson).
30/6 2004 Added panning (John A. Johnson).
3/7 2004 Made AddObject virtual and added the virtual
MoveObject function. This is to allow
trapping of added or moved objects in the
editor in derived classes. Also made
clipboard-functions and DeleteAllSelected
virtual.
5/7 2004 Made Clear virtual.
5/7 2004 Added virtual GetCursor function.
6/7 2004 Correction in VirtualToScreen, not deducting
scrollbar positions any longer (Wolfgang Busch).
6/7 2004 Coordinate conversion functions made public.
(Wolfgang Busch).
========================================================================
12/7 2004 Added scroll wheel mode. By calling
SetScrollWheelMode( WHEEL_SCROLL/WHEEL_ZOOM),
the scroll wheel will either scroll or zoom.
========================================================================
16/7 2004 Added virtual to more message handlers,
among them the scrollbar ones.
16/7 2004 Added virtual to SetZoom.
16/7 2004 Added virtual functions to set the
scrollbar positions to get one single point
where this is made.
25/7 2004 Checking if the cursor is outside of
restraint when placing an item in
OnLButtonDown.
========================================================================
3/8 2004 Added ScrollIntoView commands
4/8 2004 Fixed bug with selection markers -
virtualization of the mouse coordinates was
in discord with the selection marker
rectangles. (Marc G)
========================================================================
9/8 2004 Added new ScrollIntoView command taking
object as an inparam.
19/8 2004 Fixed bug in hit testing objects when
zooming in OnLButtonDown (Marc G)
========================================================================
28/8 2004 Added check for non-normalized rect when
hit-testing in OnLButtonDown, as lines
have them.
========================================================================
11/12 2004 Added minimum step size one pixel in
OnKeyDown to avoid 0-pixel movement for
arrow keys (Graham G Pearson)
11/12 2004 Made UnselectAll virtual (Grisha Vinevich)
========================================================================*/
#include "stdafx.h"
#include "DiagramEditor.h"
#include <math.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#pragma warning( disable : 4706 )
/////////////////////////////////////////////////////////////////////////////
// CDiagramEditor construction/destruction/initialization
CDiagramEditor::CDiagramEditor()
/* ============================================================
Function : CDiagramEditor::CDiagramEditor
Description : Constructor
Access : Public
Return : void
Parameters : none
Usage :
============================================================*/
{
m_bkgndCol = ::GetSysColor( COLOR_WINDOW );
m_nonClientBkgndCol = ::GetSysColor( COLOR_3DSHADOW );
m_gridCol = RGB( 192, 192, 192 );
m_grid = TRUE;
m_gridStyle = PS_SOLID;
m_gridSize = CSize( 8, 8 );
m_snap = FALSE;
m_bgResize = FALSE;
m_bgResizeZone = 10;
m_bgResizeSelected = FALSE;
m_markerSize = CSize( 8, 8 );
m_drawObj = NULL;
m_objs = NULL;
m_multiSelObj = NULL;
m_internalData = NULL;
m_restraint = RESTRAINT_NONE;
m_leftMargin = 8;
m_topMargin = 8;
m_rightMargin = 8;
m_bottomMargin = 16;
m_margin = FALSE;
m_marginColor = RGB( 128, 128, 255 );
m_popupMenu = NULL;
m_multiDraw = FALSE;
m_zoomFactor = 0.01;
m_zoomMax = 10.0;
m_zoomMin = 0.0;
m_panningTimer = 100;
m_panning = FALSE;
m_keyInterface = KEY_ALL;
m_cursorNorth = ::LoadCursor( NULL, IDC_SIZENS );
m_cursorNorthEast = ::LoadCursor( NULL, IDC_SIZENESW );
m_cursorEast = ::LoadCursor( NULL, IDC_SIZEWE );
m_cursorSouthEast = ::LoadCursor( NULL, IDC_SIZENWSE );
m_cursorSouth = ::LoadCursor( NULL, IDC_SIZENS );
m_cursorSouthWest = ::LoadCursor( NULL, IDC_SIZENESW );
m_cursorWest = ::LoadCursor( NULL, IDC_SIZEWE );
m_cursorNorthWest = ::LoadCursor( NULL, IDC_SIZENWSE );
SetScrollWheelMode( WHEEL_SCROLL );
Clear();
}
CDiagramEditor::~CDiagramEditor()
/* ============================================================
Function : CDiagramEditor::~CDiagramEditor
Description : Destructor
Access : Public
Return : void
Parameters : none
Usage :
============================================================*/
{
delete m_drawObj;
delete m_internalData;
delete m_popupMenu;
}
void CDiagramEditor::Clear()
/* ============================================================
Function : CDiagramEditor::Clear
Description : Clears internal run-time variables.
Access : Public
Return : void
Parameters : none
Usage : Call to reset internal states.
============================================================*/
{
// Clearing internal states and vars
m_selectionRect.SetRectEmpty();
m_interactMode = MODE_NONE;
m_zoom = 1.0;
m_bgResizeSelected = FALSE;
m_deltaPoint = CSize( 0, 0 );
m_multiSelObj = NULL;
m_drawing = FALSE;
SetPanning( FALSE );
delete m_drawObj;
m_drawObj = NULL;
if( m_hWnd )
{
SetupScrollbars();
SetHScroll( 0 );
SetVScroll( 0 );
RedrawWindow();
}
}
BOOL CDiagramEditor::Create( DWORD dwStyle, const RECT &rect, CWnd *pParentWnd, CDiagramEntityContainer* data )
/* ============================================================
Function : CDiagramEditor::Create
Description : Creates a "CDiagramEditor" window.
Access : Public
Return : BOOL - "TRUE" if success
Parameters : DWORD dwStyle - Window styles for
the editor
const RECT &rect - Window rectangle
CWnd *pParentWnd - Parent of the
editor
CDiagramEntityContainer* data - Pointer to data.
Might be "NULL".
Usage : If data is "NULL", a "CDiagramEntityContainer"
will be created internally, and the instance
of the editor will be responsible for the
container deletion.
============================================================*/
{
if( data == NULL )
{
m_internalData = new CDiagramEntityContainer;
SetInternalDiagramEntityContainer( m_internalData );
}
else
SetDiagramEntityContainer( data );
BOOL res = CWnd::Create( NULL, NULL, dwStyle, rect, pParentWnd, NULL );
CSize virtualSize;
if( GetVirtualSize().cx == 0 && GetVirtualSize().cy == 0 )
virtualSize = CSize( rect.right - rect.left, rect.bottom - rect.top );
else
virtualSize = GetVirtualSize();
SetInternalVirtualSize( virtualSize );
return res;
}
void CDiagramEditor::New()
/* ============================================================
Function : CDiagramEditor::New
Description : Clears the current 'page' and creates a
new one.
Access : Public
Return : void
Parameters : none
Usage : Call to start a new drawing.
============================================================*/
{
SetRedraw( FALSE );
Clear();
m_objs->Clear();
SetRedraw( TRUE );
RedrawWindow();
}
void CDiagramEditor::SetDiagramEntityContainer( CDiagramEntityContainer* objs )
/* ============================================================
Function : CDiagramEditor::SetDiagramEntityContainer
Description : Sets the data container for the editor.
Access : Public
Return : void
Parameters : CDiagramEntityContainer* objs - the data
container
Usage : If this function is used, the caller is
responsible for deleting the container. Can
be called before or after "Create".
============================================================*/
{
if( m_internalData )
delete m_internalData;
m_internalData = NULL;
SetInternalDiagramEntityContainer ( objs );
}
void CDiagramEditor::SetInternalDiagramEntityContainer( CDiagramEntityContainer* objs )
/* ============================================================
Function : CDiagramEditor::SetInternalDiagramEntityContainer
Description : Sets the internal data container pointer.
Access : Protected
Return : void
Parameters : CDiagramEntityContainer* objs - A pointer to the
container to set.
Usage : Internal function.
============================================================*/
{
m_objs = objs;
}
CDiagramEntityContainer* CDiagramEditor::GetDiagramEntityContainer() const
/* ============================================================
Function : CDiagramEditor::GetDiagramEntityContainer
Description : Returns a pointer to the data container.
Access : Public
Return : CDiagramEntityContainer* - The current data
container (might
be "NULL").
Parameters : none
Usage : If modifications are made to the contents of
the container, "SetModified" must be called as
appropriate. If visual changes are expected,
"RedrawWindow" must be called for the editor.
============================================================*/
{
return m_objs;
}
BEGIN_MESSAGE_MAP( CDiagramEditor, CWnd )
//{{AFX_MSG_MAP( CDiagramEditor )
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_SETCURSOR()
ON_WM_SIZE()
ON_WM_HSCROLL()
ON_WM_VSCROLL()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_RBUTTONUP()
ON_WM_RBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_GETDLGCODE()
ON_WM_KEYDOWN()
ON_WM_LBUTTONDBLCLK()
ON_WM_MBUTTONDOWN()
//}}AFX_MSG_MAP
ON_WM_KILLFOCUS()
ON_WM_TIMER()
ON_WM_MOUSEWHEEL()
ON_COMMAND_RANGE( CMD_START, CMD_END, OnObjectCommand )
ON_COMMAND( ID_EDIT_CUT, OnEditCut )
ON_COMMAND( ID_EDIT_COPY, OnEditCopy )
ON_COMMAND( ID_EDIT_PASTE, OnEditPaste )
ON_COMMAND( ID_EDIT_GROUP, OnEditGroup )
ON_COMMAND( ID_EDIT_UNGROUP, OnEditUngroup )
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDiagramEditor painting
void CDiagramEditor::OnPaint()
/* ============================================================
Function : CDiagramEditor::OnPaint
Description : Draws the screen. A memory "CDC" is created
and drawn to.
Access : Protected
Return : void
Parameters : none
Usage : Called from MFC. Do not call from code.
============================================================*/
{
CPaintDC outputdc( this );
// Getting coordinate data
CRect rect;
GetClientRect( &rect );
SCROLLINFO sih;
sih.cbSize = sizeof( SCROLLINFO );
sih.fMask = SIF_POS;
SCROLLINFO siv;
siv.cbSize = sizeof( SCROLLINFO );
siv.fMask = SIF_POS;
if( !GetScrollInfo( SB_HORZ, &sih ) )
sih.nPos = 0;
if( !GetScrollInfo( SB_VERT, &siv ) )
siv.nPos = 0;
CRect totalRect;
int virtwidth = round( static_cast< double >( GetVirtualSize().cx ) * GetZoom() ) + 1;
int virtheight = round( static_cast< double >( GetVirtualSize().cy ) * GetZoom() ) + 1;
totalRect.SetRect( 0, 0, virtwidth, virtheight );
// Creating memory CDC
CDC dc;
dc.CreateCompatibleDC( &outputdc );
CBitmap bmp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -