MFC 活动文档服务器






3.56/5 (9投票s)
2002 年 1 月 31 日
5分钟阅读

179763

1361
一篇关于 MFC 活动文档(可以放入 Wordpad、Excel、Word 等应用程序文档中的内容)的文章
引言
什么是活动文档? 它是一个 COM(组件对象模型)组件,显示由活动文档服务器提供的一些数据(图表、工作表、文本文档、位图)。活动文档必须放入应用程序(容器)中。例如,当您将 Paintbrush 位图放入 Wordpad 时,Paintbrush 就是活动文档服务器,Wordpad 就是容器。如果您想将对象放入容器,请从其菜单中选择“插入/对象...”项。尽管它是 COM 组件,但创建自己的简单 MFC 活动文档服务器不需要任何 COM 知识。
服务器有两种类型
- 迷你服务器 - 它被编译成 exe 文件,但您无法执行它。您只能将其放入容器。
- 完整服务器 - 您可以将其用作活动文档服务器,也可以用作普通的 SDI 或 MDI 应用程序。
当然,您的应用程序既可以是完整服务器,也可以是容器。
请记住!您的活动文档服务器必须在 Windows 注册表中进行注册。否则,您将在“插入对象”列表中找不到它。您的应用程序可以自行注册!您只需执行它即可。如果它是迷你服务器,它会在显示消息“此服务器只能从容器应用程序运行。”之前自行注册。
创建简单的 MFC 活动文档迷你服务器
创建自己的 MFC 活动文档服务器并不困难。AppWizard 会为您创建基本代码!从“文件”菜单中选择“新建...”。选择“MFC AppWizard (exe)”。为您的项目命名,然后单击“确定”按钮。
第 1 步:选择 SDI 或 MDI 应用程序。我认为对于迷你服务器,SDI 会更好。
第 2 步:任何数据库支持?这并非必需。
第 3 步:这是最重要的一步。您可以选择复合文档支持。容器、服务器、活动文档?您想要的任何东西!选择“迷你服务器”。选择“活动文档服务器”。考虑“ActiveX 控件”。您需要它吗?
第 4 步:单击“高级”按钮。在“高级选项”中输入文件扩展名。即使您的迷你服务器不使用文件,AppWizard 也需要它,并且没有它就无法继续。
第 5 步:没什么有趣的!
第 6 步:选择基类。这很重要!
如您所见,AppWizard 已创建了一些代码。它提供了基本功能。它还会将您的应用程序注册到注册表中(请参阅引言)。您可以看到另外两个类:CInPlaceFrame
和 CAppnameSrvItem
(“Appname”当然是您的应用程序的名称)。
服务器项和图元文件设备上下文
理解活动文档的工作原理非常重要。当它未激活时,您在容器中看到的内容只是一个绘图。您只能调整其大小,复制它(当然是所有存储的数据),但它不是交互式的。要编辑它,您必须双击它。
CAppnameSrvItem
负责绘制它。它没有任何高级功能。它最重要的函数是 OnDraw()
。它绘制您在容器中看到的内容。它接收指向图元文件设备上下文的指针,在上面绘制未激活的活动文档。您不必担心调整大小、创建、获取窗口句柄……您只需在容器提供的设备上下文中绘制您想要的内容。这非常方便。例如,您不必为打印编写单独的函数。容器将仅打印图元文件 DC。请记住,CAppnameSrvItem 对象由文档类创建。
看看下面的代码
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; }
它由 AppWizard 创建(除了绘制椭圆线)。pDC 当然是指向图元文件设备上下文的指针。重要的是,您不是以像素为单位进行绘制!您在大小为 3000x3000 HIMETRIC 单位的矩形中进行绘制。如果您将某些内容(线条、矩形、文本、位图)放置在 x=3000 处,它将始终位于活动文档的右边缘。
看看这段代码(将其放入 CAppnameSrvrItem::OnDraw
函数中,在 return TRUE;
行之前)。在容器中,它将显示如下(正常状态和调整大小后)
pDC->Rectangle(500,500,2500,2000); pDC->LineTo(1500, 1500);
使用文本函数(如 TextOut()
)时,请记住创建一个大字体。
就地激活
视图类是做什么的?我已经写过,您必须双击活动文档才能编辑它。双击后,容器会发生变化。看看这两张图片
菜单和工具栏已更改。这称为就地激活。我们的应用程序在容器“内部”运行。它有我们的工具栏和菜单(与容器的合并!)。AppWizard 已创建 IDR_SRVR_INPLACE
工具栏和菜单(请查看项目中的资源)。容器的菜单(当然不是全部)插入在两个分隔符之间。屏幕中心的矩形不是服务器项。它是视图!您可以像普通的视图类一样使用它(它派生自 CView
)。
MFC AppWizard 还创建了一个类:CInPlaceFrame
。这是什么?看看本段中的第二张图片。它负责在视图周围创建框架。要停用活动文档(就地激活后),只需单击该框架外部即可。
如果您在服务器项的绘图过程中使用了一些文档数据,在停用活动文档后,容器中的任何内容都不会改变。例如,如果您将图表放入容器并更改其中的某些数据(就地激活,双击后),返回容器后,除非刷新服务器项,否则您将看不到图表的任何更改。要刷新您的数据,只需将以下代码放入文档类(例如,在更改某些数据的函数中)
UpdateAllItems(NULL);
但有些情况,您的迷你服务器会显示为一个普通的应用程序。当您将活动文档显示为图标时(您可以在“插入对象”对话框中选择),并且双击它,它不会就地激活!它将在单独的窗口中显示。它将具有其他菜单和工具栏(IDR_MAINFRAME
)。请记住这一点!
存储数据
那么如何存储数据呢?当您将活动文档放入另一个文档时,您希望在用户从容器菜单中选择“保存”时,活动文档数据与文档数据一起保存。您所要做的就是序列化存储在文档类中的数据。App Wizard 已创建 Serialize()
函数。
看看这个例子
void CSDCDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { ar << m_someData; ar << m_otherData; } else { ar >> m_someData; ar >> m_otherData; } }
就是这样!看看示例,它们将帮助您理解 MFC 活动文档服务器。如果您想写信给我,我的电子邮件地址是 hepico@cz.onet.pl。谢谢!