Microsoft KB Archive/311765

= Visual C++ ActiveX Control for hosting Office documents in Visual Basic or HTML =

Article ID: 311765

Article Last Modified on 6/19/2007

-

APPLIES TO


 * Microsoft Office Professional 2007
 * Microsoft Office Standard Edition 2003
 * Microsoft Office XP Developer Edition
 * Microsoft Office 2000 Developer Edition
 * Microsoft Visual C++ 6.0 Professional Edition
 * Microsoft Visual Studio .NET 2003 Professional Edition
 * Microsoft Visual Studio 2005 Professional Edition

-



This article was previously published under Q311765



SUMMARY
The Microsoft Developer Support Office Framer Control Sample contains a Visual C++ ActiveX control that acts as an ActiveX document container for hosting Office documents (including Microsoft Word, Microsoft Excel, Microsoft PowerPoint, Microsoft Project, and Microsoft Visio documents) in a custom form or Web page. The control (Dsoframer.ocx) is lightweight and flexible, and gives developers new possibilities for using Office in a custom solution.

The control is designed to handle specific issues that make using ActiveX documents from a non-top-level host window difficult, and serves as a starting place for constructing your own embedded object file viewer or editor as an ActiveX control.



MORE INFORMATION
This sample shows Visual C++ developers how to construct an ActiveX control to act as an ActiveX document container, which allows developers to embed Office files for in-place editing and viewing. The control can then be used by Microsoft Visual Basic, Microsoft C#, or Web developers to view Office files inside their main solution, and give them programmatic control over the document while it is embedded.

NoteThis sample is provided &quot;AS IS&quot; with no warranty or support from Microsoft. It is a demonstration, provided for informational purposes only, and has not been rigorously tested with all environments and ActiveX document servers. It is up to you to make it &quot;production ready&quot; if you use it in any development solution.

Background information
ActiveX document technology is not new, but it has become increasingly popular in recent years, thanks in large part to Internet Explorer. The ability of Internet Explorer to view and edit Office files inside the browser is made possible because of ActiveX document technology. Many developers rely on the support that Internet Explorer offers for this type of containment in order to host Office files in their custom solutions, either in Web pages that are viewed in Internet Explorer, or in the WebBrowser control (Shdocvw.dll) that is used in a Visual Basic project. The ability to have Office run embedded inside a custom solution is very attractive to some development projects.

There are limitations, however, in how Internet Explorer implements ActiveX document containment, and in what it exposes to developers. Some of the limitations of using Internet Explorer or WebBrowser controls in a solution are as follows:
 * Programmatic control: Internet Explorer gives limited access to the embedded object, particularly when the object is embedded inside a Web page. Even when the object is used outside of a Web page (in the WebBrowser control, for example), an Automation object cannot be obtained directly after opening the file. Rather, the code must wait for the NavigateComplete2 event to fire, thereby preventing synchronous access to the object right after the Navigate method is called.
 * Documents unintentionally opened outside the browser: Internet Explorer uses certain criteria (including a check of an end-user option) to determine whether it attempts to open a document inside or outside the browser. This can be problematic if a development project requires that its documents always open inside the designated frame, because Internet Explorer does not guarantee that any non-HTML file will be opened in-place.
 * Toolbars and menus: When you view Office files, Internet Explorer automatically hides the toolbars of the document, and makes it difficult to control this behavior or selectively choose what the default setting should be. Moreover, menu support is only available if the document is shown in the top-level frame of the main Internet Explorer window, not when the document is shown in a subframe or in the WebBrowser control. Developers may want better control over both.
 * Saving to a server: Some development projects require a document to open from or save to a URL location (Web folder). The ability to save a particular embedded object to a Web server is not native to Internet Explorer or the WebBrowser control.
 * Focus/Activation problems: The control was specifically designed to overcome known issues related to focus and activation when hosting ActiveX documents from within a control.

The following sample corrects all of these issues, and many others. It also gives developers a component that they can refine and customize to suit a particular business need or environment.

Considerations about the design
ActiveX document containment is not a simple task. The requirements to be a well-written host are fairly lengthy, and participation of the top-level application is always assumed. The idea of making an ActiveX control behave as an ActiveX document container is therefore inherently problematic, and somewhat difficult. However, this idea has been presented to Microsoft several times by developers that seek alternatives to the WebBrowser control, or to aid in more customizable Web projects, and deserves some attention.

Nonetheless, it should be recognized that an ActiveX control (even this one) is not considered a suitable host for this type of embedding, and will have certain limitations that the developer must always take into account (and may never be fully able to resolve).

A fully functional ActiveX document container needs to control the following elements that belong to the application that acts as the host, for which an ActiveX control is not well-suited:
 * WindowProc: Because the purpose of ActiveX documents is to make two applications behave as one, the top-level window of the host application must forward messages to the in-place object as it receives them. These messages are not sent to ActiveX controls because controls are always in-process, and therefore do not require them. Therefore, to solve this critical issue, the sample must subclass the main window of any application on which it is inserted to capture these window messages and forward them as needed.
 * MessageLoop: All good OLE containers should forward keyboard accelerator messages to an in-place active object. Unfortunately, controls do not control the main message loop and cannot handle this for the host. As a result, certain keyboard shortcuts may not work as expected when focus is not directly inside the user interface window of the in-place object.
 * Menus: Per Graphics Device Interface (GDI) rules for the Microsoft Windows operating system, only the top-level window should have a menu bar. Because this menu is controlled by the host application and not a control, it is not possible to handle formal OLE menu merging without intimate knowledge of the target application in which the control is set to run. Because menu support is important to some developers, the sample in this article uses a pop-up menu for menu access as a workaround. Developers can choose to enable or disable the pop-up menu as needed.
 * MessageFilter: All single-threaded apartment (STA) threads in an OLE application implement a message filter for processing certain messages while in a blocking call to an OLE server. It is very important that the STA message filter does not block return calls for IOleInPlaceFrame methods, and a good ActiveX document host should implement a custom message filter. However, message filters are controlled by the thread and application, not a control, so this is not possible under COM rules. The two most common containers for this sort of control, Internet Explorer and Visual Basic, support OLE embedding on their own and have a filter that allows these calls. This means that the sample should work in these containers with no extra work needed. Other non-Visual Basic or non-Internet Explorer containers, however, may stop responding (hang) unexpectedly when they use this sample. If the containers stop responding, check the implementation for the message filter.
 * Window Focus and Z Order: Each thread maintains its own focus and Z order state with respect to windows that belong to that thread. To have two applications behave seamlessly, special care needs to be taken to ensure that focus and Z order states between both applications remain synchronized. When you display dialog boxes or other windows that overlap an in-place active object, be sure to notify the control that you are going into a modal state so that the control can notify the object and handle focus and Z order correctly.

These factors limit the ability of an ActiveX control to make a suitable ActiveX document container for all hosts, in all situations. However, the sample given below does meet the needed requirements for Office servers when it is embedded in a control that is hosted in a Visual Basic 6.0, Visual Studio .NET Windows Form, or Internet Explorer solution. Other host applications, or ActiveX document servers, may require you to satisfy more of the listed requirements than this sample provides.

Download the sample
A new version of the sample that is compatible with Office 2007 is available for download now.Download the DsoFramer_KB311765_x86.exe package now. Release Date: May 8, 2007

For more information about how to download Microsoft support files, click the following article number to view the article in the Microsoft Knowledge Base:

119591 How to obtain Microsoft support files from online services

Microsoft scanned this file for viruses. Microsoft used the most current virus-detection software that was available on the date that the file was posted. The file is stored on security-enhanced servers that help prevent any unauthorized changes to the file.

The DSO Framer ActiveX document control sample
The sample control is written in Visual C++ 6.0 using standard C++. It can be recompiled in Visual Studio .NET 2003 or in Visual Studio 2005 without modification. Version 1.3 is compatible with all current versions of Microsoft Office, including Microsoft Office 2007. A release build of the sample is provided for those who want to demonstrate the control without having to recompile the project. A Web page example is provided in the WebTest folder to show how the control can be used from HTML. Office 2000, Office XP, Office 2003, or Office 2007 must be installed on the client computer for it to be able to open Office documents.

Run the sample
To run the samples, follow these steps:  Extract the sample files to a folder of your choice. Open Webtest.htm (from the WebTest folder) in Internet Explorer. If you are prompted, select Yes to enable scripting for an ActiveX control. If you are running Windows XP SP2, Internet Explorer may temporarily block active content for the web page. You can choose to allow the content by clicking on the Information Bar. For more information about the Information Bar please see the following article in the Microsoft Knowledge Base:

843017 Description of the Internet Explorer Information Bar in Windows XP SP2

 When you see the control in the Web page, click the control. On the File menu, click New to add a new document to the control.

Code a solution using the control
The control is very customizable. You can change the color scheme of any of the control elements, as well as determine the border type and a custom caption. These can be set at run time or design time as needed.

The control also supports a property called ActiveDocument that allows you to obtain a reference to the IDispatch interface of the embedded object. From this interface you can automate the object to perform tasks, edit parts of the document, or gather information about what a user has added or removed. For example, if you have a Word document open, you can use code that resembles the following to add a line of text: Dim oDoc As Word.Document Set oDoc = DsoFramer1.ActiveDocument oDoc.Content.Text = &quot;This was added by Automation&quot; The ability to control the object while the object is embedded is very powerful.

NOTE: Automation of the control from HTML script over the Web can be very dangerous to a user, so the control has purposely been marked as NOT &quot;Safe for Scripting&quot;. Users who use the control in Web pages may be prompted to enable scripts before they use this control. This is required for proper security.

Create new documents
The component allows you to create new documents for any ActiveX document type that is registered on the system. A user can use the built-in functionality of the New dialog box from the menu, or use a custom function that you provide to create new documents.

The CreateNew method on the control allows you to build your own method to start new documents. The method takes either a Programmatic Identifier (ProgId) of the ActiveX document type that you want to start, or the path to an Office template file. For example, you can use the following Office ProgIds. Excel Spreadsheet           &quot;Excel.Sheet&quot; Excel Chart              &quot;Excel.Chart&quot; PowerPoint Presentation      &quot;PowerPoint.Show&quot; Project Database         &quot;MSProject.Project&quot; Visio Drawing            &quot;Visio.Drawing&quot; Word Document            &quot;Word.Document&quot; If the ProgId or template is not recognized or the server cannot be started, you receive one of the standard error messages that are discussed in the &quot;Custom Error Messages&quot; section.

Open documents
You can also open and edit Office documents that exist on a local drive, Universal Naming Convention (UNC) share, or Web folder. A standard Open dialog box that can be displayed by the user or called by code has been provided, and allows the user to find and select a file to open. You can also call the Open method directly and give the control a specific file to open.

Open takes either a qualified file path or a URL to a file on a remote Web server. The control attempts to gain write access to the file and keep it locked for editing unless you pass True for the ReadOnly parameter. For example, the following code opens a local file and keeps a lock on it for editing: DsoFramer1.Open &quot;C:\TestBook.xls&quot; If you want to open a file that is not associated with an Office application but that can be loaded with Office, you can specify an alternate ProgId in the Open method. For example, to open a plain text file in Word, you can use code that resembles the following: DsoFramer1.Open &quot;C:\Plain.txt&quot;,, &quot;Word.Document&quot; If you combine this ability with a URL, you can use code that resembles the following to open the resulting HTML streamed back from an ASP file and have it display as data inside of Excel: DsoFramer1.Open &quot;https://secureserver/test/mytest.asp?id=123&quot;, True, _ &quot;Excel.Sheet&quot;, &quot;MyUserAccount&quot;, &quot;MyPassword&quot; The user can then edit the results and save the file as a local file on disk, or save the file to the server as a new file in a Web folder.

In addition you can use the Open method to create and display a copy of a document you created via Automation. For example, the following code would create a new Word document, and then display it. Dim oWordApp As Object Dim oWordDoc As Object Set oWordApp = CreateObject(&quot;Word.Application&quot;) Set oWordDoc = oWordApp.Documents.Add oWordDoc.Content.Text = &quot;Hello World&quot; DsoFramer1.Open oWordDoc

Save documents
To save a document, you can use the menu or call the Save method. The Save method acts both as a simple Save command and as a SaveAs command, depending on whether you pass a file location for the first parameter. If the current file was opened read-only and you do not specify a save location, a read-only error occurs. For more information, see the &quot;Custom Error Messages&quot; section.

You can also save to a Web folder on a remote server if that server supports either Microsoft FrontPage Server Extensions (FPSE) or the Web Distributing Authoring and Versioning (WebDAV) protocol extension for HTTP. The following code shows a new file that is saved to a remote file server: DsoFramer1.CreateNew &quot;PowerPoint.Show&quot; ' Let user edit the document, then save it. DsoFramer1.Save &quot;http://myserver/mypresentations/test.ppt&quot; By default, if a file already exists at the given location, you receive an error message. However, by setting the OverwriteExisting parameter to True, you can explicitly tell the control to overwrite the file.

Handle your own file commands
Every time a user selects an item from the File menu or an item on a toolbar that is associated with a file command, the OnFileCommand event is raised. The event allows you to override the default behavior for the control and supply your own custom actions and dialog boxes to do normal file operations.

You can also enable or disable items on the File menu by using the EnableFileCommand property. For example, the following code disables the Print command, and then traps print calls to prevent a user from printing: Private Sub Form_Load DsoFramer1.EnableFileCommand(dsoFilePrint) = False End Sub

Private Sub DsoFramer1_OnFileCommand(ByVal Item As _ DSOFramer.dsoFileCommandType, Cancel As Boolean) If Item = dsoFilePrint Then MsgBox &quot;You asked to print, but I won't allow it.&quot; Cancel = True End If End Sub

Show or hide the titlebar, menubar, or toolbars
You can programmatically show or hide the title bar, menu bar, or toolbars by setting these parameters to True or False. This may be useful when you try to restrict user actions or control the appearance of the document while it is embedded.

Note that not all toolbars may be hidden when you set Toolbars to False. The ActiveX document server must determine which tools can be switched on and off, and when this is possible. It is better to set this property before you open or create a new document so that the server is aware of your choice at the time of the initial embedding. Note that although all Office servers support switching tools on and off, some third-party servers may not.

Frame hook policy
To correctly handle activation when the host gains or loses foreground status, the ActiveX control uses a frame hook. By default, the hook is set when the control is created. In some situations, especially when the control is used from a multi-threaded UI host or when the control is nested in a container control like a Tab page in a .NET WinForm application, the parent of the control at create time may not be the correct window for the control to hook when it is running. In these situations, you can use the FrameHookPolicy property to reset the hook at a more suitable time. For example, if you build a .NET WinForm solution, set the FrameHookPolicy property to dsoSetOnFirstOpen in the Properties window.

Component activation policy
The sample control can support more than one instance of itself in a given host application. However, only one control can be active at a given time. This is a requirement of ActiveX Document hosting. To handle multiple instances in a single host, the control registers itself with a component manager. This lets the component manager keep track of the active control. Use the ActivationPolicy property to control how the embedded object is handled during component changes. The ActivationPolicy property can be set to one or more of the bit flags that are defined by the dsoActivationPolicy enumeration.

Custom error messages
In addition to the standard COM error messages, the control can return one of the following custom error messages. 0x80041102  The ProgID/Template could not be found or is not associated with a COM server. 0x80041103  The associated COM server does not support ActiveX Document embedding. 0x80041104  The command is not supported by the document server. 0x80041105  Unable to perform action because document was opened in read-only mode. 0x80041106  The Microsoft Internet Publishing Provider is not installed, so the URL document cannot be open for write access. 0x80041107  No document is open to perform the operation requested. 0x80041108  Cannot access document when in modal condition. 0x80041109  Cannot Save file without a file path.

Notice of use, distribution, and support
Microsoft provides programming examples for illustration only, without warranty either expressed or implied. This includes, but is not limited to, the implied warranties of merchantability or fitness for a particular purpose. This article assumes that you are familiar with the programming language that is being demonstrated and with the tools that are used to create and to debug procedures. Microsoft support engineers can help explain the functionality of a particular procedure. However, they will not modify these examples to provide added functionality or construct procedures to meet your specific requirements.

