微光互聯 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());}

推薦閱讀