GetWindowTextW 不获取宽字符串
GetWindowTextW doesnt grab a wide string
我有以下代码从文本框输入中获取数据(纯 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[=31=]o[=31=]r[=31=]d"
但我明白了
"word"
但是我得到了一个常规的 char*
字符串,这真的很糟糕,因为我需要按某种规则解析文本,搜索字符 ',' 并根据它复制数据到另一个缓冲区,使用 wcsncpy
,所以我必须始终拥有格式正确的 wchar_t*
字符串。有什么办法可以解决这个问题,为什么 GetWindowTextW
没有形成合适的宽字符串?我正在使用 UNICODE
字符集而不是多字节编译我的项目。
更新了代码
char * test = (char*) text
给一个有效的 ansi 字符串,如果在输入框中只输入拉丁字符,格式不正确 wchar_t*
您的 text
变量是一个 wchar_t
指针(即使未显示定义),因此当然任何显示它的尝试都会显示整个 UTF-16 字符。如果您正在检查 char *
缓冲区,您只会得到嵌入的 [=12=]
字符,因为它会将每个 wchar_t
单元分成多个部分。
基于更新后的代码...
当您为应该为零的字节之一调用 OutputDebugStringA 时,您将看不到任何输出。您已经有效地打印了一个空字符串。所以它看起来好像零字节不存在,但它们确实存在。
C 风格字符串是一个字符序列,以 NUL
字符结尾。从第一个 NUL
字符开始的任何内容都不会被视为字符串的一部分。
当您使用 char[2]
类型的参数调用 OutputDebugStringA
时,其中第一个元素是 ASCII 字符,第二个字符是 [=14=]
1 它被解释为长度为 1 的字符串。因此,您只打印 ASCII 字符。
您正在处理宽字符串。你推断字符串类型的逻辑是错误的。
1 这就是 UTF-16LE 编码的 ASCII 字符在给定场景中的存储方式。
我有以下代码从文本框输入中获取数据(纯 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[=31=]o[=31=]r[=31=]d" 但我明白了 "word"
但是我得到了一个常规的 char*
字符串,这真的很糟糕,因为我需要按某种规则解析文本,搜索字符 ',' 并根据它复制数据到另一个缓冲区,使用 wcsncpy
,所以我必须始终拥有格式正确的 wchar_t*
字符串。有什么办法可以解决这个问题,为什么 GetWindowTextW
没有形成合适的宽字符串?我正在使用 UNICODE
字符集而不是多字节编译我的项目。
更新了代码
char * test = (char*) text
给一个有效的 ansi 字符串,如果在输入框中只输入拉丁字符,格式不正确 wchar_t*
您的 text
变量是一个 wchar_t
指针(即使未显示定义),因此当然任何显示它的尝试都会显示整个 UTF-16 字符。如果您正在检查 char *
缓冲区,您只会得到嵌入的 [=12=]
字符,因为它会将每个 wchar_t
单元分成多个部分。
基于更新后的代码...
当您为应该为零的字节之一调用 OutputDebugStringA 时,您将看不到任何输出。您已经有效地打印了一个空字符串。所以它看起来好像零字节不存在,但它们确实存在。
C 风格字符串是一个字符序列,以 NUL
字符结尾。从第一个 NUL
字符开始的任何内容都不会被视为字符串的一部分。
当您使用 char[2]
类型的参数调用 OutputDebugStringA
时,其中第一个元素是 ASCII 字符,第二个字符是 [=14=]
1 它被解释为长度为 1 的字符串。因此,您只打印 ASCII 字符。
您正在处理宽字符串。你推断字符串类型的逻辑是错误的。
1 这就是 UTF-16LE 编码的 ASCII 字符在给定场景中的存储方式。