在wpf应用程序中嵌入word 2010编辑器

时间:2011-06-01 06:55:22

标签: wpf editor ms-word ms-office avalonedit

如何在WPF应用程序中使用单词编辑器?是否可以仅使用WPF中的Windows窗体托管?还有另一种方法可以实现吗?

我找到了AvalonEdit,但它没有我需要的功能。所以使用这种方式,我的问题可能无法解决。

还有一些东西在WPF中托管Windows窗体控件,但它不是我的答案。

我想了解有没有办法在wpf应用中以原生方式使用word编辑器? 是否所有API都可以在该解决方案中使用?

提前致谢。

2 个答案:

答案 0 :(得分:11)

您可以在WebBrowser控件中托管MS Word(2007/2010,可能还有其他版本),这可以在WinForms中运行,也可以在WPF中运行。提供了一个.NET API来自动化Word,记录为here。所需的互操作程序集随Office 2010一起提供,因此部署比以前的Office版本简单得多。

有关在WebBrowser控件中托管Word的更多详细信息,请参阅此Microsoft Support article。下面的屏幕截图显示了嵌入主机Winforms应用程序中的Word。

enter image description here

请注意,这仅适用于单个托管的Word实例,因此您无法在同一个应用程序中并排显示2个Word文档。此外,功能区有时会丢失 - 但Word从未导致应用程序崩溃。

由于存在潜在的安全问题,因此需要管理权限才能进行必要的注册表更新。编写注册表更新的一种简单方法是编写脚本,但以下(修订/未测试)代码显示了如何在c#中为Word,Excel和PowerPoint执行此操作:

using System.Security.AccessControl;

    private Dictionary<string,uint> OfficeBrowserRegKeys()
    {
        string[] officeRegKeyArray = new string[]
            {
                @"SOFTWARE\Classes\Word.Document.12",
                @"SOFTWARE\Classes\Word.DocumentMacroEnabled.12",
                @"SOFTWARE\Classes\Excel.Sheet.12",
                @"SOFTWARE\Classes\Excel.SheetMacroEnabled.12",
                @"SOFTWARE\Classes\Excel.SheetBinaryMacroEnabled.12",
                @"SOFTWARE\Classes\PowerPoint.Show.12",
                @"SOFTWARE\Classes\PowerPoint.ShowMacroEnabled.12",
                @"SOFTWARE\Classes\PowerPoint.SlideShow.12",
                @"SOFTWARE\Classes\PowerPoint.SlideShowMacroEnabled.12"
            };
        Dictionary<string,uint> officeRegKeys = new Dictionary<string, uint>();
        uint wrdVal = 0x80000024;
        uint excelVal = 0x80000A00;
        uint powerPtVal = 0x800000A0;
        foreach(string keyName in officeRegKeyArray)
        {
            if (keyName.Contains("Word"))
            {
                officeRegKeys.Add(keyName, wrdVal);
            }
            else if (keyName.Contains("Excel"))
            {
                officeRegKeys.Add(keyName, excelVal);
            }
            else
            {
                officeRegKeys.Add(keyName, powerPtVal);
            }
        }
        return officeRegKeys;
    }

    private void setNewOfficeKeys()
    {
        uint editFlag = 0x00010000;
        Dictionary<string,uint> officeRegKeys = OfficeBrowserRegKeys();

        foreach (KeyValuePair<string, uint> kvp in officeRegKeys)
        {
            try
            {
                RegistryKey rKey = Registry.LocalMachine.OpenSubKey(kvp.Key, 
                   RegistryKeyPermissionCheck.ReadWriteSubTree,
                   System.Security.AccessControl.RegistryRights.SetValue);
                rKey.SetValue("BrowserFlags", unchecked((int)kvp.Value),
                RegistryValueKind.DWord);
                rKey.SetValue("EditFlags", unchecked((int)editFlag),
                RegistryValueKind.DWord);
            }
            catch (Exception e) { string msg = e.Message; }
        }
    }

答案 1 :(得分:0)

嗯,Word本身在技术上并不是由其他应用程序托管,无论是WPF,WINFORMS还是其他任何应用程序。

您可以使用api技巧(如SetParent)将主Word窗口移动到WPF托管窗口。我以前做过,但这是非常棘手的事情,很容易错过导致GPF的事情(包括Word和你的应用程序)。

是否有任何理由需要“在您的应用中使用Word”?为什么不写一个单词addin然后在必要时从你的应用程序启动Word。然后,Addin可以在Word中与您的应用程序或数据库或其他任何内容进行通信。

在任何情况下,用户都可能会发现这是一种更有用的方法。