在 C# 中记录击键时输入特殊字符时显示双字符

2024-04-13

我有一个应用程序可以记录用户按下的任何内容,但是当我按下特殊字符时,例如´ with a, 要得到á, I get ´´a;当我想要得到同样的东西时à,然后我得到``a,因此所有特殊字符都会输入两次,然后再输入常规字符。

我一直在寻找,却找不到任何真正的东西。但我注意到问题出在ToAscii方法,否则字符将被正确输入。

public string GetString(IntPtr lParam, int vCode)
{
    try
    {
        bool shift = Keys.Shift == Control.ModifierKeys || Console.CapsLock;

        string value = ""; 

        KeyboardHookStruct MyKeyboardHookStruct = 
            (KeyboardHookStruct)Marshal.PtrToStructure(
                lParam, typeof(KeyboardHookStruct));

        byte[] keyState = new byte[256];
        byte[] inBuffer = new byte[2];

        DllClass.GetKeyboardState(keyState);

        var ascii=
            DllClass.ToAscii(
                MyKeyboardHookStruct.vkCode, 
                MyKeyboardHookStruct.scanCode, 
                keyState, inBuffer, MyKeyboardHookStruct.flags
                );

        if (ascii == 1)
        {
            char key = (char)inBuffer[0];

            if ((shift) && Char.IsLetter(key))
                key = Char.ToUpper(key);

            value = key.ToString();
        }

        return value;
    }
    catch (Exception)
    {
        return "";
    }
}

我错过了什么或者做错了什么吗?所有其他字符都工作正常,但特殊字符以双字符形式出现。


EDIT:

尝试与ToUnicode反而。

[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern int ToUnicode(
    uint virtualKey, uint scanCode, byte[] keyStates, 
    [MarshalAs(UnmanagedType.LPArray)] [Out] char[] chars, 
    int charMaxCount, uint flags);

public string GetString(IntPtr lParam, int vCode)
{
    try
    {
        bool shift = Keys.Shift == Control.ModifierKeys || Console.CapsLock;

        string value = ""; 

        KeyboardHookStruct MyKeyboardHookStruct = 
            (KeyboardHookStruct)Marshal.PtrToStructure(
                lParam, typeof(KeyboardHookStruct));

        byte[] keyState = new byte[256];
        byte[] inBuffer = new byte[2];

        char[] chars = new char[2];

        DllClass.GetKeyboardState(keyState);

        int val = 0;

        val = ToUnicode(
                (uint)MyKeyboardHookStruct.vkCode, 
                (uint)MyKeyboardHookStruct.scanCode, 
                keyState, chars, chars.Length, 0
                );

        val = ToUnicode(
                (uint)MyKeyboardHookStruct.vkCode, 
                (uint)MyKeyboardHookStruct.scanCode, 
                keyState, chars, chars.Length, 0
                );

        if (val == 1)
        {
            char key = (char)chars[0];

            if ((shift) && Char.IsLetter(key))
                key = Char.ToUpper(key);

            value = key.ToString();
        }

        return value;
    }
    catch (Exception)
    {
        return "";
    }
}

请有人帮助我,我真的需要解决这个问题=/.


EDIT:

int val = -1;

if (IsDeadKey((uint)vCode))
{
    while (val == -1)
    {
        val = ToUnicode(
                (uint)MyKeyboardHookStruct.vkCode, 
                (uint)MyKeyboardHookStruct.scanCode, 
                keyState, chars, chars.Length, 0
                );
    }
}
else
    val = ToUnicode(
            (uint)MyKeyboardHookStruct.vkCode, 
            (uint)MyKeyboardHookStruct.scanCode, 
            keyState, chars, chars.Length, 0
            );

所以现在我尝试打电话给ToAscii or ToUnicode几次刷新真实角色但没有成功。我做错了吗?

与 ASCII 一样,首先调用´ I get -1,所以我再次调用它,然后我得到1;然后我按a, 要得到á,但后来我只得到a。如果我使用同样的事情ToUnicode两次之后,我得到了a代替á, 等等 ...


但我注意到问题出在 ToAsciii 方法中,没有正确输入字符。

这正是我所要猜测的。我很感谢你为我做的跑腿工作! :-)

问题是这些“特殊”字符是notASCII 字符。也就是说,它们实际上是某种不属于 ASCII 字符集的花式 Unicode 字符。

当您尝试将它们转换为 ASCII 字符时,该函数可能会尽力而为,分解组成的代码点á到单独的字符中´ and a.

显然这不是你想要的。你想要治疗á作为单个字符,因此需要使用 Unicode。这并不是真正的问题:Windows 内部全部采用 Unicode 至少已有十年了。抛弃陈旧的ToAscii http://msdn.microsoft.com/en-us/library/windows/desktop/ms646316.aspx功能;相反,你会想使用MapVirtualKey http://msdn.microsoft.com/en-us/library/windows/desktop/ms646306.aspx or MapVirtualKeyEx http://msdn.microsoft.com/en-us/library/windows/desktop/ms646307.aspx将通过低级键盘挂钩获得的虚拟键代码转换为字符值。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 C# 中记录击键时输入特殊字符时显示双字符 的相关文章

随机推荐