微光互联 TX800-U 扫码器无法输出中文到光标的问题( 三 )

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());}

推荐阅读