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系统了吗?
- 如何查看腾讯课堂听课记录
- 海南经济特区万物互联通信工程有限公司_工商信用信息_经营范围期限状态_法人_地址_注册资本_怎么样
- 互联网创业平台有哪些 互联网金融创业有哪些方向
- 互联网时代如何找到心仪的工作
- 互联网时代,怎样健康地使用互联网?