[心缘地方]同学录
首页 | 功能说明 | 站长通知 | 最近更新 | 编码查看转换 | 代码下载 | 常见问题及讨论 | 《深入解析ASP核心技术》 | 王小鸭自动发工资条VBA版
登录系统:用户名: 密码: 如果要讨论问题,请先注册。

[转帖]解决VB6中剪贴板Clipboard编程出现中文乱码的问题

上一篇:[转帖]Table编辑时,Ctrl+A全选的实现
下一篇:[转帖]如何刷新Project Explorer视图。How to force a refresh on the Project Explorer view?

添加日期:2011/5/16 10:41:47 快速返回   返回列表 阅读5368次
原文地址: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

 

评论 COMMENTS
没有评论 No Comments.

添加评论 Add new comment.
昵称 Name:
评论内容 Comment:
验证码(不区分大小写)
Validation Code:
(not case sensitive)
看不清?点这里换一张!(Change it here!)
 
评论由管理员查看后才能显示。the comment will be showed after it is checked by admin.
CopyRight © 心缘地方 2005-2999. All Rights Reserved