3

I've been trying for a few days now to load a word docx file into a webbrowser control that exists in a windows form c#. After struggling for days to get this done but with the help of Google and some helpful posts I've managed to do and it is beauuuuuutiful. I've done it through:

  1. Converting the docx file into a temporary html file.
  2. I navigated my webbrowser control to that temporary html document.

Only that I've noticed one problem: The webbrowser control seems to view the files in Web Layout. That is Ms-Word Web Layout, you know there are 3 main viewing layouts in Ms-Word, Read Mode, Print Layout, and Web Layout. The Problem with this is that some of the heavily formatted docx files gets skewed all up in that webbrowser control because it stretches them out as if they would appear in an actual web browser application.

Now what I would like to achieve is to be able to view the content of that webbrowser control in something similar to the Print Layout in Ms-Word, or at least for the control to refit the content within the control's own size.

(If my code is necessary then I can provide it)

Yousef Imran
  • 81
  • 1
  • 3
  • 9
  • It's a Windows Form Application. I've added it as a custom control to my toolbox from, Right click on the toolbox >> "Choose toolbox item (Window)/ .NET Framework Component (Tab)/ Web Browser (System.windows.Forms Namespace). So I think it's WinForm control but correct me if I'm wrong. – Yousef Imran Aug 14 '13 at 19:02

2 Answers2

1

Found at http://codinglight.blogspot.de/2008/10/simple-docbrowser-control.html

This uses a webBrowser-Control, but converts your document into an HTML-File. Further you will have to have MS Word installed.

Create a Class with following code:

using System;
using System.Linq;
using System.Windows.Forms;
using Microsoft.Office.Interop.Word;
using System.IO;

namespace WordControls
{
    public partial class DocBrowser : UserControl
    {
        private System.Windows.Forms.WebBrowser webBrowser1;

    delegate void ConvertDocumentDelegate(string fileName);

    public DocBrowser()
    {
        InitializeComponent();

        // Create the webBrowser control on the UserControl. 
        // This code was moved from the designer for cut and paste
        // ease. 
        webBrowser1 = new System.Windows.Forms.WebBrowser();

        webBrowser1.Dock = System.Windows.Forms.DockStyle.Fill;
        webBrowser1.Location = new System.Drawing.Point(0, 0);
        webBrowser1.MinimumSize = new System.Drawing.Size(20, 20);
        webBrowser1.Name = "webBrowser1";
        webBrowser1.Size = new System.Drawing.Size(532, 514);
        webBrowser1.TabIndex = 0;

        Controls.Add(webBrowser1);

        // set up an event handler to delete our temp file when we're done with it. 
        webBrowser1.DocumentCompleted += webBrowser1_DocumentCompleted;
    }

    string tempFileName = null;

    public void LoadDocument(string fileName)
    {
        // Call ConvertDocument asynchronously. 
        ConvertDocumentDelegate del = new ConvertDocumentDelegate(ConvertDocument);

        // Call DocumentConversionComplete when the method has completed. 
        del.BeginInvoke(fileName, DocumentConversionComplete, null);
    }

    void ConvertDocument(string fileName)
    {
        object m = System.Reflection.Missing.Value;
        object oldFileName = (object)fileName;
        object readOnly = (object)false;
        ApplicationClass ac = null;

        try
        {
            // First, create a new Microsoft.Office.Interop.Word.ApplicationClass.
            ac = new ApplicationClass();

            // Now we open the document.
            Document doc = ac.Documents.Open(ref oldFileName, ref m, ref readOnly,
                ref m, ref m, ref m, ref m, ref m, ref m, ref m,
                 ref m, ref m, ref m, ref m, ref m, ref m);

            // Create a temp file to save the HTML file to. 
            tempFileName = GetTempFile("html");

            // Cast these items to object.  The methods we're calling 
            // only take object types in their method parameters. 
            object newFileName = (object)tempFileName;

            // We will be saving this file as HTML format. 
            object fileType = (object)WdSaveFormat.wdFormatHTML;

            // Save the file. 
            doc.SaveAs(ref newFileName, ref fileType,
                ref m, ref m, ref m, ref m, ref m, ref m, ref m,
                ref m, ref m, ref m, ref m, ref m, ref m, ref m);

        }
        finally
        {
            // Make sure we close the application class. 
            if (ac != null)
                ac.Quit(ref readOnly, ref m, ref m);
        }
    }

    void DocumentConversionComplete(IAsyncResult result)
    {
        // navigate to our temp file. 
        webBrowser1.Navigate(tempFileName);
    }

    void webBrowser1_DocumentCompleted(object sender,
        WebBrowserDocumentCompletedEventArgs e)
    {
        if (tempFileName != string.Empty)
        {
            // delete the temp file we created. 
            File.Delete(tempFileName);

            // set the tempFileName to an empty string. 
            tempFileName = string.Empty;
        }
    }

    string GetTempFile(string extension)
    {
        // Uses the Combine, GetTempPath, ChangeExtension, 
        // and GetRandomFile methods of Path to 
        // create a temp file of the extension we're looking for. 
        return Path.Combine(Path.GetTempPath(),
            Path.ChangeExtension(Path.GetRandomFileName(), extension));
        }
    }
}

Add the control to your form and call LoadDocument-method.

docBrowser1.LoadDocument(@"Path_to_Doc_as_String");
Daniel Abou Chleih
  • 2,440
  • 2
  • 19
  • 31
  • I've seen the code above, and it helped me in creating my own class, except I think it is very long and so much of it is overcoded. I have my own smaller class which does the same thing. Secondly that class still have few errors when I tried it raw. And last but not least, even that class when it is properly working, having inspected the code, it will still have the same problem I'm having which is loading the word document in Web Layout. I want the document to be loaded Print Layout or for it's content to be refitted within the webbrowser control properly. Thank you. – Yousef Imran Aug 14 '13 at 22:51
  • Sure because the webBrowser-Control is not made for viewing documents. Why do you even have to use webBrowser? You could for example start word within your application – Daniel Abou Chleih Aug 17 '13 at 10:16
1

There is no such option available for the save method to choose a layout.

You can use the webbrowser as an ActiveX document server then access the word DOM. The way to set a layout type is via Document.ActiveWindow.View.Type:

private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            var webbrowser = webBrowser1.ActiveXInstance as SHDocVw.IWebBrowser2;
            var document =webbrowser.Document;
            if (document != null)
            {
                var wordDocument = document as Microsoft.Office.Interop.Word.Document ;
                if (wordDocument != null)
                {
                    var activeWindow=wordDocument.ActiveWindow;
                    if (activeWindow != null)
                    {
                        var view=activeWindow.View;
                        if (view != null)
                        {
                            view.Type = WdViewType.wdPrintView;
                            Marshal.ReleaseComObject(view);
                        }
                        Marshal.ReleaseComObject(activeWindow);
                    }
                    Marshal.ReleaseComObject(wordDocument);
                }
                Marshal.ReleaseComObject(document);
            }
            Marshal.ReleaseComObject(webbrowser);
        }
    }

Depending on the user's internet security settings for unsafe objects, you may see a prompt before opening the document, or simply get null from IWebBrowser2.Document (thus can't automate the word DOM).

Sheng Jiang 蒋晟
  • 15,125
  • 2
  • 28
  • 46