VB.NET的日语软键盘问题

小日子的外包项目,要使用VB.NET做一个软键盘,当点击软键盘上的按钮时TextBox输出对应键盘上的日语假名。
按钮ひ后台是 System.Windows.Forms.SendKeys.SendWait("ひ")
按钮゛后台是 System.Windows.Forms.SendKeys.SendWait("゛")
目前两个连在一起输出的日文是ひ゛,没有出现该日文的输入法关联词汇
而正确的显示应该是日文び,并且出现这个び输入法关联的词汇
求解答应该如何做?

该回答引用于gpt与OKX安生共同编写:
  • 该回答引用于gpt与OKX安生共同编写:

您可以使用以下代码来实现您的需求:

Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Integer, ByVal dwExtraInfo As Integer)

Private Const KEYEVENTF_KEYUP As Integer = &H2
Private Const VK_PROCESSKEY As Integer = &HE5

Private Sub SendKeyPress(ByVal keyCode As Integer)
    keybd_event(keyCode, 0, 0, 0)
    keybd_event(keyCode, 0, KEYEVENTF_KEYUP, 0)
End Sub

Private Sub btnHiragana_Click(sender As Object, e As EventArgs) Handles btnHiragana.Click
    SendKeyPress(&H15) ' 按下日语输入法切换键
    SendKeyPress(&H27) ' 按下「ひ」键
End Sub

Private Sub btnDakuten_Click(sender As Object, e As EventArgs) Handles btnDakuten.Click
    SendKeyPress(&H14) ' 按下日语输入法切换键(如果已经在日语输入法下,则不需要执行此步骤)
    SendKeyPress(&H27) ' 按下「び」键
    SendKeyPress(&HB) ' 按下濁点键
End Sub

这里使用了 Windows API 函数 keybd_event 来模拟按键操作。在 btnHiragana_Click 中,先按下日语输入法切换键,然后按下「ひ」键即可输出平假名「ひ」。而在 btnDakuten_Click 中,先按下日语输入法切换键,然后按下「び」键,再按下濁点键即可输出带濁点的平假名「び」。

这种方法能够确保正确的日语输入法被激活,并且可以输出正确的假名,并且会出现该日文的输入法关联词汇。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
这个问题的原因在于使用了组合字符。在日语中,一些字符的表示需要使用组合字符,如“ビ”可以由“ひ”和“゛”组合而成。

解决这个问题的方法是使用Unicode字符码直接输入带有组合字符的字符。例如,日文び的Unicode字符码为U+3073,而带有小゛的日文ビ的Unicode字符码为U+30D3。

下面是一个实现日语软键盘的示例代码:

Private Sub Button_Click(sender As Object, e As EventArgs)
    Dim keyCode As Integer = CInt(CType(sender, Button).Tag)
    Dim c As Char = ChrW(keyCode)
    System.Windows.Forms.SendKeys.SendWait(c)
End Sub

在这个示例中,每个按钮的Tag属性都设置为对应字符的Unicode字符码。当按钮被点击时,将该按钮的Tag属性转化为Unicode字符码,再使用ChrW函数将其转化为Unicode字符,在发送到TextBox中。

例如,发送日文び的代码为:

Button_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim c As Char = ChrW(&H3073)
    System.Windows.Forms.SendKeys.SendWait(c)
End Sub

这样可以正确地显示日文び的输入法关联词汇。
如果我的回答解决了您的问题,请采纳!

该回答引用ChatGPT
问题分析:
根据问题描述,当点击软键盘上的按钮时,TextBox输出对应键盘上的日语假名,但是输出的日文不是正确的,没有出现该日文的输入法关联词汇。具体来说,当点击按钮“ひ”和“゛”时,输出的日文是“ひ゛”,而正确的应该是“び”,并且出现这个“び”输入法关联的词汇。
这个问题的原因是,日语中有一些假名是由多个假名组合而成的,例如“び”就是由“ひ”和“゛”组合而成的。在输入法中,这些组合假名通常会被识别为一个单独的字符,而不是两个独立的字符。因此,当我们使用SendKeys发送“ひ”和“゛”时,输入法并不会将它们组合成“び”,而是将它们分别识别为“ひ”和“゛”,因此输出的日文是“ひ゛”,而不是“び”。
解决方案:
要解决这个问题,我们需要使用输入法的API来发送组合假名。具体来说,我们可以使用Windows API函数keybd_event来模拟按下和释放键盘上的按键,从而发送组合假名。
下面是一个示例代码,演示如何使用keybd_event发送“び”这个组合假名:

' 定义keybd_event函数的参数
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Integer, ByVal dwExtraInfo As Integer)
' 发送“び”这个组合假名
keybd_event(&H1E, 0, 0, 0) ' 发送“ひ”键
keybd_event(&HDE, 0, 0, 0) ' 发送“゛”键
keybd_event(&HDE, 0, &H2, 0) ' 释放“゛”键
keybd_event(&H1E, 0, &H2, 0) ' 释放“ひ”键

在这个示例代码中,我们首先定义了keybd_event函数的参数,然后使用它来发送“び”这个组合假名。具体来说,我们先发送“ひ”键,然后发送“゛”键,最后释放这两个键。这样,输入法就会将它们组合成“び”,并输出正确的日文。
需要注意的是,keybd_event函数发送的是键盘上的按键,而不是字符。因此,我们需要使用按键的虚拟键码来发送按键。在上面的示例代码中,&H1E表示“ひ”键的虚拟键码,&HDE表示“゛”键的虚拟键码。如果需要发送其他组合假名,可以根据需要修改这些虚拟键码。
另外,需要注意的是,keybd_event函数发送的按键是模拟的,不会真正地按下键盘上的按键。因此,如果需要在TextBox中输入日文,还需要使用SendKeys函数将组合假名发送到TextBox中。具体来说,可以使用以下代码将“び”这个组合假名发送到TextBox中:

' 发送“び”这个组合假名到TextBox中
keybd_event(&H1E, 0, 0, 0) ' 发送“ひ”键
keybd_event(&HDE, 0, 0, 0) ' 发送“゛”键
keybd_event(&HDE, 0, &H2, 0) ' 释放“゛”键
keybd_event(&H1E, 0, &H2, 0) ' 释放“ひ”键
SendKeys.SendWait("び") ' 发送“び”到TextBox中

在这个代码中,我们先使用keybd_event函数发送“び”这个组合假名,然后使用SendKeys函数将“び”发送到TextBox中。这样,就可以在TextBox中正确地输入日文了。
总结:
在VB.NET中使用日语软键盘时,如果需要发送组合假名,可以使用Windows API函数keybd_event来模拟按下和释放键盘上的按键,从而发送组合假名。需要注意的是,keybd_event函数发送的是键盘上的按键,而不是字符,因此还需要使用SendKeys函数将组合假名发送到TextBox中。不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

在实现软键盘输入日语假名时,可以考虑使用IME(输入法)的方式进行输入,这样可以更好地支持日语的输入法相关功能。下面是一个简单的实现方法:

在 VB.NET 中调用 ime.dll 库,使用 ime.dll 的 SetOpenStatus 函数来打开输入法(打开IME)。

通过 SendKeys 发送日语假名时,将其发送到输入框中,而不是直接发送到窗口。

在发送完日语假名后,使用 ime.dll 的 GetResultString 函数获取输入法输入的字符串,以支持输入法相关的功能。

该回答引用ChatGPT:您可以使用 SendInput 方法来模拟按下和释放键盘上的按键,以便正确地输入对应的日语假名,并在输入后出现输入法关联的词汇。以下是一个示例代码:

Imports System.Runtime.InteropServices

Public Class Form1
    Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Integer, ByVal dwExtraInfo As Integer)
    Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Integer)

    Private Const KEYEVENTF_KEYUP As Integer = &H2
    Private Const VK_LSHIFT As Byte = &HA0

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        SendInputMethod("あ")
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        SendInputMethod("か")
    End Sub

    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        SendInputMethod("さ")
    End Sub

    Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
        SendInputMethod("ひ")
    End Sub

    Private Sub SendInputMethod(ByVal str As String)
        ' 模拟按下 Shift 键
        keybd_event(VK_LSHIFT, 0, 0, 0)

        ' 模拟按下对应的键
        For Each c As Char In str
            System.Windows.Forms.SendKeys.SendWait(c)
        Next

        ' 模拟释放 Shift 键
        keybd_event(VK_LSHIFT, 0, KEYEVENTF_KEYUP, 0)

        ' 等待一段时间,以确保输入法可以正确地处理输入
        Sleep(50)

        ' 模拟按下 Enter 键,以便输入法能够显示出关联的词汇
        keybd_event(&HD, 0, 0, 0)
        keybd_event(&HD, 0, KEYEVENTF_KEYUP, 0)
    End Sub
End Class


这个示例代码使用了 keybd_event 函数来模拟按下和释放 Shift 键和 Enter 键,并使用 SendKeys.SendWait 方法来模拟按下对应的键。为了确保输入法可以正确地处理输入,代码还在每次输入后等待了一段时间,然后模拟按下 Enter 键,以便输入法能够显示出关联的词汇。