这是我的代码:
char *bufText = new char[256];
ListView_GetItemText(GetDlgItem(myWindow, MYLISTVIEW), myInt, 1, (LPTSTR)bufText, 256);
但是strlen(bufText)
等于1,唯一的字符
bufText
是列表视图子项的第一个。
我在这里做错了什么?
我认为问题在于您正在构建 Unicode 模式(自 VS2005 以来一直是默认模式),因此ListView_GetItemText()
向您发送了一个 Unicode 字符串,但您有一个mismatch,因为类型bufText
是char*
(即 ANSI/MBCS 字符串),而不是wchar_t*
(即 Unicode UTF-16 字符串)。
编译器正在帮助您,给您一条错误消息,因为您传递的是指向 ANSI/MBCS 字符串(char* bufText
参数)的指针,而不是wchar_t*
.
但是,您没有尝试听编译器,而是使用错误的类型转换将其关闭LPTSTR
(在 Unicode 构建中扩展为wchar_t*
)。
那么,为什么你只得到一个字符?
假设存储在列表视图控件中的文本(由 检索ListView_GetItemText()
)是"hello"
。
它在内存中的 Unicode 表示是:
68 00 65 00 6C 00 6C 00 6F 00 00 00
h e l l o NUL
(因为is的 Unicode UTF-16 表示,for h
is ,for is ,for is ;是 Unicode终止符。)0x0068
e
0x0065
l
0x006C
o
0x006F
0x0000
NUL
但是当您将上述字节序列解释为ANSI string时,ANSI 字符串的(单字节)终止符是(ASCII ) 字节之后的第一个字节,因此在 ANSI 中您只需得到:NUL
0x00
0x68
h
68 00 <---- ANSI stops at the *first* 0x00 byte
h \0
即"h"
ANSI 字符串,因此您只需获取初始 Unicode UTF-16 字符串的第一个字符。
我的建议是只迁移到现代软件中的 Unicode 构建。
此外,那些原始的类似 C 的字符数组不是现代 C++:它们不是异常安全的,而且您必须注意手动 delete[]
返回的指针等。
最好使用现代健壮的 RAII 容器,例如std::vector
or std::wstring
。
例如
#include <vector> // for std::vector
....
//
// Allocate a vector of 256 wchar_t's (so use Unicode).
//
// (Note: Memory is automatically cleaned up in the destructor,
// no need for *manual* delete[].)
//
std::vector<wchar_t> bufText( 256 );
//
// Get text from the list-view control.
//
ListView_GetItemText
(
GetDlgItem(myWindow, MYLISTVIEW),
myInt,
1,
&bufText[0], // <--- pointer to first character in the buffer
bufText.size() // <--- size of the buffer, in wchar_t's
);