我正在尝试使用ListView_GetItemText()
获取ListView子项的文本值
这是我的代码:
char *bufText = new char[256];
ListView_GetItemText(GetDlgItem(myWindow, MYLISTVIEW), myInt, 1, (LPTSTR)bufText, 256);
myInt
是列表视图中一行的索引。
但strlen(bufText)
等于1,bufText
中唯一的字符是list-view子项的第一个字符。
我在这里做错了什么?
答案 0 :(得分:4)
这是我的代码:
char *bufText = new char[256]; ListView_GetItemText(GetDlgItem(myWindow, MYLISTVIEW), myInt, 1, (LPTSTR)bufText, 256);
但
strlen(bufText)
等于1,是唯一的字符bufText
是list-view子项的第一个。我在这里做错了什么?
我认为问题在于你以Unicode模式构建(这是自VS2005以来的默认设置),所以ListView_GetItemText()
向你发送了一个Unicode字符串,但你有一个< strong> 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
(因为h
的Unicode UTF-16表示为0x0068
,e
的{{1}}为0x0065
,l
的{{1}}为0x006C
, o
是0x006F
; 0x0000
是Unicode NUL
终止符。)
但是当将上述字节序列解释为 ANSI字符串时,ANSI的(单字节)NUL
终止符string是0x00
(ASCII 0x68
)字节后面的第一个 h
字节,所以在ANSI中你只得到:
68 00 <---- ANSI stops at the *first* 0x00 byte
h \0
即。 "h"
ANSI字符串,因此您只需获取初始Unicode UTF-16字符串的第一个字符。
我的建议是转到现代软件中的Unicode版本。
此外,那些原始C类数组字符不是现代C ++:它们不是异常安全的,而且你必须注意手动 {{1返回的指针等。
最好使用现代强大的RAII容器,例如delete[]
或std::vector
。
e.g。
std::wstring
答案 1 :(得分:2)
您正在使用Unicode构建,但是向控件传递(使用强制转换)ANSI缓冲区。改变自:
char* bufText = new char[256];
为:
wchar_t* bufText = new wchar_t[256];
(或者,如果您特别想使用ANSI,请发送LVM_GETITEMTEXTA
消息而不是使用宏。)