【问题标题】:How do I display a messagebox with unicode characters in VBA?如何在 VBA 中显示带有 unicode 字符的消息框?
【发布时间】:2019-08-08 04:03:34
【问题描述】:

我在 VBA 中有一个包含 unicode 字符的字符串。

我想在包含它的消息框中显示该字符串。

但是,消息框只包含一个问号,而不是字符串。

MCVE:

Dim s As String
s = ChrW(5123)
MsgBox s

【问题讨论】:

  • 调度适用于all appname-vba标签; Excel 是第一个。
  • @Martijn 你能提供一个来源吗?据我所知,Shog9 说他们 can 将计划扩展到这些其他标签,并明确告诉我 Access 将在 之后 excel-vba here 被触及。由于access 标记,与access-vba 标记混淆尤其成问题。
  • 我知道access 问题并一直在解决这个问题。无论如何,对于access-vba,我认为我无法解决任何严重问题,因为有over 5k posts tagged access-vba but missing the vba tag,这是我下一步必须清理的一个组合(将access-vba 合并到ms-access) 甚至可以工作。
  • -vba 标签的整个家族长期以来一直是一个大问题,这就是我现在手动驱动它的原因。虽然access-vba 得到了暂停执行,但只有在 CM 重新获得再次正确地进行标记燃烧的能力之前(Shog 和 Jon,他们都走了,是唯一知道如何并有权访问它的人)。
  • access 很快就会消失。也许今天。至少这是一个好的开始。

标签: vba ms-access


【解决方案1】:

MsgBox 与非 ANSI unicode 字符不兼容。

但是,我们可以使用 WinAPI MessageBoxW 函数显示消息框,那就是。

让我们声明该函数,然后为其创建一个与 VBA MsgBox 函数几乎相同的包装器:

Private Declare PtrSafe Function MessageBoxW Lib "User32" (ByVal hWnd As LongPtr, ByVal lpText As LongPtr, ByVal lpCaption As LongPtr, ByVal uType As Long) As Long

Public Function MsgBoxW(Prompt As String, Optional Buttons As VbMsgBoxStyle = vbOKOnly, Optional Title As String = "Microsoft Access") As VbMsgBoxResult
    MsgBoxW = MessageBoxW(Application.hWndAccessApp, StrPtr(Prompt), StrPtr(Title), Buttons)
End Function

此功能仅与 Microsoft Access 兼容。但是,对于 Excel,您可以将 Application.hWndAccessAppApplication.hWnd 交换以使其正常工作。对于其他 VBA 兼容的应用程序,您必须找到适当的方法来获取 hWnd。

你可以像MsgBox一样使用它,只要你不使用上下文相关的帮助功能:

Dim s As String
s = ChrW(5123)
MsgBoxW s

【讨论】:

  • 不需要添加vbNullChar。我在 Word 和 Excel 中使用 Application.ActiveWindow.hWnd 而不是 Application.hWndAccessApp
  • VBA 字符串作为 COM BSTR 存储在内存中。它由一个 4 字节的无符号整数组成,它以字节为单位存储字符串的长度,后跟作为宽字符(每个字符 2 个字节)的字符串数据本身,并以 2 个空字节结尾。因此,BSTR 字符串以长度为前缀并以空值结尾。 StrPtr()函数检索到的内部指针指向的是字符串数据的内存位置,而不是长度前缀。这意味着 VBA 字符串 vbastr 可以通过 StrPtr(vbastr) 直接传递给需要指向以空字符结尾的 C 字符串的指针的 API 函数。
  • 啊,你是对的,谢谢。我不知道BSTR 除了预先指定长度之外还包含一个空终止符,一直认为具有指定长度的字符串不包含它。我已经编辑了答案。
  • @DietrichBaumgarten 实际上 ActiveWindow.hWnd 就足够了(Microsoft Word)。虽然可以在对象浏览器中搜索)________________________________________________________________________________ 在旧版本中可能无法访问,在这种情况下也可以使用 NULL (0) -- 请参阅MessageBoxW documentation
  • @user202729 请注意,我强烈建议传递一个 hWnd。如果您传递 NULL,则窗口可以在当前窗口之后打开,同时仍然是同步的,因此锁定了应用程序,这对于没有注意到消息框的用户来说可能会非常混乱。如果您使用的应用程序不提供 hWnd,则可以使用 WinAPI 检索它,请参阅stackoverflow.com/questions/2620409
【解决方案2】:

我的ModernBox

MsgMox ChrW(5125) & ChrW(5123) & ChrW(5121) & ChrW(5130), vbInformation, "Unicode"

显示:

【讨论】:

    猜你喜欢
    • 2015-12-18
    • 1970-01-01
    • 1970-01-01
    • 2017-08-30
    • 2013-05-20
    • 1970-01-01
    • 1970-01-01
    • 2013-07-15
    相关资源
    最近更新 更多