18

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

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

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

我想了解有没有办法在 wpf 应用程序中以本机方式使用文字编辑器?该解决方案中的所有 API 都可用吗?

提前致谢。

4

2 回答 2

12

您可以在 WebBrowser 控件中托管 MS Word(2007/2010 和可能的其他版本),这适用于 WinForms,也应该适用于 WPF。为自动化 Word 提供了一个 .NET API,文档在此处。所需的互操作程序集随 Office 2010 一起提供,因此部署比以前的 Office 版本简单得多。

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

在此处输入图像描述

请注意,这仅适用于 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; }
        }
    }
于 2011-06-22T20:22:46.833 回答
2

好吧,Word 本身在技术上并非设计为由另一个应用程序托管,无论是 WPF、WINFORMS 还是其他任何应用程序。

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

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

无论如何,用户可能会发现这是一种更有用的方法。

于 2011-06-02T15:30:09.063 回答