gpt4 book ai didi

excel - VBA 中的 UTF-8 字符 Shell_NotifyIconW

转载 作者:行者123 更新时间:2023-12-04 22:18:10 30 4
gpt4 key购买 nike

Shell_NotifyIcon Windows API 将消息发送到任务栏的状态区域。
我正在寻找一种使 Windows 通知 API 与 UTF-8 字符一起工作的方法。
下面的代码运行良好,但仅适用于 ANSI 字符。
UTF-8 字符显示为“??”。

Option Explicit
Private Declare PtrSafe Function Shell_NotifyIconA Lib "shell32.dll" (ByVal dwMessage As Long, ByRef nfIconData As NOTIFYICONDATA) As LongPtr
Public nfIconData As NOTIFYICONDATA
Private Type NOTIFYICONDATA
cbSize As Long
hwnd As LongPtr
uID As Long
uFlags As Long
uCallbackMessage As Long
hIcon As LongPtr
szTip As String * 128
dwState As Long
dwStateMask As Long
szInfo As String * 256
uTimeout As Long
szInfoTitle As String * 64
dwInfoFlags As Long
End Type
Public Function toast(Optional ByVal title As String, Optional ByVal info As String, Optional ByVal flag As Long)
With nfIconData
.dwInfoFlags = flag
.uFlags = &H10
.szInfoTitle = title
.szInfo = info
.cbSize = &H1F8
End With
Shell_NotifyIconW &H0, nfIconData
Shell_NotifyIconW &H1, nfIconData
End Function
'Flags for the balloon message..
'None = 0
'Information = 1
'Exclamation = 2
'Critical = 3
Sub TestANSI()
toast "Hi"
End Sub

Sub testUTF8()
toast ChrW(55357) & ChrW(56397)
End Sub
只需将 Windows API 声明中的 A 更改为 W 并不能解决此问题。
有人有使用 Shell_NotifyIconW 处理 UTF-8 字符的经验吗?
我已经尝试使用下面的代码,但它不起作用。
Option Explicit
Private Declare PtrSafe Function Shell_NotifyIconW Lib "shell32.dll" (ByVal dwMessage As Long, ByRef nfIconData As NOTIFYICONDATA) As LongPtr
Public nfIconData As NOTIFYICONDATA
Private Type NOTIFYICONDATA
cbSize As Long
hwnd As LongPtr
uID As Long
uFlags As Long
uCallbackMessage As Long
hIcon As LongPtr
szTip As String * 128
dwState As Long
dwStateMask As Long
szInfo As String * 256
uTimeout As Long
szInfoTitle As String * 64
dwInfoFlags As Long
End Type
Public Function toast(Optional ByVal title As String, Optional ByVal info As String, Optional ByVal flag As Long)
With nfIconData
.dwInfoFlags = flag
.uFlags = &H10
.szInfoTitle = title
.szInfo = info
.cbSize = &H1F8
End With
Shell_NotifyIconW &H0, nfIconData
Shell_NotifyIconW &H1, nfIconData
End Function
'Flags for the balloon message..
'None = 0
'Information = 1
'Exclamation = 2
'Critical = 3

Sub TestANSI()
toast "Hi"
End Sub
Sub testUTF8()
toast ChrW(55357) & ChrW(56397)
End Sub

最佳答案

Unicode 和 UTF-8 不是可互换的术语(请参阅 https://www.joelonsoftware.com/articles/Unicode.html)。一个是一个概念,另一个是坚持这个概念的一种方式。W Windows 中的函数使用 UTF-16 形式的 Unicode,因此您希望以这种方式为它们提供 Unicode。
您的AW版本未正确声明,您想先修复它。
然后,对于 W函数,你必须避免 implicit string conversion VB 执行,为此您需要将固定长度的字符串声明为字节数组。因为 VB 字符串在 UTF-16 中已经是 Unicode,这就是 W函数期望,您只需将这些字符串中的字节复制到这些字节数组中。不需要转换,但您需要小心将每个字符串中的最后两个字节保留为零。
请注意,与 A 不同。函数,W函数要求您同时提供标题和信息(在文档中为 called out)。如果您只提供一个,它将不会显示。
另请注意,不幸的是 VBA does not provide correct padding用于 64 位的结构成员,这严重破坏了 LongPtr 的有用性,因此您需要自己提供。

Option Explicit

Private Declare PtrSafe Function Shell_NotifyIconW Lib "shell32.dll" (ByVal dwMessage As Long, ByRef nfIconData As NOTIFYICONDATAW) As Long
Private Declare PtrSafe Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)

Private Type NOTIFYICONDATAW
cbSize As Long
#If Win64 Then
padding1 As Long
#End If
hwnd As LongPtr
uID As Long
uFlags As Long
uCallbackMessage As Long
#If Win64 Then
padding2 As Long
#End If
hIcon As LongPtr
szTip(1 To 128 * 2) As Byte
dwState As Long
dwStateMask As Long
szInfo(1 To 256 * 2) As Byte
uTimeout As Long
szInfoTitle(1 To 64 * 2) As Byte
dwInfoFlags As Long
End Type

Private Const NIM_ADD As Long = &H0&
Private Const NIM_MODIFY As Long = &H1&
Private Const NIF_INFO As Long = &H10&

Private Function Min(ByVal a As Long, ByVal b As Long) As Long
If a < b Then Min = a Else Min = b
End Function

Public Sub Toast(Optional ByVal title As String, Optional ByVal info As String, Optional ByVal flag As Long)
Dim nfIconData As NOTIFYICONDATAW

With nfIconData
.cbSize = Len(nfIconData)

.uFlags = NIF_INFO
.dwInfoFlags = flag

If Len(title) > 0 Then
CopyMemory ByVal VarPtr(.szInfoTitle(LBound(.szInfoTitle))), ByVal StrPtr(title), Min(Len(title) * 2, UBound(.szInfoTitle) - LBound(.szInfoTitle) + 1 - 2)
End If

If Len(info) > 0 Then
CopyMemory ByVal VarPtr(.szInfo(LBound(.szInfo))), ByVal StrPtr(info), Min(Len(info) * 2, UBound(.szInfo) - LBound(.szInfo) + 1 - 2)
End If
End With

Shell_NotifyIconW NIM_ADD, nfIconData
Shell_NotifyIconW NIM_MODIFY, nfIconData
End Sub
Toast ChrW$(55357) & ChrW$(56397), ChrW$(55357) & ChrW$(56397)

关于excel - VBA 中的 UTF-8 字符 Shell_NotifyIconW,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66735856/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com