windows 上编码转换都是先转到 unicode,再转其它编码,比较好理解 。那么 demo 中的输出就可以改为:
std::string gb2312 = utf8_to_gb2312(std::string((char *)readBuffers, datalen));printf("%.*s\n", gb2312.lenght(), gb2312.c_str());再次运行:
二维码长度:10京MD0926恢复正常!
输出到剪贴板上面的过程虽然能正确解析 utf-8 数据了,但还需要用户复制 console 输出的结果,很不方便 , 如果能将结果直接输出到剪贴板上岂不是很爽?说干就干:
void copy_to_system_clipboard(std::string const& data){    printf("ready to copy data: %s\n", data.c_str());    BOOL ret = OpenClipboard(NULL);    if (!ret)    {        printf("open clipboard failed\n");        return;    }    do    {        ret = EmptyClipboard();        if (!ret)        {            printf("empty clipboard failed\n");            break;        }        HGLOBAL hdata = GlobalAlloc(GMEM_MOVEABLE, data.length() + 1);        if (hdata == NULL)        {            printf("alloc data for clipboard failed");            break;        }        char* str = (char *) GlobalLock(hdata);        memcpy(str, data.c_str(), data.length());        str[data.length()] = 0;        GlobalUnlock(hdata);         // HANDLE h = SetClipboardData(CF_UNICODETEXT, hdata);        HANDLE h = SetClipboardData(CF_TEXT, hdata);        if (!h)        {            printf("set clipboard data failed");            break;        }        printf("copy to clipboard ok\n");    } while (0);    CloseClipboard();}基本上是抄了网上一个例子实现的,只是增加了一些错误提示 。调用点稍微改造就大功告成:
printf("%.*s\n", datalen, readBuffers);std::string gb2312 = utf8_to_gb2312(std::string((char *)readBuffers, datalen));copy_to_system_clipboard(gb2312);再次运行:
二维码长度:10浜琈D0926ready to copy data: 京MD0926copy to clipboard ok此时在任一文本框中按 Ctrl+V,均能得到号牌数据 。
这里请注意 copy_to_system_clipboard 中的 SetClipboardData 调用 , 使用 CF_TEXT 而不是 CF_UNICODETEXT,否则会得到下面的乱码输出:
????另外测试中发现可以同时启动多个 demo,相互之间不冲突,均能从接口拿到扫描后的数据,神奇 。
输出到当前光标上面的解决方案已经很好了,但是如果能像之前一样输出到光标就更棒了,用户可以无疑切换 。作为资深 MFCer,立刻想到了一种解决方案:查找当前桌面前台 (Foreground) 窗口,找到它的活动子窗口并投递 WM_SETTEXT 消息 。下面是参考网上一个例子的实现:
void set_text_to_active_windows(std::string const& data){    int ret = 0;    std::wstring unicode;    HWND wnd = GetForegroundWindow();    //HWND wnd = GetActiveWindow();    //HWND wnd = GetDesktopWindow();    if (wnd == NULL)    {        printf("no active windows\n");        return;    }    printf("get active window\n");    DWORD SelfThreadId = GetCurrentThreadId();    DWORD ForeThreadId = GetWindowThreadProcessId(wnd, NULL);    if (!AttachThreadInput(ForeThreadId, SelfThreadId, true))    {        printf("attach thread input failed\n");        return;    }    printf("attach thread input\n");    //wnd = GetFocus();    wnd = GetActiveWindow();    if (wnd == NULL)    {        printf("no focus windows\n");        return;    }    printf("get focus window\n");    AttachThreadInput(ForeThreadId, SelfThreadId, false);    unicode = gb2312_to_unicode(data);    ret = SendMessage(wnd, WM_SETTEXT, 0, (LPARAM)unicode.c_str());    printf("send text to active window return %d: %s\n", ret, data.c_str());}
推荐阅读
- 通过openlayers加载dwg格式的CAD图并与互联网地图叠加
 - vivo互联网机器学习平台的建设与实践
 - Go的网络编程详解
 - MES与工业互联网的关联边界在哪里?
 - 工业互联网领域的企业,都已经接入了ERP或者MES系统了吗?
 - 如何查看腾讯课堂听课记录
 - 海南经济特区万物互联通信工程有限公司_工商信用信息_经营范围期限状态_法人_地址_注册资本_怎么样
 - 互联网创业平台有哪些 互联网金融创业有哪些方向
 - 互联网时代如何找到心仪的工作
 - 互联网时代,怎样健康地使用互联网?
 
