Win8是否也为遗留应用添加了内置拼写检查功能?

时间:2014-05-18 01:27:12

标签: windows winapi windows-8

根据MSDN

  

在Windows 8中,内置拼写检查以编辑控件。

好吧,我在我的设置中启用了选项(突出显示和自动更正),我在Notepad.exe或我自己的旧版Win32应用程序中没有看到这个。

对于我的应用程序,我需要做什么才能启用(希望就是这么简单)?我确实尝试按照文章中的信息阅读并阅读了很多参考资料,但它确实不太清楚,似乎是为了创建自定义提供程序/解决方案,但我对任何“内置”行为都很满意。

1 个答案:

答案 0 :(得分:7)

内置仅适用于Rich Edit控件,EM_SETLANGOPTIONS,IMF_SPELLCHECKING选项。您需要使用更高版本的Rich Edit,即MsftEdit.dll中的版本,而不是默认情况下获得的更常见的v2.0版本。

我在Winforms控件中尝试过,效果很好。请注意,它不会使拼写检查交互活动,没有类似于允许您从一组建议的替代方案中选择的对话框。任何可以自动纠正的东西,比如" teh" """和" spelll"到"拼写"如果立即应用,没有自动更正的单词会用红色加下划线。 Ctrl + Z将自动更正的单词恢复为原始单词。

从这个C#代码到你未指定的语言,你不应该有太多麻烦。有一些样板文件Winforms管道存在,关键外卖是使用LoadLibrary来获取初始化控件的v5版本,以便您可以使用RichEdit50W窗口类名。并使用SendMessage()打开选项:

using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;

class RichTextBoxEx : RichTextBox {

    protected override CreateParams CreateParams {
        get {
            if (moduleHandle == IntPtr.Zero) {
                moduleHandle = LoadLibrary("msftedit.dll");
                if (moduleHandle == IntPtr.Zero) throw new Win32Exception("Could not load Msftedit.dll");
            }
            CreateParams createParams = base.CreateParams;
            createParams.ClassName = "RichEdit50W";
            if (this.Multiline) {
                if (((this.ScrollBars & RichTextBoxScrollBars.Horizontal) != RichTextBoxScrollBars.None) && !base.WordWrap) {
                    createParams.Style |= 0x100000;
                    if ((this.ScrollBars & ((RichTextBoxScrollBars)0x10)) != RichTextBoxScrollBars.None) {
                        createParams.Style |= 0x2000;
                    }
                }
                if ((this.ScrollBars & RichTextBoxScrollBars.Vertical) != RichTextBoxScrollBars.None) {
                    createParams.Style |= 0x200000;
                    if ((this.ScrollBars & ((RichTextBoxScrollBars)0x10)) != RichTextBoxScrollBars.None) {
                        createParams.Style |= 0x2000;
                    }
                }
            }
            if ((BorderStyle.FixedSingle == base.BorderStyle) && ((createParams.Style & 0x800000) != 0)) {
                createParams.Style &= -8388609;
                createParams.ExStyle |= 0x200;
            }
            return createParams;
        }
    }

    protected override void OnHandleCreated(EventArgs e) {
        base.OnHandleCreated(e);
        if (Environment.OSVersion.Version.Major > 6 ||
            Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor >= 2) {
            int opts = (int)SendMessage(this.Handle, EM_GETLANGOPTIONS, IntPtr.Zero, IntPtr.Zero);
            opts |= IMF_SPELLCHECKING;
            SendMessage(this.Handle, EM_SETLANGOPTIONS, IntPtr.Zero, new IntPtr(opts));
        }
    }

    private static IntPtr moduleHandle;

    private const int IMF_SPELLCHECKING = 0x0800;
    private const int EM_SETLANGOPTIONS = 0x0400 + 120;
    private const int EM_GETLANGOPTIONS = 0x0400 + 121;

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr LoadLibrary(string lpFileName);
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
}