c++ - GetWindowTextW 无法获取宽字符串

标签 c++ c winapi unicode widechar

我有以下代码,它从文本框输入获取数据(纯winapi)

BOOL CALLBACK DlgProc(HWND hw, UINT msg, WPARAM wp, LPARAM lp) {
    switch (msg)
    {
    case WM_INITDIALOG:
        SendDlgItemMessage(hw, IDC_EDITMASK, EM_SETLIMITTEXT, 512, 0);
        return true;

        case WM_CLOSE:
            DestroyWindow(hw);
            return TRUE; 


        case WM_COMMAND:
            HWND hCtrl;
            int length;
            wchar_t * text;
            switch (LOWORD(wp))
            {

                case IDCPROCESS:

                    nElements = 1;
                    hCtrl = GetDlgItem(hw, IDC_EDITMASK); 

                    length = GetWindowTextLengthW(hCtrl);        
                    if (length == 0) {
                        MessageBox(hw, L"Неверная маска", L"Ошибка", 0);
                        return FALSE;
                    }

                    text = (wchar_t*)HeapAlloc(hProcessHeap, HEAP_ZERO_MEMORY, length * sizeof(wchar_t) + sizeof(wchar_t));

                    GetWindowTextW(hCtrl, text, length + sizeof(wchar_t));

                    char *test = (char*)text;

                    int pos = 0;
                    int startPos = 0;
                    char dbg[2] = { 0 };
                    while (pos <= length) {
                        dbg[0] = text[pos];
                        OutputDebugStringA(dbg); // here i output the text by characters
                        if (text[pos] == ',' || pos == length) {

                            if(!szMasks)
                                szMasks = (wchar_t**)HeapAlloc(hProcessHeap, HEAP_ZERO_MEMORY, sizeof(wchar_t*)*nElements);
                            else
                                szMasks = (wchar_t**)HeapReAlloc(hProcessHeap, HEAP_ZERO_MEMORY,szMasks, sizeof(wchar_t*)*nElements);

                            int bufferSize = pos - startPos;
                            szMasks[nElements - 1] = (wchar_t*)HeapAlloc(hProcessHeap, HEAP_ZERO_MEMORY, (bufferSize + 2) * sizeof(wchar_t));
                            if(bufferSize % sizeof(wchar_t) != 0)
                                bufferSize++;
                            int copyLength = bufferSize / sizeof(wchar_t);

                            wcsncpy(szMasks[nElements - 1], text + startPos, copyLength);
                            OutputDebugStringW(szMasks[nElements - 1]);
                            OutputDebugStringW(L"\r\n");

                            nElements++;
                            startPos = pos+1;

                        }

                        pos++;
                    }

                    searchMasks.count = nElements-1;
                    searchMasks.szMasks = szMasks;

                    HeapFree(hProcessHeap, 0, text);
                    DestroyWindow(hw);

                    return TRUE;


            }
            break;



    case WM_DESTROY:
            PostQuitMessage(0);
            return TRUE;
    }

    return FALSE;
}

因此,例如,如果我输入俄语文本,我会得到有效的宽字符串,一切正常。如果我切换到英语,并输入“word”,我会在文本中得到缓冲区,它不是形成为宽字符串,我希望它是: “w\0o\0r\0d” 但我明白了 “词”

但是我得到了一个常规的char*字符串,这非常糟糕,因为我需要通过某种规则解析文本,搜索字符“,”并根据它将数据复制到另一个缓冲区,使用 wcsncpy ,所以我必须始终有一个正确格式的 wchar_t*字符串。有没有办法解决这个问题,为什么GetWindowTextW没有形成适当的宽字符串?我正在使用 UNICODE 编译我的项目字符集,而不是多字节。

更新了代码

char * test = (char*) text如果输入框中仅输入拉丁字符,而不是正确的格式,请给出有效的 ansi 字符串 wchar_t*

最佳答案

C 样式字符串是一个字符序列,以 NUL 字符结尾。第一个 NUL 字符中的任何内容都不被视为字符串的一部分。

当您使用 char[2] 类型的参数调用 OutputDebugStringA 时,其中第一个元素是 ASCII 字符,第二个字符是 \01 它被解释为长度为 1 的字符串。因此,您仅打印 ASCII 字符。

您正在处理宽字符串。您推断字符串类型的逻辑是错误的。

<小时/> 1 这就是 UTF-16LE 编码的 ASCII 字符在给定场景中的存储方式。

关于c++ - GetWindowTextW 无法获取宽字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38981867/

相关文章:

c++ - GetLogicalDrives 加上附加信息 C++

.net - .net for Win95?

c++ - C++ 的箭头 (->) 运算符的正式名称是什么?

c++ - 如何静态初始化包含 union 的结构数组?

c++ - 为什么 crtp 适用于结构而不适用于类?

c++ - 如何在 VS 2017 中为 C++ 添加单元测试?

c - 是否可以查看一个和零的二进制文件?

c - 如何将 GoLang 结构方法作为 C 回调传递

winapi - ListBox.FindString 最坏情况下的运行时间是什么? O(n)、O(n log n)、O(1)?

c++ - 如何将 DRY 原则应用于 C++ 中的迭代器? (迭代器、const_iterator、reverse_iterator、const_reverse_iterator)