SDK 实作VS2010复制中文乱码修复

本文介绍了在VS2010中复制包含中文字符的代码到Office应用时出现乱码的问题及解决方案。作者提供了两种修复方法,一种利用.NET的正则表达式类RegEx,另一种则是对比CF_UNICODETEXT和RTF数据进行修复。文章还展示了修复乱码的截图,并提供了源代码下载链接。
摘要由CSDN通过智能技术生成

      当复制VS2010中带有中文字符的代码到Office(Word, Excel, PowerPoint, Outlook)时,
在中文字符后面会被添加一到三个乱码。比如复制"中文字符",粘贴到word就会变成(中D文?字Á?符¤?)。

 

    通过黑暗执行绪的一篇文章提示,截取剪贴板中RTF(富文本格式)的数据流,并作出修复。该作者使用了 .NET中的正则表达式类RegEx来达到修复目的。方法调用很简单,感兴趣的可以搜索一下作者的博客空间。

 

      我这里给出另一个解决方法:同时截取CF_UNICODETEXTRTF两种剪贴板数据,以CF_UNICODETEXT中的正确数据为参照,对比剔除RTF中的乱码。

 

      写这份代码走了不少弯路,主要是一开始对RTF格式不熟悉,其中的中文接ASCII码处理着实让我差点抓破了头皮。

 

先给出乱码修复截图:

 

 

VS2010CopyModify

 

程序添加了全局热键 CTRL+Q 和 监测状态。右下角则是一个动态文字Logo,鼠标移上去就会出现Logo,

移开则改为快捷键说明。编译好的文件这里下载VS2010CopyModify.rar

 

      如果需要所有源文件,可以在我的资源空间下载VS2010CopyModify源文件

 

下面贴出程序的核心算法:

 

函数参数说明:

PTSTR        pText     (RTF数据首地址指针,切勿传递剪贴板内存,必须是程序拷贝剪贴板的。)

UINT          iText      (RTF数据大小。单位字节)

LPWSTR    pTextU   (CF_UNICODETEXT数据首地址指针,同上,不可为剪贴板内存。)

UINT          iTextU    (CF_UNICODETEXT数据大小。单位字符)

 

返回值类型  UINT      (修复完后RTF数据的大小。单位字节)


 

/*-------------------------------
  Repair.cpp - 实作乱码修正处理
  -------------------------------*/

#include <windows.h>
#include <string.h>

UINT ClobalRepair ( PTSTR pText , UINT iText , LPWSTR pTextU , UINT iTextU)
{
    const PTSTR   tZ = " // uinput2 // u" ,
                          tA = " // cf0 // par" ,
                          tP = " // par";
    TCHAR           AnsiT [ 11 ];
    PTSTR            pTextS  = pText ,
                           pTextW  = NULL ,
                          pAnsiT  = AnsiT;
    PTCHAR          pTextK  = NULL;
    UINT                i , iU , iC = 0 , iR = 0 ,
                          UTRange = 10;
    BOOL             bAnsi = FALSE;
    LPWSTR        pTextUW = pTextU;
    long int          iM;

    while( TRUE)
    {
        // 查找/uinput2/u
        pTextS = strstr( pTextS , tZ);
        if( pTextS == NULL)
            break;
        // 指向Unicode编码的首字节
        pTextS = & pTextS [ UTRange ];
        // 获取Unicode编码的十六进制值
        iM = strtol( pTextS , & pTextK , 10);
        // 修正负数补码的问题
        iM = iM & 0xFFFF;

        pTextS = pTextK;
        pTextS = & pTextS [ 1 ];
        pTextS [ 0 ] = ' ';
        pTextS = & pTextS [ 1 ];

        // 在Unicode数据中对焦中文字符
        for ( iU = 0; iU < iTextU; iU ++)
        {
            if( pTextUW [ iU ] == iM)
            {
                pTextUW = & pTextUW [ iU + 1 ];
                iTextU -= ( iU + 1);
                break;
            }
        }

        // 中文接中文的处理
        if ( pTextUW [ 0 ] > 0x80)
        {
            pTextW = strstr( pTextS , tZ);
            iC = pTextW - pTextS;
            i  = pTextS - pText;
            iR = i + iC;
            for ( i = 0; iR <= iText; i ++ , iR ++)
                pTextS [ i ] = pTextW [ i ];
            iText -= iC;
            continue;
        }
        // 文档尾的处理
        if( pTextUW [ 0 ] == NULL)
        {
            pTextW = strstr( pTextS , tP);
            iC = pTextW - pTextS;
            i  = pTextS - pText;
            iR = i + iC;
            for ( i = 0; iR <= iText; i ++ , iR ++)
                pTextS [ i ] = pTextW [ i ];
            iText -= iC;
            continue;
        }
        // 换行符、回车及水平制表
        if (
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值