原文地址:http://blog.163.com/skyshore@126/blog/static/133955136201010304444312/
(转载请注明出处!) 最近在更改我做的天笑XX软件软件时,发现VB6使用剪贴板的一个问题: 在VB6中复制一个字符串到Clipboard中一般用: Clipboard.Clear Clipboard.SetText sText
问题是:*有时*粘贴到记事本等其它软件中时会出现中文乱码,但复制到VB6或VB6生成的软件中一般不会有乱码。
问题的实质是:上述代码设置了CF_TEXT(ANSI)内容到Clipboard中,对于ANSI软件(如VB6中所用的TextBox控件)读取它没有问题;对于使用Unicode的软件,则受限于做复制时的输入法状态,即当复制时输入法为非中文(输入法状态栏显示的是非CN,如EN)时,粘贴后出现中文乱码。所以是“有时”出现乱码而有时正常。 网上搜索时,发现有人问过这问题,但都没有解决。可能这是用ANSI格式写剪贴板时常遇到的一个问题。
由于我搜索用UNICODE格式设置的方法,请参考: http://www.xtremevbtalk.com/showthread.php?t=265879 以上页面提供的代码是使用unicode格式进行复制(即指定CF_UNICODETEXT格式)。代码其实还是有一些小问题的,例如分配内容的长度等。 下面给出我的解决方案:(转载请注明出处!) 用ANSI复制,则会根据输入法状态在UNICODE软件中出现中文乱码问题;如果用UNICODE复制,则无法粘贴到ANSI软件中(如VB6制作的软件中出现"????")。所以我想到:两种格式一起设置,粘贴时可以各取所需!
Private Declare Function OpenClipboard Lib "user32" (ByVal hWnd As Long) As Long Private Declare Function SetClipboardData Lib "user32" (ByVal Format As Long, ByVal hMem As Long) As Long Private Declare Function CloseClipboard Lib "user32" () As Long Private Declare Function EmptyClipboard Lib "user32" () As Long Private Declare Function GlobalAlloc Lib "kernel32" (ByVal Flags As Long, ByVal length As Long) As Long Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal pDest As Long, ByVal pSource As Long, ByVal length As Long) Private Const CF_TEXT = 1 Private Const CF_UNICODETEXT = 13 Private Const GHND = &H42& ' hWnd 一般可用Me.HWnd,也可为0 Public Function ClipboardSetText(ByVal hWnd As Long, ByVal sText$) As Boolean Dim hMem As Long, pMem As Long, s$ Dim bOk As Boolean If OpenClipboard(hWnd) = 0 Then Exit Function EmptyClipboard ' ANSI s = StrConv(sText, vbFromUnicode) hMem = GlobalAlloc(GHND, LenB(s) + 1) pMem = GlobalLock(hMem) CopyMemory ByVal pMem, ByVal StrPtr(s), LenB(s) GlobalUnlock hMem bOk = SetClipboardData(CF_TEXT, hMem) <> 0 If Not bOk Then GlobalFree hMem ' UNICODE: hMem = GlobalAlloc(GHND, LenB(sText) + 2) pMem = GlobalLock(hMem) CopyMemory ByVal pMem, ByVal StrPtr(sText), LenB(sText) GlobalUnlock hMem bOk = SetClipboardData(CF_UNICODETEXT, hMem) <> 0 If Not bOk Then GlobalFree hMem CloseClipboard ClipboardSetText = bOk End Function Private Sub Command1_Click() MsgBox ClipboardSetText(Me.hWnd, Text1.Text) End Sub
|