Embedding Microsoft Word as a control into Desktop Forms
I’ve spent quite a bit of time today with a cool feature – integrating MS Word directly into Help Builder as an edit control. By this I mean, using Word as an embedded control into my application and using it for basic editing and more importantly for its spell checking support.
The normal editing environment in Help Builder is entirely text based and using Word too leaves the actual editing as text based with all mark up handled through Help Builder’s menus, rather than through Word.
Here’s what this looks like in Help Builder:

Although the editing doesn’t take advantage of Words layout capabilities or even its markup it does provide a smoother text typing environment and of course inline spell checking.
This feature is optional and not the default edit mode – you basically have to select this option from the Edit toolbar when you are in a specific control. As soon as you move off the field, the editor reverts to a default textbox. You could say that Word is used in this scenario merely as an overlay on the stock textbox.
Of course, the customer must have Word installed in order for this to work at all, and as this interface uses the Web Browser control to host a Word document, must have security settings to allow editing Word documents locally.
How it works
Embedding Word into a FoxPro (or any other ActiveX container) is not easily done. Although Word is an Activedocument host, it doesn’t provide a direct interface to embed itself into a host application.
You can make this happen however, by using the Microsoft Web Browser ActiveX control and hosting a Word document inside of it. You can simply navigate the WebBrowser to a Word Document and Word will load into the browser control in place and expose the Word object model via the Document property.
If you’re not familiar with the Web Browser control you can look here for more information:
http://www.west-wind.com/presentations/shellapi/shellapi.asp
The following function loads a Word document into the browser control hosted on a form (or in this case a Container control in Visual FoxPro):
FUNCTION LoadDocument
LPARAMETERS lcDocument, lcText
IF !FILE(lcDocument)
this.oBrowser.Navigate("about:blank")
MESSAGEBOX("Can't find document: " + lcDocument,48,"Word Editing")
RETURN .F.
ENDIF
this.cinternaldocument = lcDocument
DOEVENTS
THIS.oBrowser.Navigate( lcDocument )
DOEVENTS
IF !this.oBrowser.WaitForReadyState()
DOEVENTS
IF !this.oBrowser.WaitForReadyState()
RETURN .F.
ENDIF
ENDIF
IF this.oBrowser.ReadyState # 4
WAIT WINDOW TIMEOUT .2
ENDIF
LOCAL loDoc as Word.Document, loApp as Word.Application
loDoc = this.oBrowser.Document
THIS.oDoc = loDoc
this.oWord = loDoc.Application
*** Put document into 'Web View' mode
loWord.ActiveWindow.View = 6
*** Match document fonts to current font
IF !EMPTY(this.cfontinfo)
lnCount = ALINES(laWords,this.cfontinfo,",")
IF lnCount = 3
loDoc.Styles.Item("
loDoc.Styles.Item("
ENDIF
ENDIF
*** Manage display of toolbars
loDoc.CommandBars("Reviewing").visible = .f.
loDoc.CommandBars("Standard").Visible = .t.
*** Load up the text into the Word doc
IF !EMPTY(lcText)
this.oBrowser.Document.Content.Text = lcText
ENDIF
*** Try to select the same selection in the Word doc
this.oWord.Selection.Start = this.oEdit.SelStart
this.oWord.Selection.End = this.oEdit.SelStart + this.oEdit.SelLength
this.oWord.Selection.Range.Select
DOEVENTS
THIS.oBrowser.Visible = .t.
RETURN .t.
This code is part of a class that essentially handles two way editing and data exchange with a textbox. The control (a Container) receives an EditBox and the container then overlays this Editbox with the Web Browser control hosting Word. When focus is lost the the control writes the output back into the textbox, matching the selections and cursor locations etc.
The code above requires that you pass a document. Word loaded into the browser needs a Word document to start with, even if you’re only interested in the text typed into Word (as I am in Help Builder). This means no matter what, you need to load some sort of document and I have an empty template document that I use for this purpose. I copy this document to a temporary location and then load the document with this method. I can optionally pass in a second parameter which is the text that gets loaded into the editing document. lcText gets set at the very end.
Note the code to load the document: It navigates the browser to the temporary document, then waits for the document to become ready. This is tricky and you need to make sure that you use DOEVENTS extensively while polling for the Browser’s ReadyState property to get to 4. The WaitForReadyState() method provides this functionality and is outlined in the article mentioned earlier.
Once the document is loaded you can get a reference to the active document which is an instance of the Word.Document COM interface. From there you can Word.Application with Document.Application, which gives you access to the entire Word document model. The code that follows customizes the look and feel of Word a bit to match what I need in Help Builder.
Specifically I want to run in Web View which is most similar to an EditBox control. You also want to hide some toolbars – the Reviewing bar always pops up by default, but this toolbar is not used for editing. You can hide all toolbars if you choose, but be aware that resizing the browser can cause some of the toolbars to pop back up…
Finally I go and set the text of the control and match it to the text in the Edit box. I also pick up the selection of the EditBox and map it over into the Word document so the doc pops up in the same cursor position.
Once that’s done you’re ready to start editing text…
To do data exchange you can now call the SaveText() method manually:
FUNCTION SaveText()
IF TYPE("THIS.oDoc") = "O"
this.Value = THIS.oDoc.Content.Text
IF !ISNULL(THIS.oEdit )
this.oEdit.Value = this.Value
DOEVENTS
this.oEdit.SelStart = this.SelStart
this.oEdit.SelLength = this.SelLength
ENDIF
ENDIF
this.Value = ""
The control exposes a value property which contains the value from the Word document. At any point you can call SaveText to retrieve the Word documents content and also update the selection points in the edit control.
This behavior can also be Auto-Triggered when the control looses focus. By default in Help Builder the control is set up to ExitOnLostFocus() so that when you click on another control or the form the control releases and updates the underlying edit control.
FUNCTION LostFocus()
IF this.lExitOnLostfocus
*** Switch back to EditControl view
THIS.SetViewMode(1)
ELSE
*** Otherwise just save the text
THIS.SaveText()
ENDIF
To make life easier when switching Views there’s SetViewMode() method that handles swapping the EditBox and Word interfaces:
FUCNTION SetViewMode(lnViewMode)
IF lnViewMode = 2
LOCAL loBrowser
THIS.AddObject("oBrowser","wwbrowser_4")
loBrowser = this.oBrowser
*** Resize into the container control
loBrowser.Left = 0
loBrowser.Top = 0
loBrowser.Height = this.Height
loBrowser.Width = this.Width
loBrowser.Anchor = 15
DOEVENTS
*** Force a resize to occur
THIS.Width = this.Width
DOEVENTS
this.oEdit.Visible = .f. && Hide the EditBox
loBrowser.Visible = .t. && Make the browser visible
this.Visible = .t.
this.SetFocus()
IF !EMPTY(this.cInternaldocument)
this.Loaddocument(this.cInternalDocument,;
IIF(!ISNULL(this.oEdit),this.oEdit.Value,""))
ENDIF
IF TYPE("THISFORM.nWordEditMode") = "N"
THISFORM.nWordEditMode = 1 && Into Word Mode
ENDIF
ELSE
IF TYPE("THISFORM.nWordEditMode") = "N"
THISFORM.nWordEditMode = 0 && No Word/Text Mode
ENDIF
THIS.Savetext()
this.RemoveBrowser()
this.Visible = .f.
DOEVENTS
this.oEdit.Visible = .t.
ENDIF
Notice that this code actually adds and deletes an instance of the browser. It does this because the Web Browser control is finicky in some ways and I had some problems from keeping the UI working properly when the Web Browser control was hidden. From time to time it would simply pop up ontop of the text box, or would cause the textbox to not be editable. The workaround was to remove the control completely.
Removing the browser or exiting the document is also a bit tricky. The problem is that Word hosted in the browser uses the underlying document for editing. Since you’ve essentially made changes to the document when you try to move off the document or close /remove the browser, Word wants to prompt you to save. So rather than the prompt, we can fake out Word by saving our document first, then navigating to a blank page, before actually removing the browser. The process looks like this:
FUNCTION RemoveBrowser()
THIS.Visible =.t.
IF TYPE("this.oBrowser") = "O"
*** Must save so we get no dialog
IF !ISNULL(this.oDoc)
this.oDoc.Save()
ENDIF
*** Must navigate off
this.oBrowser.Navigate("about:blank")
this.oBrowser.WaitForReadyState()
ENDIF
IF !ISNULL(this.oDoc)
THIS.oDoc = .null.
ENDIF
DOEVENTS
IF !ISNULL(this.oWord)
THIS.oWord = .NULL.
ENDIF
IF TYPE("this.oBrowser") = "O"
this.RemoveObject("obrowser")
ENDIF
FUNCTION Destroy()
IF !ISNULL(THIS.oEdit)
THIS.oEdit.visible = .t.
THIS.oEdit = .null. && Clear the reference
ENDIF
this.RemoveBrowser()
DOEVENTS
IF THIS.ldeletedocument
LOCAL llError, lnX
llError = .T.
lnX=0
DO while llError AND lnX < 10
TRY
ERASE (this.cinternaldocument)
llError = .f.
CATCH
llError = .t.
ENDTRY
DOEVENTS
WAIT WINDOW "" TIMEOUT .3
lnX = lnX + 1
ENDDO
ENDIF
This code makes very sure that all object reference are released. This is important or else Word may not completely shut down.
The control also has a property for lDeleteDocument which when true deletes the document that was created when done editing. The idea being that you want to have a temporary file on disk for editing using a unique name (in case you have more than a single instance of the control on a form editing documents at the same time). If true Destroy code deletes the temporary file.
Although this code is full of a few odd ‘hacks’ to make the browser and Word behave properly I find that this works actually really well. The process of managing this ‘hot swapping’ of controls in the UI is a bit of work, but quite doable. In fact, Help Builder already supports this overlay mechanism for the HTML Edit control and this interface works of the same concepts.
Help Builder had similar Word integration in previous versions for spell checking. Previously the Spell checker would bring up Word.Application as a COM object externally and then manipulate the document the same way. While that’s much easier than this integration into a form, the in-form approach is much more intuitive and provides access to all the of the editing features that Help Builder provides such as image capture/embedding and easy cross linking. This only makes sense in a form based interface and wouldn’t really work in an external interface.
While the solution I show above is a bit implementation specific and focused on exchanging data with an EditBox you can use the same logic for direct access or for simply embedding and editing/managing saving a Word document in your own applications. Check it out…
The Voices of Reason
# RE: Embedding Microsoft Word as a control into Desktop Forms
This is good stuff!
# re: Embedding Microsoft Word as a control into Desktop Forms
IE's support for editing (either in the DOM or via the DHTML edit control) is very spotty at best too. The main problem is that it's really difficult to handle markup containership. For example, if you're in a cell in a table, doing the UI to continue outside of the table if the table is the last thing on the page is very difficult through the Html Edit interface, unless you hand edit the HTML. Heck it doesn't even work in the VS editor and is difficult even in FrontPage.
I have the basics working well, but to go beyond that some SERIOUS work is required and I fear even if I did do that it would never work perfectly.
So the support is in there with a disclaimer in the docs <g>. It's one way - once you edit HTML WYSIWYG it converts to plain HTML and stays that way - it doesn't go back to the 'formatted HTML' Help Builder uses.
I may look at this again shortly because this Word embedding has given me a few ideas how to switch into the rich edit mode more reliably which has been one of the issues with it as well.
# re: Embedding Microsoft Word as a control into Desktop Forms
What you have done has given me a solution on a problem I have been fiddling around with for awhile.
In addition to Word, I want to try something similar for Visio HTML output.
# re: Embedding Microsoft Word as a control into Desktop Forms
The Best.
Thanks Rick.
# re: Embedding Microsoft Word as a control into Desktop Forms
# re: Embedding Microsoft Word as a control into Desktop Forms
hello,
I need to apply the code that you gave but in javascript
it is possible?
it's urgent
thanks!!!!
# re: Embedding Microsoft Word as a control into Desktop Forms
# re: Embedding Microsoft Word as a control into Desktop Forms
Really a create article also i was looking for a solution. I've now only one other problem: I want to display de menu bar of word in the browser but it don't show it self when I set the visible property of the menu bar to True.
Is there also a workaround for?
Arco
# re: Embedding Microsoft Word as a control into Desktop Forms
I am newbie to Asp.Net technology.
I like to know, is it possible to create ASP.Net Server contorl using your example above, so that I can host on IE.
# re: Embedding Microsoft Word as a control into Desktop Forms
Thanks!
# re: Embedding Microsoft Word as a control into Desktop Forms
Below is the Javascript code in my html to launch MS Word. My only problem is that Word is running externally and not within my browser application.
Is there any way you or anyone could help?
<SCRIPT LANGUAGE="JavaScript">
<!-- Begin
// Your Code Here
var wdApp = new ActiveXObject("Word.Application");
wdApp.CommandBars("Standard").Visible = true;
wdApp.CommandBars("Formatting").Visible = true;
wdApp.CommandBars("Reviewing").Visible = false;
wdApp.Visible = true;
-->
</SCRIPT>
Thanks,
Wayne
# re: Embedding Microsoft Word as a control into Desktop Forms
# re: Embedding Microsoft Word as a control into Desktop Forms - Hiding/Showing toolbars
Only problem is the hiding and showing of Word toolbars. I just can not do it programmatically. If anyone has a work around please email me.
Thanks
# how to make display Microsoft Word in no-editable
thanks!
# re: Embedding Microsoft Word as a control into Desktop Forms
# re: Embedding Microsoft Word as a control into Desktop Forms
i am using the below code. but i need to insert data in to new document.pls suggest me.
var Fname=window.document.wrd.fname.value;
var Lname=window.document.wrd.lname.value;
if ((Fname!="")&&(Lname!=""))
{
var word = new ActiveXObject("Word.Document");
var doc = word.documents.open("C/Tc.doc");
doc.BookMarks("FName").range.InsertBefore(Fname);
doc.BookMarks("LName").range.InsertBefore(Lname);
word.visible=true;
}
# re: Embedding Microsoft Word as a control into Desktop Forms
Do you think your code could be adapted for use in a Access VBA or VisualBasic.NET form? My wife is a teacher and I'm trying to develop a database memory bank application with her chosen word doc in a subform or suchlike placed in the middle of the screen. Cant find much in MS knowledge base and so far have only found your articles. thanks
Val
# re: Embedding Microsoft Word as a control into Desktop Forms
I have been trying to work with Office applications in IE. Although I have achieved the same through ActiveX Control, I want to be able to opent he document normally within the browser and show the office document toolbar embedded with IE toolbar. Havent had a luck with this so far. I am using asp.net with vb as code behind. Any help would be greatly appreciated
Thanks
Dev
# re: Embedding Microsoft Word as a control into Desktop Forms
This looks great. I'm in the group that is trying to get this to work with a JSP. Have you or anybody else been able to get it to work? If so, can you please forward the example to me.
Thanks,
Scott
# re: Embedding Microsoft Word as a control into Desktop Forms
How can i control word ( edit ) in Html or Php ?
thanks.
# re: Embedding Microsoft Word as a control into Desktop Forms
# re: Embedding Microsoft Word as a control into Desktop Forms
# re: Embedding Microsoft Word as a control into Desktop Forms
I fixed the previous problem by setting the initial visible property to false.
I would like to know how can I avoid the download prompt to be shown when navigate to the word file?
Anyone can help?
# re: Embedding Microsoft Word as a control into Desktop Forms
User has to click on the 'always open in browserload' checkbox once - after that Word displays without prompting.
# re: Embedding Microsoft Word as a control into Desktop Forms
is it possible to integrate Microsoft Word as Control in a Windows Forms Aplication.
Ideas, examples, hints etc. to this address:
cottonface@t-online.de
Best Regards,
Dirk
# re: Embedding Microsoft Word as a control into ASP.net
# re: Embedding Microsoft Word as a control into Desktop Forms
# re: Embedding Microsoft Word as a control into Desktop Forms
# re: Embedding Microsoft Word as a control into Desktop Forms
we want a to insert a particular text(key) into the word doc which is read only through ASP.NET. This is a unique key for that file(only msdoc file).
So, Can i make that key read only. Any one can add some data into it but can'not edit this key(or text).
hope you reply!
Rakesh
Mechsoft, Pune
# re: Embedding Microsoft Word as a control into Desktop Forms
thanks
Brady
# re: Embedding Microsoft Word as a control into Desktop Forms
I was adopting this to a VB.NET forms based applicatin and ran into a problem. The webControl.document as not returning a reference to the document.
I discovered that the problem is that this does not appear to work with the system.windows.forms.webbroswer control. Which is the default webcontrol in my vs 2008 control box. I added the IE control AxSHDocVw.AxWebBrowswer which comes from the dll shdocvw.dll which I believe is an IE dll. And all seems to work as expected.
# re: Embedding Microsoft Word as a control into Desktop Forms
There are:
1. frame in IE, at this point load Word doc. Frame in html have object and metod window, document, body, etc (by DOM).
2. I can call Word in html by javascript - use 'oDoc = new ActiveXObject("Word.Document");' - in any case in NEW window of MS Word. And in the case in question I have control on all word-object (Document, Range, etc).
I want have control of doc-file load in frame. (now I cannot - i.e. html-frame without control of word-document or word-doc (out of frame) in NEW - not for me - window with control of him, )
Do you can help me?
# re: Embedding Microsoft Word as a control into Desktop Forms
I developed by VB Studio .Net (framework 2.0) page using Word document (COM object).So, everything works fine on my development machine (XP - IIS 6.0 - Office 2003) using VB Studio net, but when I published to website on my local II Server (localhost), the code executes without raising any error and the winword.exe is loaded in the task manager but the GUI or the word document (where by bookmarks I added data from SQL Server) does not show up. I added high access to Word but not helps.
Thank you in advance
# re: Embedding Microsoft Word as a control into Desktop Forms
# javascript code Needed -Word activex not loading inside the page
Somebody got same issue . Do you have solution for this problem?
Below is the Javascript code in my html to launch MS Word. My only problem is that Word is running externally and not within my browser application.
<SCRIPT LANGUAGE="JavaScript">
<!-- Begin
// Your Code Here
var wdApp = new ActiveXObject("Word.Application");
wdApp.CommandBars("Standard").Visible = true;
wdApp.CommandBars("Formatting").Visible = true;
wdApp.CommandBars("Reviewing").Visible = false;
wdApp.Visible = true;
-->
</SCRIPT>
Thanks,
Sam
# Re: Directly Open particular section marked by Bookmark in Word Document upon opening
I want to open a word document and upon opening, it should navigate directly to a bookmark. How can I do so?
# re: Embedding Microsoft Word as a control into Desktop Forms
One problem I can't seem to lick is that the commandbars disappear when another object like a textbox or even a command button is activated. Then the commandbars can't be recovered.
Does anyone have a workaround for this?
Thanks.
# re: Embedding Microsoft Word as a control into Desktop Forms
Thanks
# re: Embedding Microsoft Word as a control into Desktop Forms