api函数SetClipboardData可以往剪贴板中放置数据,它的函数语法如下:
HANDLE WINAPI SetClipboardData( _In_ UINT uFormat, _In_opt_ HANDLE hMem );
其中参数uFormat为要放置的数据的格式,具体的可以看剪贴板的标准数据格式。
hMem参数比较复杂,如果是要放置到剪贴板的数据是字符串数据,则hMem参数表示用于存放字符串数据的内存对象的句柄。
当我们往剪贴板中放置中文字符时,比如放置字符串”我和你”,用以下的代码:
Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long Declare Function SetClipboardData Lib "user32" (ByVal Format As Long, ByVal hMem As Long) As Long Declare Function CloseClipboard Lib "user32" () As Long Declare Function EmptyClipboard Lib "user32" () As Long Declare Function GlobalAlloc Lib "kernel32" (ByVal Flags As Long, ByVal length As Long) As Long Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal pDest As Long, ByVal pSource As Long, ByVal length As Long) Const CF_TEXT = 1 Const CF_UNICODETEXT = 13 Const GHND = &H42 Sub QQ1722187970() Dim str1 As String '要放到剪贴板中的字符串 str1 = "我和你" Dim hMem As Long '内存对象的句柄 hMem = GlobalAlloc(GHND, LenB(str1) + 2) Dim lHwnd As Long '锁定内存块,获取内存对象的第一个字节的内存地址 lHwnd = GlobalLock(hMem) '将字符串至于剪贴板内存中 CopyMemory lHwnd, StrPtr(str1), LenB(str1) + 2 '解锁内存块 GlobalUnlock (hMem) OpenClipboard (0) EmptyClipboard '关联剪贴板对象到指定的内存对象句柄 SetClipboardData CF_TEXT, hMem CloseClipboard Debug.Print VBA.Hex(lHwnd), VBA.Hex(StrPtr(str1)) End Sub
运行以上代码后,打开excel剪贴板,会发现剪贴板中显示的是乱码字符。
原因是我们设置的剪贴板数据格式不对,因为excel中字符串都是以unicode字符存储的,所以只需要把设置的剪贴板数据格式从CF_TEXT改成CF_UNICODETEXT即可。
也就是把以上代码中的
SetClipboardData CF_TEXT, hMem
改成
SetClipboardData CF_UNICODETEXT, hMem
即可避免乱码了,改后的代码如下:
Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long Declare Function SetClipboardData Lib "user32" (ByVal Format As Long, ByVal hMem As Long) As Long Declare Function CloseClipboard Lib "user32" () As Long Declare Function EmptyClipboard Lib "user32" () As Long Declare Function GlobalAlloc Lib "kernel32" (ByVal Flags As Long, ByVal length As Long) As Long Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal pDest As Long, ByVal pSource As Long, ByVal length As Long) Const CF_TEXT = 1 Const CF_UNICODETEXT = 13 Const GHND = &H42 Sub QQ1722187970() Dim str1 As String '要放到剪贴板中的字符串 str1 = "我和你" Dim hMem As Long '内存对象的句柄 hMem = GlobalAlloc(GHND, LenB(str1) + 2) Dim lHwnd As Long '锁定内存块,获取内存对象的第一个字节的内存地址 lHwnd = GlobalLock(hMem) '将字符串至于剪贴板内存中 CopyMemory lHwnd, StrPtr(str1), LenB(str1) + 2 '解锁内存块 GlobalUnlock (hMem) OpenClipboard (0) EmptyClipboard '关联剪贴板对象到指定的内存句柄 SetClipboardData CF_UNICODETEXT, hMem CloseClipboard Debug.Print VBA.Hex(lHwnd), VBA.Hex(StrPtr(str1)) End Sub
发表评论