Click here to Skip to main content
15,867,849 members
Articles / Desktop Programming / MFC
Article

MFC Active Document Servers

Rate me:
Please Sign up or sign in to vote.
3.56/5 (9 votes)
30 Jan 20025 min read 175.2K   1.4K   33   27
An article about MFC Active Documents (things that you can put into Wordpad, Excel, Word and other applications documents)

Introduction

What is an Active Document? It’s a COM (Component Object Model) component that shows some data (charts, sheets, text documents, bitmaps) which is given by Active Document Server. An Active Document has to be put into an app (Container). For example, when you put a Paintbrush bitmap into the Wordpad, the Paintbrush is an Active Document Server and the Wordpad is a Container. If you want to put an object into a Container, choose the "Insert/Object..." item from its menu. Despite being COM component, creating your own simple MFC Active Document Server doesn't need any COM knowledge.

There are two types of servers:

  • Mini-server - It is compiled into exe file, but you can't execute it. You can only put it into a Container.
  • Full-server - You can use it both as an Active Document Server and as an ordinary SDI or MDI application.

Of course your app can be both Full-server and Container.

Remember! Your Active Document Server has to be registrated in the Windows registry. Without it, you won't find it on "Insert object" list. Your app can register itself! You just have to execute it. If it's a Mini-server it will register itself before showing message "This server can only be run from a container application."

Creating a simple MFC Active Document Mini-Server

It isn't difficult to create your own MFC Active Document Server. AppWizard will create basic code for you! Select "New..." from "File" menu. Select "MFC AppWizard (exe)". Give a name to your project and click OK button.

Step 1: Select SDI or MDI app. I think for Mini-server SDI will be better.

Step 2: Any database support? It isn't necessary.

Step 3: It's the most important step. You can select compound document support. Container, server, active document? Anything you want! Choose "Mini-server". Select "Active document server". Think about "ActiveX Controls". Do you need it?

Step 4: Click "Advanced" button. In "Advanced Options" type the file extension. Even if your mini-server won't use files, the AppWizard wants it and won't continue without it.

Step 5: Nothing interesting!

Step 6: Select base class. It's important!

As you can see, AppWizard has created some code. It provides basic funcionallity. It will a³so register your app in the Registry (see Introduction). You can see two more classes: CInPlaceFrame and CAppnameSrvItem ("Appname" is of course a name of your application).

Server item and metafile device context

It is very important to understand how an Active Document works. When it isn't activated, what you can see in a Container is just a drawing. You can just resize it, copy it (of course with all stored data), but it isn't interactive. To edit it, you have to double-click on it.

CAppnameSrvItem is responsible for drawing it. It hasn't got any advanced funtions. Its most important function is OnDraw(). It draws what you can see in a Container. It receives a pointer to the metafile device context, on which unactivated Active Document is drawn. You don't have to worry about resizeing, creating, getting windows handles... You just have to draw what you want on device context given by the Container. It's very comfortable. For example, you don't have to write separate function for printing. A Container will just print the matafile DC. Remember that CAppnameSrvItem object is created by the document class.

Take a look at the following code:

BOOL CAppnameSrvrItem::OnDraw(CDC* pDC, CSize& rSize)
{
	// Remove this if you use rSize
	UNREFERENCED_PARAMETER(rSize);

	CFaceDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	// TODO: set mapping mode and extent
	//  (The extent is usually the same as the size returned from OnGetExtent)
	pDC->SetMapMode(MM_ANISOTROPIC);
	pDC->SetWindowOrg(0,0);
	pDC->SetWindowExt(3000, 3000);

	// TODO: add drawing code here.  Optionally, fill in the HIMETRIC extent.
	//  All drawing takes place in the metafile device context (pDC).
	pDC->Ellipse(500,1000,2500,2500);

	return TRUE;
}

It was created by the AppWizard (except ellipse drawing line). pDC is of course the pointer to the metafile device context. What is important, you don't draw in pixel units! You draw in a rectangle which size is 3000x3000 HIMETRIC units. If you put something (line, rectange, text, bitmap) at x=3000 it will be always at the right edge of your Acctive Document.

Take a look at this code (put it into CAppnameSrvrItem::OnDraw function just before return TRUE; line). In a Container it will be represented like this (normal and after resizeing):

pDC->Rectangle(500,500,2500,2000);
pDC->LineTo(1500, 1500);

Remember to create a large font, when usuing text functions (like TextOut()).

In-place activation

And what's a View class for? I've already written that you have to double click on an Active Document to edit it. After double click the Container changes. Look at this two pictures:

The menu and the toolbar has changed. It's called In-place activation. Our app is run "inside" a Container. It has our toolbar and menu (combined with the Container's one!). The AppWizard has created the IDR_SRVR_INPLACE toolbar and menu (take a look at Resources in your project). The Container's menu (of course not all) is added between two separators. The rectangle in the center of the screen isn't a Server item. It's the View! You can use it just like an ordinary View class (its derived from CView).

MFC AppWizard has created one more class: CInPlaceFrame. What's this? Look at the second picture in this paragraph. It's responsible for creating the frame around view. To deactivete an Active Document (after In-place activation), you just have to click outside that frame.

If you use some Document's data while drawing in Server Item, after deactivating an Active Document, nothing will change in a Container. For example, if you put a chart into a Container and change some data in it (In-place, after double-click), after returning to the Container, you won't see any changes in your chart unless you will refresh the Server Item. To refresh your data, just put the following code to the Document class (for example in function that changes some data):

UpdateAllItems(NULL);

But there are some situations, when your Mini-server will be shown as an usual app. When you put the Active Document as an icon (you can choose that in "Insert Object" dialog), and you double click on it, it won't activate in-place! It will be shown in separate Window. It will have other menu and toolbar (IDR_MAINFRAME). Remember about it!

Storing data

And how about storing data? When you put an Active Document to an other document, you would like the Active Document data to be saved with the document data, when user choose "Save" from the Container's menu. All you have to do is to serialize data, which is stored in the Document class. The App Wizard has created the Serialize() function.

Take a look at this example:

void CSDCDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		ar << m_someData;
		ar << m_otherData;
	}
	else
	{
		ar >> m_someData;
		ar >> m_otherData;
	}
}

And that's all! Take a look at the examples, it will help you to understand MFC Active Document Servers. If you want to wirte to me, my email address is hepico@cz.onet.pl. Thank you!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Poland Poland
I've been programming since I was really young. Started with HTML and Basic, looked at Pascal and Java, keen on Visual Basic and Visual C++, thinking about .NET and C#.

Comments and Discussions

 
Questionopen in IE Pin
flymolon11-May-15 19:53
flymolon11-May-15 19:53 
QuestionHow to change the metafile to enhanced one? Pin
yph200401078-Jan-09 15:18
yph200401078-Jan-09 15:18 
QuestionHow to de/activate the resize option of object in richedit ???? Pin
o0o17-Jan-05 16:46
o0o17-Jan-05 16:46 
AnswerRe: How to de/activate the resize option of object in richedit ???? Pin
Maciej Pirog18-Jan-05 8:40
Maciej Pirog18-Jan-05 8:40 
GeneralRe: How to de/activate the resize option of object in richedit ???? Pin
o0o18-Jan-05 20:02
o0o18-Jan-05 20:02 
GeneralRe: How to de/activate the resize option of object in richedit ???? Pin
Maciej Pirog19-Jan-05 4:57
Maciej Pirog19-Jan-05 4:57 
GeneralQuestion Pin
Hing29-Mar-04 14:51
Hing29-Mar-04 14:51 
GeneralRe: Question Pin
Maciej Pirog6-Apr-04 5:11
Maciej Pirog6-Apr-04 5:11 
GeneralRe: Question Pin
Hing6-Apr-04 14:50
Hing6-Apr-04 14:50 
GeneralRe: Question Pin
peterchen10-Jul-04 20:59
peterchen10-Jul-04 20:59 
GeneralRe: Question Pin
Maciej Pirog15-Jul-04 11:06
Maciej Pirog15-Jul-04 11:06 
GeneralRe: Question Pin
peterchen15-Jul-04 22:18
peterchen15-Jul-04 22:18 
GeneralAdding other 'verbs' to the server Pin
rajas5-Mar-04 6:57
rajas5-Mar-04 6:57 
QuestionHow to load Server Objects manually Pin
vimala13-May-03 18:40
vimala13-May-03 18:40 
AnswerRe: How to load Server Objects manually Pin
Maciej Pirog17-May-03 9:18
Maciej Pirog17-May-03 9:18 
AnswerRe: How to load Server Objects manually Pin
vimala18-May-03 18:03
vimala18-May-03 18:03 
GeneralUnregister Pin
Hans Ruck24-Jul-02 23:08
Hans Ruck24-Jul-02 23:08 
GeneralRe: Unregister Pin
Maciej Pirog29-Jul-02 23:29
Maciej Pirog29-Jul-02 23:29 
GeneralOnDraw and GDI+ calls Pin
Jonathan de Halleux28-May-02 0:13
Jonathan de Halleux28-May-02 0:13 
GeneralRe: OnDraw and GDI+ calls Pin
Maciej Pirog30-May-02 10:16
Maciej Pirog30-May-02 10:16 
GeneralRe: OnDraw and GDI+ calls Pin
Jonathan de Halleux30-May-02 23:22
Jonathan de Halleux30-May-02 23:22 
QuestionNew question in serialization Pin
rsuresh77711-Apr-07 21:24
rsuresh77711-Apr-07 21:24 
GeneralLegacy Pin
Nemanja Trifunovic1-Feb-02 4:54
Nemanja Trifunovic1-Feb-02 4:54 
GeneralWow !!!! Pin
Braulio Dez4-Feb-02 6:15
Braulio Dez4-Feb-02 6:15 
GeneralRe: Wow !!!! Pin
Nemanja Trifunovic4-Feb-02 6:25
Nemanja Trifunovic4-Feb-02 6:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.