Click here to Skip to main content
15,885,985 members
Articles / Desktop Programming / MFC

UMLEditor - revisiting the vector editor

Rate me:
Please Sign up or sign in to vote.
4.99/5 (156 votes)
5 Jul 2006Public Domain8 min read 376.2K   37.1K   326  
An UML editor with code-generation capabilities derived from CDiagramEditor.
<html>
<head>
<style>
body{font-size: 10pt;color: black;font-family: Verdana, Helvetica, Arial, sans-serif;background-color: #ffffff}
p{font-size: 10pt;color: black;font-family: Verdana, Helvetica, Arial, sans-serif;}
h2{font-size: 13pt;color: #ff9900;font-family: Verdana, Helvetica, Arial, sans-serif;font-weight: bold;}
h3{color: #ff9900;font-weight: bold;font-size: 11pt;font-family: Arial, sans-serif;}
table{background-color:#f0f0ff;}
td{font-size: 10pt;color: black;font-family: Verdana, Helvetica, Arial, sans-serif;padding:4px;}
pre{padding-right: 7pt;padding-left: 7pt;padding-bottom: 7pt;font: 9pt 'Courier New', Courier, mono;width: 100%;padding-top: 7pt;white-space: pre;background-color: #fbedbb}
code{color: #990000;font-family: 'Courier New', Courier, mono;}
A:link{text-decoration: none}
A:visited{text-decoration: none}
A:active{text-decoration: underline}
A:hover{text-decoration: underline}
A.top:link{font-size:8pt;color:red;font-family:Verdana,Helvetica,Arial,sans-serif;}
A.top:visited{font-size:8pt;color:red;font-family:Verdana,Helvetica,Arial,sans-serif;}
A.top:active{font-size:8pt;color:red;font-family:Verdana,Helvetica,Arial,sans-serif;}
A.top:hoover{font-size:8pt;color:red;font-family:Verdana,Helvetica,Arial,sans-serif;}
</style>
</head>
<body>
<h2>Adding an UMLEditor to your application</h2>
<h3>Include it in...</h3>
<a href="#dialog">A dialog application</a><br>
<a href="#sdi">A SDI application</a><br>
<a href="#mdi">A MDI application</a><br>
<a name="dialog"></a><h3>A dialog application</h3>
<ul>
<li>First of all, enable <b>RTTI </b>for your application (in the project settings, the C/C++-tab)</li>
<li>Add all the files in the <i>UMLEditor </i>folder except <b>UMLEditor.rc</b> and <b>resource.h</b>, and the files from all subfolders except <i>res</i> to the project.</li>
<li>Open <b>UMLEditor.rc </b>and Ctrl+drag all the resources to the resource tab of your project.</li>
<li>Add a <code>CUMLEditor</code>-member to your main dialog class. I'll call it <code>m_editor</code> below.</li>
<li>In the main dialog <code>OnInitDialog</code>, call <code>m_editor.Create</code>. The style should normally be <code>WS_CHILD | WS_VISIBLE</code>, you decide the client rectangle yorself and the parent window is <code>this</code>. You can leave the last parameter empty.</li>
<li>You will now have to add UI to draw objects, of course. Include the objects you will want to be able to draw, normally all of them:
<pre>
#include "UMLEditor/UMLEntityClass.h"
#include "UMLEditor/UMLEntityPackage.h"
#include "UMLEditor/UMLEntityInterface.h"
#include "UMLEditor/UMLEntityNote.h"
#include "UMLEditor/UMLEntityLabel.h"
#include "UMLEditor/UMLLineSegment.h"
</pre>
Add functions calling <code>m_editor.StartDrawingObject</code>, so:
<pre>
  m_editor.StartDrawingObject( new CUMLEntityClass );
</pre>
</li>
<li>Add support for saving and loading. Call <code>m_editor.Save </code>and <code>m_editor.Load </code>respectively. The functions take a <code>CString </code>with a filename as input parameter, if you pass in an empty <code>CString</code>, the functions will show the standard file dialog automatically, and the name selected will be filled in on output.</li>
</ul>
<p><a href="index.html">Back to the contents page</a></p>

<a name="sdi"></a><h3>A SDI application</h3>
<ul>
<li>First of all, enable <b>RTTI </b>for your application (in the project settings, the C/C++-tab)</li>
<li>Add all the files in the <i>UMLEditor </i>folder except <b>UMLEditor.rc</b> and <b>resource.h</b>, and the files from all subfolders except <i>res</i> to the project.</li>
<li>Open <b>UMLEditor.rc </b>and Ctrl+drag all the resources to the resource tab of your project.</li>
<li>In your document class, add a <code>CUMLEntityContainer</code>-member. I'll call it <code>m_objs</code> below.</li>
<li>In the document <code>OnNewDocument</code>, call <code>m_objs.Clear()</code>.</li>
<li>In the document <code>Serialize</code>, do the following:
<pre>
	if (ar.IsStoring())
		m_objs.Save( ar );
	else
		m_objs.Load( ar );
</pre>
</li>
<li>Add the virtual document member <code>SaveModified</code>. Put the following code inside:
<pre>
	SetModifiedFlag( m_objs.IsModified() );
	return CDocument::SaveModified();
</pre>
</li>
<li>Add a public member <code>GetData</code> to the document, returning a pointer to <code>m_objs</code> if you've made the container private.</li>
<li>Add a <code>CUMLEditor</code>-member to your view class. I'll call it <code>m_editor</code> below.</li>
<li>In the view <code>OnInitialUpdate</code>, call <code>m_editor.Create</code>. The style should normally be <code>WS_CHILD | WS_VISIBLE</code>, you decide the client rectangle yorself and the parent window is <code>this</code>. Add the pointer to the document container as the last parameter. An example:
<pre>

	CView::OnInitialUpdate();
	
	if( !m_editor.m_hWnd )
	{
		CUMLEditorDemoDoc* pDoc = GetDocument();
		CRect rect;
		GetClientRect( rect );
		m_editor.Create( WS_CHILD | WS_VISIBLE, rect, this, pDoc->GetData() );
		m_editor.SetModified( FALSE );
	}

</pre>
</li>
<li>Add a handler for <code>OnSize</code> in the view. In <code>OnSize</code>, move the editor so it covers all of the view:
<pre>
	CView::OnSize(nType, cx, cy);
	
	if( m_editor.m_hWnd )
		m_editor.MoveWindow(0,0,cx,cy);
</pre>
</li>
<li>To avoid flicker, you want to handle the view <code>OnEraseBkgnd</code>, returning <code>TRUE</code> from the function.</li>
</ul>
<p><a href="index.html">Back to the contents page</a></p>

<a name="mdi"></a><h3>A MDI application</h3>
<ul>
<li>First of all, enable <b>RTTI </b>for your application (in the project settings, the C/C++-tab)</li>
<li>Add all the files in the <i>UMLEditor </i>folder except <b>UMLEditor.rc</b> and <b>resource.h</b>, and the files from all subfolders except <i>res</i> to the project.</li>
<li>Open <b>UMLEditor.rc </b>and Ctrl+drag all the resources to the resource tab of your project.</li>
<li>In the application class, add a <code>CUMLClipboardHandler</code> member, either make it public or add a public accessor. I'll call it <ode>m_clip</code> below.</li>
<li>Add a declaration
<pre>
extern CUMLEditorDemoApp theApp;
</pre>
outside the class definition.
</li>
<li>In your document class, add a <code>CUMLEntityContainer</code>-member. I'll call it <code>m_objs</code> below.</li>
<li>In the document <code>ctor</code>, add the following line
<pre>
	m_objs.SetClipboardHandler( &theApp.m_clip );
</pre>
</li>
<li>In the document <code>OnNewDocument</code>, call <code>m_objs.Clear()</code>.</li>
<li>In the document <code>Serialize</code>, do the following:
<pre>
	if (ar.IsStoring())
		m_objs.Save( ar );
	else
		m_objs.Load( ar );
</pre>
</li>
<li>Add the virtual document member <code>SaveModified</code>. Put the following code inside:
<pre>
	SetModifiedFlag( m_objs.IsModified() );
	return CDocument::SaveModified();
</pre>
</li>
<li>Add a public member <code>GetData</code> to the document, returning a pointer to <code>m_objs</code> if you've made the container private.</li>
<li>In the view <code>OnInitialUpdate</code>, call <code>m_editor.Create</code>. The style should normally be <code>WS_CHILD | WS_VISIBLE</code>, you decide the client rectangle yorself and the parent window is <code>this</code>. Add the pointer to the document container as the last parameter. An example:
<pre>

	CView::OnInitialUpdate();
	
	if( !m_editor.m_hWnd )
	{
		CUMLEditorDemoDoc* pDoc = GetDocument();
		CRect rect;
		GetClientRect( rect );
		m_editor.Create( WS_CHILD | WS_VISIBLE, rect, this, pDoc->GetData() );
		m_editor.SetModified( FALSE );
	}
	else
		m_editor.Clear();
</pre>
</li>
<li>Add a handler for <code>OnSize</code> in the view. In <code>OnSize</code>, move the editor so it covers all of the view:
<pre>
	CView::OnSize(nType, cx, cy);
	
	if( m_editor.m_hWnd )
		m_editor.MoveWindow(0,0,cx,cy);
</pre>
</li>
<li>To avoid flicker, you want to handle the view <code>OnEraseBkgnd</code>, returning <code>TRUE</code> from the function.</li>
</ul>

<a href="index.html">Back to the contents page</a>
<hr><small><b>Copyright 2004 Johan Rosengren Abstrakt Mekanik AB</b></small>
</body>
</html>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication


Written By
Software Developer (Senior) Abstrakt Mekanik AB
Sweden Sweden
45 years old, married, three kids.

Started with computers more than 20 years ago on a CBM-64.

Read Theoretical Philosophy at the University of Lund.

Working as a C++ consultant developer.

Science-fiction freak. Enjoy vintage punkrock.

Comments and Discussions